import 'package:provider/provider.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_web_plugins/url_strategy.dart'; import 'auth/custom_auth/auth_util.dart'; import 'auth/custom_auth/custom_auth_user_provider.dart'; import 'backend/firebase/firebase_config.dart'; import '/flutter_flow/flutter_flow_theme.dart'; import 'flutter_flow/flutter_flow_util.dart'; import 'flutter_flow/internationalization.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter/foundation.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'flutter_flow/nav/nav.dart'; import 'index.dart'; import 'dart:async'; import 'package:easy_debounce/easy_debounce.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); GoRouter.optionURLReflectsImperativeAPIs = true; usePathUrlStrategy(); await initFirebase(); await FlutterFlowTheme.initialize(); await authManager.initialize(); final appState = FFAppState(); // Initialize FFAppState await appState.initializePersistedState(); debugLogAppState(appState); appState.addListener(() { debugLogAppState(appState); }); if (!kIsWeb) { FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError; } final originalErrorWidgetBuilder = ErrorWidget.builder; ErrorWidget.builder = (FlutterErrorDetails details) { try { final match = RegExp( r'The relevant error-causing widget was:\s+([a-zA-Z0-9]+)(.|\n)*When the exception was thrown, this was the stack:((.|\n)*)') .firstMatch(details.toString()); if (match == null) { return originalErrorWidgetBuilder(details); } final widgetName = match.group(1); final stackTrace = match.group(3)!; // The stack trace usually is very long, and most of it is entirely // irrelevant for troubleshooting, e.g.: // // dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 251:49 throw_ // dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 29:3 assertFailed // packages/flutter/src/widgets/text.dart 378:14 new // packages/debug_screen_test/home_page/home_page_widget.dart 51:15 build // packages/flutter/src/widgets/framework.dart 4870:27 build // packages/flutter/src/widgets/framework.dart 4754:15 performRebuild // packages/flutter/src/widgets/framework.dart 4928:11 performRebuild // packages/flutter/src/widgets/framework.dart 4477:5 rebuild // // // We truncate everything after project-specific code. final filteredStackTrace = []; var foundProjectTraces = false; for (final line in stackTrace.split('\n')) { if (line.startsWith('packages/uitgaanskrant/')) { foundProjectTraces = true; } else { if (foundProjectTraces) { filteredStackTrace.add('...'); break; } } filteredStackTrace.add(line); } final result = '''${details.exceptionAsString()} The relevant error-causing widget was: $widgetName Stack trace: ${filteredStackTrace.join("\n")}'''; return ErrorWidget.withDetails(message: result); } catch (_) { return originalErrorWidgetBuilder(details); } }; /// Every second, fire logging call for different channel (tag) so that frequent /// logging calls don't get delayed too much Timer.periodic(const Duration(seconds: 2), (timer) { EasyDebounce.fire('405ebf2ff50c295c675b5802889ea941f081fd51'); EasyDebounce.cancel('405ebf2ff50c295c675b5802889ea941f081fd51'); EasyDebounce.fire('fbcc19a787981a30d86b10103c2f3951604b2ae6'); EasyDebounce.cancel('fbcc19a787981a30d86b10103c2f3951604b2ae6'); EasyDebounce.fire('c0186d2c21d5d9300ee148206df9fbd1850b8d41'); EasyDebounce.cancel('c0186d2c21d5d9300ee148206df9fbd1850b8d41'); EasyDebounce.fire('508f3c74205c87928b71f49040062e732f9c20b0'); EasyDebounce.cancel('508f3c74205c87928b71f49040062e732f9c20b0'); }); runApp(ChangeNotifierProvider( create: (context) => appState, child: MyApp(), )); } class MyApp extends StatefulWidget { // This widget is the root of your application. @override State createState() => _MyAppState(); static _MyAppState of(BuildContext context) => context.findAncestorStateOfType<_MyAppState>()!; } class _MyAppState extends State { Locale? _locale; Locale? get locale => _locale; ThemeMode _themeMode = FlutterFlowTheme.themeMode; late AppStateNotifier _appStateNotifier; late GoRouter _router; String getRoute([RouteMatch? routeMatch]) { final RouteMatch lastMatch = routeMatch ?? _router.routerDelegate.currentConfiguration.last; final RouteMatchList matchList = lastMatch is ImperativeRouteMatch ? lastMatch.matches : _router.routerDelegate.currentConfiguration; return matchList.uri.path; } List getRouteStack() => _router.routerDelegate.currentConfiguration.matches .map((e) => getRoute(e)) .toList(); late Stream userStream; @override void initState() { super.initState(); _appStateNotifier = AppStateNotifier.instance; _router = createRouter(_appStateNotifier); userStream = uitgaanskrantAuthUserStream() ..listen((user) { _appStateNotifier.update(user); debugLogAuthenticatedUser(); }); Future.delayed( Duration(milliseconds: 1000), () => _appStateNotifier.stopShowingSplashImage(), ); _router.routerDelegate.addListener(() { if (mounted) { debugLogGlobalProperty( context, locale: locale.toString(), routePath: getRoute(), routeStack: getRouteStack(), ); } }); } void setLocale(String language) { safeSetState(() => _locale = createLocale(language)); } void setThemeMode(ThemeMode mode) => safeSetState(() { _themeMode = mode; FlutterFlowTheme.saveThemeMode(mode); }); @override Widget build(BuildContext context) { return MaterialApp.router( debugShowCheckedModeBanner: false, title: 'Uitgaanskrant', localizationsDelegates: [ FFLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, FallbackMaterialLocalizationDelegate(), FallbackCupertinoLocalizationDelegate(), ], locale: _locale, supportedLocales: const [ Locale('nl'), Locale('en'), ], theme: ThemeData( brightness: Brightness.light, ), darkTheme: ThemeData( brightness: Brightness.dark, ), themeMode: _themeMode, routerConfig: _router, ); } }