import 'dart:async'; import 'package:dynamic_color/dynamic_color.dart'; import 'package:fl_clash/l10n/l10n.dart'; import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/state.dart'; import 'package:fl_clash/widgets/widgets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; import 'controller.dart'; import 'models/models.dart'; import 'pages/pages.dart'; runAppWithPreferences( Widget child, { required AppState appState, required Config config, required ClashConfig clashConfig, }) { runApp(MultiProvider( providers: [ ChangeNotifierProvider( create: (_) => clashConfig, ), ChangeNotifierProvider( create: (_) => config, ), ChangeNotifierProxyProvider2( create: (_) => appState, update: (_, config, clashConfig, appState) { appState?.mode = clashConfig.mode; appState?.isCompatible = config.isCompatible; appState?.selectedMap = config.currentSelectedMap; return appState!; }, ) ], child: child, )); } class Application extends StatefulWidget { const Application({ super.key, }); @override State createState() => ApplicationState(); } class ApplicationState extends State { late SystemColorSchemes systemColorSchemes; final _pageTransitionsTheme = const PageTransitionsTheme( builders: { TargetPlatform.android: CupertinoPageTransitionsBuilder(), TargetPlatform.windows: CupertinoPageTransitionsBuilder(), TargetPlatform.linux: CupertinoPageTransitionsBuilder(), TargetPlatform.macOS: CupertinoPageTransitionsBuilder(), }, ); ColorScheme _getAppColorScheme({ required Brightness brightness, int? primaryColor, required SystemColorSchemes systemColorSchemes, }) { if (primaryColor != null) { return ColorScheme.fromSeed( seedColor: Color(primaryColor), brightness: brightness, ); } else { return systemColorSchemes.getSystemColorSchemeForBrightness(brightness); } } @override void initState() { super.initState(); globalState.appController = AppController(context); WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { globalState.appController.updateViewWidth(); globalState.appController.afterInit(); globalState.appController.initLink(); _updateGroups(); }); } _buildApp(Widget app) { if (system.isDesktop) { return WindowContainer( child: TrayContainer( child: app, ), ); } return AndroidContainer( child: TileContainer( child: app, ), ); } _updateSystemColorSchemes( ColorScheme? lightDynamic, ColorScheme? darkDynamic, ) { systemColorSchemes = SystemColorSchemes( lightColorScheme: lightDynamic, darkColorScheme: darkDynamic, ); WidgetsBinding.instance.addPostFrameCallback((_) { globalState.appController.updateSystemColorSchemes(systemColorSchemes); }); } _updateGroups() { if (globalState.groupsUpdateTimer != null) { globalState.groupsUpdateTimer?.cancel(); globalState.groupsUpdateTimer = null; } globalState.groupsUpdateTimer ??= Timer.periodic( httpTimeoutDuration, (timer) async { await globalState.appController.updateGroups(); globalState.appController.appState.sortNum++; }, ); } @override Widget build(context) { return AppStateContainer( child: ClashMessageContainer( child: _buildApp( Selector2( selector: (_, appState, config) => ApplicationSelectorState( locale: config.locale, themeMode: config.themeMode, primaryColor: config.primaryColor, ), builder: (_, state, child) { return DynamicColorBuilder( builder: (lightDynamic, darkDynamic) { _updateSystemColorSchemes(lightDynamic, darkDynamic); return MaterialApp( navigatorKey: globalState.navigatorKey, localizationsDelegates: const [ AppLocalizations.delegate, GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, GlobalWidgetsLocalizations.delegate ], title: appName, locale: other.getLocaleForString(state.locale), supportedLocales: AppLocalizations.delegate.supportedLocales, themeMode: state.themeMode, theme: ThemeData( pageTransitionsTheme: _pageTransitionsTheme, useMaterial3: true, colorScheme: _getAppColorScheme( brightness: Brightness.light, systemColorSchemes: systemColorSchemes, primaryColor: state.primaryColor, ), ), darkTheme: ThemeData( useMaterial3: true, pageTransitionsTheme: _pageTransitionsTheme, colorScheme: _getAppColorScheme( brightness: Brightness.dark, systemColorSchemes: systemColorSchemes, primaryColor: state.primaryColor, ), ), home: child, ); }, ); }, child: const HomePage(), ), ), ), ); } @override Future dispose() async { linkManager.destroy(); await globalState.appController.savePreferences(); super.dispose(); } }