2024-05-06 10:32:39 +08:00
|
|
|
import 'dart:async';
|
|
|
|
|
|
2024-04-30 23:38:49 +08:00
|
|
|
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<ClashConfig>(
|
|
|
|
|
create: (_) => clashConfig,
|
|
|
|
|
),
|
|
|
|
|
ChangeNotifierProvider<Config>(
|
|
|
|
|
create: (_) => config,
|
|
|
|
|
),
|
2024-05-07 13:50:00 +08:00
|
|
|
ChangeNotifierProxyProvider2<Config, ClashConfig, AppState>(
|
2024-04-30 23:38:49 +08:00
|
|
|
create: (_) => appState,
|
2024-05-07 13:50:00 +08:00
|
|
|
update: (_, config, clashConfig, appState) {
|
|
|
|
|
appState?.mode = clashConfig.mode;
|
2024-05-10 10:11:27 +08:00
|
|
|
appState?.isCompatible = config.isCompatible;
|
|
|
|
|
appState?.selectedMap = config.currentSelectedMap;
|
2024-05-07 13:50:00 +08:00
|
|
|
return appState!;
|
|
|
|
|
},
|
2024-04-30 23:38:49 +08:00
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
child: child,
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Application extends StatefulWidget {
|
|
|
|
|
const Application({
|
|
|
|
|
super.key,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
State<Application> createState() => ApplicationState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ApplicationState extends State<Application> {
|
|
|
|
|
late SystemColorSchemes systemColorSchemes;
|
|
|
|
|
|
2024-05-20 15:15:09 +08:00
|
|
|
final _pageTransitionsTheme = const PageTransitionsTheme(
|
|
|
|
|
builders: <TargetPlatform, PageTransitionsBuilder>{
|
|
|
|
|
TargetPlatform.android: CupertinoPageTransitionsBuilder(),
|
|
|
|
|
TargetPlatform.windows: CupertinoPageTransitionsBuilder(),
|
|
|
|
|
TargetPlatform.linux: CupertinoPageTransitionsBuilder(),
|
|
|
|
|
TargetPlatform.macOS: CupertinoPageTransitionsBuilder(),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
2024-04-30 23:38:49 +08:00
|
|
|
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();
|
2024-05-11 17:02:34 +08:00
|
|
|
globalState.appController = AppController(context);
|
2024-04-30 23:38:49 +08:00
|
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
2024-06-13 23:43:42 +08:00
|
|
|
final currentContext = globalState.navigatorKey.currentContext;
|
|
|
|
|
if (currentContext != null) {
|
|
|
|
|
globalState.appController = AppController(currentContext);
|
|
|
|
|
}
|
2024-06-11 20:50:57 +08:00
|
|
|
await globalState.appController.init();
|
2024-05-11 17:02:34 +08:00
|
|
|
globalState.appController.initLink();
|
2024-05-10 10:11:27 +08:00
|
|
|
_updateGroups();
|
2024-04-30 23:38:49 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_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((_) {
|
2024-05-11 17:02:34 +08:00
|
|
|
globalState.appController.updateSystemColorSchemes(systemColorSchemes);
|
2024-04-30 23:38:49 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-10 10:11:27 +08:00
|
|
|
_updateGroups() {
|
|
|
|
|
if (globalState.groupsUpdateTimer != null) {
|
|
|
|
|
globalState.groupsUpdateTimer?.cancel();
|
|
|
|
|
globalState.groupsUpdateTimer = null;
|
|
|
|
|
}
|
2024-05-11 17:02:34 +08:00
|
|
|
globalState.groupsUpdateTimer ??= Timer.periodic(
|
2024-05-20 15:15:09 +08:00
|
|
|
httpTimeoutDuration,
|
2024-05-11 17:02:34 +08:00
|
|
|
(timer) async {
|
2024-07-26 08:05:22 +08:00
|
|
|
await globalState.appController.updateGroupDebounce();
|
2024-05-11 17:02:34 +08:00
|
|
|
},
|
|
|
|
|
);
|
2024-05-10 10:11:27 +08:00
|
|
|
}
|
|
|
|
|
|
2024-04-30 23:38:49 +08:00
|
|
|
@override
|
|
|
|
|
Widget build(context) {
|
|
|
|
|
return AppStateContainer(
|
2024-07-26 08:05:22 +08:00
|
|
|
child: ClashContainer(
|
2024-07-19 02:14:58 +08:00
|
|
|
child: Selector2<AppState, Config, ApplicationSelectorState>(
|
|
|
|
|
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(
|
|
|
|
|
debugShowCheckedModeBanner: false,
|
|
|
|
|
navigatorKey: globalState.navigatorKey,
|
|
|
|
|
localizationsDelegates: const [
|
|
|
|
|
AppLocalizations.delegate,
|
|
|
|
|
GlobalMaterialLocalizations.delegate,
|
|
|
|
|
GlobalCupertinoLocalizations.delegate,
|
|
|
|
|
GlobalWidgetsLocalizations.delegate
|
|
|
|
|
],
|
|
|
|
|
builder: (_, child) {
|
2024-07-24 01:27:49 +08:00
|
|
|
return _buildApp(child!);
|
2024-07-19 02:14:58 +08:00
|
|
|
},
|
|
|
|
|
scrollBehavior: BaseScrollBehavior(),
|
|
|
|
|
title: appName,
|
|
|
|
|
locale: other.getLocaleForString(state.locale),
|
|
|
|
|
supportedLocales: AppLocalizations.delegate.supportedLocales,
|
|
|
|
|
themeMode: state.themeMode,
|
|
|
|
|
theme: ThemeData(
|
|
|
|
|
useMaterial3: true,
|
|
|
|
|
pageTransitionsTheme: _pageTransitionsTheme,
|
|
|
|
|
colorScheme: _getAppColorScheme(
|
|
|
|
|
brightness: Brightness.light,
|
|
|
|
|
systemColorSchemes: systemColorSchemes,
|
|
|
|
|
primaryColor: state.primaryColor,
|
2024-04-30 23:38:49 +08:00
|
|
|
),
|
2024-07-19 02:14:58 +08:00
|
|
|
),
|
|
|
|
|
darkTheme: ThemeData(
|
|
|
|
|
useMaterial3: true,
|
|
|
|
|
pageTransitionsTheme: _pageTransitionsTheme,
|
|
|
|
|
colorScheme: _getAppColorScheme(
|
|
|
|
|
brightness: Brightness.dark,
|
|
|
|
|
systemColorSchemes: systemColorSchemes,
|
|
|
|
|
primaryColor: state.primaryColor,
|
2024-04-30 23:38:49 +08:00
|
|
|
),
|
2024-07-19 02:14:58 +08:00
|
|
|
),
|
|
|
|
|
home: child,
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
child: const HomePage(),
|
2024-04-30 23:38:49 +08:00
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Future<void> dispose() async {
|
|
|
|
|
linkManager.destroy();
|
2024-05-11 17:02:34 +08:00
|
|
|
await globalState.appController.savePreferences();
|
2024-04-30 23:38:49 +08:00
|
|
|
super.dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|