Compare commits
1 Commits
v0.8.92-pr
...
v0.8.92-pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5113733ab2 |
@@ -64,7 +64,7 @@ android {
|
||||
buildTypes {
|
||||
debug {
|
||||
isMinifyEnabled = false
|
||||
applicationIdSuffix = ".dev"
|
||||
applicationIdSuffix = ".debug"
|
||||
}
|
||||
|
||||
release {
|
||||
|
||||
@@ -14,26 +14,20 @@ class Migration {
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
Future<Config> migrationIfNeeded(
|
||||
Map<String, Object?>? configMap, {
|
||||
required Future<Config> Function(MigrationData data) sync,
|
||||
}) async {
|
||||
Future<MigrationData> migrationIfNeeded(
|
||||
Map<String, Object?>? configMap,
|
||||
) async {
|
||||
_oldVersion = await preferences.getVersion();
|
||||
MigrationData data = MigrationData(configMap: configMap);
|
||||
if (_oldVersion == currentVersion) {
|
||||
return Config.realFromJson(configMap);
|
||||
}
|
||||
if (_oldVersion == 0 && configMap != null) {
|
||||
final clashConfigMap = await preferences.getClashConfigMap();
|
||||
if (clashConfigMap != null) {
|
||||
configMap['patchClashConfig'] = clashConfigMap;
|
||||
await preferences.clearClashConfig();
|
||||
}
|
||||
data = await _oldToNow(configMap);
|
||||
}
|
||||
final res = await sync(data);
|
||||
await preferences.setVersion(currentVersion);
|
||||
return res;
|
||||
return data;
|
||||
}
|
||||
|
||||
Future<void> rollback() async {
|
||||
await preferences.setVersion(_oldVersion);
|
||||
}
|
||||
|
||||
Future<MigrationData> _oldToNow(Map<String, Object?> configMap) async {
|
||||
|
||||
@@ -40,36 +40,11 @@ class Preferences {
|
||||
}
|
||||
|
||||
Future<Map<String, Object?>?> getConfigMap() async {
|
||||
try {
|
||||
final preferences = await sharedPreferencesCompleter.future;
|
||||
final configString = preferences?.getString(configKey);
|
||||
if (configString == null) return null;
|
||||
final Map<String, Object?>? configMap = json.decode(configString);
|
||||
return configMap;
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, Object?>?> getClashConfigMap() async {
|
||||
try {
|
||||
final preferences = await sharedPreferencesCompleter.future;
|
||||
final clashConfigString = preferences?.getString(clashConfigKey);
|
||||
if (clashConfigString == null) return null;
|
||||
return json.decode(clashConfigString);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> clearClashConfig() async {
|
||||
try {
|
||||
final preferences = await sharedPreferencesCompleter.future;
|
||||
await preferences?.remove(clashConfigKey);
|
||||
return;
|
||||
} catch (_) {
|
||||
return;
|
||||
}
|
||||
final preferences = await sharedPreferencesCompleter.future;
|
||||
final configString = preferences?.getString(configKey);
|
||||
if (configString == null) return null;
|
||||
final Map<String, Object?>? configMap = json.decode(configString);
|
||||
return configMap;
|
||||
}
|
||||
|
||||
Future<Config?> getConfig() async {
|
||||
|
||||
@@ -16,9 +16,6 @@ class CommonPrint {
|
||||
void log(String? text, {LogLevel logLevel = LogLevel.info}) {
|
||||
final payload = '[APP] $text';
|
||||
debugPrint(payload);
|
||||
if (!appController.isAttach) {
|
||||
return;
|
||||
}
|
||||
appController.addLog(Log.app(payload).copyWith(logLevel: logLevel));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,7 +402,6 @@ Future<MigrationData> _oldToNowTask(
|
||||
final addedRules = standardOverwrite['addedRules'] as List? ?? [];
|
||||
for (final addRule in addedRules) {
|
||||
final id = idMap.updateCacheValue(addRule['id'], () => snowflake.id);
|
||||
addRule['id'] = id;
|
||||
rules.add(Rule.fromJson(addRule));
|
||||
links.add(
|
||||
ProfileRuleLink(
|
||||
@@ -431,9 +430,9 @@ Future<MigrationData> _oldToNowTask(
|
||||
final scriptOverwrite = overwrite['scriptOverwrite'] as Map?;
|
||||
if (scriptOverwrite != null) {
|
||||
final scriptId = scriptOverwrite['scriptId'] as String?;
|
||||
rawProfile['scriptId'] = scriptId != null ? idMap[scriptId] : null;
|
||||
configMap['scriptId'] = scriptId != null ? idMap[scriptId] : null;
|
||||
}
|
||||
rawProfile['overwriteType'] = overwrite['type'];
|
||||
configMap['overwriteType'] = overwrite['type'];
|
||||
}
|
||||
|
||||
final sourceFile = File(_getProfilePath(sourcePath, rawId));
|
||||
@@ -443,8 +442,9 @@ Future<MigrationData> _oldToNowTask(
|
||||
}
|
||||
final currentProfileId = configMap['currentProfileId'];
|
||||
configMap['currentProfileId'] = currentProfileId != null
|
||||
? idMap[currentProfileId]
|
||||
? idMap[currentProfileId.toString()]
|
||||
: null;
|
||||
|
||||
return MigrationData(
|
||||
configMap: configMap,
|
||||
profiles: profiles,
|
||||
|
||||
@@ -20,7 +20,6 @@ import 'providers/database.dart';
|
||||
class AppController {
|
||||
late final BuildContext _context;
|
||||
late final WidgetRef _ref;
|
||||
bool isAttach = false;
|
||||
|
||||
static AppController? _instance;
|
||||
|
||||
@@ -35,12 +34,17 @@ class AppController {
|
||||
_context = context;
|
||||
_ref = ref;
|
||||
await _init();
|
||||
isAttach = true;
|
||||
}
|
||||
}
|
||||
|
||||
extension InitControllerExt on AppController {
|
||||
Future<void> _init() async {
|
||||
FlutterError.onError = (details) {
|
||||
commonPrint.log(
|
||||
'exception: ${details.exception} stack: ${details.stack}',
|
||||
logLevel: LogLevel.warning,
|
||||
);
|
||||
};
|
||||
try {
|
||||
updateTray();
|
||||
autoUpdateProfiles();
|
||||
|
||||
@@ -243,11 +243,4 @@ abstract class Config with _$Config {
|
||||
}) = _Config;
|
||||
|
||||
factory Config.fromJson(Map<String, Object?> json) => _$ConfigFromJson(json);
|
||||
|
||||
factory Config.realFromJson(Map<String, Object?>? json) {
|
||||
if (json == null) {
|
||||
return Config(themeProps: defaultThemeProps);
|
||||
}
|
||||
return _$ConfigFromJson(json);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,7 +323,6 @@ class NetworkDetection extends _$NetworkDetection
|
||||
with AutoDisposeNotifierMixin {
|
||||
bool? _preIsStart;
|
||||
CancelToken? _cancelToken;
|
||||
int _startMillisecondsEpoch = 0;
|
||||
|
||||
@override
|
||||
NetworkDetectionState build() {
|
||||
@@ -345,9 +344,6 @@ class NetworkDetection extends _$NetworkDetection
|
||||
if (!isStart && _preIsStart == false && state.ipInfo != null) {
|
||||
return;
|
||||
}
|
||||
final millisecondsEpoch = DateTime.now().millisecondsSinceEpoch;
|
||||
_startMillisecondsEpoch = millisecondsEpoch;
|
||||
final runTime = millisecondsEpoch + 1;
|
||||
_cancelToken?.cancel();
|
||||
_cancelToken = CancelToken();
|
||||
commonPrint.log('checkIp start');
|
||||
@@ -355,7 +351,7 @@ class NetworkDetection extends _$NetworkDetection
|
||||
_preIsStart = isStart;
|
||||
final res = await request.checkIp(cancelToken: _cancelToken);
|
||||
commonPrint.log('checkIp res: $res');
|
||||
if (res.isError && runTime > _startMillisecondsEpoch) {
|
||||
if (res.isError) {
|
||||
state = state.copyWith(isLoading: true, ipInfo: null);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import 'common/common.dart';
|
||||
import 'database/database.dart';
|
||||
import 'enum/enum.dart';
|
||||
import 'l10n/l10n.dart';
|
||||
import 'models/models.dart';
|
||||
|
||||
@@ -56,12 +55,6 @@ class GlobalState {
|
||||
}
|
||||
|
||||
Future<ProviderContainer> init(int version) async {
|
||||
FlutterError.onError = (details) {
|
||||
commonPrint.log(
|
||||
'exception: ${details.exception} stack: ${details.stack}',
|
||||
logLevel: LogLevel.warning,
|
||||
);
|
||||
};
|
||||
coreSHA256 = const String.fromEnvironment('CORE_SHA256');
|
||||
isPre = const String.fromEnvironment('APP_ENV') != 'stable';
|
||||
await _initDynamicColor();
|
||||
@@ -78,45 +71,51 @@ class GlobalState {
|
||||
}
|
||||
|
||||
Future<ProviderContainer> _initData(int version) async {
|
||||
final appState = AppState(
|
||||
brightness: WidgetsBinding.instance.platformDispatcher.platformBrightness,
|
||||
version: version,
|
||||
viewSize: Size.zero,
|
||||
requests: FixedList(maxLength),
|
||||
logs: FixedList(maxLength),
|
||||
traffics: FixedList(30),
|
||||
totalTraffic: Traffic(),
|
||||
systemUiOverlayStyle: const SystemUiOverlayStyle(),
|
||||
);
|
||||
final appStateOverrides = buildAppStateOverrides(appState);
|
||||
packageInfo = await PackageInfo.fromPlatform();
|
||||
final configMap = await preferences.getConfigMap();
|
||||
final config = await migration.migrationIfNeeded(
|
||||
configMap,
|
||||
sync: (data) async {
|
||||
final newConfigMap = data.configMap;
|
||||
final config = newConfigMap != null
|
||||
? Config.fromJson(newConfigMap)
|
||||
: Config(themeProps: defaultThemeProps);
|
||||
await Future.wait([
|
||||
database.restore(data.profiles, data.scripts, data.rules, data.links),
|
||||
preferences.saveConfig(config),
|
||||
]);
|
||||
return config;
|
||||
},
|
||||
);
|
||||
final configOverrides = buildConfigOverrides(config);
|
||||
final container = ProviderContainer(
|
||||
overrides: [...appStateOverrides, ...configOverrides],
|
||||
);
|
||||
final profiles = await database.profilesDao.all().get();
|
||||
container.read(profilesProvider.notifier).setAndReorder(profiles);
|
||||
await AppLocalizations.load(
|
||||
utils.getLocaleForString(config.appSettingProps.locale) ??
|
||||
WidgetsBinding.instance.platformDispatcher.locale,
|
||||
);
|
||||
await window?.init(version, config.windowProps);
|
||||
return container;
|
||||
try {
|
||||
final appState = AppState(
|
||||
brightness:
|
||||
WidgetsBinding.instance.platformDispatcher.platformBrightness,
|
||||
version: version,
|
||||
viewSize: Size.zero,
|
||||
requests: FixedList(maxLength),
|
||||
logs: FixedList(maxLength),
|
||||
traffics: FixedList(30),
|
||||
totalTraffic: Traffic(),
|
||||
systemUiOverlayStyle: const SystemUiOverlayStyle(),
|
||||
);
|
||||
final appStateOverrides = buildAppStateOverrides(appState);
|
||||
packageInfo = await PackageInfo.fromPlatform();
|
||||
final configMap = await preferences.getConfigMap();
|
||||
final migrationData = await migration.migrationIfNeeded(configMap);
|
||||
final newConfigMap = migrationData.configMap;
|
||||
|
||||
final config = newConfigMap != null
|
||||
? Config.fromJson(newConfigMap)
|
||||
: Config(themeProps: defaultThemeProps);
|
||||
final configOverrides = buildConfigOverrides(config);
|
||||
await database.restore(
|
||||
migrationData.profiles,
|
||||
migrationData.scripts,
|
||||
migrationData.rules,
|
||||
migrationData.links,
|
||||
);
|
||||
final container = ProviderContainer(
|
||||
overrides: [...appStateOverrides, ...configOverrides],
|
||||
);
|
||||
final profiles = await database.profilesDao.all().get();
|
||||
container.read(profilesProvider.notifier).setAndReorder(profiles);
|
||||
await AppLocalizations.load(
|
||||
utils.getLocaleForString(config.appSettingProps.locale) ??
|
||||
WidgetsBinding.instance.platformDispatcher.locale,
|
||||
);
|
||||
|
||||
await window?.init(version, config.windowProps);
|
||||
return container;
|
||||
} catch (e) {
|
||||
await migration.rollback();
|
||||
commonPrint.log('init failed $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> startUpdateTasks([UpdateTasks? tasks]) async {
|
||||
|
||||
Reference in New Issue
Block a user