242 lines
7.3 KiB
Dart
242 lines
7.3 KiB
Dart
import 'dart:async';
|
|
import 'package:firebase_auth/firebase_auth.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:hum/core/constants/app_theme.dart';
|
|
import 'package:hum/views/auth/auth_view.dart';
|
|
import 'package:hum/views/home/home_view.dart';
|
|
import 'package:hum/views/home/modes/home_map.dart';
|
|
import 'package:hum/views/listings/views/new/drawer_new_item.dart';
|
|
|
|
import 'package:firebase_core/firebase_core.dart';
|
|
import 'package:hum/views/notifications/view_notifications.dart';
|
|
import 'package:hum/views/profile/profile_view.dart';
|
|
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
|
|
import 'package:phosphor_flutter/phosphor_flutter.dart';
|
|
import 'firebase_options.dart';
|
|
import 'package:firebase_remote_config/firebase_remote_config.dart';
|
|
|
|
Future<void> setupRemoteConfig() async {
|
|
final remoteConfig = FirebaseRemoteConfig.instance;
|
|
|
|
await remoteConfig.setConfigSettings(
|
|
RemoteConfigSettings(
|
|
fetchTimeout: const Duration(minutes: 1),
|
|
minimumFetchInterval: kDebugMode
|
|
? const Duration(seconds: 10) // Dev: 10 seconds
|
|
: const Duration(hours: 5), // Prod: 5 hours
|
|
),
|
|
);
|
|
|
|
// 2. Set default values
|
|
// If the fetch fails (e.g., no internet), the app will use this backup URL.
|
|
await remoteConfig.setDefaults(const {
|
|
"fn_ai_parse_image": "https://us-central1-hum-app-d68e3.cloudfunctions.net/humprocessimage",
|
|
});
|
|
|
|
// 3. Fetch and Activate
|
|
// This pulls the latest values from the cloud and makes them available to the app.
|
|
try {
|
|
await remoteConfig.fetchAndActivate();
|
|
print('Remote Config fetched and activated');
|
|
} catch (e) {
|
|
print('Failed to fetch remote config: $e');
|
|
}
|
|
}
|
|
|
|
void main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
|
|
|
// Increase image cache size for better performance
|
|
PaintingBinding.instance.imageCache.maximumSize = 200; // Default is 1000
|
|
PaintingBinding.instance.imageCache.maximumSizeBytes = 150 << 20; // 150 MB (default is 100 MB)
|
|
|
|
// Pulls the remote config
|
|
await setupRemoteConfig();
|
|
|
|
// Activates the App
|
|
runApp(const HUMApp());
|
|
}
|
|
|
|
class HUMApp extends StatelessWidget {
|
|
const HUMApp({super.key});
|
|
|
|
// This widget is the root of your application.
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return CupertinoApp(
|
|
title: 'Flutter Demo',
|
|
debugShowCheckedModeBanner: false,
|
|
theme: CupertinoThemeData(
|
|
brightness: Brightness.dark,
|
|
// primaryColor: colorAccentPrimary,
|
|
barBackgroundColor: colorBarBackground,
|
|
scaffoldBackgroundColor: colorBackground,
|
|
),
|
|
// home: const HomeView(),
|
|
home: RootTabs(),
|
|
);
|
|
}
|
|
}
|
|
|
|
class RootTabs extends StatefulWidget {
|
|
const RootTabs({super.key});
|
|
@override
|
|
State<RootTabs> createState() => _RootTabsState();
|
|
}
|
|
|
|
class _RootTabsState extends State<RootTabs> {
|
|
int _index = 0;
|
|
StreamSubscription<User?>? _userSubscription;
|
|
bool _userIsLoggedIn = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_userSubscription = FirebaseAuth.instance.authStateChanges().listen((user) {
|
|
if (!mounted) return;
|
|
if (user == null) {
|
|
setState(() {
|
|
_userIsLoggedIn = false;
|
|
});
|
|
} else {
|
|
setState(() {
|
|
_userIsLoggedIn = true;
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_userSubscription?.cancel();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Stack(
|
|
alignment: Alignment.bottomCenter,
|
|
children: [
|
|
CupertinoTabScaffold(
|
|
tabBar: CupertinoTabBar(
|
|
backgroundColor: CupertinoDynamicColor.resolve(colorBackground, context),
|
|
activeColor: CupertinoDynamicColor.resolve(colorAccentSecondary, context),
|
|
// height: 58,
|
|
currentIndex: _index,
|
|
onTap: (i) {
|
|
if (i == 2) {
|
|
return;
|
|
}
|
|
setState(() => _index = i);
|
|
},
|
|
items: [
|
|
buildTabItem(
|
|
PhosphorIcons.house(
|
|
(_index == 0) ? PhosphorIconsStyle.fill : PhosphorIconsStyle.duotone,
|
|
),
|
|
'Home',
|
|
),
|
|
buildTabItem(
|
|
PhosphorIcons.mapPin(
|
|
(_index == 1) ? PhosphorIconsStyle.fill : PhosphorIconsStyle.duotone,
|
|
),
|
|
'Messages',
|
|
),
|
|
buildTabItem(CupertinoIcons.rectangle_expand_vertical, ''),
|
|
buildTabItem(
|
|
PhosphorIcons.chatCircle(
|
|
(_index == 3) ? PhosphorIconsStyle.fill : PhosphorIconsStyle.duotone,
|
|
),
|
|
'Notifications',
|
|
),
|
|
buildTabItem(
|
|
PhosphorIcons.userCircle(
|
|
(_index == 4) ? PhosphorIconsStyle.fill : PhosphorIconsStyle.duotone,
|
|
),
|
|
'Profile',
|
|
),
|
|
],
|
|
),
|
|
tabBuilder: (context, index) {
|
|
return CupertinoTabView(
|
|
builder: (context) {
|
|
switch (index) {
|
|
case 0:
|
|
return const HomeView();
|
|
case 1:
|
|
return _userIsLoggedIn ? const HomeViewMap() : const AuthView();
|
|
case 2:
|
|
return const HomeView();
|
|
case 3:
|
|
return _userIsLoggedIn ? const ViewNotifications() : const AuthView();
|
|
case 4:
|
|
return _userIsLoggedIn ? const ProfileView() : const AuthView();
|
|
default:
|
|
return const HomeView();
|
|
}
|
|
},
|
|
);
|
|
},
|
|
),
|
|
|
|
// 👇 Floating round button
|
|
Positioned(
|
|
bottom: 30, // distance from bottom nav
|
|
child: GestureDetector(
|
|
onTap: () {
|
|
showCupertinoModalBottomSheet(
|
|
topRadius: Radius.circular(radiusCards),
|
|
useRootNavigator: true,
|
|
isDismissible: true,
|
|
context: context,
|
|
builder: (context) => Container(
|
|
height: MediaQuery.of(context).size.height,
|
|
color: CupertinoDynamicColor.resolve(colorBarBackground, context),
|
|
child: DrawerNewItem(),
|
|
),
|
|
);
|
|
},
|
|
child: Container(
|
|
height: 56,
|
|
width: 56,
|
|
decoration: BoxDecoration(color: CupertinoColors.activeGreen, shape: BoxShape.circle),
|
|
child: const Icon(
|
|
CupertinoIcons.add,
|
|
color: CupertinoColors.white,
|
|
size: 28,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
BottomNavigationBarItem buildTabItem(IconData icon, String label) {
|
|
return BottomNavigationBarItem(
|
|
icon: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 5.0, bottom: 1.0),
|
|
child: PhosphorIcon(
|
|
icon,
|
|
// color: Colors.green,
|
|
size: 30.0,
|
|
),
|
|
),
|
|
// Text(
|
|
// label,
|
|
// style: TextStyle(
|
|
// fontSize: 10,
|
|
// ),
|
|
// ),
|
|
],
|
|
),
|
|
);
|
|
}
|