Initial commit

This commit is contained in:
Yas Opisso
2025-12-12 14:31:36 -05:00
commit 83775bdc72
175 changed files with 17284 additions and 0 deletions

241
lib/main.dart Normal file
View File

@@ -0,0 +1,241 @@
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,
// ),
// ),
],
),
);
}