Optimize desktop view
Optimize logs, requests, connection pages Optimize windows tray auto hide Optimize some details Update core
This commit is contained in:
+170
-122
@@ -2,7 +2,6 @@ import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:isolate';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:archive/archive.dart';
|
||||
import 'package:fl_clash/clash/clash.dart';
|
||||
@@ -12,7 +11,9 @@ import 'package:fl_clash/plugins/app.dart';
|
||||
import 'package:fl_clash/providers/providers.dart';
|
||||
import 'package:fl_clash/state.dart';
|
||||
import 'package:fl_clash/widgets/dialog.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
@@ -29,29 +30,29 @@ class AppController {
|
||||
|
||||
AppController(this.context, WidgetRef ref) : _ref = ref;
|
||||
|
||||
setupClashConfigDebounce() {
|
||||
void setupClashConfigDebounce() {
|
||||
debouncer.call(FunctionTag.setupClashConfig, () async {
|
||||
await setupClashConfig();
|
||||
});
|
||||
}
|
||||
|
||||
updateClashConfigDebounce() {
|
||||
Future<void> updateClashConfigDebounce() async {
|
||||
debouncer.call(FunctionTag.updateClashConfig, () async {
|
||||
await updateClashConfig();
|
||||
});
|
||||
}
|
||||
|
||||
updateGroupsDebounce() {
|
||||
void updateGroupsDebounce() {
|
||||
debouncer.call(FunctionTag.updateGroups, updateGroups);
|
||||
}
|
||||
|
||||
addCheckIpNumDebounce() {
|
||||
void addCheckIpNumDebounce() {
|
||||
debouncer.call(FunctionTag.addCheckIpNum, () {
|
||||
_ref.read(checkIpNumProvider.notifier).add();
|
||||
});
|
||||
}
|
||||
|
||||
applyProfileDebounce({
|
||||
void applyProfileDebounce({
|
||||
bool silence = false,
|
||||
}) {
|
||||
debouncer.call(FunctionTag.applyProfile, (silence) {
|
||||
@@ -59,11 +60,11 @@ class AppController {
|
||||
}, args: [silence]);
|
||||
}
|
||||
|
||||
savePreferencesDebounce() {
|
||||
void savePreferencesDebounce() {
|
||||
debouncer.call(FunctionTag.savePreferences, savePreferences);
|
||||
}
|
||||
|
||||
changeProxyDebounce(String groupName, String proxyName) {
|
||||
void changeProxyDebounce(String groupName, String proxyName) {
|
||||
debouncer.call(FunctionTag.changeProxy,
|
||||
(String groupName, String proxyName) async {
|
||||
await changeProxy(
|
||||
@@ -74,8 +75,8 @@ class AppController {
|
||||
}, args: [groupName, proxyName]);
|
||||
}
|
||||
|
||||
restartCore() async {
|
||||
commonPrint.log("restart core");
|
||||
Future<void> restartCore() async {
|
||||
commonPrint.log('restart core');
|
||||
await clashService?.reStart();
|
||||
await _initCore();
|
||||
if (_ref.read(runTimeProvider.notifier).isStart) {
|
||||
@@ -83,7 +84,7 @@ class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
updateStatus(bool isStart) async {
|
||||
Future<void> updateStatus(bool isStart) async {
|
||||
if (isStart) {
|
||||
await globalState.handleStart([
|
||||
updateRunTime,
|
||||
@@ -102,7 +103,7 @@ class AppController {
|
||||
applyProfileDebounce();
|
||||
} else {
|
||||
await globalState.handleStop();
|
||||
await clashCore.resetTraffic();
|
||||
clashCore.resetTraffic();
|
||||
_ref.read(trafficsProvider.notifier).clear();
|
||||
_ref.read(totalTrafficProvider.notifier).value = Traffic();
|
||||
_ref.read(runTimeProvider.notifier).value = null;
|
||||
@@ -110,7 +111,7 @@ class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
updateRunTime() {
|
||||
void updateRunTime() {
|
||||
final startTime = globalState.startTime;
|
||||
if (startTime != null) {
|
||||
final startTimeStamp = startTime.millisecondsSinceEpoch;
|
||||
@@ -121,20 +122,20 @@ class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
updateTraffic() async {
|
||||
Future<void> updateTraffic() async {
|
||||
final traffic = await clashCore.getTraffic();
|
||||
_ref.read(trafficsProvider.notifier).addTraffic(traffic);
|
||||
_ref.read(totalTrafficProvider.notifier).value =
|
||||
await clashCore.getTotalTraffic();
|
||||
}
|
||||
|
||||
addProfile(Profile profile) async {
|
||||
Future<void> addProfile(Profile profile) async {
|
||||
_ref.read(profilesProvider.notifier).setProfile(profile);
|
||||
if (_ref.read(currentProfileIdProvider) != null) return;
|
||||
_ref.read(currentProfileIdProvider.notifier).value = profile.id;
|
||||
}
|
||||
|
||||
deleteProfile(String id) async {
|
||||
Future<void> deleteProfile(String id) async {
|
||||
_ref.read(profilesProvider.notifier).deleteProfileById(id);
|
||||
clearEffect(id);
|
||||
if (globalState.config.currentProfileId == id) {
|
||||
@@ -150,12 +151,12 @@ class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
updateProviders() async {
|
||||
Future<void> updateProviders() async {
|
||||
_ref.read(providersProvider.notifier).value =
|
||||
await clashCore.getExternalProviders();
|
||||
}
|
||||
|
||||
updateLocalIp() async {
|
||||
Future<void> updateLocalIp() async {
|
||||
_ref.read(localIpProvider.notifier).value = null;
|
||||
await Future.delayed(commonDuration);
|
||||
_ref.read(localIpProvider.notifier).value = await utils.getLocalIpAddress();
|
||||
@@ -171,26 +172,26 @@ class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
setProfile(Profile profile) {
|
||||
void setProfile(Profile profile) {
|
||||
_ref.read(profilesProvider.notifier).setProfile(profile);
|
||||
}
|
||||
|
||||
setProfileAndAutoApply(Profile profile) {
|
||||
void setProfileAndAutoApply(Profile profile) {
|
||||
_ref.read(profilesProvider.notifier).setProfile(profile);
|
||||
if (profile.id == _ref.read(currentProfileIdProvider)) {
|
||||
applyProfileDebounce(silence: true);
|
||||
}
|
||||
}
|
||||
|
||||
setProfiles(List<Profile> profiles) {
|
||||
void setProfiles(List<Profile> profiles) {
|
||||
_ref.read(profilesProvider.notifier).value = profiles;
|
||||
}
|
||||
|
||||
addLog(Log log) {
|
||||
void addLog(Log log) {
|
||||
_ref.read(logsProvider).add(log);
|
||||
}
|
||||
|
||||
updateOrAddHotKeyAction(HotKeyAction hotKeyAction) {
|
||||
void updateOrAddHotKeyAction(HotKeyAction hotKeyAction) {
|
||||
final hotKeyActions = _ref.read(hotKeyActionsProvider);
|
||||
final index =
|
||||
hotKeyActions.indexWhere((item) => item.action == hotKeyAction.action);
|
||||
@@ -219,26 +220,26 @@ class AppController {
|
||||
return _ref.read(getProxiesColumnsProvider);
|
||||
}
|
||||
|
||||
addSortNum() {
|
||||
dynamic addSortNum() {
|
||||
return _ref.read(sortNumProvider.notifier).add();
|
||||
}
|
||||
|
||||
getCurrentGroupName() {
|
||||
String? getCurrentGroupName() {
|
||||
final currentGroupName = _ref.read(currentProfileProvider.select(
|
||||
(state) => state?.currentGroupName,
|
||||
));
|
||||
return currentGroupName;
|
||||
}
|
||||
|
||||
ProxyCardState getProxyCardState(proxyName) {
|
||||
ProxyCardState getProxyCardState(String proxyName) {
|
||||
return _ref.read(getProxyCardStateProvider(proxyName));
|
||||
}
|
||||
|
||||
getSelectedProxyName(groupName) {
|
||||
String? getSelectedProxyName(String groupName) {
|
||||
return _ref.read(getSelectedProxyNameProvider(groupName));
|
||||
}
|
||||
|
||||
updateCurrentGroupName(String groupName) {
|
||||
void updateCurrentGroupName(String groupName) {
|
||||
final profile = _ref.read(currentProfileProvider);
|
||||
if (profile == null || profile.currentGroupName == groupName) {
|
||||
return;
|
||||
@@ -249,11 +250,12 @@ class AppController {
|
||||
}
|
||||
|
||||
Future<void> updateClashConfig() async {
|
||||
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
||||
if (commonScaffoldState?.mounted != true) return;
|
||||
await commonScaffoldState?.loadingRun(() async {
|
||||
await _updateClashConfig();
|
||||
});
|
||||
await safeRun(
|
||||
() async {
|
||||
await _updateClashConfig();
|
||||
},
|
||||
needLoading: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _updateClashConfig() async {
|
||||
@@ -272,13 +274,16 @@ class AppController {
|
||||
}
|
||||
|
||||
Future<Result<bool>> _requestAdmin(bool enableTun) async {
|
||||
if(system.isWindows && kDebugMode){
|
||||
return Result.success(false);
|
||||
}
|
||||
final realTunEnable = _ref.read(realTunEnableProvider);
|
||||
if (enableTun != realTunEnable && realTunEnable == false) {
|
||||
final code = await system.authorizeCore();
|
||||
switch (code) {
|
||||
case AuthorizeCode.success:
|
||||
await restartCore();
|
||||
return Result.error("");
|
||||
return Result.error('');
|
||||
case AuthorizeCode.none:
|
||||
break;
|
||||
case AuthorizeCode.error:
|
||||
@@ -291,14 +296,15 @@ class AppController {
|
||||
}
|
||||
|
||||
Future<void> setupClashConfig() async {
|
||||
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
||||
if (commonScaffoldState?.mounted != true) return;
|
||||
await commonScaffoldState?.loadingRun(() async {
|
||||
await _setupClashConfig();
|
||||
});
|
||||
await safeRun(
|
||||
() async {
|
||||
await _setupClashConfig();
|
||||
},
|
||||
needLoading: true,
|
||||
);
|
||||
}
|
||||
|
||||
_setupClashConfig() async {
|
||||
Future<void> _setupClashConfig() async {
|
||||
await _ref.read(currentProfileProvider)?.checkAndUpdate();
|
||||
final patchConfig = _ref.read(patchClashConfigProvider);
|
||||
final res = await _requestAdmin(patchConfig.tun.enable);
|
||||
@@ -332,29 +338,32 @@ class AppController {
|
||||
if (silence) {
|
||||
await _applyProfile();
|
||||
} else {
|
||||
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
||||
if (commonScaffoldState?.mounted != true) return;
|
||||
await commonScaffoldState?.loadingRun(() async {
|
||||
await _applyProfile();
|
||||
});
|
||||
await safeRun(
|
||||
() async {
|
||||
await _applyProfile();
|
||||
},
|
||||
needLoading: true,
|
||||
);
|
||||
}
|
||||
addCheckIpNumDebounce();
|
||||
}
|
||||
|
||||
handleChangeProfile() {
|
||||
void handleChangeProfile() {
|
||||
_ref.read(delayDataSourceProvider.notifier).value = {};
|
||||
applyProfile();
|
||||
_ref.read(logsProvider.notifier).value = FixedList(500);
|
||||
_ref.read(requestsProvider.notifier).value = FixedList(500);
|
||||
globalState.cacheHeightMap = {};
|
||||
globalState.cacheScrollPosition = {};
|
||||
globalState.computeHeightMapCache = {};
|
||||
}
|
||||
|
||||
updateBrightness(Brightness brightness) {
|
||||
_ref.read(appBrightnessProvider.notifier).value = brightness;
|
||||
void updateBrightness() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_ref.read(systemBrightnessProvider.notifier).value =
|
||||
WidgetsBinding.instance.platformDispatcher.platformBrightness;
|
||||
});
|
||||
}
|
||||
|
||||
autoUpdateProfiles() async {
|
||||
Future<void> autoUpdateProfiles() async {
|
||||
for (final profile in _ref.read(profilesProvider)) {
|
||||
if (!profile.autoUpdate) continue;
|
||||
final isNotNeedUpdate = profile.lastUpdateDate
|
||||
@@ -386,7 +395,7 @@ class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
updateProfiles() async {
|
||||
Future<void> updateProfiles() async {
|
||||
for (final profile in _ref.read(profilesProvider)) {
|
||||
if (profile.type == ProfileType.file) {
|
||||
continue;
|
||||
@@ -395,12 +404,12 @@ class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
savePreferences() async {
|
||||
commonPrint.log("save preferences");
|
||||
Future<void> savePreferences() async {
|
||||
commonPrint.log('save preferences');
|
||||
await preferences.saveConfig(globalState.config);
|
||||
}
|
||||
|
||||
changeProxy({
|
||||
Future<void> changeProxy({
|
||||
required String groupName,
|
||||
required String proxyName,
|
||||
}) async {
|
||||
@@ -416,13 +425,13 @@ class AppController {
|
||||
addCheckIpNumDebounce();
|
||||
}
|
||||
|
||||
handleBackOrExit() async {
|
||||
Future<void> handleBackOrExit() async {
|
||||
if (_ref.read(backBlockProvider)) {
|
||||
return;
|
||||
}
|
||||
if (_ref.read(appSettingProvider).minimizeOnExit) {
|
||||
if (system.isDesktop) {
|
||||
await savePreferencesDebounce();
|
||||
await savePreferences();
|
||||
}
|
||||
await system.back();
|
||||
} else {
|
||||
@@ -430,21 +439,21 @@ class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
backBlock() {
|
||||
void backBlock() {
|
||||
_ref.read(backBlockProvider.notifier).value = true;
|
||||
}
|
||||
|
||||
unBackBlock() {
|
||||
void unBackBlock() {
|
||||
_ref.read(backBlockProvider.notifier).value = false;
|
||||
}
|
||||
|
||||
handleExit() async {
|
||||
Future<void> handleExit() async {
|
||||
Future.delayed(commonDuration, () {
|
||||
system.exit();
|
||||
});
|
||||
try {
|
||||
await savePreferences();
|
||||
await system.setMacOSDns(true);
|
||||
await macOS?.updateDns(true);
|
||||
await proxy?.stopProxy();
|
||||
await clashCore.shutdown();
|
||||
await clashService?.destroy();
|
||||
@@ -455,19 +464,19 @@ class AppController {
|
||||
|
||||
Future handleClear() async {
|
||||
await preferences.clearPreferences();
|
||||
commonPrint.log("clear preferences");
|
||||
commonPrint.log('clear preferences');
|
||||
globalState.config = Config(
|
||||
themeProps: defaultThemeProps,
|
||||
);
|
||||
}
|
||||
|
||||
autoCheckUpdate() async {
|
||||
Future<void> autoCheckUpdate() async {
|
||||
if (!_ref.read(appSettingProvider).autoCheckUpdate) return;
|
||||
final res = await request.checkForUpdate();
|
||||
checkUpdateResultHandle(data: res);
|
||||
}
|
||||
|
||||
checkUpdateResultHandle({
|
||||
Future<void> checkUpdateResultHandle({
|
||||
Map<String, dynamic>? data,
|
||||
bool handleError = false,
|
||||
}) async {
|
||||
@@ -482,16 +491,16 @@ class AppController {
|
||||
final res = await globalState.showMessage(
|
||||
title: appLocalizations.discoverNewVersion,
|
||||
message: TextSpan(
|
||||
text: "$tagName \n",
|
||||
text: '$tagName \n',
|
||||
style: textTheme.headlineSmall,
|
||||
children: [
|
||||
TextSpan(
|
||||
text: "\n",
|
||||
text: '\n',
|
||||
style: textTheme.bodyMedium,
|
||||
),
|
||||
for (final submit in submits)
|
||||
TextSpan(
|
||||
text: "- $submit \n",
|
||||
text: '- $submit \n',
|
||||
style: textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
@@ -502,7 +511,7 @@ class AppController {
|
||||
return;
|
||||
}
|
||||
launchUrl(
|
||||
Uri.parse("https://github.com/$repository/releases/latest"),
|
||||
Uri.parse('https://github.com/$repository/releases/latest'),
|
||||
);
|
||||
} else if (handleError) {
|
||||
globalState.showMessage(
|
||||
@@ -514,7 +523,7 @@ class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
_handlePreference() async {
|
||||
Future<void> _handlePreference() async {
|
||||
if (await preferences.isInit) {
|
||||
return;
|
||||
}
|
||||
@@ -543,9 +552,11 @@ class AppController {
|
||||
await applyProfile();
|
||||
}
|
||||
|
||||
init() async {
|
||||
Future<void> init() async {
|
||||
FlutterError.onError = (details) {
|
||||
commonPrint.log(details.stack.toString());
|
||||
if (kDebugMode) {
|
||||
commonPrint.log(details.stack.toString());
|
||||
}
|
||||
};
|
||||
updateTray(true);
|
||||
await _initCore();
|
||||
@@ -565,8 +576,8 @@ class AppController {
|
||||
_ref.read(initProvider.notifier).value = true;
|
||||
}
|
||||
|
||||
_initStatus() async {
|
||||
if (Platform.isAndroid) {
|
||||
Future<void> _initStatus() async {
|
||||
if (system.isAndroid) {
|
||||
await globalState.updateStartTime();
|
||||
}
|
||||
final status = globalState.isStart == true
|
||||
@@ -579,28 +590,28 @@ class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
setDelay(Delay delay) {
|
||||
void setDelay(Delay delay) {
|
||||
_ref.read(delayDataSourceProvider.notifier).setDelay(delay);
|
||||
}
|
||||
|
||||
toPage(PageLabel pageLabel) {
|
||||
void toPage(PageLabel pageLabel) {
|
||||
_ref.read(currentPageLabelProvider.notifier).value = pageLabel;
|
||||
}
|
||||
|
||||
toProfiles() {
|
||||
void toProfiles() {
|
||||
toPage(PageLabel.profiles);
|
||||
}
|
||||
|
||||
initLink() {
|
||||
void initLink() {
|
||||
linkManager.initAppLinksListen(
|
||||
(url) async {
|
||||
final res = await globalState.showMessage(
|
||||
title: "${appLocalizations.add}${appLocalizations.profile}",
|
||||
title: '${appLocalizations.add}${appLocalizations.profile}',
|
||||
message: TextSpan(
|
||||
children: [
|
||||
TextSpan(text: appLocalizations.doYouWantToPass),
|
||||
TextSpan(
|
||||
text: " $url ",
|
||||
text: ' $url ',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
decoration: TextDecoration.underline,
|
||||
@@ -609,7 +620,7 @@ class AppController {
|
||||
),
|
||||
TextSpan(
|
||||
text:
|
||||
"${appLocalizations.create}${appLocalizations.profile}"),
|
||||
'${appLocalizations.create}${appLocalizations.profile}'),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -652,7 +663,7 @@ class AppController {
|
||||
false;
|
||||
}
|
||||
|
||||
_handlerDisclaimer() async {
|
||||
Future<void> _handlerDisclaimer() async {
|
||||
if (_ref.read(appSettingProvider).disclaimerAccepted) {
|
||||
return;
|
||||
}
|
||||
@@ -663,62 +674,64 @@ class AppController {
|
||||
return;
|
||||
}
|
||||
|
||||
addProfileFormURL(String url) async {
|
||||
Future<void> addProfileFormURL(String url) async {
|
||||
if (globalState.navigatorKey.currentState?.canPop() ?? false) {
|
||||
globalState.navigatorKey.currentState?.popUntil((route) => route.isFirst);
|
||||
}
|
||||
toProfiles();
|
||||
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
||||
if (commonScaffoldState?.mounted != true) return;
|
||||
final profile = await commonScaffoldState?.loadingRun<Profile>(
|
||||
|
||||
final profile = await safeRun(
|
||||
() async {
|
||||
return await Profile.normal(
|
||||
url: url,
|
||||
).update();
|
||||
},
|
||||
title: "${appLocalizations.add}${appLocalizations.profile}",
|
||||
needLoading: true,
|
||||
title: '${appLocalizations.add}${appLocalizations.profile}',
|
||||
);
|
||||
if (profile != null) {
|
||||
await addProfile(profile);
|
||||
}
|
||||
}
|
||||
|
||||
addProfileFormFile() async {
|
||||
final platformFile = await globalState.safeRun(picker.pickerFile);
|
||||
Future<void> addProfileFormFile() async {
|
||||
final platformFile = await safeRun(picker.pickerFile);
|
||||
final bytes = platformFile?.bytes;
|
||||
if (bytes == null) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
globalState.navigatorKey.currentState?.popUntil((route) => route.isFirst);
|
||||
toProfiles();
|
||||
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
||||
if (commonScaffoldState?.mounted != true) return;
|
||||
final profile = await commonScaffoldState?.loadingRun<Profile?>(
|
||||
|
||||
final profile = await safeRun(
|
||||
() async {
|
||||
await Future.delayed(const Duration(milliseconds: 300));
|
||||
return await Profile.normal(label: platformFile?.name).saveFile(bytes);
|
||||
},
|
||||
title: "${appLocalizations.add}${appLocalizations.profile}",
|
||||
needLoading: true,
|
||||
title: '${appLocalizations.add}${appLocalizations.profile}',
|
||||
);
|
||||
if (profile != null) {
|
||||
await addProfile(profile);
|
||||
}
|
||||
}
|
||||
|
||||
addProfileFormQrCode() async {
|
||||
final url = await globalState.safeRun(picker.pickerConfigQRCode);
|
||||
Future<void> addProfileFormQrCode() async {
|
||||
final url = await safeRun(
|
||||
picker.pickerConfigQRCode,
|
||||
);
|
||||
if (url == null) return;
|
||||
addProfileFormURL(url);
|
||||
}
|
||||
|
||||
updateViewSize(Size size) {
|
||||
void updateViewSize(Size size) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_ref.read(viewSizeProvider.notifier).value = size;
|
||||
});
|
||||
}
|
||||
|
||||
setProvider(ExternalProvider? provider) {
|
||||
void setProvider(ExternalProvider? provider) {
|
||||
_ref.read(providersProvider.notifier).setProvider(provider);
|
||||
}
|
||||
|
||||
@@ -763,18 +776,22 @@ class AppController {
|
||||
);
|
||||
}
|
||||
|
||||
List<Proxy> getSortProxies(List<Proxy> proxies, [String? url]) {
|
||||
return switch (_ref.read(proxiesStyleSettingProvider).sortType) {
|
||||
List<Proxy> getSortProxies({
|
||||
required List<Proxy> proxies,
|
||||
required ProxiesSortType sortType,
|
||||
String? testUrl,
|
||||
}) {
|
||||
return switch (sortType) {
|
||||
ProxiesSortType.none => proxies,
|
||||
ProxiesSortType.delay => _sortOfDelay(
|
||||
proxies: proxies,
|
||||
testUrl: url,
|
||||
testUrl: testUrl,
|
||||
),
|
||||
ProxiesSortType.name => _sortOfName(proxies),
|
||||
};
|
||||
}
|
||||
|
||||
clearEffect(String profileId) async {
|
||||
Future<Null> clearEffect(String profileId) async {
|
||||
final profilePath = await appPath.getProfilePath(profileId);
|
||||
final providersDirPath = await appPath.getProvidersDirPath(profileId);
|
||||
return await Isolate.run(() async {
|
||||
@@ -791,13 +808,13 @@ class AppController {
|
||||
});
|
||||
}
|
||||
|
||||
updateTun() {
|
||||
void updateTun() {
|
||||
_ref.read(patchClashConfigProvider.notifier).updateState(
|
||||
(state) => state.copyWith.tun(enable: !state.tun.enable),
|
||||
);
|
||||
}
|
||||
|
||||
updateSystemProxy() {
|
||||
void updateSystemProxy() {
|
||||
_ref.read(networkSettingProvider.notifier).updateState(
|
||||
(state) => state.copyWith(
|
||||
systemProxy: !state.systemProxy,
|
||||
@@ -816,11 +833,11 @@ class AppController {
|
||||
return _ref.read(packagesProvider);
|
||||
}
|
||||
|
||||
updateStart() {
|
||||
void updateStart() {
|
||||
updateStatus(!_ref.read(runTimeProvider.notifier).isStart);
|
||||
}
|
||||
|
||||
updateCurrentSelectedMap(String groupName, String proxyName) {
|
||||
void updateCurrentSelectedMap(String groupName, String proxyName) {
|
||||
final currentProfile = _ref.read(currentProfileProvider);
|
||||
if (currentProfile != null &&
|
||||
currentProfile.selectedMap[groupName] != proxyName) {
|
||||
@@ -835,7 +852,7 @@ class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
updateCurrentUnfoldSet(Set<String> value) {
|
||||
void updateCurrentUnfoldSet(Set<String> value) {
|
||||
final currentProfile = _ref.read(currentProfileProvider);
|
||||
if (currentProfile == null) {
|
||||
return;
|
||||
@@ -847,7 +864,7 @@ class AppController {
|
||||
);
|
||||
}
|
||||
|
||||
changeMode(Mode mode) {
|
||||
void changeMode(Mode mode) {
|
||||
_ref.read(patchClashConfigProvider.notifier).updateState(
|
||||
(state) => state.copyWith(mode: mode),
|
||||
);
|
||||
@@ -857,7 +874,7 @@ class AppController {
|
||||
addCheckIpNumDebounce();
|
||||
}
|
||||
|
||||
updateAutoLaunch() {
|
||||
void updateAutoLaunch() {
|
||||
_ref.read(appSettingProvider.notifier).updateState(
|
||||
(state) => state.copyWith(
|
||||
autoLaunch: !state.autoLaunch,
|
||||
@@ -865,7 +882,7 @@ class AppController {
|
||||
);
|
||||
}
|
||||
|
||||
updateVisible() async {
|
||||
Future<void> updateVisible() async {
|
||||
final visible = await window?.isVisible;
|
||||
if (visible != null && !visible) {
|
||||
window?.show();
|
||||
@@ -874,7 +891,7 @@ class AppController {
|
||||
}
|
||||
}
|
||||
|
||||
updateMode() {
|
||||
void updateMode() {
|
||||
_ref.read(patchClashConfigProvider.notifier).updateState(
|
||||
(state) {
|
||||
final index = Mode.values.indexWhere((item) => item == state.mode);
|
||||
@@ -889,7 +906,7 @@ class AppController {
|
||||
);
|
||||
}
|
||||
|
||||
handleAddOrUpdate(WidgetRef ref, [Rule? rule]) async {
|
||||
Future<void> handleAddOrUpdate(WidgetRef ref, [Rule? rule]) async {
|
||||
final res = await globalState.showCommonDialog<Rule>(
|
||||
child: AddRuleDialog(
|
||||
rule: rule,
|
||||
@@ -926,7 +943,7 @@ class AppController {
|
||||
(item) => item.toString(),
|
||||
);
|
||||
final data = await Isolate.run<List<int>>(() async {
|
||||
final logsRawString = logsRaw.join("\n");
|
||||
final logsRawString = logsRaw.join('\n');
|
||||
return utf8.encode(logsRawString);
|
||||
});
|
||||
return await picker.saveFile(
|
||||
@@ -942,20 +959,20 @@ class AppController {
|
||||
final configJson = globalState.config.toJson();
|
||||
return Isolate.run<List<int>>(() async {
|
||||
final archive = Archive();
|
||||
archive.add("config.json", configJson);
|
||||
await archive.addDirectoryToArchive(profilesPath, homeDirPath);
|
||||
archive.add('config.json', configJson);
|
||||
archive.addDirectoryToArchive(profilesPath, homeDirPath);
|
||||
final zipEncoder = ZipEncoder();
|
||||
return zipEncoder.encode(archive) ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
updateTray([bool focus = false]) async {
|
||||
Future<void> updateTray([bool focus = false]) async {
|
||||
tray.update(
|
||||
trayState: _ref.read(trayStateProvider),
|
||||
);
|
||||
}
|
||||
|
||||
recoveryData(
|
||||
Future<void> recoveryData(
|
||||
List<int> data,
|
||||
RecoveryOption recoveryOption,
|
||||
) async {
|
||||
@@ -965,12 +982,12 @@ class AppController {
|
||||
});
|
||||
final homeDirPath = await appPath.homeDirPath;
|
||||
final configs =
|
||||
archive.files.where((item) => item.name.endsWith(".json")).toList();
|
||||
archive.files.where((item) => item.name.endsWith('.json')).toList();
|
||||
final profiles =
|
||||
archive.files.where((item) => !item.name.endsWith(".json"));
|
||||
archive.files.where((item) => !item.name.endsWith('.json'));
|
||||
final configIndex =
|
||||
configs.indexWhere((config) => config.name == "config.json");
|
||||
if (configIndex == -1) throw "invalid backup file";
|
||||
configs.indexWhere((config) => config.name == 'config.json');
|
||||
if (configIndex == -1) throw 'invalid backup file';
|
||||
final configFile = configs[configIndex];
|
||||
var tempConfig = Config.compatibleFromJson(
|
||||
json.decode(
|
||||
@@ -984,7 +1001,7 @@ class AppController {
|
||||
await file.writeAsBytes(profile.content);
|
||||
}
|
||||
final clashConfigIndex =
|
||||
configs.indexWhere((config) => config.name == "clashConfig.json");
|
||||
configs.indexWhere((config) => config.name == 'clashConfig.json');
|
||||
if (clashConfigIndex != -1) {
|
||||
final clashConfigFile = configs[clashConfigIndex];
|
||||
tempConfig = tempConfig.copyWith(
|
||||
@@ -1003,7 +1020,7 @@ class AppController {
|
||||
);
|
||||
}
|
||||
|
||||
_recovery(Config config, RecoveryOption recoveryOption) {
|
||||
void _recovery(Config config, RecoveryOption recoveryOption) {
|
||||
final recoveryStrategy = _ref.read(appSettingProvider.select(
|
||||
(state) => state.recoveryStrategy,
|
||||
));
|
||||
@@ -1040,4 +1057,35 @@ class AppController {
|
||||
_ref.read(currentProfileIdProvider.notifier).value = profiles.first.id;
|
||||
}
|
||||
}
|
||||
|
||||
Future<T?> safeRun<T>(
|
||||
FutureOr<T> Function() futureFunction, {
|
||||
String? title,
|
||||
bool needLoading = false,
|
||||
bool silence = true,
|
||||
}) async {
|
||||
final realSilence = needLoading == true ? true : silence;
|
||||
try {
|
||||
if (needLoading) {
|
||||
_ref.read(loadingProvider.notifier).value = true;
|
||||
}
|
||||
final res = await futureFunction();
|
||||
return res;
|
||||
} catch (e) {
|
||||
commonPrint.log('$e');
|
||||
if (realSilence) {
|
||||
globalState.showNotifier(e.toString());
|
||||
} else {
|
||||
globalState.showMessage(
|
||||
title: title ?? appLocalizations.tip,
|
||||
message: TextSpan(
|
||||
text: e.toString(),
|
||||
),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
} finally {
|
||||
_ref.read(loadingProvider.notifier).value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user