import 'dart:async'; import 'dart:io' show Platform; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:marionette_flutter/marionette_flutter.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:app_links/app_links.dart'; import 'package:firebase_core/firebase_core.dart'; import 'firebase_options.dart'; import 'core/theme/theme.dart'; import 'core/theme/theme_mode_provider.dart'; import 'core/router.dart'; import 'features/records/records_service.dart'; import 'services/sync/sync_observer.dart'; Future main() async { final isFlutterTest = !kIsWeb && Platform.environment.containsKey('FLUTTER_TEST'); if (kDebugMode && !isFlutterTest) { MarionetteBinding.ensureInitialized(); } else { WidgetsFlutterBinding.ensureInitialized(); } try { await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); } catch (e) { debugPrint('[Firebase] Standalone offline mode active: $e'); } final sharedPreferences = await SharedPreferences.getInstance(); runApp( ProviderScope( overrides: [ sharedPreferencesProvider.overrideWithValue(sharedPreferences), ], child: const MotorcycleDashApp(), ), ); } class MotorcycleDashApp extends ConsumerStatefulWidget { const MotorcycleDashApp({super.key}); @override ConsumerState createState() => _MotorcycleDashAppState(); } class _MotorcycleDashAppState extends ConsumerState { late final AppLinks _appLinks; StreamSubscription? _linkSubscription; @override void initState() { super.initState(); // Eagerly construct the sync observer so completed rides enter the durable // outbox at startup scope, not only after visiting a sync UI. ref.read(syncObserverProvider); _initDeepLinks(); } Future _initDeepLinks() async { _appLinks = AppLinks(); try { final initialUri = await _appLinks.getInitialLink(); if (initialUri != null) _handleDeepLink(initialUri); } catch (_) {} _linkSubscription = _appLinks.uriLinkStream.listen( (uri) => _handleDeepLink(uri), onError: (_) {}, ); } void _handleDeepLink(Uri uri) { final uriStr = uri.toString(); if (uriStr.contains('callback') || uri.host == 'oauth' || uri.scheme == 'motorsignal') { try { appRouter.go('/oauth/callback?${uri.query}'); } catch (_) {} } } @override void dispose() { _linkSubscription?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { final themeMode = ref.watch(appThemeModeProvider); return MaterialApp.router( title: 'MotorSignal', theme: AppTheme.lightTheme, darkTheme: AppTheme.darkTheme, themeMode: themeMode, routerConfig: appRouter, debugShowCheckedModeBanner: false, ); } }