import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart' as fr; import 'package:go_router/go_router.dart'; import 'package:logging/logging.dart'; import 'package:media_kit/media_kit.dart'; import 'package:multi_trigger_autocomplete/multi_trigger_autocomplete.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:path_provider/path_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'app_theme.dart'; import 'data/objectbox/objectbox_cache.dart'; import 'globals.dart'; import 'riverpod_controllers/account_services.dart'; import 'riverpod_controllers/globals_services.dart'; import 'riverpod_controllers/log_service.dart'; import 'riverpod_controllers/settings_services.dart'; import 'routes.dart'; import 'services/secrets_service.dart'; import 'utils/app_scrolling_behavior.dart'; import 'utils/old_android_letsencrypte_cert.dart'; final preInitializationLogEventQueue = []; void main() async { WidgetsFlutterBinding.ensureInitialized(); MediaKit.ensureInitialized(); // await dotenv.load(fileName: '.env'); Logger.root.level = Level.OFF; await fixLetsEncryptCertOnOldAndroid(); await setupPackageInfoAndUserAgent(); final prefs = await SharedPreferences.getInstance(); final appSupportDir = await getApplicationSupportDirectory(); final objectBoxCache = await ObjectBoxCache.create(); final secretsService = SecretsService(); await secretsService.initialize(); // TODO Add back Device Preview once supported in Flutter 3.22+ // runApp(DevicePreview( // enabled: !kReleaseMode && enablePreview, // builder: (context) => const App(), // )); runApp( fr.ProviderScope( overrides: [ sharedPreferencesProvider.overrideWithValue(prefs), applicationSupportDirectoryProvider.overrideWithValue(appSupportDir), secretsServiceProvider.overrideWithValue(secretsService), userAgentProvider.overrideWithValue('Relatica/$appVersion'), objectBoxCacheProvider.overrideWithValue(objectBoxCache), ], child: const App(), ), ); } Future setupPackageInfoAndUserAgent() async { PackageInfo packageInfo = await PackageInfo.fromPlatform(); appVersion = packageInfo.version; } class App extends fr.ConsumerStatefulWidget { const App({super.key}); // This widget is the root of your application. @override fr.ConsumerState createState() => _AppState(); } class _AppState extends fr.ConsumerState { @override void initState() { super.initState(); Future.delayed(const Duration(), ref.read(accountServicesInitializerProvider.notifier).initialize); } @override Widget build(BuildContext context) { ref.watch(accountServicesInitializerProvider); ref.watch(activeProfileProvider); ref.watch(logServiceProvider); final appRouter = GoRouter( initialLocation: ScreenPaths.timelines, debugLogDiagnostics: true, // refreshListenable: authService, redirect: (context, state) async { final loggedIn = ref.watch(activeProfileProvider.notifier).hasActiveProfile; final initializing = !ref.watch(accountServicesInitializerProvider.notifier).initialized; if (!loggedIn && initializing && state.matchedLocation != ScreenPaths.splash) { return ScreenPaths.splash; } if (!loggedIn && !allowedLoggedOut.contains(state.uri.toString())) { return ScreenPaths.signin; } if (loggedIn && allowedLoggedOut.contains(state.uri.toString())) { return ScreenPaths.timelines; } return null; }, routes: routes, ); Logger.root.level = ref.read(logLevelSettingProvider); return Portal( child: MaterialApp.router( // TODO Add back Device Preview once supported in Flutter 3.22+ // locale: DevicePreview.locale(context), // builder: DevicePreview.appBuilder, theme: buildTheme( brightness: Brightness.light, blindnessType: ref.watch(colorBlindnessTestingModeSettingProvider), ), darkTheme: buildTheme( brightness: Brightness.dark, blindnessType: ref.watch(colorBlindnessTestingModeSettingProvider), ), themeMode: ref.watch(themeModeSettingProvider), debugShowCheckedModeBanner: false, scrollBehavior: AppScrollingBehavior(), routerDelegate: appRouter.routerDelegate, routeInformationProvider: appRouter.routeInformationProvider, routeInformationParser: appRouter.routeInformationParser, ), ); } }