import 'dart:async'; import 'dart:developer'; import 'dart:io'; import 'dart:ui'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:jiffy/jiffy.dart'; import 'package:loader_overlay/loader_overlay.dart'; import 'package:path_provider/path_provider.dart'; import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart'; import 'api/mhsl/breaker/getBreakers/getBreakersResponse.dart'; import 'app.dart'; import 'firebase_options.dart'; import 'model/account_data.dart'; import 'widget/breaker/breaker.dart'; import 'state/app/modules/account/bloc/account_bloc.dart'; import 'state/app/modules/account/bloc/account_state.dart'; import 'state/app/modules/breaker/bloc/breaker_bloc.dart'; import 'state/app/modules/chat/bloc/chat_bloc.dart'; import 'state/app/modules/chatList/bloc/chat_list_bloc.dart'; import 'state/app/modules/settings/bloc/settings_cubit.dart'; import 'state/app/modules/timetable/bloc/timetable_bloc.dart'; import 'storage/settings.dart'; import 'theming/dark_app_theme.dart'; import 'theming/light_app_theme.dart'; import 'view/login/login.dart'; import 'widget/placeholder_view.dart'; Future main() async { log('MarianumMobile started'); WidgetsFlutterBinding.ensureInitialized(); void addCertificateAsTrusted(ByteData certificate) => SecurityContext.defaultContext.setTrustedCertificatesBytes(certificate.buffer.asUint8List()); final initialisationTasks = [ Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform) .then((_) {}) .onError((error, _) => log('Error initializing Firebase: $error')), PlatformAssetBundle().load('assets/ca/lets-encrypt-r3.pem').then(addCertificateAsTrusted), PlatformAssetBundle().load('assets/ca/lets-encrypt-r10.pem').then(addCertificateAsTrusted), PlatformAssetBundle().load('assets/ca/lets-encrypt-r13.pem').then(addCertificateAsTrusted), Future(() async { final storage = await HydratedStorage.build( storageDirectory: HydratedStorageDirectory((await getTemporaryDirectory()).path), ); HydratedBloc.storage = storage; }), AccountData().waitForPopulation(), ]; log('starting app initialisation...'); await Future.wait(initialisationTasks); log('app initialisation done!'); unawaited( FirebaseMessaging.instance.getToken().then( (token) => log('Firebase token: ${token ?? "Error: no Firebase token!"}'), ), ); if (kReleaseMode) { ErrorWidget.builder = (error) => PlaceholderView( icon: Icons.phonelink_erase_rounded, text: error.toStringShort(), ); } // Capture uncaught Flutter and platform errors so they show up in logs // instead of being silently swallowed. FlutterError.onError = (details) { log('Uncaught Flutter error: ${details.exception}', stackTrace: details.stack); FlutterError.presentError(details); }; PlatformDispatcher.instance.onError = (error, stack) { log('Uncaught platform error: $error', stackTrace: stack); return true; }; log('running app...'); runApp( MultiBlocProvider( providers: [ BlocProvider(create: (_) => SettingsCubit()), BlocProvider(create: (_) => AccountBloc( initialStatus: AccountData().isPopulated() ? AccountStatus.loggedIn : AccountStatus.loggedOut, )), BlocProvider(create: (_) => BreakerBloc()), BlocProvider(create: (_) => ChatListBloc()), BlocProvider(create: (_) => ChatBloc()), BlocProvider(create: (_) => TimetableBloc()), ], child: const Main(), ), ); } class Main extends StatefulWidget { const Main({super.key}); static PersistentTabController bottomNavigator = PersistentTabController(initialIndex: 0); @override State
createState() => _MainState(); } class _MainState extends State
{ @override void initState() { super.initState(); Jiffy.setLocale('de'); AccountData().waitForPopulation().then((value) { if (!mounted) return; context.read().setStatus(value ? AccountStatus.loggedIn : AccountStatus.loggedOut); }); } @override Widget build(BuildContext context) => Directionality( textDirection: TextDirection.ltr, child: BlocBuilder( builder: (context, settings) { final devToolsSettings = settings.devToolsSettings; return MaterialApp( showPerformanceOverlay: devToolsSettings.showPerformanceOverlay, checkerboardOffscreenLayers: devToolsSettings.checkerboardOffscreenLayers, checkerboardRasterCacheImages: devToolsSettings.checkerboardRasterCacheImages, debugShowCheckedModeBanner: false, localizationsDelegates: const [ ...GlobalMaterialLocalizations.delegates, GlobalWidgetsLocalizations.delegate, ], supportedLocales: const [Locale('de'), Locale('en')], locale: const Locale('de'), title: 'Marianum Fulda', themeMode: settings.appTheme, theme: LightAppTheme.theme, darkTheme: DarkAppTheme.theme, home: LoaderOverlay( child: Breaker( breaker: BreakerArea.global, child: BlocBuilder( builder: (context, accountState) { switch (accountState.status) { case AccountStatus.loggedIn: return const App(); case AccountStatus.loggedOut: return const Login(); case AccountStatus.undefined: return const PlaceholderView(icon: Icons.timer, text: 'Daten werden geladen'); } }, ), ), ), ); }, ), ); }