Add linux deb dependencies Add backup recovery strategy select Support custom text scaling Optimize the display of different text scale Optimize windows setup experience Optimize startTun performance Optimize android tv experience Optimize default option Optimize computed text size Optimize hyperOS freeform window Add developer mode Update core Optimize more details
198 lines
5.7 KiB
Dart
198 lines
5.7 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:fl_clash/clash/clash.dart';
|
|
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';
|
|
import 'package:fl_clash/providers/providers.dart';
|
|
import 'package:fl_clash/state.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import 'controller.dart';
|
|
import 'pages/pages.dart';
|
|
|
|
class Application extends ConsumerStatefulWidget {
|
|
const Application({
|
|
super.key,
|
|
});
|
|
|
|
@override
|
|
ConsumerState<Application> createState() => ApplicationState();
|
|
}
|
|
|
|
class ApplicationState extends ConsumerState<Application> {
|
|
Timer? _autoUpdateGroupTaskTimer;
|
|
Timer? _autoUpdateProfilesTaskTimer;
|
|
|
|
final _pageTransitionsTheme = const PageTransitionsTheme(
|
|
builders: <TargetPlatform, PageTransitionsBuilder>{
|
|
TargetPlatform.android: CommonPageTransitionsBuilder(),
|
|
TargetPlatform.windows: CommonPageTransitionsBuilder(),
|
|
TargetPlatform.linux: CommonPageTransitionsBuilder(),
|
|
TargetPlatform.macOS: CommonPageTransitionsBuilder(),
|
|
},
|
|
);
|
|
|
|
ColorScheme _getAppColorScheme({
|
|
required Brightness brightness,
|
|
int? primaryColor,
|
|
}) {
|
|
return ref.read(genColorSchemeProvider(brightness));
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_autoUpdateGroupTask();
|
|
_autoUpdateProfilesTask();
|
|
globalState.appController = AppController(context, ref);
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
|
final currentContext = globalState.navigatorKey.currentContext;
|
|
if (currentContext != null) {
|
|
globalState.appController = AppController(currentContext, ref);
|
|
}
|
|
await globalState.appController.init();
|
|
globalState.appController.initLink();
|
|
app?.initShortcuts();
|
|
});
|
|
}
|
|
|
|
_autoUpdateGroupTask() {
|
|
_autoUpdateGroupTaskTimer = Timer(const Duration(milliseconds: 20000), () {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
globalState.appController.updateGroupsDebounce();
|
|
_autoUpdateGroupTask();
|
|
});
|
|
});
|
|
}
|
|
|
|
_autoUpdateProfilesTask() {
|
|
_autoUpdateProfilesTaskTimer = Timer(const Duration(minutes: 20), () async {
|
|
await globalState.appController.autoUpdateProfiles();
|
|
_autoUpdateProfilesTask();
|
|
});
|
|
}
|
|
|
|
_buildPlatformState(Widget child) {
|
|
if (system.isDesktop) {
|
|
return WindowManager(
|
|
child: TrayManager(
|
|
child: HotKeyManager(
|
|
child: ProxyManager(
|
|
child: child,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
return AndroidManager(
|
|
child: TileManager(
|
|
child: child,
|
|
),
|
|
);
|
|
}
|
|
|
|
_buildState(Widget child) {
|
|
return AppStateManager(
|
|
child: ClashManager(
|
|
child: ConnectivityManager(
|
|
onConnectivityChanged: () {
|
|
globalState.appController.updateLocalIp();
|
|
globalState.appController.addCheckIpNumDebounce();
|
|
},
|
|
child: child,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
_buildPlatformApp(Widget child) {
|
|
if (system.isDesktop) {
|
|
return WindowHeaderContainer(
|
|
child: child,
|
|
);
|
|
}
|
|
return VpnManager(
|
|
child: child,
|
|
);
|
|
}
|
|
|
|
_buildApp(Widget child) {
|
|
return MessageManager(
|
|
child: ThemeManager(
|
|
child: child,
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(context) {
|
|
return _buildPlatformState(
|
|
_buildState(
|
|
Consumer(
|
|
builder: (_, ref, child) {
|
|
final locale =
|
|
ref.watch(appSettingProvider.select((state) => state.locale));
|
|
final themeProps = ref.watch(themeSettingProvider);
|
|
return MaterialApp(
|
|
debugShowCheckedModeBanner: false,
|
|
navigatorKey: globalState.navigatorKey,
|
|
localizationsDelegates: const [
|
|
AppLocalizations.delegate,
|
|
GlobalMaterialLocalizations.delegate,
|
|
GlobalCupertinoLocalizations.delegate,
|
|
GlobalWidgetsLocalizations.delegate
|
|
],
|
|
builder: (_, child) {
|
|
return AppEnvManager(
|
|
child: _buildPlatformApp(
|
|
_buildApp(child!),
|
|
),
|
|
);
|
|
},
|
|
scrollBehavior: BaseScrollBehavior(),
|
|
title: appName,
|
|
locale: utils.getLocaleForString(locale),
|
|
supportedLocales: AppLocalizations.delegate.supportedLocales,
|
|
themeMode: themeProps.themeMode,
|
|
theme: ThemeData(
|
|
useMaterial3: true,
|
|
pageTransitionsTheme: _pageTransitionsTheme,
|
|
colorScheme: _getAppColorScheme(
|
|
brightness: Brightness.light,
|
|
primaryColor: themeProps.primaryColor,
|
|
),
|
|
),
|
|
darkTheme: ThemeData(
|
|
useMaterial3: true,
|
|
pageTransitionsTheme: _pageTransitionsTheme,
|
|
colorScheme: _getAppColorScheme(
|
|
brightness: Brightness.dark,
|
|
primaryColor: themeProps.primaryColor,
|
|
).toPureBlack(themeProps.pureBlack),
|
|
),
|
|
home: child,
|
|
);
|
|
},
|
|
child: const HomePage(),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Future<void> dispose() async {
|
|
linkManager.destroy();
|
|
_autoUpdateGroupTaskTimer?.cancel();
|
|
_autoUpdateProfilesTaskTimer?.cancel();
|
|
await clashCore.destroy();
|
|
await globalState.appController.savePreferences();
|
|
await globalState.appController.handleExit();
|
|
super.dispose();
|
|
}
|
|
}
|