/// Application entry point: wires services, Provider, and [MaterialApp]. library; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'providers/item_provider.dart'; import 'providers/theme_provider.dart'; import 'screens/splash_screen.dart'; import 'services/item_repository.dart'; import 'services/storage_service.dart'; import 'utils/app_theme.dart'; import 'utils/constants.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); final storage = StorageService(); await storage.init(); runApp( MyApp( storage: storage, repository: ItemRepository(useRemoteData: storage.useRemoteData), ), ); } /// Root widget. Theme and catalog controllers live here so every route /// can `context.watch` them. class MyApp extends StatelessWidget { const MyApp({ super.key, required this.storage, required this.repository, }); final StorageService storage; final ItemRepository repository; @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => ThemeController(storage)), ChangeNotifierProvider( create: (_) => ItemController( repository: repository, storage: storage, )..loadItems(), ), ], child: const _MaterialRoot(), ); } } class _MaterialRoot extends StatelessWidget { const _MaterialRoot(); @override Widget build(BuildContext context) { final themeMode = context.watch().themeMode; return MaterialApp( title: kAppName, debugShowCheckedModeBanner: false, theme: AppTheme.light(), darkTheme: AppTheme.dark(), themeMode: themeMode, home: const SplashScreen(), ); } }