import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'login_view.dart'; import 'jobs_view.dart'; import 'cargo_items_view.dart'; import 'chats_view.dart'; import 'chat_details_view.dart'; import 'settings_view.dart'; import 'models/job.dart'; import 'models/chat.dart'; import 'services/database_service.dart'; import 'services/chat_service.dart'; import 'app_state.dart'; import 'navigation_observer.dart'; import 'services/notification_service.dart'; import 'l10n/app_localizations.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); // Initialize SQLite database await DatabaseService().initialize(); // Load data from database await AppState().loadLoginFromDatabase(); // Load language preference await AppState().loadLanguagePreference(); // Load jobs from database to trigger message type logging at startup await AppState().refreshJobsFromDatabase(); // Prepare chat service before WebSocket events start flowing await ChatService().initialize(); // Initialize notification service for local notifications with sound await NotificationService().initialize(); // Note: WebSocket connection is initiated from the view that needs it: // - If userId exists: JobsView initiates connection on startup // - If no userId: LoginView initiates connection when login button is clicked runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { // Check if user is already logged in final appState = AppState(); final initialRoute = appState.isLoggedIn ? '/jobs' : '/login'; return ValueListenableBuilder( valueListenable: localeNotifier, builder: (context, locale, child) { return MaterialApp( title: 'VotianLT App', debugShowCheckedModeBanner: false, theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true), // Localization configuration locale: locale, localizationsDelegates: const [AppLocalizations.delegate, GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate], supportedLocales: supportedLanguageCodes.map((code) => Locale(code)).toList(), navigatorObservers: [routeObserver], initialRoute: initialRoute, onGenerateRoute: (settings) { switch (settings.name) { case '/login': final arg = settings.arguments; final suppress = (arg is bool) ? arg : false; return MaterialPageRoute(builder: (_) => LoginView(suppressConnectionSnack: suppress)); case '/jobs': return MaterialPageRoute(builder: (_) => const JobsView()); case '/cargo_items': final job = settings.arguments as Job; return MaterialPageRoute(builder: (_) => CargoItemsView(job: job)); case '/chats': return MaterialPageRoute(builder: (_) => const ChatsView()); case '/chat_details': final chat = settings.arguments as Chat; return MaterialPageRoute(builder: (_) => ChatDetailsView(chat: chat)); case '/settings': return MaterialPageRoute(builder: (_) => const SettingsView()); default: return MaterialPageRoute(builder: (_) => const LoginView(suppressConnectionSnack: false)); } }, ); }, ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title)), body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [const Text('You have pushed the button this many times:'), Text('$_counter', style: Theme.of(context).textTheme.headlineMedium)])), floatingActionButton: FloatingActionButton(onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add)), // This trailing comma makes auto-formatting nicer for build methods. ); } }