Files
MWClash/lib/application.dart

257 lines
7.9 KiB
Dart
Raw Normal View History

2024-05-06 10:32:39 +08:00
import 'dart:async';
import 'package:animations/animations.dart';
2024-04-30 23:38:49 +08:00
import 'package:dynamic_color/dynamic_color.dart';
import 'package:fl_clash/clash/clash.dart';
2024-04-30 23:38:49 +08:00
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/l10n/l10n.dart';
import 'package:fl_clash/manager/hotkey_manager.dart';
import 'package:fl_clash/manager/manager.dart';
import 'package:fl_clash/plugins/app.dart';
2024-04-30 23:38:49 +08:00
import 'package:fl_clash/state.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 AppFlowingState appFlowingState,
2024-04-30 23:38:49 +08:00
required ClashConfig clashConfig,
}) {
runApp(MultiProvider(
providers: [
ChangeNotifierProvider<ClashConfig>(
create: (_) => clashConfig,
),
ChangeNotifierProvider<Config>(
create: (_) => config,
),
ChangeNotifierProvider<AppFlowingState>(
create: (_) => appFlowingState,
),
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;
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;
Timer? timer;
2024-04-30 23:38:49 +08:00
final _pageTransitionsTheme = const PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.android: SharedAxisPageTransitionsBuilder(
transitionType: SharedAxisTransitionType.horizontal,
),
TargetPlatform.windows: SharedAxisPageTransitionsBuilder(
transitionType: SharedAxisTransitionType.horizontal,
),
TargetPlatform.linux: SharedAxisPageTransitionsBuilder(
transitionType: SharedAxisTransitionType.horizontal,
),
TargetPlatform.macOS: SharedAxisPageTransitionsBuilder(
transitionType: SharedAxisTransitionType.horizontal,
),
},
);
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();
_initTimer();
globalState.appController = AppController(context);
globalState.measure = Measure.of(context);
2024-04-30 23:38:49 +08:00
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final currentContext = globalState.navigatorKey.currentContext;
if (currentContext != null) {
globalState.appController = AppController(currentContext);
}
await globalState.appController.init();
globalState.appController.initLink();
app?.initShortcuts();
2024-04-30 23:38:49 +08:00
});
}
_initTimer() {
_cancelTimer();
timer = Timer.periodic(const Duration(milliseconds: 20000), (_) {
WidgetsBinding.instance.addPostFrameCallback((_) {
globalState.appController.updateGroupDebounce();
});
});
}
_cancelTimer() {
if (timer != null) {
timer?.cancel();
timer = null;
}
}
2024-04-30 23:38:49 +08:00
_buildApp(Widget app) {
if (system.isDesktop) {
return WindowManager(
child: TrayManager(
child: HotKeyManager(
child: ProxyManager(
child: app,
),
),
2024-04-30 23:38:49 +08:00
),
);
}
return AndroidManager(
child: TileManager(
2024-04-30 23:38:49 +08:00
child: app,
),
);
}
_buildPage(Widget page) {
if (system.isDesktop) {
return WindowHeaderContainer(
child: page,
);
}
return VpnManager(
child: page,
);
}
2024-04-30 23:38:49 +08:00
_updateSystemColorSchemes(
ColorScheme? lightDynamic,
ColorScheme? darkDynamic,
) {
systemColorSchemes = SystemColorSchemes(
lightColorScheme: lightDynamic,
darkColorScheme: darkDynamic,
);
WidgetsBinding.instance.addPostFrameCallback((_) {
globalState.appController.updateSystemColorSchemes(systemColorSchemes);
2024-04-30 23:38:49 +08:00
});
}
@override
Widget build(context) {
return _buildApp(
AppStateManager(
child: ClashManager(
child: Selector2<AppState, Config, ApplicationSelectorState>(
selector: (_, appState, config) => ApplicationSelectorState(
locale: config.appSetting.locale,
themeMode: config.themeProps.themeMode,
primaryColor: config.themeProps.primaryColor,
prueBlack: config.themeProps.prueBlack,
fontFamily: config.themeProps.fontFamily,
),
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
],
builder: (_, child) {
return LayoutBuilder(
builder: (_, container) {
final appController = globalState.appController;
final maxWidth = container.maxWidth;
if (appController.appState.viewWidth != maxWidth) {
globalState.appController.updateViewWidth(maxWidth);
}
return _buildPage(child!);
},
);
},
scrollBehavior: BaseScrollBehavior(),
title: appName,
locale: other.getLocaleForString(state.locale),
supportedLocales:
AppLocalizations.delegate.supportedLocales,
themeMode: state.themeMode,
theme: ThemeData(
useMaterial3: true,
fontFamily: state.fontFamily.value,
pageTransitionsTheme: _pageTransitionsTheme,
colorScheme: _getAppColorScheme(
brightness: Brightness.light,
systemColorSchemes: systemColorSchemes,
primaryColor: state.primaryColor,
),
2024-04-30 23:38:49 +08:00
),
darkTheme: ThemeData(
useMaterial3: true,
fontFamily: state.fontFamily.value,
pageTransitionsTheme: _pageTransitionsTheme,
colorScheme: _getAppColorScheme(
brightness: Brightness.dark,
systemColorSchemes: systemColorSchemes,
primaryColor: state.primaryColor,
).toPrueBlack(state.prueBlack),
),
home: child,
);
},
);
},
child: const HomePage(),
),
2024-04-30 23:38:49 +08:00
),
),
);
}
@override
Future<void> dispose() async {
linkManager.destroy();
_cancelTimer();
await clashService?.destroy();
await globalState.appController.savePreferences();
await globalState.appController.handleExit();
2024-04-30 23:38:49 +08:00
super.dispose();
}
}