Add sqlite store

Optimize android quick action

Optimize backup and restore

Optimize more details
This commit is contained in:
chen08209
2025-12-16 11:23:09 +08:00
parent 243b3037d9
commit 2fbb96f5c1
214 changed files with 15659 additions and 10751 deletions

View File

@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:fl_clash/common/common.dart';
@@ -25,6 +26,7 @@ class Application extends ConsumerStatefulWidget {
class ApplicationState extends ConsumerState<Application> {
Timer? _autoUpdateProfilesTaskTimer;
bool _preHasVpn = false;
final _pageTransitionsTheme = const PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
@@ -45,22 +47,22 @@ class ApplicationState extends ConsumerState<Application> {
@override
void initState() {
super.initState();
_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 appController.attach(currentContext, ref);
} else {
exit(0);
}
await globalState.appController.init();
globalState.appController.initLink();
_autoUpdateProfilesTask();
appController.initLink();
app?.initShortcuts();
});
}
void _autoUpdateProfilesTask() {
_autoUpdateProfilesTaskTimer = Timer(const Duration(minutes: 20), () async {
await globalState.appController.autoUpdateProfiles();
await appController.autoUpdateProfiles();
_autoUpdateProfilesTask();
});
}
@@ -81,11 +83,13 @@ class ApplicationState extends ConsumerState<Application> {
child: CoreManager(
child: ConnectivityManager(
onConnectivityChanged: (results) async {
if (!results.contains(ConnectivityResult.vpn)) {
coreController.closeConnections();
commonPrint.log('connectivityChanged ${results.toString()}');
appController.updateLocalIp();
final hasVpn = results.contains(ConnectivityResult.vpn);
if (_preHasVpn == hasVpn) {
appController.addCheckIp();
}
globalState.appController.updateLocalIp();
globalState.appController.addCheckIpNumDebounce();
_preHasVpn = hasVpn;
},
child: child,
),
@@ -163,8 +167,7 @@ class ApplicationState extends ConsumerState<Application> {
linkManager.destroy();
_autoUpdateProfilesTaskTimer?.cancel();
await coreController.destroy();
await globalState.appController.savePreferences();
await globalState.appController.handleExit();
await appController.handleExit();
super.dispose();
}
}

View File

@@ -1,4 +1,3 @@
import 'dart:convert';
import 'dart:io';
import 'package:archive/archive_io.dart';
@@ -18,14 +17,11 @@ extension ArchiveExt on Archive {
final archiveFile = ArchiveFile(relativePath, data.length, data);
addFile(archiveFile);
}
// else if (entity is Directory) {
// addDirectoryToArchive(entity.path, parentPath);
// }
}
}
void addTextFile<T>(String name, T raw) {
final data = json.encode(raw);
addFile(ArchiveFile.string(name, data));
}
// void addTextFile<T>(String name, T raw) {
// final data = json.encode(raw);
// addFile(ArchiveFile.string(name, data));
// }
}

View File

@@ -6,17 +6,21 @@ export 'constant.dart';
export 'context.dart';
export 'converter.dart';
export 'datetime.dart';
export 'file.dart';
export 'fixed.dart';
export 'function.dart';
export 'future.dart';
export 'hive.dart';
export 'http.dart';
export 'icons.dart';
export 'indexing.dart';
export 'iterable.dart';
export 'keyboard.dart';
export 'launch.dart';
export 'link.dart';
export 'lock.dart';
export 'measure.dart';
export 'migration.dart';
export 'mixin.dart';
export 'navigation.dart';
export 'navigator.dart';
@@ -32,8 +36,10 @@ export 'proxy.dart';
export 'render.dart';
export 'request.dart';
export 'scroll.dart';
export 'snowflake.dart';
export 'string.dart';
export 'system.dart';
export 'task.dart';
export 'text.dart';
export 'tray.dart';
export 'utils.dart';

View File

@@ -1,8 +1,7 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'string.dart';
List<Group> computeSort({
required List<Group> groups,
required ProxiesSortType sortType,
@@ -10,53 +9,54 @@ List<Group> computeSort({
required Map<String, String> selectedMap,
required String defaultTestUrl,
}) {
List<Proxy> sortOfDelay({
required List<Group> groups,
required List<Proxy> proxies,
required DelayMap delayMap,
required Map<String, String> selectedMap,
required String testUrl,
}) {
return List.from(proxies)..sort((a, b) {
final aDelayState = computeProxyDelayState(
proxyName: a.name,
testUrl: testUrl,
groups: groups,
selectedMap: selectedMap,
delayMap: delayMap,
);
final bDelayState = computeProxyDelayState(
proxyName: b.name,
testUrl: testUrl,
groups: groups,
selectedMap: selectedMap,
delayMap: delayMap,
);
return aDelayState.compareTo(bDelayState);
});
}
List<Proxy> sortOfName(List<Proxy> proxies) {
return List.of(proxies)..sort((a, b) => a.name.compareTo(b.name));
}
return groups.map((group) {
final proxies = group.all;
final newProxies = switch (sortType) {
ProxiesSortType.none => proxies,
ProxiesSortType.delay => _sortOfDelay(
ProxiesSortType.delay => sortOfDelay(
groups: groups,
proxies: proxies,
delayMap: delayMap,
selectedMap: selectedMap,
testUrl: group.testUrl.getSafeValue(defaultTestUrl),
testUrl: group.testUrl.takeFirstValid([defaultTestUrl]),
),
ProxiesSortType.name => _sortOfName(proxies),
ProxiesSortType.name => sortOfName(proxies),
};
return group.copyWith(all: newProxies);
}).toList();
}
DelayState computeProxyDelayState({
required String proxyName,
required String testUrl,
required List<Group> groups,
required Map<String, String> selectedMap,
required DelayMap delayMap,
}) {
final state = computeRealSelectedProxyState(
proxyName,
groups: groups,
selectedMap: selectedMap,
);
final currentDelayMap = delayMap[state.testUrl.getSafeValue(testUrl)] ?? {};
final delay = currentDelayMap[state.proxyName];
return DelayState(delay: delay ?? 0, group: state.group);
}
SelectedProxyState computeRealSelectedProxyState(
String proxyName, {
required List<Group> groups,
required Map<String, String> selectedMap,
}) {
return _getRealSelectedProxyState(
SelectedProxyState(proxyName: proxyName),
groups: groups,
selectedMap: selectedMap,
);
}
SelectedProxyState _getRealSelectedProxyState(
SelectedProxyState getRealSelectedProxyState(
SelectedProxyState state, {
required List<Group> groups,
required Map<String, String> selectedMap,
@@ -72,39 +72,39 @@ SelectedProxyState _getRealSelectedProxyState(
if (currentSelectedName.isEmpty) {
return newState;
}
return _getRealSelectedProxyState(
return getRealSelectedProxyState(
newState.copyWith(proxyName: currentSelectedName, testUrl: group.testUrl),
groups: groups,
selectedMap: selectedMap,
);
}
List<Proxy> _sortOfDelay({
SelectedProxyState computeRealSelectedProxyState(
String proxyName, {
required List<Group> groups,
required List<Proxy> proxies,
required DelayMap delayMap,
required Map<String, String> selectedMap,
required String testUrl,
}) {
return List.from(proxies)..sort((a, b) {
final aDelayState = computeProxyDelayState(
proxyName: a.name,
testUrl: testUrl,
groups: groups,
selectedMap: selectedMap,
delayMap: delayMap,
);
final bDelayState = computeProxyDelayState(
proxyName: b.name,
testUrl: testUrl,
groups: groups,
selectedMap: selectedMap,
delayMap: delayMap,
);
return aDelayState.compareTo(bDelayState);
});
return getRealSelectedProxyState(
SelectedProxyState(proxyName: proxyName),
groups: groups,
selectedMap: selectedMap,
);
}
List<Proxy> _sortOfName(List<Proxy> proxies) {
return List.of(proxies)..sort((a, b) => a.name.compareTo(b.name));
DelayState computeProxyDelayState({
required String proxyName,
required String testUrl,
required List<Group> groups,
required Map<String, String> selectedMap,
required DelayMap delayMap,
}) {
final state = computeRealSelectedProxyState(
proxyName,
groups: groups,
selectedMap: selectedMap,
);
final currentDelayMap =
delayMap[state.testUrl.takeFirstValid([testUrl])] ?? {};
final delay = currentDelayMap[state.proxyName];
return DelayState(delay: delay ?? 0, group: state.group);
}

View File

@@ -20,16 +20,18 @@ const helperPort = 47890;
const maxTextScale = 1.4;
const minTextScale = 0.8;
final baseInfoEdgeInsets = EdgeInsets.symmetric(
vertical: 16.ap,
horizontal: 16.ap,
vertical: 16.mAp,
horizontal: 16.mAp,
);
final listHeaderPadding = EdgeInsets.only(
left: 16.ap,
right: 8.ap,
top: 24.ap,
bottom: 8.ap,
left: 16.mAp,
right: 8.mAp,
top: 24.mAp,
bottom: 8.mAp,
);
const watchExecution = true;
final defaultTextScaleFactor =
WidgetsBinding.instance.platformDispatcher.textScaleFactor;
const httpTimeoutDuration = Duration(milliseconds: 5000);
@@ -63,6 +65,7 @@ final commonFilter = ImageFilter.blur(
tileMode: TileMode.mirror,
);
const listEquality = ListEquality();
const navigationItemListEquality = ListEquality<NavigationItem>();
const trackerInfoListEquality = ListEquality<TrackerInfo>();
const stringListEquality = ListEquality<String>();
@@ -70,15 +73,18 @@ const intListEquality = ListEquality<int>();
const logListEquality = ListEquality<Log>();
const groupListEquality = ListEquality<Group>();
const ruleListEquality = ListEquality<Rule>();
const scriptEquality = ListEquality<Script>();
const scriptListEquality = ListEquality<Script>();
const externalProviderListEquality = ListEquality<ExternalProvider>();
const packageListEquality = ListEquality<Package>();
const profileListEquality = ListEquality<Profile>();
const hotKeyActionListEquality = ListEquality<HotKeyAction>();
const stringAndStringMapEquality = MapEquality<String, String>();
const stringAndStringMapEntryListEquality =
ListEquality<MapEntry<String, String>>();
const stringAndStringMapEntryIterableEquality =
IterableEquality<MapEntry<String, String>>();
const stringAndObjectMapEntryIterableEquality =
IterableEquality<MapEntry<String, Object?>>();
const delayMapEquality = MapEquality<String, Map<String, int?>>();
const stringSetEquality = SetEquality<String>();
const keyboardModifierListEquality = SetEquality<KeyboardModifier>();
@@ -96,7 +102,8 @@ const profilesStoreKey = PageStorageKey<String>('profiles');
const defaultPrimaryColor = 0XFFD8C0C3;
double getWidgetHeight(num lines) {
return max(lines * 80 + (lines - 1) * 16, 0).ap;
final space = 14.mAp;
return max(lines * (80.ap + space) - space, 0);
}
const maxLength = 1000;
@@ -119,3 +126,6 @@ const scriptTemplate = '''
const main = (config) => {
return config;
}''';
const backupDatabaseName = 'database.sqlite';
const configJsonName = 'config.json';

View File

@@ -1,6 +1,6 @@
import 'package:fl_clash/l10n/l10n.dart';
import 'package:fl_clash/manager/manager.dart';
import 'package:fl_clash/models/widget.dart';
import 'package:fl_clash/models/state.dart';
import 'package:fl_clash/widgets/scaffold.dart';
import 'package:flutter/material.dart';

View File

@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/models/models.dart';
@@ -10,19 +9,10 @@ class DAVClient {
Completer<bool> pingCompleter = Completer();
late String fileName;
DAVClient(DAV dav) {
client = newClient(
dav.uri,
user: dav.user,
password: dav.password,
);
DAVClient(DAVProps dav) {
client = newClient(dav.uri, user: dav.user, password: dav.password);
fileName = dav.fileName;
client.setHeaders(
{
'accept-charset': 'utf-8',
'Content-Type': 'text/xml',
},
);
client.setHeaders({'accept-charset': 'utf-8', 'Content-Type': 'text/xml'});
client.setConnectTimeout(8000);
client.setSendTimeout(60000);
client.setReceiveTimeout(60000);
@@ -42,15 +32,16 @@ class DAVClient {
String get backupFile => '$root/$fileName';
Future<bool> backup(Uint8List data) async {
Future<bool> backup(String localFilePath) async {
await client.mkdir(root);
await client.write(backupFile, data);
await client.writeFromFile(localFilePath, backupFile);
return true;
}
Future<List<int>> recovery() async {
Future<bool> restore() async {
await client.mkdir(root);
final data = await client.read(backupFile);
return data;
final backupFilePath = await appPath.backupFilePath;
await client.read2File(backupFile, backupFilePath);
return true;
}
}

38
lib/common/file.dart Normal file
View File

@@ -0,0 +1,38 @@
import 'dart:io';
extension FileExt on File {
Future<void> safeCopy(String newPath) async {
if (!await exists()) {
await create(recursive: true);
return;
}
final targetFile = File(newPath);
if (!await targetFile.exists()) {
await targetFile.create(recursive: true);
}
await copy(newPath);
}
Future<File> safeWriteAsString(String str) async {
if (!await exists()) {
await create(recursive: true);
}
return await writeAsString(str);
}
Future<File> safeWriteAsBytes(List<int> bytes) async {
if (!await exists()) {
await create(recursive: true);
}
return await writeAsBytes(bytes);
}
}
extension FileSystemEntityExt on FileSystemEntity {
Future<void> safeDelete({bool recursive = false}) async {
if (!await exists()) {
return;
}
await delete(recursive: recursive);
}
}

View File

@@ -1,15 +1,15 @@
import 'dart:io';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/controller.dart';
class FlClashHttpOverrides extends HttpOverrides {
static String handleFindProxy(Uri url) {
if ([localhost].contains(url.host)) {
return 'DIRECT';
}
final port = globalState.config.patchClashConfig.mixedPort;
final isStart = globalState.appState.runTime != null;
final port = appController.config.patchClashConfig.mixedPort;
final isStart = appController.isStart;
commonPrint.log('find $url proxy:$isStart');
if (!isStart) return 'DIRECT';
return 'PROXY localhost:$port';

260
lib/common/indexing.dart Normal file
View File

@@ -0,0 +1,260 @@
import 'dart:math';
class Indexing {
static const String digits =
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
static const String integerZero = 'a0';
static const String smallestInteger = 'A00000000000000000000000000';
static Indexing? _instance;
Indexing._internal();
factory Indexing() {
_instance ??= Indexing._internal();
return _instance!;
}
int _getIntegerLength(String head) {
if (head.compareTo('a') >= 0 && head.compareTo('z') <= 0) {
return head.codeUnitAt(0) - 'a'.codeUnitAt(0) + 2;
} else if (head.compareTo('A') >= 0 && head.compareTo('Z') <= 0) {
return 'Z'.codeUnitAt(0) - head.codeUnitAt(0) + 2;
} else {
throw Exception('Invalid order key head: $head');
}
}
bool _validateInteger(String integer) {
if (integer.length != _getIntegerLength(integer[0])) {
throw Exception('Invalid integer part of order key: $integer');
}
return true;
}
String? _incrementInteger(String x) {
_validateInteger(x);
String head = x[0];
List<String> digs = x.substring(1).split('');
bool carry = true;
for (int i = digs.length - 1; carry && i >= 0; i--) {
int d = digits.indexOf(digs[i]) + 1;
if (d == digits.length) {
digs[i] = '0';
} else {
digs[i] = digits[d];
carry = false;
}
}
if (carry) {
if (head == 'Z') {
return 'a0';
}
if (head == 'z') {
return null;
}
String h = String.fromCharCode(head.codeUnitAt(0) + 1);
if (h.compareTo('a') > 0) {
digs.add('0');
} else {
digs.removeLast();
}
return h + digs.join('');
} else {
return head + digs.join('');
}
}
String? _decrementInteger(String x) {
_validateInteger(x);
String head = x[0];
List<String> digs = x.substring(1).split('');
bool borrow = true;
for (int i = digs.length - 1; borrow && i >= 0; i--) {
int d = digits.indexOf(digs[i]) - 1;
if (d == -1) {
digs[i] = digits[digits.length - 1];
} else {
digs[i] = digits[d];
borrow = false;
}
}
if (borrow) {
if (head == 'a') {
return 'Z${digits[digits.length - 1]}';
}
if (head == 'A') {
return null;
}
String h = String.fromCharCode(head.codeUnitAt(0) - 1);
if (h.compareTo('Z') < 0) {
digs.add(digits[digits.length - 1]);
} else {
digs.removeLast();
}
return h + digs.join('');
} else {
return head + digs.join('');
}
}
String _midpoint(String a, String? b) {
if (b != null && a.compareTo(b) >= 0) {
throw Exception(
'Second order key must be greater than the first: $a, $b',
);
}
if (a.isNotEmpty && a[a.length - 1] == '0' ||
(b != null && b.isNotEmpty && b[b.length - 1] == '0')) {
throw Exception('Trailing zeros are not allowed: $a, $b');
}
if (b != null) {
int n = 0;
while ((n < a.length ? a[n] : '0') == b[n]) {
n++;
}
if (n > 0) {
return b.substring(0, n) +
_midpoint(
a.substring(min(n, a.length)),
b.substring(min(n, b.length)),
);
}
}
int digitA = (a.isNotEmpty) ? digits.indexOf(a[0]) : 0;
int digitB = (b != null && b.isNotEmpty)
? digits.indexOf(b[0])
: digits.length;
if (digitB - digitA > 1) {
int midDigit = (digitA + digitB + 1) ~/ 2;
return digits[midDigit];
} else {
if (b != null && b.length > 1) {
return b.substring(0, 1);
} else {
return digits[digitA] +
_midpoint(a.isNotEmpty ? a.substring(1) : '', null);
}
}
}
String _getIntegerPart(String key) {
int integerPartLength = _getIntegerLength(key[0]);
if (integerPartLength > key.length) {
throw Exception('Invalid order key: $key');
}
return key.substring(0, integerPartLength);
}
bool _validateOrderKey(String key) {
if (key == smallestInteger) {
throw Exception('Invalid order key: $key');
}
String i = _getIntegerPart(key);
String f = key.substring(i.length);
if (f.isNotEmpty && f[f.length - 1] == '0') {
throw Exception('Invalid order key: $key');
}
return true;
}
String? generateKeyBetween(String? a, String? b) {
if (a != null) {
_validateOrderKey(a);
}
if (b != null) {
_validateOrderKey(b);
}
if (a != null && b != null && a.compareTo(b) >= 0) {
throw Exception(
'Second order key must be greater than the first: $a, $b',
);
}
if (a == null && b == null) {
return integerZero;
}
if (a == null) {
b = b!;
String ib = _getIntegerPart(b);
String fb = b.substring(ib.length);
if (ib == smallestInteger) {
return ib + _midpoint('', fb);
}
return ib.compareTo(b) < 0 ? ib : _decrementInteger(ib);
}
if (b == null) {
String ia = _getIntegerPart(a);
String fa = a.substring(ia.length);
String? i = _incrementInteger(ia);
return i ?? ia + _midpoint(fa, null);
}
String ia = _getIntegerPart(a);
String fa = a.substring(ia.length);
String ib = _getIntegerPart(b);
String fb = b.substring(ib.length);
if (ia == ib) {
return ia + _midpoint(fa, fb);
}
String? i = _incrementInteger(ia);
return (i == null || i.compareTo(b) < 0) ? i : ia + _midpoint(fa, null);
}
List<String?> generateNKeysBetween(String? a, String? b, int n) {
if (n <= 0) {
return [];
}
if (n == 1) {
return [generateKeyBetween(a, b)];
}
if (b == null) {
String? c = generateKeyBetween(a, b);
List<String?> result = [c];
for (int i = 1; i < n; i++) {
c = generateKeyBetween(c, b);
result.add(c);
}
return result;
}
if (a == null) {
String? c = generateKeyBetween(a, b);
List<String?> result = [c];
for (int i = 1; i < n; i++) {
c = generateKeyBetween(a, c);
result.add(c);
}
return result.reversed.toList();
}
int mid = n ~/ 2;
String? c = generateKeyBetween(a, b);
return generateNKeysBetween(a, c, mid)
.followedBy([c])
.followedBy(generateNKeysBetween(c, b, n - mid - 1))
.toList();
}
}
final indexing = Indexing();

View File

@@ -1,5 +1,5 @@
extension IterableExt<T> on Iterable<T> {
Iterable<T> separated(T separator) sync* {
extension IterableExt<E> on Iterable<E> {
Iterable<E> separated(E separator) sync* {
final iterator = this.iterator;
if (!iterator.moveNext()) return;
@@ -11,7 +11,7 @@ extension IterableExt<T> on Iterable<T> {
}
}
Iterable<List<T>> chunks(int size) sync* {
Iterable<List<E>> chunks(int size) sync* {
if (length == 0) return;
var iterator = this.iterator;
while (iterator.moveNext()) {
@@ -23,7 +23,7 @@ extension IterableExt<T> on Iterable<T> {
}
}
Iterable<T> fill(int length, {required T Function(int count) filler}) sync* {
Iterable<E> fill(int length, {required E Function(int count) filler}) sync* {
int count = 0;
for (var item in this) {
yield item;
@@ -36,7 +36,7 @@ extension IterableExt<T> on Iterable<T> {
}
}
Iterable<T> takeLast({int count = 50}) {
Iterable<E> takeLast({int count = 50}) {
if (count <= 0) return Iterable.empty();
return count >= length ? this : toList().skip(length - count);
}
@@ -78,16 +78,18 @@ extension ListExt<T> on List<T> {
return sublist(start);
}
T safeGet(int index) {
if (length > index) return this[index];
return last;
T? safeGet(int index, {T? defaultValue}) {
if (index < 0 || index >= length) {
return defaultValue;
}
return this[index];
}
T safeLast(T value) {
T safeLast(T defaultValue) {
if (isNotEmpty) {
return last;
}
return value;
return defaultValue;
}
void addOrRemove(T value) {

53
lib/common/migration.dart Normal file
View File

@@ -0,0 +1,53 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/models/models.dart';
class Migration {
static Migration? _instance;
late int _oldVersion;
Migration._internal();
final currentVersion = 1;
factory Migration() {
_instance ??= Migration._internal();
return _instance!;
}
Future<Config> migrationIfNeeded(
Map<String, Object?>? configMap, {
required Future<Config> Function(MigrationData data) sync,
}) async {
_oldVersion = await preferences.getVersion();
if (_oldVersion == currentVersion) {
try {
return Config.realFromJson(configMap);
} catch (_) {
final isV0 = configMap?['proxiesStyle'] != null;
if (isV0) {
_oldVersion = 0;
} else {
throw 'Local data is damaged. A reset is required to fix this issue.';
}
}
}
MigrationData data = MigrationData(configMap: 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;
}
Future<MigrationData> _oldToNow(Map<String, Object?> configMap) async {
return await oldToNowTask(configMap);
}
}
final migration = Migration();

View File

@@ -2,17 +2,21 @@ import 'package:riverpod/riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
mixin AutoDisposeNotifierMixin<T> on AnyNotifier<T, T> {
T get value => state;
set value(T value) {
if (ref.mounted) {
state = value;
} else {
onUpdate(value);
}
state = value;
}
bool equals(T previous, T next) {
return false;
}
@override
bool updateShouldNotify(previous, next) {
final res = super.updateShouldNotify(previous, next);
final res = !equals(previous, next)
? super.updateShouldNotify(previous, next)
: true;
if (res) {
onUpdate(next);
}
@@ -21,31 +25,19 @@ mixin AutoDisposeNotifierMixin<T> on AnyNotifier<T, T> {
void onUpdate(T value) {}
void update(T Function(T) builder) {
final value = builder(state);
this.value = value;
void update(T? Function(T) builder) {
final res = builder(value);
if (res == null) {
return;
}
value = res;
}
}
mixin AnyNotifierMixin<T> on AnyNotifier<T, T> {
mixin AsyncNotifierMixin<T> on AnyNotifier<AsyncValue<T>, T> {
T get value;
set value(T value) {
if (ref.mounted) {
state = value;
} else {
onUpdate(value);
}
state = AsyncData(value);
}
@override
bool updateShouldNotify(previous, next) {
final res = super.updateShouldNotify(previous, next);
if (res) {
onUpdate(next);
}
return res;
}
void onUpdate(T value) {}
}

View File

@@ -1,13 +1,11 @@
import 'package:animations/animations.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/controller.dart';
import 'package:flutter/material.dart';
class BaseNavigator {
static Future<T?> push<T>(BuildContext context, Widget child) async {
if (globalState.appState.viewMode != ViewMode.mobile) {
if (!appController.isMobile) {
return await Navigator.of(
context,
).push<T>(CommonDesktopRoute(builder: (context) => child));

View File

@@ -1,3 +1,5 @@
import 'dart:math';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/common.dart';
import 'package:fl_clash/state.dart';
@@ -20,6 +22,10 @@ extension NumExt on num {
return this * (1 + (globalState.theme.textScaleFactor - 1) * 0.5);
}
double get mAp {
return this * min((1 + (globalState.theme.textScaleFactor - 1) * 0.5), 1);
}
TrafficShow get traffic {
final units = TrafficUnit.values;
var size = toDouble();
@@ -51,7 +57,7 @@ extension NumExt on num {
extension DoubleExt on double {
bool moreOrEqual(double value) {
return this > value || (value - this).abs() < precisionErrorTolerance + 2;
return this > value || (value - this).abs() < precisionErrorTolerance + 1;
}
}

View File

@@ -61,19 +61,39 @@ class AppPath {
return directory.path;
}
Future<String> get databasePath async {
final mHomeDirPath = await homeDirPath;
return join(mHomeDirPath, 'database.sqlite');
}
Future<String> get backupFilePath async {
final mHomeDirPath = await homeDirPath;
return join(mHomeDirPath, 'backup.zip');
}
Future<String> get restoreDirPath async {
final mHomeDirPath = await homeDirPath;
return join(mHomeDirPath, 'restore');
}
Future<String> get tempFilePath async {
final mTempDir = await tempDir.future;
return join(mTempDir.path, 'temp${utils.id}');
}
Future<String> get lockFilePath async {
final homeDirPath = await appPath.homeDirPath;
return join(homeDirPath, 'FlClash.lock');
}
Future<String> get configFilePath async {
final homeDirPath = await appPath.homeDirPath;
return join(homeDirPath, 'config.yaml');
final mHomeDirPath = await homeDirPath;
return join(mHomeDirPath, 'config.yaml');
}
Future<String> get validateFilePath async {
final homeDirPath = await appPath.homeDirPath;
return join(homeDirPath, 'temp', 'validate${utils.id}.yaml');
Future<String> get sharedFilePath async {
final mHomeDirPath = await homeDirPath;
return join(mHomeDirPath, 'shared.json');
}
Future<String> get sharedPreferencesPath async {
@@ -86,9 +106,18 @@ class AppPath {
return join(directory.path, profilesDirectoryName);
}
Future<String> getProfilePath(String id) async {
final directory = await profilesPath;
return join(directory, '$id.yaml');
Future<String> getProfilePath(String fileName) async {
return join(await profilesPath, '$fileName.yaml');
}
Future<String> get scriptsDirPath async {
final path = await homeDirPath;
return join(path, 'scripts');
}
Future<String> getScriptPath(String fileName) async {
final path = await scriptsDirPath;
return join(path, '$fileName.js');
}
Future<String> getIconsCacheDir() async {

View File

@@ -7,9 +7,9 @@ import 'package:image_picker/image_picker.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
class Picker {
Future<PlatformFile?> pickerFile() async {
Future<PlatformFile?> pickerFile({bool withData = true}) async {
final filePickerResult = await FilePicker.platform.pickFiles(
withData: true,
withData: withData,
allowMultiple: false,
initialDirectory: await appPath.downloadDirPath,
);
@@ -20,15 +20,33 @@ class Picker {
final path = await FilePicker.platform.saveFile(
fileName: fileName,
initialDirectory: await appPath.downloadDirPath,
bytes: system.isAndroid ? bytes : null,
bytes: bytes,
);
if (!system.isAndroid && path != null) {
final file = await File(path).create(recursive: true);
await file.writeAsBytes(bytes);
final file = File(path);
await file.safeWriteAsBytes(bytes);
}
return path;
}
Future<String?> saveFileWithPath(String fileName, String localPath) async {
final localFile = File(localPath);
if (!await localFile.exists()) {
await localFile.create(recursive: true);
}
final bytes = Platform.isAndroid ? await localFile.readAsBytes() : null;
final path = await FilePicker.platform.saveFile(
fileName: fileName,
initialDirectory: await appPath.downloadDirPath,
bytes: bytes,
);
if (path != null && bytes == null) {
await localFile.copy(path);
}
await localFile.safeDelete();
return path;
}
Future<String?> pickerConfigQRCode() async {
final xFile = await ImagePicker().pickImage(source: ImageSource.gallery);
if (xFile == null) {

View File

@@ -24,20 +24,60 @@ class Preferences {
return _instance!;
}
Future<ClashConfig?> getClashConfig() async {
Future<int> getVersion() async {
final preferences = await sharedPreferencesCompleter.future;
final clashConfigString = preferences?.getString(clashConfigKey);
if (clashConfigString == null) return null;
final clashConfigMap = json.decode(clashConfigString);
return ClashConfig.fromJson(clashConfigMap);
return preferences?.getInt('version') ?? 0;
}
Future<void> setVersion(int version) async {
final preferences = await sharedPreferencesCompleter.future;
await preferences?.setInt('version', version);
}
Future<void> saveShareState(SharedState shareState) async {
final preferences = await sharedPreferencesCompleter.future;
await preferences?.setString('sharedState', json.encode(shareState));
}
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;
}
}
Future<Config?> getConfig() async {
final preferences = await sharedPreferencesCompleter.future;
final configString = preferences?.getString(configKey);
if (configString == null) return null;
final configMap = json.decode(configString);
return Config.compatibleFromJson(configMap);
final configMap = await getConfigMap();
if (configMap == null) {
return null;
}
return Config.fromJson(configMap);
}
Future<bool> saveConfig(Config config) async {
@@ -45,14 +85,9 @@ class Preferences {
return preferences?.setString(configKey, json.encode(config)) ?? false;
}
Future<void> clearClashConfig() async {
final preferences = await sharedPreferencesCompleter.future;
preferences?.remove(clashConfigKey);
}
Future<void> clearPreferences() async {
final sharedPreferencesIns = await sharedPreferencesCompleter.future;
sharedPreferencesIns?.clear();
await sharedPreferencesIns?.clear();
}
}

View File

@@ -1,7 +1,7 @@
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CommonPrint {
static CommonPrint? _instance;
@@ -16,12 +16,10 @@ class CommonPrint {
void log(String? text, {LogLevel logLevel = LogLevel.info}) {
final payload = '[APP] $text';
debugPrint(payload);
if (!globalState.isInit) {
if (!appController.isAttach) {
return;
}
globalState.appController.addLog(
Log.app(payload).copyWith(logLevel: logLevel),
);
appController.addLog(Log.app(payload).copyWith(logLevel: logLevel));
}
}

View File

@@ -6,6 +6,8 @@ import 'dart:typed_data';
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/cupertino.dart';
@@ -22,7 +24,7 @@ class Request {
createHttpClient: () {
final client = HttpClient();
client.findProxy = (Uri uri) {
client.userAgent = globalState.ua;
client.userAgent = appController.ua;
return FlClashHttpOverrides.handleFindProxy(uri);
};
return client;
@@ -31,10 +33,23 @@ class Request {
}
Future<Response<Uint8List>> getFileResponseForUrl(String url) async {
return await _clashDio.get<Uint8List>(
url,
options: Options(responseType: ResponseType.bytes),
);
try {
return await _clashDio.get<Uint8List>(
url,
options: Options(responseType: ResponseType.bytes),
);
} catch (e) {
commonPrint.log('getFileResponseForUrl error ${e.toString()}');
if (e is DioException) {
if (e.type == DioExceptionType.unknown) {
throw appLocalizations.unknownNetworkError;
} else if (e.type == DioExceptionType.badResponse) {
throw appLocalizations.networkException;
}
rethrow;
}
throw appLocalizations.unknownNetworkError;
}
}
Future<Response<String>> getTextResponseForUrl(String url) async {
@@ -57,18 +72,23 @@ class Request {
}
Future<Map<String, dynamic>?> checkForUpdate() async {
final response = await dio.get(
'https://api.github.com/repos/$repository/releases/latest',
options: Options(responseType: ResponseType.json),
);
if (response.statusCode != 200) return null;
final data = response.data as Map<String, dynamic>;
final remoteVersion = data['tag_name'];
final version = globalState.packageInfo.version;
final hasUpdate =
utils.compareVersions(remoteVersion.replaceAll('v', ''), version) > 0;
if (!hasUpdate) return null;
return data;
try {
final response = await dio.get(
'https://api.github.com/repos/$repository/releases/latest',
options: Options(responseType: ResponseType.json),
);
if (response.statusCode != 200) return null;
final data = response.data as Map<String, dynamic>;
final remoteVersion = data['tag_name'];
final version = globalState.packageInfo.version;
final hasUpdate =
utils.compareVersions(remoteVersion.replaceAll('v', ''), version) > 0;
if (!hasUpdate) return null;
return data;
} catch (e) {
commonPrint.log('checkForUpdate failed', logLevel: LogLevel.warning);
return null;
}
}
final Map<String, IpInfo Function(Map<String, dynamic>)> _ipInfoSources = {
@@ -83,6 +103,7 @@ class Request {
Future<Result<IpInfo?>> checkIp({CancelToken? cancelToken}) async {
var failureCount = 0;
final token = cancelToken ?? CancelToken();
final futures = _ipInfoSources.entries.map((source) async {
final Completer<Result<IpInfo?>> completer = Completer();
handleFailRes() {
@@ -94,7 +115,7 @@ class Request {
final future = dio
.get<Map<String, dynamic>>(
source.key,
cancelToken: cancelToken,
cancelToken: token,
options: Options(responseType: ResponseType.json),
)
.timeout(const Duration(seconds: 10));
@@ -117,7 +138,7 @@ class Request {
return completer.future;
});
final res = await Future.any(futures);
cancelToken?.cancel();
token.cancel();
return res;
}

58
lib/common/snowflake.dart Normal file
View File

@@ -0,0 +1,58 @@
class Snowflake {
static Snowflake? _instance;
Snowflake._internal();
factory Snowflake() {
_instance ??= Snowflake._internal();
return _instance!;
}
static const int twepoch = 1704067200000;
static const int workerIdBits = 10;
static const int sequenceBits = 12;
static const int maxWorkerId = -1 ^ (-1 << workerIdBits);
static const int sequenceMask = -1 ^ (-1 << sequenceBits);
static const int workerIdShift = sequenceBits;
static const int timestampLeftShift = sequenceBits + workerIdBits;
final int workerId = 1;
int _lastTimestamp = -1;
int _sequence = 0;
int get id {
int timestamp = DateTime.now().millisecondsSinceEpoch;
if (timestamp < _lastTimestamp) {
throw ArgumentError(
'Clock moved backwards. Refusing to generate id for ${_lastTimestamp - timestamp} milliseconds',
);
}
if (timestamp == _lastTimestamp) {
_sequence = (_sequence + 1) & sequenceMask;
if (_sequence == 0) {
timestamp = _getNextMillis(_lastTimestamp);
}
} else {
_sequence = 0;
}
_lastTimestamp = timestamp;
return ((timestamp - twepoch) << timestampLeftShift) |
(workerId << workerIdShift) |
_sequence;
}
int _getNextMillis(int lastTimestamp) {
int timestamp = DateTime.now().millisecondsSinceEpoch;
while (timestamp <= lastTimestamp) {
timestamp = DateTime.now().millisecondsSinceEpoch;
}
return timestamp;
}
}
final snowflake = Snowflake();

33
lib/common/store.dart Normal file
View File

@@ -0,0 +1,33 @@
import 'dart:async';
class Store<T> {
late T _data;
Store(Stream stream, T defaultValue) {
stream.listen((data) {
_add(data);
});
_data = defaultValue;
}
bool equals(T oldValue, T newValue) {
return oldValue == newValue;
}
void _add(T value) {
if (!equals(_data, value)) {
_streamController.add(value);
_data = value;
}
}
final StreamController<T> _streamController = StreamController<T>.broadcast();
Stream<T> get stream => _streamController.stream;
T get value => _data;
set value(T value) {
_add(value);
}
}

View File

@@ -2,8 +2,7 @@ import 'dart:convert';
import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'print.dart';
import 'package:fl_clash/common/common.dart';
extension StringExtension on String {
bool get isUrl {
@@ -78,13 +77,26 @@ extension StringExtension on String {
// bool containsToLower(String target) {
// return toLowerCase().contains(target);
// }
}
extension StringExtensionSafe on String? {
String getSafeValue(String defaultValue) {
if (this == null || this!.isEmpty) {
return defaultValue;
Future<T> commonToJSON<T>() async {
final thresholdLimit = 51200;
if (length < thresholdLimit) {
return json.decode(this);
} else {
return await decodeJSONTask<T>(this);
}
return this!;
}
}
extension StringNullExt on String? {
String takeFirstValid(List<String?> others, {String defaultValue = ''}) {
if (this != null && this!.trim().isNotEmpty) return this!.trim();
for (final s in others) {
if (s != null && s.trim().isNotEmpty) {
return s.trim();
}
}
return defaultValue;
}
}

View File

@@ -260,8 +260,9 @@ class Windows {
await Future.delayed(Duration(milliseconds: 300));
final retryStatus = await retry(
task: checkService,
maxAttempts: 5,
retryIf: (status) => status != WindowsHelperServiceStatus.running,
delay: commonDuration,
delay: Duration(seconds: 1),
);
return res && retryStatus == WindowsHelperServiceStatus.running;
}

612
lib/common/task.dart Normal file
View File

@@ -0,0 +1,612 @@
import 'dart:convert';
import 'dart:io';
import 'package:archive/archive_io.dart';
import 'package:drift/drift.dart';
import 'package:drift_flutter/drift_flutter.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/database/database.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:path/path.dart';
Future<T> decodeJSONTask<T>(String data) async {
return await compute<String, T>(_decodeJSON, data);
}
Future<T> _decodeJSON<T>(String content) async {
return json.decode(content);
}
Future<String> encodeJSONTask<T>(T data) async {
return await compute<T, String>(_encodeJSON, data);
}
Future<String> _encodeJSON<T>(T content) async {
return json.encode(content);
}
Future<String> encodeYamlTask<T>(T data) async {
return await compute<T, String>(_encodeYaml, data);
}
Future<String> _encodeYaml<T>(T content) async {
return yaml.encode(content);
}
Future<List<Group>> toGroupsTask(ComputeGroupsState data) async {
return await compute<ComputeGroupsState, List<Group>>(_toGroupsTask, data);
}
Future<List<Group>> _toGroupsTask(ComputeGroupsState state) async {
final proxiesData = state.proxiesData;
final all = proxiesData.all;
final sortType = state.sortType;
final delayMap = state.delayMap;
final selectedMap = state.selectedMap;
final defaultTestUrl = state.defaultTestUrl;
final proxies = proxiesData.proxies;
if (proxies.isEmpty) return [];
final groupsRaw = all
.where((name) {
final proxy = proxies[name] ?? {};
return GroupTypeExtension.valueList.contains(proxy['type']);
})
.map((groupName) {
final group = proxies[groupName];
group['all'] = ((group['all'] ?? []) as List)
.map((name) => proxies[name])
.where((proxy) => proxy != null)
.toList();
return group;
})
.toList();
final groups = groupsRaw.map((e) => Group.fromJson(e)).toList();
return computeSort(
groups: groups,
sortType: sortType,
delayMap: delayMap,
selectedMap: selectedMap,
defaultTestUrl: defaultTestUrl,
);
}
Future<Map<String, dynamic>> makeRealProfileTask(
MakeRealProfileState data,
) async {
return await compute<MakeRealProfileState, Map<String, dynamic>>(
_makeRealProfileTask,
data,
);
}
Future<Map<String, dynamic>> _makeRealProfileTask(
MakeRealProfileState data,
) async {
final rawConfig = Map.from(data.rawConfig);
final realPatchConfig = data.realPatchConfig;
final profilesPath = data.profilesPath;
final profileId = data.profileId;
final overrideDns = data.overrideDns;
final addedRules = data.addedRules;
final appendSystemDns = data.appendSystemDns;
final defaultUA = data.defaultUA;
String getProvidersFilePathInner(String type, String url) {
return join(
profilesPath,
'providers',
profileId.toString(),
type,
url.toMd5(),
);
}
rawConfig['external-controller'] = realPatchConfig.externalController.value;
rawConfig['external-ui'] = '';
rawConfig['interface-name'] = '';
rawConfig['external-ui-url'] = '';
rawConfig['tcp-concurrent'] = realPatchConfig.tcpConcurrent;
rawConfig['unified-delay'] = realPatchConfig.unifiedDelay;
rawConfig['ipv6'] = realPatchConfig.ipv6;
rawConfig['log-level'] = realPatchConfig.logLevel.name;
rawConfig['port'] = 0;
rawConfig['socks-port'] = 0;
rawConfig['keep-alive-interval'] = realPatchConfig.keepAliveInterval;
rawConfig['mixed-port'] = realPatchConfig.mixedPort;
rawConfig['port'] = realPatchConfig.port;
rawConfig['socks-port'] = realPatchConfig.socksPort;
rawConfig['redir-port'] = realPatchConfig.redirPort;
rawConfig['tproxy-port'] = realPatchConfig.tproxyPort;
rawConfig['find-process-mode'] = realPatchConfig.findProcessMode.name;
rawConfig['allow-lan'] = realPatchConfig.allowLan;
rawConfig['mode'] = realPatchConfig.mode.name;
if (rawConfig['tun'] == null) {
rawConfig['tun'] = {};
}
rawConfig['tun']['enable'] = realPatchConfig.tun.enable;
rawConfig['tun']['device'] = realPatchConfig.tun.device;
rawConfig['tun']['dns-hijack'] = realPatchConfig.tun.dnsHijack;
rawConfig['tun']['stack'] = realPatchConfig.tun.stack.name;
rawConfig['tun']['route-address'] = realPatchConfig.tun.routeAddress;
rawConfig['tun']['auto-route'] = realPatchConfig.tun.autoRoute;
rawConfig['geodata-loader'] = realPatchConfig.geodataLoader.name;
if (rawConfig['sniffer']?['sniff'] != null) {
for (final value in (rawConfig['sniffer']?['sniff'] as Map).values) {
if (value['ports'] != null && value['ports'] is List) {
value['ports'] =
value['ports']?.map((item) => item.toString()).toList() ?? [];
}
}
}
if (rawConfig['profile'] == null) {
rawConfig['profile'] = {};
}
if (rawConfig['proxy-providers'] != null) {
final proxyProviders = rawConfig['proxy-providers'] as Map;
for (final key in proxyProviders.keys) {
final proxyProvider = proxyProviders[key];
if (proxyProvider['type'] != 'http') {
continue;
}
if (proxyProvider['url'] != null) {
proxyProvider['path'] = getProvidersFilePathInner(
'proxies',
proxyProvider['url'],
);
}
}
}
if (rawConfig['rule-providers'] != null) {
final ruleProviders = rawConfig['rule-providers'] as Map;
for (final key in ruleProviders.keys) {
final ruleProvider = ruleProviders[key];
if (ruleProvider['type'] != 'http') {
continue;
}
if (ruleProvider['url'] != null) {
ruleProvider['path'] = getProvidersFilePathInner(
'rules',
ruleProvider['url'],
);
}
}
}
rawConfig['profile']['store-selected'] = false;
rawConfig['geox-url'] = realPatchConfig.geoXUrl.toJson();
rawConfig['global-ua'] = realPatchConfig.globalUa ?? defaultUA;
if (rawConfig['hosts'] == null) {
rawConfig['hosts'] = {};
}
for (final host in realPatchConfig.hosts.entries) {
rawConfig['hosts'][host.key] = host.value.splitByMultipleSeparators;
}
if (rawConfig['dns'] == null) {
rawConfig['dns'] = {};
}
final isEnableDns = rawConfig['dns']['enable'] == true;
final systemDns = 'system://';
if (overrideDns || !isEnableDns) {
final dns = switch (!isEnableDns) {
true => realPatchConfig.dns.copyWith(
nameserver: [...realPatchConfig.dns.nameserver, systemDns],
),
false => realPatchConfig.dns,
};
rawConfig['dns'] = dns.toJson();
rawConfig['dns']['nameserver-policy'] = {};
for (final entry in dns.nameserverPolicy.entries) {
rawConfig['dns']['nameserver-policy'][entry.key] =
entry.value.splitByMultipleSeparators;
}
}
if (appendSystemDns) {
final List<String> nameserver = List<String>.from(
rawConfig['dns']['nameserver'] ?? [],
);
if (!nameserver.contains(systemDns)) {
rawConfig['dns']['nameserver'] = [...nameserver, systemDns];
}
}
List<String> rules = [];
if (rawConfig['rules'] != null) {
rules = List<String>.from(rawConfig['rules']);
}
rawConfig.remove('rules');
if (addedRules.isNotEmpty) {
final parsedNewRules = addedRules
.map((item) => ParsedRule.parseString(item.value))
.toList();
final hasMatchPlaceholder = parsedNewRules.any(
(item) => item.ruleTarget?.toUpperCase() == 'MATCH',
);
String? replacementTarget;
if (hasMatchPlaceholder) {
for (int i = rules.length - 1; i >= 0; i--) {
final parsed = ParsedRule.parseString(rules[i]);
if (parsed.ruleAction == RuleAction.MATCH) {
final target = parsed.ruleTarget;
if (target != null && target.isNotEmpty) {
replacementTarget = target;
break;
}
}
}
}
final List<String> finalAddedRules;
if (replacementTarget?.isNotEmpty == true) {
finalAddedRules = [];
for (int i = 0; i < parsedNewRules.length; i++) {
final parsed = parsedNewRules[i];
if (parsed.ruleTarget?.toUpperCase() == 'MATCH') {
finalAddedRules.add(
parsed.copyWith(ruleTarget: replacementTarget).value,
);
} else {
finalAddedRules.add(addedRules[i].value);
}
}
} else {
finalAddedRules = addedRules.map((e) => e.value).toList();
}
rules = [...finalAddedRules, ...rules];
}
rawConfig['rules'] = rules;
return Map<String, dynamic>.from(rawConfig);
}
Future<List<String>> shakingProfileTask(
VM2<Iterable<int>, Iterable<int>> data,
) async {
return await compute<
VM3<Iterable<int>, Iterable<int>, RootIsolateToken>,
List<String>
>(_shakingProfileTask, VM3(data.a, data.b, RootIsolateToken.instance!));
}
Future<List<String>> _shakingProfileTask(
VM3<Iterable<int>, Iterable<int>, RootIsolateToken> data,
) async {
final profileIds = data.a;
final scriptIds = data.b;
final token = data.c;
BackgroundIsolateBinaryMessenger.ensureInitialized(token);
final profilesDir = Directory(await appPath.profilesPath);
final scriptsDir = Directory(await appPath.scriptsDirPath);
final providersDir = Directory(await appPath.getProvidersRootPath());
final List<String> targets = [];
void scanDirectory(
Directory dir,
Iterable<int> baseNames, {
bool skipProvidersFolder = false,
}) {
if (!dir.existsSync()) return;
final entities = dir.listSync(recursive: false, followLinks: false);
for (final entity in entities) {
if (entity is File) {
final id = basenameWithoutExtension(entity.path);
if (!baseNames.contains(int.tryParse(id))) {
targets.add(entity.path);
}
} else if (skipProvidersFolder && entity is Directory) {
if (basename(entity.path) == 'providers') {
continue;
}
}
}
}
scanDirectory(profilesDir, profileIds, skipProvidersFolder: true);
scanDirectory(providersDir, profileIds);
scanDirectory(scriptsDir, scriptIds);
return targets;
}
Future<String> encodeLogsTask(List<Log> data) async {
return await compute<List<Log>, String>(_encodeLogsTask, data);
}
Future<String> _encodeLogsTask(List<Log> data) async {
final logsRaw = data.map((item) => item.toString());
final logsRawString = logsRaw.join('\n');
return logsRawString;
}
Future<MigrationData> oldToNowTask(Map<String, Object?> data) async {
final homeDir = await appPath.homeDirPath;
return await compute<
VM3<Map<String, Object?>, String, String>,
MigrationData
>(_oldToNowTask, VM3(data, homeDir, homeDir));
}
Future<MigrationData> _oldToNowTask(
VM3<Map<String, Object?>, String, String> data,
) async {
final configMap = data.a;
final sourcePath = data.b;
final targetPath = data.c;
final accessControlMap = configMap['accessControl'];
final isAccessControl = configMap['isAccessControl'];
if (accessControlMap != null) {
(accessControlMap as Map)['enable'] = isAccessControl;
if (configMap['vpnProps'] != null) {
final vpnPropsRaw = configMap['vpnProps'] as Map;
vpnPropsRaw['accessControl'] = accessControlMap;
}
}
if (configMap['vpnProps'] != null) {
final vpnPropsRaw = configMap['vpnProps'] as Map;
vpnPropsRaw['accessControlProps'] = vpnPropsRaw['accessControl'];
}
configMap['davProps'] = configMap['dav'];
final appSettingProps = configMap['appSetting'] as Map? ?? {};
appSettingProps['restoreStrategy'] = appSettingProps['recoveryStrategy'];
configMap['appSettingProps'] = appSettingProps;
configMap['proxiesStyleProps'] = configMap['proxiesStyle'];
configMap['proxiesStyleProps'] = configMap['proxiesStyle'];
// final overwriteMap = configMap['overwrite'] as Map? ?? {};
// configMap['overwriteType'] = overwriteMap['type'];
// configMap['scriptId'] = overwriteMap['scriptOverwrite'];
List rawScripts = configMap['scripts'] as List<dynamic>? ?? [];
if (rawScripts.isEmpty) {
final scriptPropsJson = configMap['scriptProps'] as Map<String, dynamic>?;
if (scriptPropsJson != null) {
rawScripts = scriptPropsJson['scripts'] as List<dynamic>? ?? [];
}
}
final Map<String, int> idMap = {};
final List<Script> scripts = [];
for (final rawScript in rawScripts) {
final id = rawScript['id'] as String?;
final content = rawScript['content'] as String?;
final label = rawScript['label'] as String?;
if (id == null || content == null || label == null) {
continue;
}
final newId = idMap.updateCacheValue(rawScript['id'], () => snowflake.id);
final path = _getScriptPath(targetPath, newId.toString());
final file = File(path);
await file.safeWriteAsString(content);
scripts.add(
Script(id: newId, label: label, lastUpdateTime: DateTime.now()),
);
}
List rawRules = configMap['rules'] as List<dynamic>? ?? [];
final List<Rule> rules = [];
final List<ProfileRuleLink> links = [];
for (final rawRule in rawRules) {
final id = idMap.updateCacheValue(rawRule['id'], () => snowflake.id);
rawRule['id'] = id;
rules.add(Rule.fromJson(rawRule));
links.add(ProfileRuleLink(ruleId: id));
}
List rawProfiles = configMap['profiles'] as List<dynamic>? ?? [];
final List<Profile> profiles = [];
for (final rawProfile in rawProfiles) {
final rawId = rawProfile['id'] as String?;
if (rawId == null) {
continue;
}
final profileId = idMap.updateCacheValue(rawId, () => snowflake.id);
rawProfile['id'] = profileId;
final overwrite = rawProfile['overwrite'] as Map?;
if (overwrite != null) {
final standardOverwrite = overwrite['standardOverwrite'] as Map?;
if (standardOverwrite != null) {
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(
profileId: profileId,
ruleId: id,
scene: RuleScene.added,
),
);
}
final disabledRuleIds = standardOverwrite['disabledRuleIds'] as List?;
if (disabledRuleIds != null) {
for (final disabledRuleId in disabledRuleIds) {
final newDisabledRuleId = idMap[disabledRuleId];
if (newDisabledRuleId != null) {
links.add(
ProfileRuleLink(
profileId: profileId,
ruleId: newDisabledRuleId,
scene: RuleScene.disabled,
),
);
}
}
}
}
final scriptOverwrite = overwrite['scriptOverwrite'] as Map?;
if (scriptOverwrite != null) {
final scriptId = scriptOverwrite['scriptId'] as String?;
rawProfile['scriptId'] = scriptId != null ? idMap[scriptId] : null;
}
rawProfile['overwriteType'] = overwrite['type'];
}
final sourceFile = File(_getProfilePath(sourcePath, rawId));
final targetFilePath = _getProfilePath(targetPath, profileId.toString());
await sourceFile.safeCopy(targetFilePath);
profiles.add(Profile.fromJson(rawProfile));
}
final currentProfileId = configMap['currentProfileId'];
configMap['currentProfileId'] = currentProfileId != null
? idMap[currentProfileId]
: null;
return MigrationData(
configMap: configMap,
profiles: profiles,
rules: rules,
scripts: scripts,
links: links,
);
}
Future<String> backupTask(
Map<String, dynamic> configMap,
Iterable<String> fileNames,
) async {
return await compute<
VM3<Map<String, dynamic>, Iterable<String>, RootIsolateToken>,
String
>(_backupTask, VM3(configMap, fileNames, RootIsolateToken.instance!));
}
Future<String> _backupTask<T>(
VM3<Map<String, dynamic>, Iterable<String>, RootIsolateToken> args,
) async {
final configMap = args.a;
final fileNames = args.b;
final token = args.c;
BackgroundIsolateBinaryMessenger.ensureInitialized(token);
final dbPath = await appPath.databasePath;
final configStr = json.encode(configMap);
final profilesDir = Directory(await appPath.profilesPath);
final scriptsDir = Directory(await appPath.scriptsDirPath);
final tempZipFilePath = await appPath.tempFilePath;
final tempDBFile = File(await appPath.tempFilePath);
final tempConfigFile = File(await appPath.tempFilePath);
final dbFile = File(dbPath);
if (await dbFile.exists()) {
await dbFile.copy(tempDBFile.path);
}
final encoder = ZipFileEncoder();
encoder.create(tempZipFilePath);
await tempConfigFile.writeAsString(configStr);
await encoder.addFile(tempDBFile, backupDatabaseName);
await encoder.addFile(tempConfigFile, configJsonName);
if (await profilesDir.exists()) {
await encoder.addDirectory(
profilesDir,
filter: (file, _) {
if (!fileNames.contains(basename(file.path))) {
return ZipFileOperation.skip;
}
return ZipFileOperation.include;
},
);
}
if (await scriptsDir.exists()) {
await encoder.addDirectory(
scriptsDir,
filter: (file, _) {
if (!fileNames.contains(basename(file.path))) {
return ZipFileOperation.skip;
}
return ZipFileOperation.include;
},
);
}
encoder.close();
await tempConfigFile.safeDelete();
await tempDBFile.safeDelete();
return tempZipFilePath;
}
Future<MigrationData> restoreTask() async {
return await compute<RootIsolateToken, MigrationData>(
_restoreTask,
RootIsolateToken.instance!,
);
}
Future<MigrationData> _restoreTask(RootIsolateToken token) async {
BackgroundIsolateBinaryMessenger.ensureInitialized(token);
final backupFilePath = await appPath.backupFilePath;
final restoreDirPath = await appPath.restoreDirPath;
final homeDirPath = await appPath.homeDirPath;
final zipDecoder = ZipDecoder();
final input = InputFileStream(backupFilePath);
final archive = zipDecoder.decodeStream(input);
final dir = Directory(restoreDirPath);
await dir.create(recursive: true);
for (final file in archive.files) {
final outPath = join(restoreDirPath, posix.normalize(file.name));
final outputStream = OutputFileStream(outPath);
file.writeContent(outputStream);
await outputStream.close();
}
await input.close();
final restoreConfigFile = File(join(restoreDirPath, configJsonName));
if (!await restoreConfigFile.exists()) {
throw appLocalizations.invalidBackupFile;
}
final restoreConfigMap =
json.decode(await restoreConfigFile.readAsString())
as Map<String, Object?>?;
final version = restoreConfigMap?['version'] ?? 0;
MigrationData migrationData = MigrationData(configMap: restoreConfigMap);
if (version == 0 && restoreConfigMap != null) {
migrationData = await _oldToNowTask(
VM3(restoreConfigMap, restoreDirPath, homeDirPath),
);
return migrationData;
}
final backupDatabaseFile = File(join(restoreDirPath, backupDatabaseName));
if (!await backupDatabaseFile.exists()) {
return migrationData;
}
final database = Database(
driftDatabase(
name: 'database',
native: DriftNativeOptions(
databaseDirectory: () async => Directory(restoreDirPath),
),
),
);
final results = await Future.wait([
database.profilesDao.all().get(),
database.scriptsDao.all().get(),
database.rules.all().map((item) => item.toRule()).get(),
database.profileRuleLinks.all().map((item) => item.toLink()).get(),
]);
final profiles = results[0].cast<Profile>();
final scripts = results[1].cast<Script>();
final profilesMigration = profiles.map(
(item) => VM2(
_getProfilePath(restoreDirPath, item.id.toString()),
_getProfilePath(homeDirPath, item.id.toString()),
),
);
final scriptsMigration = scripts.map(
(item) => VM2(
_getScriptPath(restoreDirPath, item.id.toString()),
_getScriptPath(homeDirPath, item.id.toString()),
),
);
await _copyWithMapList([...profilesMigration, ...scriptsMigration]);
migrationData = migrationData.copyWith(
profiles: profiles,
scripts: scripts,
rules: results[2].cast<Rule>(),
links: results[3].cast<ProfileRuleLink>(),
);
await database.close();
return migrationData;
}
Future<void> _copyWithMapList(List<VM2<String, String>> copyMapList) async {
await Future.wait(
copyMapList.map((item) => File(item.a).safeCopy(item.b)).toList(),
);
}
String _getScriptPath(String root, String fileName) {
return join(root, 'scripts', '$fileName.js');
}
String _getProfilePath(String root, String fileName) {
return join(root, 'profiles', '$fileName.yaml');
}

View File

@@ -1,9 +1,8 @@
import 'dart:io';
import 'package:fl_clash/common/iterable.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
import 'package:tray_manager/tray_manager.dart';
@@ -14,10 +13,23 @@ import 'system.dart';
import 'window.dart';
class Tray {
static Tray? _instance;
Tray._internal();
factory Tray() {
_instance ??= Tray._internal();
return _instance!;
}
String get trayIconSuffix {
return system.isWindows ? 'ico' : 'png';
}
Future<void> destroy() async {
await trayManager.destroy();
}
String getTryIcon({required bool isStart, required bool tunEnable}) {
if (system.isMacOS || !isStart) {
return 'assets/images/icon/status_1.$trayIconSuffix';
@@ -29,11 +41,10 @@ class Tray {
}
Future _updateSystemTray({
bool force = false,
required bool isStart,
required bool tunEnable,
}) async {
if (Platform.isLinux || force) {
if (Platform.isLinux) {
await trayManager.destroy();
}
await trayManager.setIcon(
@@ -47,7 +58,7 @@ class Tray {
Future<void> update({
required TrayState trayState,
bool focus = false,
required Traffic traffic,
}) async {
if (system.isAndroid) {
return;
@@ -56,7 +67,6 @@ class Tray {
await _updateSystemTray(
isStart: trayState.isStart,
tunEnable: trayState.tunEnable,
force: focus,
);
}
List<MenuItem> menuItems = [];
@@ -70,7 +80,7 @@ class Tray {
final startMenuItem = MenuItem.checkbox(
label: trayState.isStart ? appLocalizations.stop : appLocalizations.start,
onClick: (_) async {
globalState.appController.updateStart();
appController.updateStart();
},
checked: false,
);
@@ -79,7 +89,7 @@ class Tray {
final speedStatistics = MenuItem.checkbox(
label: appLocalizations.speedStatistics,
onClick: (_) async {
globalState.appController.updateSpeedStatistics();
appController.updateSpeedStatistics();
},
checked: trayState.showTrayTitle,
);
@@ -91,7 +101,7 @@ class Tray {
MenuItem.checkbox(
label: Intl.message(mode.name),
onClick: (_) {
globalState.appController.changeMode(mode);
appController.changeMode(mode);
},
checked: mode == trayState.mode,
),
@@ -106,9 +116,8 @@ class Tray {
MenuItem.checkbox(
label: proxy.name,
checked:
globalState.getSelectedProxyName(group.name) == proxy.name,
appController.getSelectedProxyName(group.name) == proxy.name,
onClick: (_) {
final appController = globalState.appController;
appController.updateCurrentSelectedMap(group.name, proxy.name);
appController.changeProxy(
groupName: group.name,
@@ -134,7 +143,7 @@ class Tray {
MenuItem.checkbox(
label: appLocalizations.tun,
onClick: (_) {
globalState.appController.updateTun();
appController.updateTun();
},
checked: trayState.tunEnable,
),
@@ -143,7 +152,7 @@ class Tray {
MenuItem.checkbox(
label: appLocalizations.systemProxy,
onClick: (_) {
globalState.appController.updateSystemProxy();
appController.updateSystemProxy();
},
checked: trayState.systemProxy,
),
@@ -153,7 +162,7 @@ class Tray {
final autoStartMenuItem = MenuItem.checkbox(
label: appLocalizations.autoLaunch,
onClick: (_) async {
globalState.appController.updateAutoLaunch();
appController.updateAutoLaunch();
},
checked: trayState.autoLaunch,
);
@@ -169,7 +178,7 @@ class Tray {
final exitMenuItem = MenuItem(
label: appLocalizations.exit,
onClick: (_) async {
await globalState.appController.handleExit();
await appController.handleExit();
},
);
menuItems.add(exitMenuItem);
@@ -179,13 +188,9 @@ class Tray {
await _updateSystemTray(
isStart: trayState.isStart,
tunEnable: trayState.tunEnable,
force: focus,
);
}
updateTrayTitle(
showTrayTitle: trayState.showTrayTitle,
traffic: globalState.appState.traffics.list.safeLast(Traffic()),
);
updateTrayTitle(showTrayTitle: trayState.showTrayTitle, traffic: traffic);
}
Future<void> updateTrayTitle({

View File

@@ -10,6 +10,15 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class Utils {
static Utils? _instance;
Utils._internal();
factory Utils() {
_instance ??= Utils._internal();
return _instance!;
}
Color? getDelayColor(int? delay) {
if (delay == null) return null;
if (delay < 0) return Colors.red;
@@ -319,7 +328,7 @@ class Utils {
required Function function,
required void Function(T data, int elapsedMilliseconds) onWatch,
}) async {
if (kDebugMode) {
if (kDebugMode && watchExecution) {
final stopwatch = Stopwatch()..start();
final res = await function();
stopwatch.stop();
@@ -328,6 +337,21 @@ class Utils {
}
return await function();
}
int fastHash(String string) {
var hash = 0xcbf29ce484222325;
var i = 0;
while (i < string.length) {
final codeUnit = string.codeUnitAt(i++);
hash ^= codeUnit >> 8;
hash *= 0x100000001b3;
hash ^= codeUnit & 0xFF;
hash *= 0x100000001b3;
}
return hash;
}
}
final utils = Utils();

View File

@@ -2,14 +2,21 @@ import 'dart:io';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/models/config.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:screen_retriever/screen_retriever.dart';
import 'package:window_manager/window_manager.dart';
class Window {
Future<void> init(int version) async {
final props = globalState.config.windowProps;
static Window? _instance;
Window._internal();
factory Window() {
_instance ??= Window._internal();
return _instance!;
}
Future<void> init(int version, WindowProps props) async {
final acquire = await singleInstanceLock.acquire();
if (!acquire) {
exit(0);
@@ -76,6 +83,7 @@ class Window {
}
Future<void> close() async {
await windowManager.close();
exit(0);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,12 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/core/core.dart';
import 'package:fl_clash/core/interface.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/services.dart';
import 'package:path/path.dart';
@@ -67,25 +65,23 @@ class CoreController {
);
}
Future<void> shutdown() async {
await _interface.shutdown();
Future<void> shutdown(bool isUser) async {
await _interface.shutdown(isUser);
}
FutureOr<bool> get isInit => _interface.isInit;
Future<String> validateConfig(String data) async {
final path = await appPath.validateFilePath;
await globalState.genValidateFile(path, data);
Future<String> validateConfig(String path) async {
final res = await _interface.validateConfig(path);
await File(path).delete();
return res;
}
Future<String> validateConfigFormBytes(Uint8List bytes) async {
final path = await appPath.validateFilePath;
await globalState.genValidateFileFormBytes(path, bytes);
Future<String> validateConfigWithData(String data) async {
final path = await appPath.tempFilePath;
final file = File(path);
await file.safeWriteAsString(data);
final res = await _interface.validateConfig(path);
await File(path).delete();
await File(path).safeDelete();
return res;
}
@@ -111,33 +107,16 @@ class CoreController {
required Map<String, String> selectedMap,
required String defaultTestUrl,
}) async {
final proxies = await _interface.getProxies();
return Isolate.run<List<Group>>(() {
if (proxies.isEmpty) return [];
final groupNames = [
UsedProxy.GLOBAL.name,
...(proxies[UsedProxy.GLOBAL.name]['all'] as List).where((e) {
final proxy = proxies[e] ?? {};
return GroupTypeExtension.valueList.contains(proxy['type']);
}),
];
final groupsRaw = groupNames.map((groupName) {
final group = proxies[groupName];
group['all'] = ((group['all'] ?? []) as List)
.map((name) => proxies[name])
.where((proxy) => proxy != null)
.toList();
return group;
}).toList();
final groups = groupsRaw.map((e) => Group.fromJson(e)).toList();
return computeSort(
groups: groups,
final proxiesData = await _interface.getProxies();
return toGroupsTask(
ComputeGroupsState(
proxiesData: proxiesData,
sortType: sortType,
delayMap: delayMap,
selectedMap: selectedMap,
defaultTestUrl: defaultTestUrl,
);
});
),
);
}
FutureOr<String> changeProxy(ChangeProxyParams changeProxyParams) async {
@@ -168,13 +147,11 @@ class CoreController {
if (externalProvidersRawString.isEmpty) {
return [];
}
return Isolate.run<List<ExternalProvider>>(() {
final externalProviders =
(json.decode(externalProvidersRawString) as List<dynamic>)
.map((item) => ExternalProvider.fromJson(item))
.toList();
return externalProviders;
});
final externalProviders =
(await externalProvidersRawString.commonToJSON<List<dynamic>>())
.map((item) => ExternalProvider.fromJson(item))
.toList();
return externalProviders;
}
Future<ExternalProvider?> getExternalProvider(
@@ -220,11 +197,14 @@ class CoreController {
return Delay.fromJson(json.decode(data));
}
Future<Map<String, dynamic>> getConfig(String id) async {
final profilePath = await appPath.getProfilePath(id);
Future<Map<String, dynamic>> getConfig(int id) async {
final profilePath = await appPath.getProfilePath(id.toString());
final res = await _interface.getConfig(profilePath);
if (res.isSuccess) {
return res.data;
final data = Map<String, dynamic>.from(res.data);
data['rules'] = data['rule'];
data.remove('rule');
return data;
} else {
throw res.message;
}

View File

@@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:isolate';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
@@ -12,7 +11,7 @@ mixin CoreInterface {
Future<String> preload();
Future<bool> shutdown();
Future<bool> shutdown(bool isUser);
Future<bool> get isInit;
@@ -28,7 +27,7 @@ mixin CoreInterface {
Future<String> setupConfig(SetupParams setupParams);
Future<Map> getProxies();
Future<ProxiesData> getProxies();
Future<String> changeProxy(ChangeProxyParams changeProxyParams);
@@ -95,13 +94,13 @@ abstract class CoreHandlerInterface with CoreInterface {
);
return null;
}
if (kDebugMode) {
if (kDebugMode && watchExecution) {
commonPrint.log('Invoke ${method.name} ${DateTime.now()} $data');
}
return utils.handleWatch(
return await utils.handleWatch(
function: () async {
return await invoke(method: method, data: data, timeout: timeout);
return await invoke<T>(method: method, data: data, timeout: timeout);
},
onWatch: (data, elapsedMilliseconds) {
commonPrint.log('Invoke ${method.name} ${elapsedMilliseconds}ms');
@@ -132,7 +131,7 @@ abstract class CoreHandlerInterface with CoreInterface {
}
@override
Future<bool> shutdown();
Future<bool> shutdown(bool isUser);
@override
Future<bool> get isInit async {
@@ -164,16 +163,15 @@ abstract class CoreHandlerInterface with CoreInterface {
@override
Future<Result> getConfig(String path) async {
return await _invoke<Result>(method: ActionMethod.getConfig, data: path) ??
Result.success({});
final res = await _invoke(method: ActionMethod.getConfig, data: path);
return res ?? Result.success({});
}
@override
Future<String> setupConfig(SetupParams setupParams) async {
final data = await Isolate.run(() => json.encode(setupParams));
return await _invoke<String>(
method: ActionMethod.setupConfig,
data: data,
data: json.encode(setupParams),
) ??
'';
}
@@ -184,9 +182,13 @@ abstract class CoreHandlerInterface with CoreInterface {
}
@override
Future<Map> getProxies() async {
final map = await _invoke<Map>(method: ActionMethod.getProxies);
return map ?? {};
Future<ProxiesData> getProxies() async {
final data = await _invoke<Map<String, dynamic>>(
method: ActionMethod.getProxies,
);
return data != null
? ProxiesData.fromJson(data)
: ProxiesData(proxies: {}, all: []);
}
@override

View File

@@ -1,10 +1,10 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/core.dart';
import 'package:fl_clash/plugins/service.dart';
import 'package:fl_clash/state.dart';
import 'interface.dart';
@@ -22,9 +22,7 @@ class CoreLib extends CoreHandlerInterface {
return res ?? '';
}
_connectedCompleter.complete(true);
final syncRes = await service?.syncAndroidState(
globalState.getAndroidState(),
);
final syncRes = await service?.syncState(appController.sharedState);
return syncRes ?? '';
}
@@ -39,10 +37,12 @@ class CoreLib extends CoreHandlerInterface {
}
@override
Future<bool> shutdown() async {
await service?.shutdown();
Future<bool> shutdown(_) async {
if (!_connectedCompleter.isCompleted) {
return false;
}
_connectedCompleter = Completer();
return true;
return service?.shutdown() ?? true;
}
@override

View File

@@ -16,6 +16,8 @@ class CoreService extends CoreHandlerInterface {
Completer<Socket> _socketCompleter = Completer();
Completer<bool> _shutdownCompleter = Completer();
final Map<String, Completer> _callbackCompleterMap = {};
Process? _process;
@@ -35,6 +37,9 @@ class CoreService extends CoreHandlerInterface {
if (result.id?.isEmpty == true) {
coreEventManager.sendEvent(CoreEvent.fromJson(result.data));
}
if (completer?.isCompleted == true) {
return;
}
completer?.complete(data);
}
@@ -70,11 +75,15 @@ class CoreService extends CoreHandlerInterface {
.transform(uint8ListToListIntConverter)
.transform(utf8.decoder)
.transform(LineSplitter())
.listen((data) {
handleResult(ActionResult.fromJson(json.decode(data.trim())));
.listen((data) async {
final dataJson = await data.trim().commonToJSON<dynamic>();
handleResult(ActionResult.fromJson(dataJson));
})
.onDone(() {
_handleInvokeCrashEvent();
if (!_shutdownCompleter.isCompleted) {
_shutdownCompleter.complete(true);
}
});
}
@@ -86,7 +95,7 @@ class CoreService extends CoreHandlerInterface {
Future<void> start() async {
if (_process != null) {
await shutdown();
await shutdown(false);
}
final serverSocket = await _serverCompleter.future;
final arg = system.isWindows
@@ -112,7 +121,7 @@ class CoreService extends CoreHandlerInterface {
@override
destroy() async {
final server = await _serverCompleter.future;
await shutdown();
await shutdown(false);
await server.close();
await _deleteSocketFile();
return true;
@@ -126,9 +135,7 @@ class CoreService extends CoreHandlerInterface {
Future<void> _deleteSocketFile() async {
if (!system.isWindows) {
final file = File(unixSocketPath);
if (await file.exists()) {
await file.delete();
}
await file.safeDelete();
}
}
@@ -136,12 +143,16 @@ class CoreService extends CoreHandlerInterface {
if (_socketCompleter.isCompleted) {
final socket = await _socketCompleter.future;
_socketCompleter = Completer();
socket.close();
await socket.close();
}
}
@override
shutdown() async {
shutdown(bool isUser) async {
if (!_socketCompleter.isCompleted && _process == null) {
return false;
}
_shutdownCompleter = Completer();
await _destroySocket();
_clearCompleter();
if (system.isWindows) {
@@ -149,7 +160,11 @@ class CoreService extends CoreHandlerInterface {
}
_process?.kill();
_process = null;
return true;
if (isUser) {
return _shutdownCompleter.future;
} else {
return true;
}
}
void _clearCompleter() {

View File

@@ -0,0 +1,78 @@
import 'dart:convert';
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
part 'generated/database.g.dart';
part 'links.dart';
part 'profiles.dart';
part 'rules.dart';
part 'scripts.dart';
@DriftDatabase(
tables: [Profiles, Scripts, Rules, ProfileRuleLinks],
daos: [ProfilesDao, ScriptsDao, RulesDao],
)
class Database extends _$Database {
Database([QueryExecutor? executor]) : super(executor ?? _openConnection());
@override
int get schemaVersion => 1;
static LazyDatabase _openConnection() {
return LazyDatabase(() async {
final databaseFile = File(await appPath.databasePath);
return NativeDatabase.createInBackground(databaseFile);
});
}
Future<void> restore(
List<Profile> profiles,
List<Script> scripts,
List<Rule> rules,
List<ProfileRuleLink> links, {
bool isOverride = false,
}) async {
if (profiles.isNotEmpty ||
scripts.isNotEmpty ||
rules.isNotEmpty ||
links.isNotEmpty) {
await batch((b) {
isOverride
? profilesDao.setAllWithBatch(b, profiles)
: profilesDao.putAllWithBatch(
b,
profiles.map((item) => item.toCompanion()),
);
scriptsDao.setAllWithBatch(b, scripts);
rulesDao.restoreWithBatch(b, rules, links);
});
}
}
}
extension TableInfoExt<Tbl extends Table, Row> on TableInfo<Tbl, Row> {
void setAll(
Batch batch,
Iterable<Insertable<Row>> items, {
required Expression<bool> Function(Tbl tbl) deleteFilter,
}) async {
batch.insertAllOnConflictUpdate(this, items);
batch.deleteWhere(this, deleteFilter);
}
Future<int> remove(Expression<bool> Function(Tbl tbl) filter) async {
return await (delete()..where(filter)).go();
}
Future<int> put(Insertable<Row> item) async {
return await insertOnConflictUpdate(item);
}
}
final database = Database();

File diff suppressed because it is too large Load Diff

52
lib/database/links.dart Normal file
View File

@@ -0,0 +1,52 @@
part of 'database.dart';
@DataClassName('RawProfileRuleLink')
@TableIndex(
name: 'idx_profile_scene_order',
columns: {#profileId, #scene, #order},
)
class ProfileRuleLinks extends Table {
@override
String get tableName => 'profile_rule_mapping';
TextColumn get id => text()();
IntColumn get profileId => integer().nullable().references(
Profiles,
#id,
onDelete: KeyAction.cascade,
)();
IntColumn get ruleId =>
integer().references(Rules, #id, onDelete: KeyAction.cascade)();
TextColumn get scene => textEnum<RuleScene>().nullable()();
TextColumn get order => text().nullable()();
@override
Set<Column> get primaryKey => {id};
}
extension RawProfileRuleLinkExt on RawProfileRuleLink {
ProfileRuleLink toLink() {
return ProfileRuleLink(
profileId: profileId,
ruleId: ruleId,
scene: scene,
order: order,
);
}
}
extension ProfileRuleLinksCompanionExt on ProfileRuleLink {
ProfileRuleLinksCompanion toCompanion() {
return ProfileRuleLinksCompanion.insert(
id: key,
ruleId: ruleId,
scene: Value(scene),
profileId: Value(profileId),
order: Value(order),
);
}
}

168
lib/database/profiles.dart Normal file
View File

@@ -0,0 +1,168 @@
part of 'database.dart';
@DataClassName('RawProfile')
class Profiles extends Table {
@override
String get tableName => 'profiles';
IntColumn get id => integer()();
TextColumn get label => text()();
TextColumn get currentGroupName => text().nullable()();
TextColumn get url => text()();
DateTimeColumn get lastUpdateDate => dateTime().nullable()();
TextColumn get overwriteType => textEnum<OverwriteType>()();
IntColumn get scriptId => integer().nullable()();
IntColumn get autoUpdateDurationMillis => integer()();
TextColumn get subscriptionInfo =>
text().map(const SubscriptionInfoConverter()).nullable()();
BoolColumn get autoUpdate => boolean()();
TextColumn get selectedMap => text().map(const StringMapConverter())();
TextColumn get unfoldSet => text().map(const StringSetConverter())();
IntColumn get order => integer().nullable()();
@override
Set<Column> get primaryKey => {id};
}
class SubscriptionInfoConverter
extends TypeConverter<SubscriptionInfo?, String?> {
const SubscriptionInfoConverter();
@override
SubscriptionInfo? fromSql(String? fromDb) {
if (fromDb == null) return null;
return SubscriptionInfo.fromJson(json.decode(fromDb));
}
@override
String? toSql(SubscriptionInfo? value) {
if (value == null) return null;
return json.encode(value.toJson());
}
}
@DriftAccessor(tables: [Profiles])
class ProfilesDao extends DatabaseAccessor<Database> with _$ProfilesDaoMixin {
ProfilesDao(super.attachedDatabase);
Selectable<Profile> all() {
final stmt = profiles.select();
stmt.orderBy([
(t) => OrderingTerm(expression: t.order, nulls: NullsOrder.last),
(t) => OrderingTerm.asc(t.id),
]);
return stmt.map((item) => item.toProfile());
}
Future<void> setAll(Iterable<Profile> profiles) async {
await batch((b) async {
setAllWithBatch(b, profiles);
});
}
Future<void> putAll<T extends Table, D extends DataClass>(
Iterable<Insertable<D>> items,
) async {
await batch((b) async {
putAllWithBatch(b, items);
});
}
void putAllWithBatch<T extends Table, D extends DataClass>(
Batch batch,
Iterable<Insertable<D>> items,
) {
batch.insertAllOnConflictUpdate(profiles, items);
}
void setAllWithBatch(Batch batch, Iterable<Profile> profiles) {
final List<ProfilesCompanion> items = [];
final List<int> ids = [];
profiles.forEachIndexed((index, profile) {
ids.add(profile.id);
items.add(profile.toCompanion(index));
});
this.profiles.setAll(batch, items, deleteFilter: (t) => t.id.isNotIn(ids));
}
}
class StringMapConverter extends TypeConverter<Map<String, String>, String> {
const StringMapConverter();
@override
Map<String, String> fromSql(String fromDb) {
return Map<String, String>.from(json.decode(fromDb));
}
@override
String toSql(Map<String, String> value) {
return json.encode(value);
}
}
class StringSetConverter extends TypeConverter<Set<String>, String> {
const StringSetConverter();
@override
Set<String> fromSql(String fromDb) {
return Set<String>.from(json.decode(fromDb));
}
@override
String toSql(Set<String> value) {
return json.encode(value.toList());
}
}
extension RawProfilExt on RawProfile {
Profile toProfile() {
return Profile(
id: id,
label: label,
currentGroupName: currentGroupName,
url: url,
lastUpdateDate: lastUpdateDate,
autoUpdateDuration: Duration(milliseconds: autoUpdateDurationMillis),
subscriptionInfo: subscriptionInfo,
autoUpdate: autoUpdate,
selectedMap: selectedMap,
unfoldSet: unfoldSet,
overwriteType: overwriteType,
scriptId: scriptId,
order: order,
);
}
}
extension ProfilesCompanionExt on Profile {
ProfilesCompanion toCompanion([int? order]) {
return ProfilesCompanion.insert(
id: Value(id),
label: label,
currentGroupName: Value(currentGroupName),
url: url,
lastUpdateDate: Value(lastUpdateDate),
autoUpdateDurationMillis: autoUpdateDuration.inMilliseconds,
subscriptionInfo: Value(subscriptionInfo),
autoUpdate: autoUpdate,
selectedMap: selectedMap,
unfoldSet: unfoldSet,
overwriteType: overwriteType,
scriptId: Value(scriptId),
order: Value(order ?? this.order),
);
}
}

283
lib/database/rules.dart Normal file
View File

@@ -0,0 +1,283 @@
part of 'database.dart';
@DataClassName('RawRule')
class Rules extends Table {
@override
String get tableName => 'rules';
IntColumn get id => integer()();
TextColumn get value => text()();
@override
Set<Column> get primaryKey => {id};
}
@DriftAccessor(tables: [Rules, ProfileRuleLinks])
class RulesDao extends DatabaseAccessor<Database> with _$RulesDaoMixin {
RulesDao(super.attachedDatabase);
Selectable<Rule> allGlobalAddedRules() {
return _get();
}
Selectable<Rule> allProfileAddedRules(int profileId) {
return _get(profileId: profileId, scene: RuleScene.added);
}
Selectable<Rule> allProfileDisabledRules(int profileId) {
return _get(profileId: profileId, scene: RuleScene.disabled);
}
Selectable<Rule> allAddedRules(int profileId) {
final disabledIdsQuery = selectOnly(profileRuleLinks)
..addColumns([profileRuleLinks.ruleId])
..where(
profileRuleLinks.profileId.equals(profileId) &
profileRuleLinks.scene.equalsValue(RuleScene.disabled),
);
final query = select(rules).join([
innerJoin(profileRuleLinks, profileRuleLinks.ruleId.equalsExp(rules.id)),
]);
query.where(
(profileRuleLinks.profileId.isNull() |
(profileRuleLinks.profileId.equals(profileId) &
profileRuleLinks.scene.equalsValue(RuleScene.added))) &
profileRuleLinks.ruleId.isNotInQuery(disabledIdsQuery),
);
query.orderBy([
OrderingTerm.desc(
profileRuleLinks.profileId.isNull().caseMatch<int>(
when: {const Constant(true): const Constant(1)},
orElse: const Constant(0),
),
),
OrderingTerm.desc(profileRuleLinks.order),
]);
return query.map((row) {
final ruleData = row.readTable(rules);
final order = row.read(profileRuleLinks.order);
return ruleData.toRule(order);
});
}
void restoreWithBatch(
Batch batch,
Iterable<Rule> rules,
Iterable<ProfileRuleLink> links,
) {
batch.insertAllOnConflictUpdate(
this.rules,
rules.map((item) => item.toCompanion()),
);
final ruleIds = rules.map((item) => item.id);
batch.deleteWhere(this.rules, (t) => t.id.isNotIn(ruleIds));
batch.insertAllOnConflictUpdate(
profileRuleLinks,
links.map((item) => item.toCompanion()),
);
final linkKeys = links.map((item) => item.key);
batch.deleteWhere(profileRuleLinks, (t) => t.id.isNotIn(linkKeys));
}
Future<void> delRules(Iterable<int> ruleIds) {
return _delAll(ruleIds);
}
Future<void> putGlobalRule(Rule rule) {
return _put(rule);
}
Future<void> putProfileAddedRule(int profileId, Rule rule) {
return _put(rule, profileId: profileId, scene: RuleScene.added);
}
Future<void> putProfileDisabledRule(int profileId, Rule rule) {
return _put(rule, profileId: profileId, scene: RuleScene.added);
}
Future<void> putGlobalRules(Iterable<Rule> rules) {
return _putAll(rules);
}
Future<void> setGlobalRules(Iterable<Rule> rules) {
return _set(rules);
}
Future<int> putDisabledLink(int profileId, int ruleId) async {
return await profileRuleLinks.insertOnConflictUpdate(
ProfileRuleLink(
ruleId: ruleId,
profileId: profileId,
scene: RuleScene.disabled,
).toCompanion(),
);
}
Future<bool> delDisabledLink(int profileId, int ruleId) async {
return await profileRuleLinks.deleteOne(
ProfileRuleLink(
profileId: profileId,
ruleId: ruleId,
scene: RuleScene.disabled,
).toCompanion(),
);
}
Future<int> orderGlobalRule({
required int ruleId,
required String order,
}) async {
return await _order(ruleId: ruleId, order: order);
}
Future<int> orderProfileAddedRule(
int profileId, {
required int ruleId,
required String order,
}) async {
return await _order(
ruleId: ruleId,
order: order,
profileId: profileId,
scene: RuleScene.added,
);
}
Selectable<Rule> _get({int? profileId, RuleScene? scene}) {
final query = select(rules).join([
innerJoin(profileRuleLinks, profileRuleLinks.ruleId.equalsExp(rules.id)),
]);
query.where(
profileId == null
? profileRuleLinks.profileId.isNull()
: profileRuleLinks.profileId.equals(profileId) &
profileRuleLinks.scene.equalsValue(scene),
);
query.orderBy([
OrderingTerm.desc(profileRuleLinks.order),
OrderingTerm.desc(profileRuleLinks.id),
]);
return query.map((row) {
return row.readTable(rules).toRule(row.read(profileRuleLinks.order));
});
}
Future<int> _order({
required int ruleId,
required String order,
int? profileId,
RuleScene? scene,
}) async {
final stmt = profileRuleLinks.update();
stmt.where((t) {
return (profileId == null
? t.profileId.isNull()
: t.profileId.equals(profileId)) &
t.ruleId.equals(ruleId) &
t.scene.equalsValue(scene);
});
return await stmt.write(ProfileRuleLinksCompanion(order: Value(order)));
}
Future<int> _put(Rule rule, {int? profileId, RuleScene? scene}) async {
return transaction(() async {
final row = await rules.insertOnConflictUpdate(rule.toCompanion());
if (row == 0) {
return 0;
}
return await profileRuleLinks.insertOnConflictUpdate(
ProfileRuleLink(
ruleId: rule.id,
profileId: profileId,
scene: scene,
).toCompanion(),
);
});
}
Future<void> _delAll(Iterable<int> ruleIds) async {
await rules.deleteWhere((t) => t.id.isIn(ruleIds));
}
Future<void> _putAll(
Iterable<Rule> rules, {
int? profileId,
RuleScene? scene,
}) async {
await batch((b) {
b.insertAllOnConflictUpdate(
this.rules,
rules.map((item) => item.toCompanion()),
);
b.insertAllOnConflictUpdate(
profileRuleLinks,
rules.map(
(item) => ProfileRuleLink(
ruleId: item.id,
profileId: profileId,
scene: scene,
).toCompanion(),
),
);
});
}
Future<void> _set(
Iterable<Rule> rules, {
int? profileId,
RuleScene? scene,
}) async {
await batch((b) {
b.insertAllOnConflictUpdate(
this.rules,
rules.map((item) => item.toCompanion()),
);
b.deleteWhere(
profileRuleLinks,
(t) =>
(profileId == null
? t.profileId.isNull()
: t.profileId.equals(profileId)) &
(scene == null ? const Constant(true) : t.scene.equalsValue(scene)),
);
b.insertAllOnConflictUpdate(
profileRuleLinks,
rules.map(
(item) => ProfileRuleLink(
ruleId: item.id,
profileId: profileId,
scene: scene,
).toCompanion(),
),
);
b.deleteWhere(this.rules, (r) {
final linkedIds = selectOnly(profileRuleLinks);
linkedIds.addColumns([profileRuleLinks.ruleId]);
return r.id.isNotInQuery(linkedIds);
});
});
}
}
extension RawRuleExt on RawRule {
Rule toRule([String? order]) {
return Rule(id: id, value: value, order: order);
}
}
extension RulesCompanionExt on Rule {
RulesCompanion toCompanion() {
return RulesCompanion.insert(id: Value(id), value: value);
}
}

63
lib/database/scripts.dart Normal file
View File

@@ -0,0 +1,63 @@
part of 'database.dart';
@DataClassName('RawScript')
class Scripts extends Table {
@override
String get tableName => 'scripts';
IntColumn get id => integer()();
TextColumn get label => text()();
DateTimeColumn get lastUpdateTime => dateTime()();
@override
Set<Column> get primaryKey => {id};
}
@DriftAccessor(tables: [Scripts])
class ScriptsDao extends DatabaseAccessor<Database> with _$ScriptsDaoMixin {
ScriptsDao(super.attachedDatabase);
Selectable<Script> all() {
return scripts.select().map((item) => item.toScript());
}
Selectable<Script> get(int scriptId) {
final stmt = scripts.select();
stmt.where((t) => t.id.equals(scriptId));
return stmt.map((it) => it.toScript());
}
Future<void> setAll(Iterable<Script> scripts) async {
await batch((b) async {
await setAllWithBatch(b, scripts);
});
}
Future<void> setAllWithBatch(Batch batch, Iterable<Script> scripts) async {
final List<ScriptsCompanion> items = [];
final List<int> ids = [];
for (final script in scripts) {
ids.add(script.id);
items.add(script.toCompanion());
}
this.scripts.setAll(batch, items, deleteFilter: (t) => t.id.isNotIn(ids));
}
}
extension RawScriptExt on RawScript {
Script toScript() {
return Script(id: id, label: label, lastUpdateTime: lastUpdateTime);
}
}
extension ScriptsCompanionExt on Script {
ScriptsCompanion toCompanion() {
return ScriptsCompanion.insert(
id: Value(id),
label: label,
lastUpdateTime: lastUpdateTime,
);
}
}

View File

@@ -133,7 +133,7 @@ enum InvokeMessageType { protect, process }
enum FindProcessMode { always, off }
enum RecoveryOption { all, onlyProfiles }
enum RestoreOption { all, onlyProfiles }
enum ChipType { action, delete }
@@ -260,8 +260,8 @@ enum AuthorizeCode { none, success, error }
enum WindowsHelperServiceStatus { none, presence, running }
enum FunctionTag {
updateClashConfig,
setupClashConfig,
updateConfig,
setupConfig,
updateStatus,
updateGroups,
addCheckIpNum,
@@ -281,6 +281,7 @@ enum FunctionTag {
requests,
autoScrollToEnd,
loadedProvider,
saveSharedFile,
}
enum DashboardWidget {
@@ -406,7 +407,7 @@ enum OverwriteType {
enum RuleTarget { DIRECT, REJECT, MATCH }
enum RecoveryStrategy { compatible, override }
enum RestoreStrategy { compatible, override }
enum CacheTag { logs, rules, requests, proxiesList }
@@ -418,4 +419,8 @@ enum ScrollPositionCacheKey { tools, profiles, proxiesList, proxiesTabList }
enum QueryTag { proxies, access }
enum LoadingTag { profiles, backup_restore, access, proxies }
enum CoreStatus { connecting, connected, disconnected }
enum RuleScene { added, disabled, custom }

View File

@@ -14,7 +14,7 @@ class RuleItem extends StatelessWidget {
final bool isSelected;
final bool isEditing;
final Rule rule;
final void Function(String id) onSelected;
final void Function() onSelected;
final void Function(Rule rule) onEdit;
const RuleItem({
@@ -31,7 +31,7 @@ class RuleItem extends StatelessWidget {
return CommonSelectedListItem(
isSelected: isSelected,
onSelected: () {
onSelected(rule.id);
onSelected();
},
title: Text(
rule.value,

View File

@@ -81,6 +81,7 @@ class MessageLookup extends MessageLookupByLibrary {
"action_tun": MessageLookupByLibrary.simpleMessage("TUN"),
"action_view": MessageLookupByLibrary.simpleMessage("Show/Hide"),
"add": MessageLookupByLibrary.simpleMessage("Add"),
"addProfile": MessageLookupByLibrary.simpleMessage("Add Profile"),
"addRule": MessageLookupByLibrary.simpleMessage("Add rule"),
"addedOriginRules": MessageLookupByLibrary.simpleMessage(
"Attach on the original rules",
@@ -164,11 +165,11 @@ class MessageLookup extends MessageLookupByLibrary {
"Auto update interval (minutes)",
),
"backup": MessageLookupByLibrary.simpleMessage("Backup"),
"backupAndRecovery": MessageLookupByLibrary.simpleMessage(
"Backup and Recovery",
"backupAndRestore": MessageLookupByLibrary.simpleMessage(
"Backup and Restore",
),
"backupAndRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"Sync data via WebDAV or file",
"backupAndRestoreDesc": MessageLookupByLibrary.simpleMessage(
"Sync data via WebDAV or files",
),
"backupSuccess": MessageLookupByLibrary.simpleMessage("Backup success"),
"basicConfig": MessageLookupByLibrary.simpleMessage("Basic configuration"),
@@ -269,6 +270,7 @@ class MessageLookup extends MessageLookupByLibrary {
"defaultText": MessageLookupByLibrary.simpleMessage("Default"),
"delay": MessageLookupByLibrary.simpleMessage("Delay"),
"delaySort": MessageLookupByLibrary.simpleMessage("Sort by delay"),
"delayTest": MessageLookupByLibrary.simpleMessage("Delay Test"),
"delete": MessageLookupByLibrary.simpleMessage("Delete"),
"deleteMultipTip": m1,
"deleteTip": m2,
@@ -425,6 +427,9 @@ class MessageLookup extends MessageLookupByLibrary {
"internet": MessageLookupByLibrary.simpleMessage("Internet"),
"interval": MessageLookupByLibrary.simpleMessage("Interval"),
"intranetIP": MessageLookupByLibrary.simpleMessage("Intranet IP"),
"invalidBackupFile": MessageLookupByLibrary.simpleMessage(
"Invalid backup file",
),
"ipcidr": MessageLookupByLibrary.simpleMessage("Ipcidr"),
"ipv6Desc": MessageLookupByLibrary.simpleMessage(
"When turned on it will be able to receive IPv6 traffic",
@@ -450,9 +455,6 @@ class MessageLookup extends MessageLookupByLibrary {
"localBackupDesc": MessageLookupByLibrary.simpleMessage(
"Backup local data to local",
),
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"Recovery data from file",
),
"log": MessageLookupByLibrary.simpleMessage("Log"),
"logLevel": MessageLookupByLibrary.simpleMessage("LogLevel"),
"logcat": MessageLookupByLibrary.simpleMessage("Logcat"),
@@ -504,6 +506,12 @@ class MessageLookup extends MessageLookupByLibrary {
"networkDetection": MessageLookupByLibrary.simpleMessage(
"Network detection",
),
"networkException": MessageLookupByLibrary.simpleMessage(
"Network exception, please check your connection and try again",
),
"networkRequestException": MessageLookupByLibrary.simpleMessage(
"Network request exception, please try again later.",
),
"networkSpeed": MessageLookupByLibrary.simpleMessage("Network speed"),
"networkType": MessageLookupByLibrary.simpleMessage("Network type"),
"neutralScheme": MessageLookupByLibrary.simpleMessage("Neutral"),
@@ -564,6 +572,10 @@ class MessageLookup extends MessageLookupByLibrary {
"Override the original rule",
),
"overrideScript": MessageLookupByLibrary.simpleMessage("Override script"),
"overwriteTypeCustom": MessageLookupByLibrary.simpleMessage("Custom"),
"overwriteTypeCustomDesc": MessageLookupByLibrary.simpleMessage(
"Custom mode, fully customize proxy groups and rules",
),
"palette": MessageLookupByLibrary.simpleMessage("Palette"),
"password": MessageLookupByLibrary.simpleMessage("Password"),
"paste": MessageLookupByLibrary.simpleMessage("Paste"),
@@ -636,27 +648,13 @@ class MessageLookup extends MessageLookupByLibrary {
"Set the Clash listening port",
),
"proxyProviders": MessageLookupByLibrary.simpleMessage("Proxy providers"),
"pruneCache": MessageLookupByLibrary.simpleMessage("Prune cache"),
"pureBlackMode": MessageLookupByLibrary.simpleMessage("Pure black mode"),
"qrcode": MessageLookupByLibrary.simpleMessage("QR code"),
"qrcodeDesc": MessageLookupByLibrary.simpleMessage(
"Scan QR code to obtain profile",
),
"rainbowScheme": MessageLookupByLibrary.simpleMessage("Rainbow"),
"recovery": MessageLookupByLibrary.simpleMessage("Recovery"),
"recoveryAll": MessageLookupByLibrary.simpleMessage("Recovery all data"),
"recoveryProfiles": MessageLookupByLibrary.simpleMessage(
"Only recovery profiles",
),
"recoveryStrategy": MessageLookupByLibrary.simpleMessage(
"Recovery strategy",
),
"recoveryStrategy_compatible": MessageLookupByLibrary.simpleMessage(
"Compatible",
),
"recoveryStrategy_override": MessageLookupByLibrary.simpleMessage(
"Override",
),
"recoverySuccess": MessageLookupByLibrary.simpleMessage("Recovery success"),
"redirPort": MessageLookupByLibrary.simpleMessage("Redir Port"),
"redo": MessageLookupByLibrary.simpleMessage("redo"),
"regExp": MessageLookupByLibrary.simpleMessage("RegExp"),
@@ -668,9 +666,6 @@ class MessageLookup extends MessageLookupByLibrary {
"remoteDestination": MessageLookupByLibrary.simpleMessage(
"Remote destination",
),
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"Recovery data from WebDAV",
),
"remove": MessageLookupByLibrary.simpleMessage("Remove"),
"rename": MessageLookupByLibrary.simpleMessage("Rename"),
"request": MessageLookupByLibrary.simpleMessage("Request"),
@@ -695,6 +690,28 @@ class MessageLookup extends MessageLookupByLibrary {
"restartCoreTip": MessageLookupByLibrary.simpleMessage(
"Are you sure you want to restart the core?",
),
"restore": MessageLookupByLibrary.simpleMessage("Restore"),
"restoreAllData": MessageLookupByLibrary.simpleMessage("Restore all data"),
"restoreException": MessageLookupByLibrary.simpleMessage(
"Recovery exception",
),
"restoreFromFileDesc": MessageLookupByLibrary.simpleMessage(
"Restore data via file",
),
"restoreFromWebDAVDesc": MessageLookupByLibrary.simpleMessage(
"Restore data via WebDAV",
),
"restoreOnlyConfig": MessageLookupByLibrary.simpleMessage(
"Restore configuration files only",
),
"restoreStrategy": MessageLookupByLibrary.simpleMessage("Restore strategy"),
"restoreStrategy_compatible": MessageLookupByLibrary.simpleMessage(
"Compatible",
),
"restoreStrategy_override": MessageLookupByLibrary.simpleMessage(
"Override",
),
"restoreSuccess": MessageLookupByLibrary.simpleMessage("Restore success"),
"routeAddress": MessageLookupByLibrary.simpleMessage("Route address"),
"routeAddressDesc": MessageLookupByLibrary.simpleMessage(
"Config listen route address",
@@ -806,6 +823,9 @@ class MessageLookup extends MessageLookupByLibrary {
"Remove extra delays such as handshaking",
),
"unknown": MessageLookupByLibrary.simpleMessage("Unknown"),
"unknownNetworkError": MessageLookupByLibrary.simpleMessage(
"Unknown network error",
),
"unnamed": MessageLookupByLibrary.simpleMessage("Unnamed"),
"update": MessageLookupByLibrary.simpleMessage("Update"),
"upload": MessageLookupByLibrary.simpleMessage("Upload"),

View File

@@ -72,6 +72,7 @@ class MessageLookup extends MessageLookupByLibrary {
"action_tun": MessageLookupByLibrary.simpleMessage("TUN"),
"action_view": MessageLookupByLibrary.simpleMessage("表示/非表示"),
"add": MessageLookupByLibrary.simpleMessage("追加"),
"addProfile": MessageLookupByLibrary.simpleMessage("プロファイルを追加"),
"addRule": MessageLookupByLibrary.simpleMessage("ルールを追加"),
"addedOriginRules": MessageLookupByLibrary.simpleMessage("元のルールに追加"),
"addedRules": MessageLookupByLibrary.simpleMessage("追加ルール"),
@@ -117,9 +118,9 @@ class MessageLookup extends MessageLookupByLibrary {
"autoUpdate": MessageLookupByLibrary.simpleMessage("自動更新"),
"autoUpdateInterval": MessageLookupByLibrary.simpleMessage("自動更新間隔(分)"),
"backup": MessageLookupByLibrary.simpleMessage("バックアップ"),
"backupAndRecovery": MessageLookupByLibrary.simpleMessage("バックアップと復元"),
"backupAndRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"WebDAVまたはファイルデータを同期",
"backupAndRestore": MessageLookupByLibrary.simpleMessage("バックアップと復元"),
"backupAndRestoreDesc": MessageLookupByLibrary.simpleMessage(
"WebDAVまたはファイルを介してデータを同期する",
),
"backupSuccess": MessageLookupByLibrary.simpleMessage("バックアップ成功"),
"basicConfig": MessageLookupByLibrary.simpleMessage("基本設定"),
@@ -204,6 +205,7 @@ class MessageLookup extends MessageLookupByLibrary {
"defaultText": MessageLookupByLibrary.simpleMessage("デフォルト"),
"delay": MessageLookupByLibrary.simpleMessage("遅延"),
"delaySort": MessageLookupByLibrary.simpleMessage("遅延順"),
"delayTest": MessageLookupByLibrary.simpleMessage("遅延テスト"),
"delete": MessageLookupByLibrary.simpleMessage("削除"),
"deleteMultipTip": m1,
"deleteTip": m2,
@@ -318,6 +320,7 @@ class MessageLookup extends MessageLookupByLibrary {
"internet": MessageLookupByLibrary.simpleMessage("インターネット"),
"interval": MessageLookupByLibrary.simpleMessage("インターバル"),
"intranetIP": MessageLookupByLibrary.simpleMessage("イントラネットIP"),
"invalidBackupFile": MessageLookupByLibrary.simpleMessage("無効なバックアップファイル"),
"ipcidr": MessageLookupByLibrary.simpleMessage("IPCIDR"),
"ipv6Desc": MessageLookupByLibrary.simpleMessage("有効化するとIPv6トラフィックを受信可能"),
"ipv6InboundDesc": MessageLookupByLibrary.simpleMessage("IPv6インバウンドを許可"),
@@ -337,7 +340,6 @@ class MessageLookup extends MessageLookupByLibrary {
"loading": MessageLookupByLibrary.simpleMessage("読み込み中..."),
"local": MessageLookupByLibrary.simpleMessage("ローカル"),
"localBackupDesc": MessageLookupByLibrary.simpleMessage("ローカルにデータをバックアップ"),
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage("ファイルからデータを復元"),
"log": MessageLookupByLibrary.simpleMessage("ログ"),
"logLevel": MessageLookupByLibrary.simpleMessage("ログレベル"),
"logcat": MessageLookupByLibrary.simpleMessage("ログキャット"),
@@ -375,6 +377,12 @@ class MessageLookup extends MessageLookupByLibrary {
"network": MessageLookupByLibrary.simpleMessage("ネットワーク"),
"networkDesc": MessageLookupByLibrary.simpleMessage("ネットワーク関連設定の変更"),
"networkDetection": MessageLookupByLibrary.simpleMessage("ネットワーク検出"),
"networkException": MessageLookupByLibrary.simpleMessage(
"ネットワーク例外、接続を確認してもう一度お試しください",
),
"networkRequestException": MessageLookupByLibrary.simpleMessage(
"ネットワーク要求例外、後でもう一度試してください。",
),
"networkSpeed": MessageLookupByLibrary.simpleMessage("ネットワーク速度"),
"networkType": MessageLookupByLibrary.simpleMessage("ネットワーク種別"),
"neutralScheme": MessageLookupByLibrary.simpleMessage("ニュートラル"),
@@ -423,6 +431,10 @@ class MessageLookup extends MessageLookupByLibrary {
"overrideMode": MessageLookupByLibrary.simpleMessage("上書きモード"),
"overrideOriginRules": MessageLookupByLibrary.simpleMessage("元のルールを上書き"),
"overrideScript": MessageLookupByLibrary.simpleMessage("上書きスクリプト"),
"overwriteTypeCustom": MessageLookupByLibrary.simpleMessage("カスタム"),
"overwriteTypeCustomDesc": MessageLookupByLibrary.simpleMessage(
"カスタムモード、プロキシグループとルールを完全にカスタマイズ可能",
),
"palette": MessageLookupByLibrary.simpleMessage("パレット"),
"password": MessageLookupByLibrary.simpleMessage("パスワード"),
"paste": MessageLookupByLibrary.simpleMessage("貼り付け"),
@@ -483,19 +495,11 @@ class MessageLookup extends MessageLookupByLibrary {
"proxyPort": MessageLookupByLibrary.simpleMessage("プロキシポート"),
"proxyPortDesc": MessageLookupByLibrary.simpleMessage("Clashのリスニングポートを設定"),
"proxyProviders": MessageLookupByLibrary.simpleMessage("プロキシプロバイダー"),
"pruneCache": MessageLookupByLibrary.simpleMessage("キャッシュの削除"),
"pureBlackMode": MessageLookupByLibrary.simpleMessage("純黒モード"),
"qrcode": MessageLookupByLibrary.simpleMessage("QRコード"),
"qrcodeDesc": MessageLookupByLibrary.simpleMessage("QRコードをスキャンしてプロファイルを取得"),
"rainbowScheme": MessageLookupByLibrary.simpleMessage("レインボー"),
"recovery": MessageLookupByLibrary.simpleMessage("復元"),
"recoveryAll": MessageLookupByLibrary.simpleMessage("全データ復元"),
"recoveryProfiles": MessageLookupByLibrary.simpleMessage("プロファイルのみ復元"),
"recoveryStrategy": MessageLookupByLibrary.simpleMessage("リカバリー戦略"),
"recoveryStrategy_compatible": MessageLookupByLibrary.simpleMessage("互換性"),
"recoveryStrategy_override": MessageLookupByLibrary.simpleMessage(
"オーバーライド",
),
"recoverySuccess": MessageLookupByLibrary.simpleMessage("復元成功"),
"redirPort": MessageLookupByLibrary.simpleMessage("Redirポート"),
"redo": MessageLookupByLibrary.simpleMessage("やり直す"),
"regExp": MessageLookupByLibrary.simpleMessage("正規表現"),
@@ -505,9 +509,6 @@ class MessageLookup extends MessageLookupByLibrary {
"WebDAVにデータをバックアップ",
),
"remoteDestination": MessageLookupByLibrary.simpleMessage("リモート宛先"),
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"WebDAVからデータを復元",
),
"remove": MessageLookupByLibrary.simpleMessage("削除"),
"rename": MessageLookupByLibrary.simpleMessage("リネーム"),
"request": MessageLookupByLibrary.simpleMessage("リクエスト"),
@@ -526,6 +527,20 @@ class MessageLookup extends MessageLookupByLibrary {
),
"restart": MessageLookupByLibrary.simpleMessage("再起動"),
"restartCoreTip": MessageLookupByLibrary.simpleMessage("コアを再起動してもよろしいですか?"),
"restore": MessageLookupByLibrary.simpleMessage("復元"),
"restoreAllData": MessageLookupByLibrary.simpleMessage("すべてのデータを復元する"),
"restoreException": MessageLookupByLibrary.simpleMessage("復元例外"),
"restoreFromFileDesc": MessageLookupByLibrary.simpleMessage(
"ファイルを介してデータを復元する",
),
"restoreFromWebDAVDesc": MessageLookupByLibrary.simpleMessage(
"WebDAVを介してデータを復元する",
),
"restoreOnlyConfig": MessageLookupByLibrary.simpleMessage("設定ファイルのみを復元する"),
"restoreStrategy": MessageLookupByLibrary.simpleMessage("復元ストラテジー"),
"restoreStrategy_compatible": MessageLookupByLibrary.simpleMessage("互換"),
"restoreStrategy_override": MessageLookupByLibrary.simpleMessage("上書き"),
"restoreSuccess": MessageLookupByLibrary.simpleMessage("復元に成功しました"),
"routeAddress": MessageLookupByLibrary.simpleMessage("ルートアドレス"),
"routeAddressDesc": MessageLookupByLibrary.simpleMessage("ルートアドレスを設定"),
"routeMode": MessageLookupByLibrary.simpleMessage("ルートモード"),
@@ -619,6 +634,7 @@ class MessageLookup extends MessageLookupByLibrary {
"ハンドシェイクなどの余分な遅延を削除",
),
"unknown": MessageLookupByLibrary.simpleMessage("不明"),
"unknownNetworkError": MessageLookupByLibrary.simpleMessage("不明なネットワークエラー"),
"unnamed": MessageLookupByLibrary.simpleMessage("無題"),
"update": MessageLookupByLibrary.simpleMessage("更新"),
"upload": MessageLookupByLibrary.simpleMessage("アップロード"),

View File

@@ -80,6 +80,7 @@ class MessageLookup extends MessageLookupByLibrary {
"action_tun": MessageLookupByLibrary.simpleMessage("TUN"),
"action_view": MessageLookupByLibrary.simpleMessage("Показать/Скрыть"),
"add": MessageLookupByLibrary.simpleMessage("Добавить"),
"addProfile": MessageLookupByLibrary.simpleMessage("Добавить профиль"),
"addRule": MessageLookupByLibrary.simpleMessage("Добавить правило"),
"addedOriginRules": MessageLookupByLibrary.simpleMessage(
"Добавить к оригинальным правилам",
@@ -161,11 +162,11 @@ class MessageLookup extends MessageLookupByLibrary {
"Интервал автообновления (минуты)",
),
"backup": MessageLookupByLibrary.simpleMessage("Резервное копирование"),
"backupAndRecovery": MessageLookupByLibrary.simpleMessage(
"backupAndRestore": MessageLookupByLibrary.simpleMessage(
"Резервное копирование и восстановление",
),
"backupAndRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"Синхронизация данных через WebDAV или файл",
"backupAndRestoreDesc": MessageLookupByLibrary.simpleMessage(
"Синхронизация данных через WebDAV или файлы",
),
"backupSuccess": MessageLookupByLibrary.simpleMessage(
"Резервное копирование успешно",
@@ -276,6 +277,7 @@ class MessageLookup extends MessageLookupByLibrary {
"defaultText": MessageLookupByLibrary.simpleMessage("По умолчанию"),
"delay": MessageLookupByLibrary.simpleMessage("Задержка"),
"delaySort": MessageLookupByLibrary.simpleMessage("Сортировка по задержке"),
"delayTest": MessageLookupByLibrary.simpleMessage("Тест задержки"),
"delete": MessageLookupByLibrary.simpleMessage("Удалить"),
"deleteMultipTip": m1,
"deleteTip": m2,
@@ -444,6 +446,9 @@ class MessageLookup extends MessageLookupByLibrary {
"internet": MessageLookupByLibrary.simpleMessage("Интернет"),
"interval": MessageLookupByLibrary.simpleMessage("Интервал"),
"intranetIP": MessageLookupByLibrary.simpleMessage("Внутренний IP"),
"invalidBackupFile": MessageLookupByLibrary.simpleMessage(
"Неверный файл резервной копии",
),
"ipcidr": MessageLookupByLibrary.simpleMessage("IPCIDR"),
"ipv6Desc": MessageLookupByLibrary.simpleMessage(
"При включении будет возможно получать IPv6 трафик",
@@ -469,9 +474,6 @@ class MessageLookup extends MessageLookupByLibrary {
"localBackupDesc": MessageLookupByLibrary.simpleMessage(
"Резервное копирование локальных данных на локальный диск",
),
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"Восстановление данных из файла",
),
"log": MessageLookupByLibrary.simpleMessage("Журнал"),
"logLevel": MessageLookupByLibrary.simpleMessage("Уровень логов"),
"logcat": MessageLookupByLibrary.simpleMessage("Logcat"),
@@ -527,6 +529,12 @@ class MessageLookup extends MessageLookupByLibrary {
"networkDetection": MessageLookupByLibrary.simpleMessage(
"Обнаружение сети",
),
"networkException": MessageLookupByLibrary.simpleMessage(
"Ошибка сети, проверьте соединение и попробуйте еще раз",
),
"networkRequestException": MessageLookupByLibrary.simpleMessage(
"Исключение сетевого запроса, пожалуйста, попробуйте позже.",
),
"networkSpeed": MessageLookupByLibrary.simpleMessage("Скорость сети"),
"networkType": MessageLookupByLibrary.simpleMessage("Тип сети"),
"neutralScheme": MessageLookupByLibrary.simpleMessage("Нейтральные"),
@@ -595,6 +603,12 @@ class MessageLookup extends MessageLookupByLibrary {
"overrideScript": MessageLookupByLibrary.simpleMessage(
"Скрипт переопределения",
),
"overwriteTypeCustom": MessageLookupByLibrary.simpleMessage(
"Пользовательский",
),
"overwriteTypeCustomDesc": MessageLookupByLibrary.simpleMessage(
"Пользовательский режим, полная настройка групп прокси и правил",
),
"palette": MessageLookupByLibrary.simpleMessage("Палитра"),
"password": MessageLookupByLibrary.simpleMessage("Пароль"),
"paste": MessageLookupByLibrary.simpleMessage("Вставить"),
@@ -669,31 +683,13 @@ class MessageLookup extends MessageLookupByLibrary {
"Установить порт прослушивания Clash",
),
"proxyProviders": MessageLookupByLibrary.simpleMessage("Провайдеры прокси"),
"pruneCache": MessageLookupByLibrary.simpleMessage("Очистить кэш"),
"pureBlackMode": MessageLookupByLibrary.simpleMessage("Чисто черный режим"),
"qrcode": MessageLookupByLibrary.simpleMessage("QR-код"),
"qrcodeDesc": MessageLookupByLibrary.simpleMessage(
"Сканируйте QR-код для получения профиля",
),
"rainbowScheme": MessageLookupByLibrary.simpleMessage("Радужные"),
"recovery": MessageLookupByLibrary.simpleMessage("Восстановление"),
"recoveryAll": MessageLookupByLibrary.simpleMessage(
"Восстановить все данные",
),
"recoveryProfiles": MessageLookupByLibrary.simpleMessage(
"Только восстановление профилей",
),
"recoveryStrategy": MessageLookupByLibrary.simpleMessage(
"Стратегия восстановления",
),
"recoveryStrategy_compatible": MessageLookupByLibrary.simpleMessage(
"Совместимый",
),
"recoveryStrategy_override": MessageLookupByLibrary.simpleMessage(
"Переопределение",
),
"recoverySuccess": MessageLookupByLibrary.simpleMessage(
"Восстановление успешно",
),
"redirPort": MessageLookupByLibrary.simpleMessage("Redir-порт"),
"redo": MessageLookupByLibrary.simpleMessage("Повторить"),
"regExp": MessageLookupByLibrary.simpleMessage("Регулярное выражение"),
@@ -705,9 +701,6 @@ class MessageLookup extends MessageLookupByLibrary {
"remoteDestination": MessageLookupByLibrary.simpleMessage(
"Удалённое назначение",
),
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"Восстановление данных с WebDAV",
),
"remove": MessageLookupByLibrary.simpleMessage("Удалить"),
"rename": MessageLookupByLibrary.simpleMessage("Переименовать"),
"request": MessageLookupByLibrary.simpleMessage("Запрос"),
@@ -734,6 +727,34 @@ class MessageLookup extends MessageLookupByLibrary {
"restartCoreTip": MessageLookupByLibrary.simpleMessage(
"Вы уверены, что хотите перезапустить ядро?",
),
"restore": MessageLookupByLibrary.simpleMessage("Восстановить"),
"restoreAllData": MessageLookupByLibrary.simpleMessage(
"Восстановить все данные",
),
"restoreException": MessageLookupByLibrary.simpleMessage(
"Ошибка восстановления",
),
"restoreFromFileDesc": MessageLookupByLibrary.simpleMessage(
"Восстановить данные из файла",
),
"restoreFromWebDAVDesc": MessageLookupByLibrary.simpleMessage(
"Восстановить данные через WebDAV",
),
"restoreOnlyConfig": MessageLookupByLibrary.simpleMessage(
"Восстановить только файлы конфигурации",
),
"restoreStrategy": MessageLookupByLibrary.simpleMessage(
"Стратегия восстановления",
),
"restoreStrategy_compatible": MessageLookupByLibrary.simpleMessage(
"Совместимый",
),
"restoreStrategy_override": MessageLookupByLibrary.simpleMessage(
"Перезаписать",
),
"restoreSuccess": MessageLookupByLibrary.simpleMessage(
"Восстановление успешно",
),
"routeAddress": MessageLookupByLibrary.simpleMessage("Адрес маршрутизации"),
"routeAddressDesc": MessageLookupByLibrary.simpleMessage(
"Настройка адреса прослушивания маршрутизации",
@@ -851,6 +872,9 @@ class MessageLookup extends MessageLookupByLibrary {
"Убрать дополнительные задержки, такие как рукопожатие",
),
"unknown": MessageLookupByLibrary.simpleMessage("Неизвестно"),
"unknownNetworkError": MessageLookupByLibrary.simpleMessage(
"Неизвестная сетевая ошибка",
),
"unnamed": MessageLookupByLibrary.simpleMessage("Без имени"),
"update": MessageLookupByLibrary.simpleMessage("Обновить"),
"upload": MessageLookupByLibrary.simpleMessage("Загрузка"),

View File

@@ -70,6 +70,7 @@ class MessageLookup extends MessageLookupByLibrary {
"action_tun": MessageLookupByLibrary.simpleMessage("虚拟网卡"),
"action_view": MessageLookupByLibrary.simpleMessage("显示/隐藏"),
"add": MessageLookupByLibrary.simpleMessage("添加"),
"addProfile": MessageLookupByLibrary.simpleMessage("添加配置"),
"addRule": MessageLookupByLibrary.simpleMessage("添加规则"),
"addedOriginRules": MessageLookupByLibrary.simpleMessage("附加到原始规则"),
"addedRules": MessageLookupByLibrary.simpleMessage("附加规则"),
@@ -109,8 +110,8 @@ class MessageLookup extends MessageLookupByLibrary {
"autoUpdate": MessageLookupByLibrary.simpleMessage("自动更新"),
"autoUpdateInterval": MessageLookupByLibrary.simpleMessage("自动更新间隔(分钟)"),
"backup": MessageLookupByLibrary.simpleMessage("备份"),
"backupAndRecovery": MessageLookupByLibrary.simpleMessage("备份与恢复"),
"backupAndRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"backupAndRestore": MessageLookupByLibrary.simpleMessage("备份与恢复"),
"backupAndRestoreDesc": MessageLookupByLibrary.simpleMessage(
"通过WebDAV或者文件同步数据",
),
"backupSuccess": MessageLookupByLibrary.simpleMessage("备份成功"),
@@ -184,6 +185,7 @@ class MessageLookup extends MessageLookupByLibrary {
"defaultText": MessageLookupByLibrary.simpleMessage("默认"),
"delay": MessageLookupByLibrary.simpleMessage("延迟"),
"delaySort": MessageLookupByLibrary.simpleMessage("按延迟排序"),
"delayTest": MessageLookupByLibrary.simpleMessage("延迟测试"),
"delete": MessageLookupByLibrary.simpleMessage("删除"),
"deleteMultipTip": m1,
"deleteTip": m2,
@@ -284,6 +286,7 @@ class MessageLookup extends MessageLookupByLibrary {
"internet": MessageLookupByLibrary.simpleMessage("互联网"),
"interval": MessageLookupByLibrary.simpleMessage("间隔"),
"intranetIP": MessageLookupByLibrary.simpleMessage("内网 IP"),
"invalidBackupFile": MessageLookupByLibrary.simpleMessage("无效备份文件"),
"ipcidr": MessageLookupByLibrary.simpleMessage("IP/掩码"),
"ipv6Desc": MessageLookupByLibrary.simpleMessage("开启后将可以接收IPv6流量"),
"ipv6InboundDesc": MessageLookupByLibrary.simpleMessage("允许IPv6入站"),
@@ -301,7 +304,6 @@ class MessageLookup extends MessageLookupByLibrary {
"loading": MessageLookupByLibrary.simpleMessage("加载中..."),
"local": MessageLookupByLibrary.simpleMessage("本地"),
"localBackupDesc": MessageLookupByLibrary.simpleMessage("备份数据到本地"),
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage("通过文件恢复数据"),
"log": MessageLookupByLibrary.simpleMessage("日志"),
"logLevel": MessageLookupByLibrary.simpleMessage("日志等级"),
"logcat": MessageLookupByLibrary.simpleMessage("日志捕获"),
@@ -335,6 +337,10 @@ class MessageLookup extends MessageLookupByLibrary {
"network": MessageLookupByLibrary.simpleMessage("网络"),
"networkDesc": MessageLookupByLibrary.simpleMessage("修改网络相关设置"),
"networkDetection": MessageLookupByLibrary.simpleMessage("网络检测"),
"networkException": MessageLookupByLibrary.simpleMessage("网络异常,请检查连接后重试"),
"networkRequestException": MessageLookupByLibrary.simpleMessage(
"网络请求异常,请稍后再试。",
),
"networkSpeed": MessageLookupByLibrary.simpleMessage("网络速度"),
"networkType": MessageLookupByLibrary.simpleMessage("网络类型"),
"neutralScheme": MessageLookupByLibrary.simpleMessage("中性"),
@@ -373,6 +379,10 @@ class MessageLookup extends MessageLookupByLibrary {
"overrideMode": MessageLookupByLibrary.simpleMessage("覆写模式"),
"overrideOriginRules": MessageLookupByLibrary.simpleMessage("覆盖原始规则"),
"overrideScript": MessageLookupByLibrary.simpleMessage("覆写脚本"),
"overwriteTypeCustom": MessageLookupByLibrary.simpleMessage("自定义"),
"overwriteTypeCustomDesc": MessageLookupByLibrary.simpleMessage(
"自定义模式,支持完全自定义修改代理组以及规则",
),
"palette": MessageLookupByLibrary.simpleMessage("调色板"),
"password": MessageLookupByLibrary.simpleMessage("密码"),
"paste": MessageLookupByLibrary.simpleMessage("粘贴"),
@@ -423,17 +433,11 @@ class MessageLookup extends MessageLookupByLibrary {
"proxyPort": MessageLookupByLibrary.simpleMessage("代理端口"),
"proxyPortDesc": MessageLookupByLibrary.simpleMessage("设置Clash监听端口"),
"proxyProviders": MessageLookupByLibrary.simpleMessage("代理提供者"),
"pruneCache": MessageLookupByLibrary.simpleMessage("修剪缓存"),
"pureBlackMode": MessageLookupByLibrary.simpleMessage("纯黑模式"),
"qrcode": MessageLookupByLibrary.simpleMessage("二维码"),
"qrcodeDesc": MessageLookupByLibrary.simpleMessage("扫描二维码获取配置文件"),
"rainbowScheme": MessageLookupByLibrary.simpleMessage("彩虹"),
"recovery": MessageLookupByLibrary.simpleMessage("恢复"),
"recoveryAll": MessageLookupByLibrary.simpleMessage("恢复所有数据"),
"recoveryProfiles": MessageLookupByLibrary.simpleMessage("仅恢复配置文件"),
"recoveryStrategy": MessageLookupByLibrary.simpleMessage("恢复策略"),
"recoveryStrategy_compatible": MessageLookupByLibrary.simpleMessage("兼容"),
"recoveryStrategy_override": MessageLookupByLibrary.simpleMessage("覆盖"),
"recoverySuccess": MessageLookupByLibrary.simpleMessage("恢复成功"),
"redirPort": MessageLookupByLibrary.simpleMessage("Redir端口"),
"redo": MessageLookupByLibrary.simpleMessage("重做"),
"regExp": MessageLookupByLibrary.simpleMessage("正则"),
@@ -441,7 +445,6 @@ class MessageLookup extends MessageLookupByLibrary {
"remote": MessageLookupByLibrary.simpleMessage("远程"),
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage("备份数据到WebDAV"),
"remoteDestination": MessageLookupByLibrary.simpleMessage("远程目标"),
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage("通过WebDAV恢复数据"),
"remove": MessageLookupByLibrary.simpleMessage("移除"),
"rename": MessageLookupByLibrary.simpleMessage("重命名"),
"request": MessageLookupByLibrary.simpleMessage("请求"),
@@ -460,6 +463,18 @@ class MessageLookup extends MessageLookupByLibrary {
),
"restart": MessageLookupByLibrary.simpleMessage("重启"),
"restartCoreTip": MessageLookupByLibrary.simpleMessage("您确定要重启核心吗?"),
"restore": MessageLookupByLibrary.simpleMessage("恢复"),
"restoreAllData": MessageLookupByLibrary.simpleMessage("恢复所有数据"),
"restoreException": MessageLookupByLibrary.simpleMessage("恢复异常"),
"restoreFromFileDesc": MessageLookupByLibrary.simpleMessage("通过文件恢复数据"),
"restoreFromWebDAVDesc": MessageLookupByLibrary.simpleMessage(
"通过WebDAV恢复数据",
),
"restoreOnlyConfig": MessageLookupByLibrary.simpleMessage("仅恢复配置文件"),
"restoreStrategy": MessageLookupByLibrary.simpleMessage("恢复策略"),
"restoreStrategy_compatible": MessageLookupByLibrary.simpleMessage("兼容"),
"restoreStrategy_override": MessageLookupByLibrary.simpleMessage("覆盖"),
"restoreSuccess": MessageLookupByLibrary.simpleMessage("恢复成功"),
"routeAddress": MessageLookupByLibrary.simpleMessage("路由地址"),
"routeAddressDesc": MessageLookupByLibrary.simpleMessage("配置监听路由地址"),
"routeMode": MessageLookupByLibrary.simpleMessage("路由模式"),
@@ -547,6 +562,7 @@ class MessageLookup extends MessageLookupByLibrary {
"unifiedDelay": MessageLookupByLibrary.simpleMessage("统一延迟"),
"unifiedDelayDesc": MessageLookupByLibrary.simpleMessage("去除握手等额外延迟"),
"unknown": MessageLookupByLibrary.simpleMessage("未知"),
"unknownNetworkError": MessageLookupByLibrary.simpleMessage("未知网络错误"),
"unnamed": MessageLookupByLibrary.simpleMessage("未命名"),
"update": MessageLookupByLibrary.simpleMessage("更新"),
"upload": MessageLookupByLibrary.simpleMessage("上传"),

View File

@@ -999,26 +999,6 @@ class AppLocalizations {
return Intl.message('tip', name: 'tip', desc: '', args: []);
}
/// `Backup and Recovery`
String get backupAndRecovery {
return Intl.message(
'Backup and Recovery',
name: 'backupAndRecovery',
desc: '',
args: [],
);
}
/// `Sync data via WebDAV or file`
String get backupAndRecoveryDesc {
return Intl.message(
'Sync data via WebDAV or file',
name: 'backupAndRecoveryDesc',
desc: '',
args: [],
);
}
/// `Account`
String get account {
return Intl.message('Account', name: 'account', desc: '', args: []);
@@ -1029,41 +1009,6 @@ class AppLocalizations {
return Intl.message('Backup', name: 'backup', desc: '', args: []);
}
/// `Recovery`
String get recovery {
return Intl.message('Recovery', name: 'recovery', desc: '', args: []);
}
/// `Only recovery profiles`
String get recoveryProfiles {
return Intl.message(
'Only recovery profiles',
name: 'recoveryProfiles',
desc: '',
args: [],
);
}
/// `Recovery all data`
String get recoveryAll {
return Intl.message(
'Recovery all data',
name: 'recoveryAll',
desc: '',
args: [],
);
}
/// `Recovery success`
String get recoverySuccess {
return Intl.message(
'Recovery success',
name: 'recoverySuccess',
desc: '',
args: [],
);
}
/// `Backup success`
String get backupSuccess {
return Intl.message(
@@ -1689,16 +1634,6 @@ class AppLocalizations {
);
}
/// `Recovery data from WebDAV`
String get remoteRecoveryDesc {
return Intl.message(
'Recovery data from WebDAV',
name: 'remoteRecoveryDesc',
desc: '',
args: [],
);
}
/// `Backup local data to local`
String get localBackupDesc {
return Intl.message(
@@ -1709,16 +1644,6 @@ class AppLocalizations {
);
}
/// `Recovery data from file`
String get localRecoveryDesc {
return Intl.message(
'Recovery data from file',
name: 'localRecoveryDesc',
desc: '',
args: [],
);
}
/// `Mode`
String get mode {
return Intl.message('Mode', name: 'mode', desc: '', args: []);
@@ -2934,31 +2859,31 @@ class AppLocalizations {
return Intl.message('Contact me', name: 'contactMe', desc: '', args: []);
}
/// `Recovery strategy`
String get recoveryStrategy {
/// `Restore strategy`
String get restoreStrategy {
return Intl.message(
'Recovery strategy',
name: 'recoveryStrategy',
'Restore strategy',
name: 'restoreStrategy',
desc: '',
args: [],
);
}
/// `Override`
String get recoveryStrategy_override {
String get restoreStrategy_override {
return Intl.message(
'Override',
name: 'recoveryStrategy_override',
name: 'restoreStrategy_override',
desc: '',
args: [],
);
}
/// `Compatible`
String get recoveryStrategy_compatible {
String get restoreStrategy_compatible {
return Intl.message(
'Compatible',
name: 'recoveryStrategy_compatible',
name: 'restoreStrategy_compatible',
desc: '',
args: [],
);
@@ -3663,6 +3588,166 @@ class AppLocalizations {
args: [],
);
}
/// `Custom`
String get overwriteTypeCustom {
return Intl.message(
'Custom',
name: 'overwriteTypeCustom',
desc: '',
args: [],
);
}
/// `Custom mode, fully customize proxy groups and rules`
String get overwriteTypeCustomDesc {
return Intl.message(
'Custom mode, fully customize proxy groups and rules',
name: 'overwriteTypeCustomDesc',
desc: '',
args: [],
);
}
/// `Unknown network error`
String get unknownNetworkError {
return Intl.message(
'Unknown network error',
name: 'unknownNetworkError',
desc: '',
args: [],
);
}
/// `Network request exception, please try again later.`
String get networkRequestException {
return Intl.message(
'Network request exception, please try again later.',
name: 'networkRequestException',
desc: '',
args: [],
);
}
/// `Recovery exception`
String get restoreException {
return Intl.message(
'Recovery exception',
name: 'restoreException',
desc: '',
args: [],
);
}
/// `Network exception, please check your connection and try again`
String get networkException {
return Intl.message(
'Network exception, please check your connection and try again',
name: 'networkException',
desc: '',
args: [],
);
}
/// `Invalid backup file`
String get invalidBackupFile {
return Intl.message(
'Invalid backup file',
name: 'invalidBackupFile',
desc: '',
args: [],
);
}
/// `Prune cache`
String get pruneCache {
return Intl.message('Prune cache', name: 'pruneCache', desc: '', args: []);
}
/// `Backup and Restore`
String get backupAndRestore {
return Intl.message(
'Backup and Restore',
name: 'backupAndRestore',
desc: '',
args: [],
);
}
/// `Sync data via WebDAV or files`
String get backupAndRestoreDesc {
return Intl.message(
'Sync data via WebDAV or files',
name: 'backupAndRestoreDesc',
desc: '',
args: [],
);
}
/// `Restore`
String get restore {
return Intl.message('Restore', name: 'restore', desc: '', args: []);
}
/// `Restore success`
String get restoreSuccess {
return Intl.message(
'Restore success',
name: 'restoreSuccess',
desc: '',
args: [],
);
}
/// `Restore data via WebDAV`
String get restoreFromWebDAVDesc {
return Intl.message(
'Restore data via WebDAV',
name: 'restoreFromWebDAVDesc',
desc: '',
args: [],
);
}
/// `Restore data via file`
String get restoreFromFileDesc {
return Intl.message(
'Restore data via file',
name: 'restoreFromFileDesc',
desc: '',
args: [],
);
}
/// `Restore configuration files only`
String get restoreOnlyConfig {
return Intl.message(
'Restore configuration files only',
name: 'restoreOnlyConfig',
desc: '',
args: [],
);
}
/// `Restore all data`
String get restoreAllData {
return Intl.message(
'Restore all data',
name: 'restoreAllData',
desc: '',
args: [],
);
}
/// `Add Profile`
String get addProfile {
return Intl.message('Add Profile', name: 'addProfile', desc: '', args: []);
}
/// `Delay Test`
String get delayTest {
return Intl.message('Delay Test', name: 'delayTest', desc: '', args: []);
}
}
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations> {

View File

@@ -1,65 +1,31 @@
import 'dart:async';
import 'dart:io';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/plugins/tile.dart';
import 'package:fl_clash/pages/error.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'application.dart';
import 'common/common.dart';
import 'core/controller.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final version = await system.version;
await globalState.initApp(version);
HttpOverrides.global = FlClashHttpOverrides();
runApp(ProviderScope(child: const Application()));
}
@pragma('vm:entry-point')
Future<void> _service(List<String> flags) async {
WidgetsFlutterBinding.ensureInitialized();
globalState.isService = true;
await globalState.init();
await coreController.preload();
tile?.addListener(
_TileListenerWithService(
onStop: () async {
await app?.tip(appLocalizations.stopVpn);
await globalState.handleStop();
},
),
);
app?.tip(appLocalizations.startVpn);
final version = await system.version;
await coreController.init(version);
final clashConfig = globalState.config.patchClashConfig.copyWith.tun(
enable: false,
);
final setupState = globalState.getSetupState(
globalState.config.currentProfileId,
);
globalState.setupConfig(
setupState: setupState,
patchConfig: clashConfig,
preloadInvoke: () {
globalState.handleStart();
},
);
}
@immutable
class _TileListenerWithService with TileListener {
final Function() _onStop;
const _TileListenerWithService({required Function() onStop})
: _onStop = onStop;
@override
void onStop() {
_onStop();
try {
WidgetsFlutterBinding.ensureInitialized();
final version = await system.version;
final container = await globalState.init(version);
HttpOverrides.global = FlClashHttpOverrides();
runApp(
UncontrolledProviderScope(
container: container,
child: const Application(),
),
);
} catch (e, s) {
return runApp(
MaterialApp(
home: InitErrorScreen(error: e, stack: s),
),
);
}
}

View File

@@ -1,6 +1,7 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/core/core.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/core.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/plugins/service.dart';
import 'package:fl_clash/providers/providers.dart';
@@ -27,9 +28,14 @@ class _AndroidContainerState extends ConsumerState<AndroidManager>
) {
app?.updateExcludeFromRecents(next);
}, fireImmediately: true);
ref.listenManual(androidStateProvider, (prev, next) {
ref.listenManual(sharedStateProvider, (prev, next) {
if (prev != next) {
service?.syncAndroidState(next);
debouncer.call(FunctionTag.saveSharedFile, () async {
preferences.saveShareState(next);
}, duration: Duration(seconds: 1));
if (prev?.needSyncSharedState != next.needSyncSharedState) {
service?.syncState(next.needSyncSharedState);
}
}
});
service?.addListener(this);

View File

@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/manager/window_manager.dart';
import 'package:fl_clash/providers/providers.dart';
@@ -25,26 +26,19 @@ class _AppStateManagerState extends ConsumerState<AppStateManager>
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
ref.listenManual(layoutChangeProvider, (prev, next) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (prev != next) {
globalState.computeHeightMapCache = {};
}
});
});
ref.listenManual(checkIpProvider, (prev, next) {
if (prev != next && next.b) {
detectionState.startCheck();
if (prev != next && next.a && next.c) {
ref.read(networkDetectionProvider.notifier).startCheck();
}
}, fireImmediately: true);
ref.listenManual(configStateProvider, (prev, next) {
});
ref.listenManual(configProvider, (prev, next) {
if (prev != next) {
globalState.appController.savePreferencesDebounce();
appController.savePreferencesDebounce();
}
});
ref.listenManual(needUpdateGroupsProvider, (prev, next) {
if (prev != next) {
globalState.appController.updateGroupsDebounce();
appController.updateGroupsDebounce();
}
});
if (window == null) {
@@ -73,20 +67,18 @@ class _AppStateManagerState extends ConsumerState<AppStateManager>
commonPrint.log('$state');
if (state == AppLifecycleState.resumed) {
render?.resume();
}
if (state == AppLifecycleState.resumed) {
WidgetsBinding.instance.addPostFrameCallback((_) {
detectionState.tryStartCheck();
appController.tryCheckIp();
if (system.isAndroid) {
appController.tryStartCore();
}
});
if (system.isAndroid) {
globalState.appController.tryStartCore();
}
}
}
@override
void didChangePlatformBrightness() {
globalState.appController.updateBrightness();
appController.updateBrightness();
}
@override
@@ -132,20 +124,20 @@ class AppSidebarContainer extends ConsumerWidget {
const AppSidebarContainer({super.key, required this.child});
Widget _buildLoading() {
return Consumer(
builder: (_, ref, _) {
final loading = ref.watch(loadingProvider);
final isMobileView = ref.watch(isMobileViewProvider);
return loading && !isMobileView
? RotatedBox(
quarterTurns: 1,
child: const LinearProgressIndicator(),
)
: Container();
},
);
}
// Widget _buildLoading() {
// return Consumer(
// builder: (_, ref, _) {
// final loading = ref.watch(loadingProvider);
// final isMobileView = ref.watch(isMobileViewProvider);
// return loading && !isMobileView
// ? RotatedBox(
// quarterTurns: 1,
// child: const LinearProgressIndicator(),
// )
// : Container();
// },
// );
// }
Widget _buildBackground({
required BuildContext context,
@@ -187,84 +179,74 @@ class AppSidebarContainer extends ConsumerWidget {
_buildBackground(
context: context,
child: SafeArea(
child: Stack(
alignment: Alignment.topRight,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (system.isMacOS) SizedBox(height: 22),
SizedBox(height: 10),
if (!system.isMacOS) ...[
ClipRect(child: AppIcon()),
SizedBox(height: 12),
],
Expanded(
child: ScrollConfiguration(
behavior: HiddenBarScrollBehavior(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: NavigationRail(
scrollable: true,
minExtendedWidth: 200,
backgroundColor: Colors.transparent,
selectedLabelTextStyle: context
.textTheme
.labelLarge!
.copyWith(
color: context.colorScheme.onSurface,
),
unselectedLabelTextStyle: context
.textTheme
.labelLarge!
.copyWith(
color: context.colorScheme.onSurface,
),
destinations: navigationItems
.map(
(e) => NavigationRailDestination(
icon: e.icon,
label: Text(Intl.message(e.label.name)),
),
)
.toList(),
onDestinationSelected: (index) {
globalState.appController.toPage(
navigationItems[index].label,
);
},
extended: false,
selectedIndex: currentIndex,
labelType: showLabel
? NavigationRailLabelType.all
: NavigationRailLabelType.none,
),
),
],
if (system.isMacOS) SizedBox(height: 22),
SizedBox(height: 10),
if (!system.isMacOS) ...[
ClipRect(child: AppIcon()),
SizedBox(height: 12),
],
Expanded(
child: ScrollConfiguration(
behavior: HiddenBarScrollBehavior(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: NavigationRail(
scrollable: true,
minExtendedWidth: 200,
backgroundColor: Colors.transparent,
selectedLabelTextStyle: context
.textTheme
.labelLarge!
.copyWith(color: context.colorScheme.onSurface),
unselectedLabelTextStyle: context
.textTheme
.labelLarge!
.copyWith(color: context.colorScheme.onSurface),
destinations: navigationItems
.map(
(e) => NavigationRailDestination(
icon: e.icon,
label: Text(Intl.message(e.label.name)),
),
)
.toList(),
onDestinationSelected: (index) {
appController.toPage(
navigationItems[index].label,
);
},
extended: false,
selectedIndex: currentIndex,
labelType: showLabel
? NavigationRailLabelType.all
: NavigationRailLabelType.none,
),
),
),
],
),
const SizedBox(height: 16),
IconButton(
onPressed: () {
ref
.read(appSettingProvider.notifier)
.updateState(
(state) =>
state.copyWith(showLabel: !state.showLabel),
);
},
icon: Icon(
Icons.menu,
color: context.colorScheme.onSurfaceVariant,
),
),
const SizedBox(height: 16),
],
),
),
_buildLoading(),
const SizedBox(height: 16),
IconButton(
onPressed: () {
ref
.read(appSettingProvider.notifier)
.update(
(state) =>
state.copyWith(showLabel: !state.showLabel),
);
},
icon: Icon(
Icons.menu,
color: context.colorScheme.onSurfaceVariant,
),
),
const SizedBox(height: 16),
],
),
),

View File

@@ -1,4 +1,5 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/core/core.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
@@ -29,14 +30,17 @@ class _CoreContainerState extends ConsumerState<CoreManager>
void initState() {
super.initState();
coreEventManager.addListener(this);
ref.listenManual(needSetupProvider, (prev, next) {
if (prev != next) {
globalState.appController.handleChangeProfile();
}
});
ref.listenManual(
currentSetupStateProvider.select((state) => state?.profileId),
(prev, next) {
if (prev != next) {
appController.fullSetup();
}
},
);
ref.listenManual(updateParamsProvider, (prev, next) {
if (prev != next) {
globalState.appController.updateClashConfigDebounce();
appController.updateConfigDebounce();
}
});
ref.listenManual(appSettingProvider.select((state) => state.openLogs), (
@@ -60,7 +64,6 @@ class _CoreContainerState extends ConsumerState<CoreManager>
@override
Future<void> onDelay(Delay delay) async {
super.onDelay(delay);
final appController = globalState.appController;
appController.setDelay(delay);
debouncer.call(FunctionTag.updateDelay, () async {
appController.updateGroupsDebounce();
@@ -88,23 +91,21 @@ class _CoreContainerState extends ConsumerState<CoreManager>
.read(providersProvider.notifier)
.setProvider(await coreController.getExternalProvider(providerName));
debouncer.call(FunctionTag.loadedProvider, () async {
globalState.appController.updateGroupsDebounce();
appController.updateGroupsDebounce();
}, duration: const Duration(milliseconds: 5000));
super.onLoaded(providerName);
}
@override
Future<void> onCrash(String message) async {
if (!globalState.isUserDisconnected &&
WidgetsBinding.instance.lifecycleState == AppLifecycleState.resumed) {
context.showNotifier(message);
}
globalState.isUserDisconnected = false;
if (ref.read(coreStatusProvider) != CoreStatus.connected) {
return;
}
ref.read(coreStatusProvider.notifier).value = CoreStatus.disconnected;
await coreController.shutdown();
if (WidgetsBinding.instance.lifecycleState == AppLifecycleState.resumed) {
context.showNotifier(message);
}
await coreController.shutdown(false);
super.onCrash(message);
}
}

View File

@@ -1,8 +1,8 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/common.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -11,10 +11,7 @@ import 'package:hotkey_manager/hotkey_manager.dart';
class HotKeyManager extends ConsumerStatefulWidget {
final Widget child;
const HotKeyManager({
super.key,
required this.child,
});
const HotKeyManager({super.key, required this.child});
@override
ConsumerState<HotKeyManager> createState() => _HotKeyManagerState();
@@ -24,29 +21,25 @@ class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
@override
void initState() {
super.initState();
ref.listenManual(
hotKeyActionsProvider,
(prev, next) {
if (!hotKeyActionListEquality.equals(prev, next)) {
_updateHotKeys(hotKeyActions: next);
}
},
fireImmediately: true,
);
ref.listenManual(hotKeyActionsProvider, (prev, next) {
if (!hotKeyActionListEquality.equals(prev, next)) {
_updateHotKeys(hotKeyActions: next);
}
}, fireImmediately: true);
}
Future<void> _handleHotKeyAction(HotAction action) async {
switch (action) {
case HotAction.mode:
globalState.appController.updateMode();
appController.updateMode();
case HotAction.start:
globalState.appController.updateStart();
appController.updateStart();
case HotAction.view:
globalState.appController.updateVisible();
appController.updateVisible();
case HotAction.proxy:
globalState.appController.updateSystemProxy();
appController.updateSystemProxy();
case HotAction.tun:
globalState.appController.updateTun();
appController.updateTun();
}
}
@@ -54,27 +47,25 @@ class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
required List<HotKeyAction> hotKeyActions,
}) async {
await hotKeyManager.unregisterAll();
final hotkeyActionHandles = hotKeyActions.where(
(hotKeyAction) {
return hotKeyAction.key != null && hotKeyAction.modifiers.isNotEmpty;
},
).map<Future>(
(hotKeyAction) async {
final modifiers = hotKeyAction.modifiers
.map((item) => item.toHotKeyModifier())
.toList();
final hotKey = HotKey(
key: PhysicalKeyboardKey(hotKeyAction.key!),
modifiers: modifiers,
);
return await hotKeyManager.register(
hotKey,
keyDownHandler: (_) {
_handleHotKeyAction(hotKeyAction.action);
},
);
},
);
final hotkeyActionHandles = hotKeyActions
.where((hotKeyAction) {
return hotKeyAction.key != null && hotKeyAction.modifiers.isNotEmpty;
})
.map<Future>((hotKeyAction) async {
final modifiers = hotKeyAction.modifiers
.map((item) => item.toHotKeyModifier())
.toList();
final hotKey = HotKey(
key: PhysicalKeyboardKey(hotKeyAction.key!),
modifiers: modifiers,
);
return await hotKeyManager.register(
hotKey,
keyDownHandler: (_) {
_handleHotKeyAction(hotKeyAction.action);
},
);
});
await Future.wait(hotkeyActionHandles);
}
@@ -87,7 +78,7 @@ class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
child: Actions(
actions: {
CloseWindowIntent: CallbackAction<CloseWindowIntent>(
onInvoke: (_) => globalState.appController.handleBackOrExit(),
onInvoke: (_) => appController.handleBackOrExit(),
),
DoNothingIntent: CallbackAction<DoNothingIntent>(
onInvoke: (_) => null,
@@ -100,8 +91,6 @@ class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
@override
Widget build(BuildContext context) {
return _buildShortcuts(
widget.child,
);
return _buildShortcuts(widget.child);
}
}

View File

@@ -6,7 +6,6 @@ import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/widgets/fade_box.dart';
import 'package:fl_clash/widgets/loading.dart';
import 'package:fl_clash/widgets/theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -191,7 +190,7 @@ class StatusManagerState extends State<StatusManager> {
),
),
),
LoadingIndicator(),
// LoadingIndicator(),
],
),
),
@@ -200,63 +199,63 @@ class StatusManagerState extends State<StatusManager> {
}
}
class LoadingIndicator extends ConsumerWidget {
const LoadingIndicator({super.key});
@override
Widget build(BuildContext context, ref) {
final loading = ref.watch(loadingProvider);
final isMobileView = ref.watch(isMobileViewProvider);
return AnimatedSwitcher(
switchInCurve: Curves.easeIn,
switchOutCurve: Curves.easeOut,
duration: midDuration,
transitionBuilder: (Widget child, Animation<double> animation) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(1, 0),
end: Offset.zero,
).animate(animation),
child: child,
);
},
child: loading && isMobileView
? Container(
height: 54,
margin: EdgeInsets.only(top: 8, left: 14, right: 14),
child: Material(
elevation: 3,
color: context.colorScheme.surfaceContainer,
surfaceTintColor: context.colorScheme.surfaceTint,
shape: const RoundedSuperellipseBorder(
borderRadius: BorderRadius.all(Radius.circular(14)),
),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Row(
mainAxisSize: MainAxisSize.min,
spacing: 12,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Text(
context.appLocalizations.loading,
style: context.textTheme.labelLarge?.copyWith(
color: context.colorScheme.onSurfaceVariant,
),
),
),
SizedBox(
height: 32,
width: 32,
child: CommonCircleLoading(),
),
],
),
),
),
)
: SizedBox(),
);
}
}
// class LoadingIndicator extends ConsumerWidget {
// const LoadingIndicator({super.key});
//
// @override
// Widget build(BuildContext context, ref) {
// final loading = ref.watch(loadingProvider);
// final isMobileView = ref.watch(isMobileViewProvider);
// return AnimatedSwitcher(
// switchInCurve: Curves.easeIn,
// switchOutCurve: Curves.easeOut,
// duration: midDuration,
// transitionBuilder: (Widget child, Animation<double> animation) {
// return SlideTransition(
// position: Tween<Offset>(
// begin: const Offset(1, 0),
// end: Offset.zero,
// ).animate(animation),
// child: child,
// );
// },
// child: loading && isMobileView
// ? Container(
// height: 54,
// margin: EdgeInsets.only(top: 8, left: 14, right: 14),
// child: Material(
// elevation: 3,
// color: context.colorScheme.surfaceContainer,
// surfaceTintColor: context.colorScheme.surfaceTint,
// shape: const RoundedSuperellipseBorder(
// borderRadius: BorderRadius.all(Radius.circular(14)),
// ),
// child: Padding(
// padding: EdgeInsets.symmetric(horizontal: 16),
// child: Row(
// mainAxisSize: MainAxisSize.min,
// spacing: 12,
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Flexible(
// child: Text(
// context.appLocalizations.loading,
// style: context.textTheme.labelLarge?.copyWith(
// color: context.colorScheme.onSurfaceVariant,
// ),
// ),
// ),
// SizedBox(
// height: 32,
// width: 32,
// child: CommonCircleLoading(),
// ),
// ],
// ),
// ),
// ),
// )
// : SizedBox(),
// );
// }
// }

View File

@@ -2,6 +2,8 @@ import 'dart:math';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/common/theme.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
@@ -28,17 +30,27 @@ class ThemeManager extends ConsumerWidget {
final iconBrightness = brightness == Brightness.light
? Brightness.dark
: Brightness.light;
globalState.appState = globalState.appState.copyWith(
systemUiOverlayStyle: SystemUiOverlayStyle(
WidgetsBinding.instance.addPostFrameCallback((_) {
ref
.read(systemUiOverlayStyleStateProvider.notifier)
.update(
(state) => state.copyWith(
statusBarColor: Colors.transparent,
statusBarIconBrightness: iconBrightness,
systemNavigationBarIconBrightness: iconBrightness,
systemNavigationBarColor: context.colorScheme.surface,
systemNavigationBarDividerColor: Colors.transparent,
),
);
});
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: iconBrightness,
systemNavigationBarIconBrightness: iconBrightness,
systemNavigationBarColor: context.colorScheme.surface,
systemNavigationBarDividerColor: Colors.transparent,
),
);
return AnnotatedRegion<SystemUiOverlayStyle>(
value: globalState.appState.systemUiOverlayStyle,
sized: false,
child: child,
);
@@ -98,7 +110,7 @@ class ThemeManager extends ConsumerWidget {
),
child: LayoutBuilder(
builder: (_, container) {
globalState.appController.updateViewSize(
appController.updateViewSize(
Size(container.maxWidth, container.maxHeight),
);
return _buildSystemUi(child);

View File

@@ -1,38 +1,46 @@
import 'package:fl_clash/models/app.dart';
import 'package:fl_clash/common/app_localizations.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/core/controller.dart';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/plugins/tile.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class TileManager extends StatefulWidget {
class TileManager extends ConsumerStatefulWidget {
final Widget child;
const TileManager({super.key, required this.child});
@override
State<TileManager> createState() => _TileContainerState();
ConsumerState<TileManager> createState() => _TileContainerState();
}
class _TileContainerState extends State<TileManager> with TileListener {
class _TileContainerState extends ConsumerState<TileManager> with TileListener {
@override
Widget build(BuildContext context) {
return widget.child;
}
bool get isStart => ref.read(isStartProvider);
@override
Future<void> onStart() async {
if (globalState.appState.isStart) {
if (isStart && coreController.isCompleted) {
return;
}
globalState.appController.updateStatus(true);
appController.updateStatus(true);
app?.tip(appLocalizations.startVpn);
super.onStart();
}
@override
Future<void> onStop() async {
if (!globalState.appState.isStart) {
if (!isStart) {
return;
}
globalState.appController.updateStatus(false);
appController.updateStatus(false);
app?.tip(appLocalizations.stopVpn);
super.onStop();
}

View File

@@ -1,6 +1,6 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/providers/state.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:tray_manager/tray_manager.dart';
@@ -21,7 +21,7 @@ class _TrayContainerState extends ConsumerState<TrayManager> with TrayListener {
trayManager.addListener(this);
ref.listenManual(trayStateProvider, (prev, next) {
if (prev != next) {
globalState.appController.updateTray();
appController.updateTray();
}
});
if (system.isMacOS) {

View File

@@ -1,4 +1,5 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/state.dart';
@@ -39,7 +40,7 @@ class _VpnContainerState extends ConsumerState<VpnManager> {
actionText: appLocalizations.restart,
action: () async {
await globalState.handleStop();
await globalState.appController.updateStatus(true);
await appController.updateStatus(true);
},
),
);

View File

@@ -1,9 +1,9 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:window_ext/window_ext.dart';
@@ -44,7 +44,7 @@ class _WindowContainerState extends ConsumerState<WindowManager>
@override
void onWindowClose() async {
await globalState.appController.handleBackOrExit();
await appController.handleBackOrExit();
super.onWindowClose();
}
@@ -57,19 +57,17 @@ class _WindowContainerState extends ConsumerState<WindowManager>
@override
Future<void> onShouldTerminate() async {
await globalState.appController.handleExit();
await appController.handleExit();
super.onShouldTerminate();
}
@override
Future<void> onWindowMoved() async {
void onWindowMoved() {
super.onWindowMoved();
final offset = await windowManager.getPosition();
ref
.read(windowSettingProvider.notifier)
.updateState(
(state) => state.copyWith(top: offset.dy, left: offset.dx),
);
windowManager.getPosition().then((offset) {
ref.read(windowSettingProvider.notifier);
// .update((state) => state.copyWith(top: offset.dy, left: offset.dx));
});
}
@override
@@ -78,14 +76,14 @@ class _WindowContainerState extends ConsumerState<WindowManager>
final size = await windowManager.getSize();
ref
.read(windowSettingProvider.notifier)
.updateState(
.update(
(state) => state.copyWith(width: size.width, height: size.height),
);
}
@override
void onWindowMinimize() async {
globalState.appController.savePreferencesDebounce();
appController.savePreferencesDebounce();
commonPrint.log('minimize');
render?.pause();
super.onWindowMinimize();
@@ -222,7 +220,7 @@ class _WindowHeaderState extends State<WindowHeader> {
),
IconButton(
onPressed: () {
globalState.appController.handleBackOrExit();
appController.handleBackOrExit();
},
icon: const Icon(Icons.close),
),

View File

@@ -1,6 +1,5 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/selector.dart';
import 'package:flutter/services.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
@@ -36,10 +35,6 @@ abstract class AppState with _$AppState {
@Default(false) bool realTunEnable,
@Default(false) bool loading,
required SystemUiOverlayStyle systemUiOverlayStyle,
ProfileOverrideModel? profileOverrideModel,
@Default({}) Map<QueryTag, String> queryMap,
@Default({}) Map<String, String> selectedItemMap,
@Default({}) Map<String, Set<String>> selectedItemsMap,
@Default(CoreStatus.connecting) CoreStatus coreStatus,
}) = _AppState;
}

View File

@@ -375,17 +375,18 @@ extension ParsedRuleExt on ParsedRule {
@freezed
abstract class Rule with _$Rule {
const factory Rule({required String id, required String value}) = _Rule;
const factory Rule({required int id, required String value, String? order}) =
_Rule;
factory Rule.value(String value) {
return Rule(value: value, id: utils.uuidV4);
return Rule(value: value, id: snowflake.id);
}
factory Rule.fromJson(Map<String, Object?> json) => _$RuleFromJson(json);
}
extension RulesExt on List<Rule> {
List<Rule> updateWith(Rule rule) {
List<Rule> copyAndPut(Rule rule) {
var newList = List<Rule>.from(this);
final index = newList.indexWhere((item) => item.id == rule.id);
if (index != -1) {

View File

@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
@@ -215,15 +217,16 @@ extension TrackerInfosStateExt on TrackerInfosState {
const defaultDavFileName = 'backup.zip';
@freezed
abstract class DAV with _$DAV {
const factory DAV({
abstract class DAVProps with _$DAVProps {
const factory DAVProps({
required String uri,
required String user,
required String password,
@Default(defaultDavFileName) String fileName,
}) = _DAV;
}) = _DAVProps;
factory DAV.fromJson(Map<String, Object?> json) => _$DAVFromJson(json);
factory DAVProps.fromJson(Map<String, Object?> json) =>
_$DAVPropsFromJson(json);
}
@freezed
@@ -471,19 +474,6 @@ class PopupMenuItemData {
final List<PopupMenuItemData> subItems;
}
@freezed
abstract class AndroidState with _$AndroidState {
const factory AndroidState({
required String currentProfileName,
required String stopText,
required bool onlyStatisticsProxy,
required bool crashlytics,
}) = _AndroidState;
factory AndroidState.fromJson(Map<String, Object?> json) =>
_$AndroidStateFromJson(json);
}
class CloseWindowIntent extends Intent {
const CloseWindowIntent();
}
@@ -512,20 +502,24 @@ extension ResultExt on Result {
@freezed
abstract class Script with _$Script {
const factory Script({
required String id,
required int id,
required String label,
required String content,
required DateTime lastUpdateTime,
}) = _Script;
factory Script.create({required String label, required String content}) {
return Script(id: utils.uuidV4, label: label, content: content);
}
factory Script.fromJson(Map<String, Object?> json) => _$ScriptFromJson(json);
factory Script.create({required String label}) {
return Script(
id: snowflake.id,
label: label,
lastUpdateTime: DateTime.now(),
);
}
}
extension ScriptsExt on List<Script> {
Script? get(String? id) {
Script? get(int? id) {
if (id == null) {
return null;
}
@@ -537,6 +531,38 @@ extension ScriptsExt on List<Script> {
}
}
extension ScriptExt on Script {
String get fileName => '$id.js';
Future<String> get path async => await appPath.getScriptPath(id.toString());
Future<String?> get content async {
final file = File(await path);
if (await file.exists()) {
return file.readAsString();
}
return null;
}
Future<Script> save(String content) async {
final file = File(await path);
if (!await file.exists()) {
await file.create(recursive: true);
}
await file.writeAsString(content);
return copyWith(lastUpdateTime: DateTime.now());
}
Future<Script> saveWithPath(String copyPath) async {
final file = File(await path);
if (!await file.exists()) {
await file.create(recursive: true);
}
await File(copyPath).copy(copyPath);
return copyWith(lastUpdateTime: DateTime.now());
}
}
@freezed
abstract class DelayState with _$DelayState {
const factory DelayState({required int delay, required bool group}) =
@@ -562,3 +588,11 @@ extension DelayStateExt on DelayState {
return 0;
}
}
@freezed
abstract class UpdatingMessage with _$UpdatingMessage {
const factory UpdatingMessage({
required String label,
required String message,
}) = _UpdatingMessage;
}

View File

@@ -31,9 +31,9 @@ const defaultBypassDomain = [
const defaultAppSettingProps = AppSettingProps();
const defaultVpnProps = VpnProps();
const defaultNetworkProps = NetworkProps();
const defaultProxiesStyle = ProxiesStyle();
const defaultProxiesStyleProps = ProxiesStyleProps();
const defaultWindowProps = WindowProps();
const defaultAccessControl = AccessControl();
const defaultAccessControlProps = AccessControlProps();
final defaultThemeProps = ThemeProps(primaryColor: defaultPrimaryColor);
const List<DashboardWidget> defaultDashboardWidgets = [
@@ -82,7 +82,7 @@ abstract class AppSettingProps with _$AppSettingProps {
@Default(true) bool minimizeOnExit,
@Default(false) bool hidden,
@Default(false) bool developerMode,
@Default(RecoveryStrategy.compatible) RecoveryStrategy recoveryStrategy,
@Default(RestoreStrategy.compatible) RestoreStrategy restoreStrategy,
@Default(true) bool showTrayTitle,
}) = _AppSettingProps;
@@ -97,8 +97,8 @@ abstract class AppSettingProps with _$AppSettingProps {
}
@freezed
abstract class AccessControl with _$AccessControl {
const factory AccessControl({
abstract class AccessControlProps with _$AccessControlProps {
const factory AccessControlProps({
@Default(false) bool enable,
@Default(AccessControlMode.rejectSelected) AccessControlMode mode,
@Default([]) List<String> acceptList,
@@ -106,19 +106,19 @@ abstract class AccessControl with _$AccessControl {
@Default(AccessSortType.none) AccessSortType sort,
@Default(true) bool isFilterSystemApp,
@Default(true) bool isFilterNonInternetApp,
}) = _AccessControl;
}) = _AccessControlProps;
factory AccessControl.fromJson(Map<String, Object?> json) =>
_$AccessControlFromJson(json);
factory AccessControlProps.fromJson(Map<String, Object?> json) =>
_$AccessControlPropsFromJson(json);
}
extension AccessControlExt on AccessControl {
extension AccessControlPropsExt on AccessControlProps {
List<String> get currentList => switch (mode) {
AccessControlMode.acceptSelected => acceptList,
AccessControlMode.rejectSelected => rejectList,
};
AccessControl copyWithNewList(List<String> value) => switch (mode) {
AccessControlProps copyWithNewList(List<String> value) => switch (mode) {
AccessControlMode.acceptSelected => copyWith(acceptList: value),
AccessControlMode.rejectSelected => copyWith(rejectList: value),
};
@@ -151,7 +151,7 @@ abstract class VpnProps with _$VpnProps {
@Default(false) bool ipv6,
@Default(true) bool allowBypass,
@Default(false) bool dnsHijacking,
@Default(defaultAccessControl) AccessControl accessControl,
@Default(defaultAccessControlProps) AccessControlProps accessControlProps,
}) = _VpnProps;
factory VpnProps.fromJson(Map<String, Object?>? json) =>
@@ -173,17 +173,18 @@ abstract class NetworkProps with _$NetworkProps {
}
@freezed
abstract class ProxiesStyle with _$ProxiesStyle {
const factory ProxiesStyle({
abstract class ProxiesStyleProps with _$ProxiesStyleProps {
const factory ProxiesStyleProps({
@Default(ProxiesType.tab) ProxiesType type,
@Default(ProxiesSortType.none) ProxiesSortType sortType,
@Default(ProxiesLayout.standard) ProxiesLayout layout,
@Default(ProxiesIconStyle.standard) ProxiesIconStyle iconStyle,
@Default(ProxyCardType.expand) ProxyCardType cardType,
}) = _ProxiesStyle;
}) = _ProxiesStyleProps;
factory ProxiesStyle.fromJson(Map<String, Object?>? json) =>
json == null ? defaultProxiesStyle : _$ProxiesStyleFromJson(json);
factory ProxiesStyleProps.fromJson(Map<String, Object?>? json) => json == null
? defaultProxiesStyleProps
: _$ProxiesStylePropsFromJson(json);
}
@freezed
@@ -223,63 +224,30 @@ abstract class ThemeProps with _$ThemeProps {
}
}
@freezed
abstract class ScriptProps with _$ScriptProps {
const factory ScriptProps({
String? currentId,
@Default([]) List<Script> scripts,
}) = _ScriptProps;
factory ScriptProps.fromJson(Map<String, Object?> json) =>
_$ScriptPropsFromJson(json);
}
@freezed
abstract class Config with _$Config {
const factory Config({
int? currentProfileId,
@Default(false) bool overrideDns,
@Default([]) List<HotKeyAction> hotKeyActions,
@JsonKey(fromJson: AppSettingProps.safeFromJson)
@Default(defaultAppSettingProps)
AppSettingProps appSetting,
@Default([]) List<Profile> profiles,
@Default([]) List<HotKeyAction> hotKeyActions,
String? currentProfileId,
@Default(false) bool overrideDns,
DAV? dav,
AppSettingProps appSettingProps,
DAVProps? davProps,
@Default(defaultNetworkProps) NetworkProps networkProps,
@Default(defaultVpnProps) VpnProps vpnProps,
@JsonKey(fromJson: ThemeProps.safeFromJson) required ThemeProps themeProps,
@Default(defaultProxiesStyle) ProxiesStyle proxiesStyle,
@Default(defaultProxiesStyleProps) ProxiesStyleProps proxiesStyleProps,
@Default(defaultWindowProps) WindowProps windowProps,
@Default(defaultClashConfig) ClashConfig patchClashConfig,
@Default([]) List<Script> scripts,
@Default([]) List<Rule> rules,
}) = _Config;
factory Config.fromJson(Map<String, Object?> json) => _$ConfigFromJson(json);
factory Config.compatibleFromJson(Map<String, Object?> json) {
try {
final accessControlMap = json['accessControl'];
final isAccessControl = json['isAccessControl'];
if (accessControlMap != null) {
(accessControlMap as Map)['enable'] = isAccessControl;
if (json['vpnProps'] != null) {
(json['vpnProps'] as Map)['accessControl'] = accessControlMap;
}
}
if (json['scripts'] == null) {
final scriptPropsJson = json['scriptProps'] as Map<String, Object?>?;
if (scriptPropsJson != null) {
json['scripts'] = scriptPropsJson['scripts'];
}
}
} catch (_) {}
return Config.fromJson(json);
}
}
extension ConfigExt on Config {
Profile? get currentProfile {
return profiles.getProfile(currentProfileId);
factory Config.realFromJson(Map<String, Object?>? json) {
if (json == null) {
return Config(themeProps: defaultThemeProps);
}
return _$ConfigFromJson(json);
}
}

View File

@@ -44,7 +44,7 @@ abstract class VpnOptions with _$VpnOptions {
required int port,
required bool ipv6,
required bool dnsHijacking,
required AccessControl accessControl,
required AccessControlProps accessControlProps,
required bool allowBypass,
required bool systemProxy,
required List<String> bypassDomain,
@@ -154,7 +154,6 @@ abstract class ExternalProvider with _$ExternalProvider {
required int count,
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
SubscriptionInfo? subscriptionInfo,
@Default(false) bool isUpdating,
@JsonKey(name: 'vehicle-type') required String vehicleType,
@JsonKey(name: 'update-at') required DateTime updateAt,
}) = _ExternalProvider;
@@ -163,6 +162,10 @@ abstract class ExternalProvider with _$ExternalProvider {
_$ExternalProviderFromJson(json);
}
extension ExternalProviderExt on ExternalProvider {
String get updatingKey => 'provider_$name';
}
@freezed
abstract class Action with _$Action {
const factory Action({
@@ -174,6 +177,17 @@ abstract class Action with _$Action {
factory Action.fromJson(Map<String, Object?> json) => _$ActionFromJson(json);
}
@freezed
abstract class ProxiesData with _$ProxiesData {
const factory ProxiesData({
required Map<String, dynamic> proxies,
required List<String> all,
}) = _ProxiesData;
factory ProxiesData.fromJson(Map<String, Object?> json) =>
_$ProxiesDataFromJson(json);
}
@freezed
abstract class ActionResult with _$ActionResult {
const factory ActionResult({

View File

@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$AppState {
bool get isInit; bool get backBlock; PageLabel get pageLabel; List<Package> get packages; int get sortNum; Size get viewSize; double get sideWidth; DelayMap get delayMap; List<Group> get groups; int get checkIpNum; Brightness get brightness; int? get runTime; List<ExternalProvider> get providers; String? get localIp; FixedList<TrackerInfo> get requests; int get version; FixedList<Log> get logs; FixedList<Traffic> get traffics; Traffic get totalTraffic; bool get realTunEnable; bool get loading; SystemUiOverlayStyle get systemUiOverlayStyle; ProfileOverrideModel? get profileOverrideModel; Map<QueryTag, String> get queryMap; Map<String, String> get selectedItemMap; Map<String, Set<String>> get selectedItemsMap; CoreStatus get coreStatus;
bool get isInit; bool get backBlock; PageLabel get pageLabel; List<Package> get packages; int get sortNum; Size get viewSize; double get sideWidth; DelayMap get delayMap; List<Group> get groups; int get checkIpNum; Brightness get brightness; int? get runTime; List<ExternalProvider> get providers; String? get localIp; FixedList<TrackerInfo> get requests; int get version; FixedList<Log> get logs; FixedList<Traffic> get traffics; Traffic get totalTraffic; bool get realTunEnable; bool get loading; SystemUiOverlayStyle get systemUiOverlayStyle; CoreStatus get coreStatus;
/// Create a copy of AppState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -25,16 +25,16 @@ $AppStateCopyWith<AppState> get copyWith => _$AppStateCopyWithImpl<AppState>(thi
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppState&&(identical(other.isInit, isInit) || other.isInit == isInit)&&(identical(other.backBlock, backBlock) || other.backBlock == backBlock)&&(identical(other.pageLabel, pageLabel) || other.pageLabel == pageLabel)&&const DeepCollectionEquality().equals(other.packages, packages)&&(identical(other.sortNum, sortNum) || other.sortNum == sortNum)&&(identical(other.viewSize, viewSize) || other.viewSize == viewSize)&&(identical(other.sideWidth, sideWidth) || other.sideWidth == sideWidth)&&const DeepCollectionEquality().equals(other.delayMap, delayMap)&&const DeepCollectionEquality().equals(other.groups, groups)&&(identical(other.checkIpNum, checkIpNum) || other.checkIpNum == checkIpNum)&&(identical(other.brightness, brightness) || other.brightness == brightness)&&(identical(other.runTime, runTime) || other.runTime == runTime)&&const DeepCollectionEquality().equals(other.providers, providers)&&(identical(other.localIp, localIp) || other.localIp == localIp)&&(identical(other.requests, requests) || other.requests == requests)&&(identical(other.version, version) || other.version == version)&&(identical(other.logs, logs) || other.logs == logs)&&(identical(other.traffics, traffics) || other.traffics == traffics)&&(identical(other.totalTraffic, totalTraffic) || other.totalTraffic == totalTraffic)&&(identical(other.realTunEnable, realTunEnable) || other.realTunEnable == realTunEnable)&&(identical(other.loading, loading) || other.loading == loading)&&(identical(other.systemUiOverlayStyle, systemUiOverlayStyle) || other.systemUiOverlayStyle == systemUiOverlayStyle)&&(identical(other.profileOverrideModel, profileOverrideModel) || other.profileOverrideModel == profileOverrideModel)&&const DeepCollectionEquality().equals(other.queryMap, queryMap)&&const DeepCollectionEquality().equals(other.selectedItemMap, selectedItemMap)&&const DeepCollectionEquality().equals(other.selectedItemsMap, selectedItemsMap)&&(identical(other.coreStatus, coreStatus) || other.coreStatus == coreStatus));
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppState&&(identical(other.isInit, isInit) || other.isInit == isInit)&&(identical(other.backBlock, backBlock) || other.backBlock == backBlock)&&(identical(other.pageLabel, pageLabel) || other.pageLabel == pageLabel)&&const DeepCollectionEquality().equals(other.packages, packages)&&(identical(other.sortNum, sortNum) || other.sortNum == sortNum)&&(identical(other.viewSize, viewSize) || other.viewSize == viewSize)&&(identical(other.sideWidth, sideWidth) || other.sideWidth == sideWidth)&&const DeepCollectionEquality().equals(other.delayMap, delayMap)&&const DeepCollectionEquality().equals(other.groups, groups)&&(identical(other.checkIpNum, checkIpNum) || other.checkIpNum == checkIpNum)&&(identical(other.brightness, brightness) || other.brightness == brightness)&&(identical(other.runTime, runTime) || other.runTime == runTime)&&const DeepCollectionEquality().equals(other.providers, providers)&&(identical(other.localIp, localIp) || other.localIp == localIp)&&(identical(other.requests, requests) || other.requests == requests)&&(identical(other.version, version) || other.version == version)&&(identical(other.logs, logs) || other.logs == logs)&&(identical(other.traffics, traffics) || other.traffics == traffics)&&(identical(other.totalTraffic, totalTraffic) || other.totalTraffic == totalTraffic)&&(identical(other.realTunEnable, realTunEnable) || other.realTunEnable == realTunEnable)&&(identical(other.loading, loading) || other.loading == loading)&&(identical(other.systemUiOverlayStyle, systemUiOverlayStyle) || other.systemUiOverlayStyle == systemUiOverlayStyle)&&(identical(other.coreStatus, coreStatus) || other.coreStatus == coreStatus));
}
@override
int get hashCode => Object.hashAll([runtimeType,isInit,backBlock,pageLabel,const DeepCollectionEquality().hash(packages),sortNum,viewSize,sideWidth,const DeepCollectionEquality().hash(delayMap),const DeepCollectionEquality().hash(groups),checkIpNum,brightness,runTime,const DeepCollectionEquality().hash(providers),localIp,requests,version,logs,traffics,totalTraffic,realTunEnable,loading,systemUiOverlayStyle,profileOverrideModel,const DeepCollectionEquality().hash(queryMap),const DeepCollectionEquality().hash(selectedItemMap),const DeepCollectionEquality().hash(selectedItemsMap),coreStatus]);
int get hashCode => Object.hashAll([runtimeType,isInit,backBlock,pageLabel,const DeepCollectionEquality().hash(packages),sortNum,viewSize,sideWidth,const DeepCollectionEquality().hash(delayMap),const DeepCollectionEquality().hash(groups),checkIpNum,brightness,runTime,const DeepCollectionEquality().hash(providers),localIp,requests,version,logs,traffics,totalTraffic,realTunEnable,loading,systemUiOverlayStyle,coreStatus]);
@override
String toString() {
return 'AppState(isInit: $isInit, backBlock: $backBlock, pageLabel: $pageLabel, packages: $packages, sortNum: $sortNum, viewSize: $viewSize, sideWidth: $sideWidth, delayMap: $delayMap, groups: $groups, checkIpNum: $checkIpNum, brightness: $brightness, runTime: $runTime, providers: $providers, localIp: $localIp, requests: $requests, version: $version, logs: $logs, traffics: $traffics, totalTraffic: $totalTraffic, realTunEnable: $realTunEnable, loading: $loading, systemUiOverlayStyle: $systemUiOverlayStyle, profileOverrideModel: $profileOverrideModel, queryMap: $queryMap, selectedItemMap: $selectedItemMap, selectedItemsMap: $selectedItemsMap, coreStatus: $coreStatus)';
return 'AppState(isInit: $isInit, backBlock: $backBlock, pageLabel: $pageLabel, packages: $packages, sortNum: $sortNum, viewSize: $viewSize, sideWidth: $sideWidth, delayMap: $delayMap, groups: $groups, checkIpNum: $checkIpNum, brightness: $brightness, runTime: $runTime, providers: $providers, localIp: $localIp, requests: $requests, version: $version, logs: $logs, traffics: $traffics, totalTraffic: $totalTraffic, realTunEnable: $realTunEnable, loading: $loading, systemUiOverlayStyle: $systemUiOverlayStyle, coreStatus: $coreStatus)';
}
@@ -45,11 +45,11 @@ abstract mixin class $AppStateCopyWith<$Res> {
factory $AppStateCopyWith(AppState value, $Res Function(AppState) _then) = _$AppStateCopyWithImpl;
@useResult
$Res call({
bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, bool realTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, ProfileOverrideModel? profileOverrideModel, Map<QueryTag, String> queryMap, Map<String, String> selectedItemMap, Map<String, Set<String>> selectedItemsMap, CoreStatus coreStatus
bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, bool realTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus
});
$TrafficCopyWith<$Res> get totalTraffic;$ProfileOverrideModelCopyWith<$Res>? get profileOverrideModel;
$TrafficCopyWith<$Res> get totalTraffic;
}
/// @nodoc
@@ -62,7 +62,7 @@ class _$AppStateCopyWithImpl<$Res>
/// Create a copy of AppState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? isInit = null,Object? backBlock = null,Object? pageLabel = null,Object? packages = null,Object? sortNum = null,Object? viewSize = null,Object? sideWidth = null,Object? delayMap = null,Object? groups = null,Object? checkIpNum = null,Object? brightness = null,Object? runTime = freezed,Object? providers = null,Object? localIp = freezed,Object? requests = null,Object? version = null,Object? logs = null,Object? traffics = null,Object? totalTraffic = null,Object? realTunEnable = null,Object? loading = null,Object? systemUiOverlayStyle = null,Object? profileOverrideModel = freezed,Object? queryMap = null,Object? selectedItemMap = null,Object? selectedItemsMap = null,Object? coreStatus = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? isInit = null,Object? backBlock = null,Object? pageLabel = null,Object? packages = null,Object? sortNum = null,Object? viewSize = null,Object? sideWidth = null,Object? delayMap = null,Object? groups = null,Object? checkIpNum = null,Object? brightness = null,Object? runTime = freezed,Object? providers = null,Object? localIp = freezed,Object? requests = null,Object? version = null,Object? logs = null,Object? traffics = null,Object? totalTraffic = null,Object? realTunEnable = null,Object? loading = null,Object? systemUiOverlayStyle = null,Object? coreStatus = null,}) {
return _then(_self.copyWith(
isInit: null == isInit ? _self.isInit : isInit // ignore: cast_nullable_to_non_nullable
as bool,backBlock: null == backBlock ? _self.backBlock : backBlock // ignore: cast_nullable_to_non_nullable
@@ -86,11 +86,7 @@ as FixedList<Traffic>,totalTraffic: null == totalTraffic ? _self.totalTraffic :
as Traffic,realTunEnable: null == realTunEnable ? _self.realTunEnable : realTunEnable // ignore: cast_nullable_to_non_nullable
as bool,loading: null == loading ? _self.loading : loading // ignore: cast_nullable_to_non_nullable
as bool,systemUiOverlayStyle: null == systemUiOverlayStyle ? _self.systemUiOverlayStyle : systemUiOverlayStyle // ignore: cast_nullable_to_non_nullable
as SystemUiOverlayStyle,profileOverrideModel: freezed == profileOverrideModel ? _self.profileOverrideModel : profileOverrideModel // ignore: cast_nullable_to_non_nullable
as ProfileOverrideModel?,queryMap: null == queryMap ? _self.queryMap : queryMap // ignore: cast_nullable_to_non_nullable
as Map<QueryTag, String>,selectedItemMap: null == selectedItemMap ? _self.selectedItemMap : selectedItemMap // ignore: cast_nullable_to_non_nullable
as Map<String, String>,selectedItemsMap: null == selectedItemsMap ? _self.selectedItemsMap : selectedItemsMap // ignore: cast_nullable_to_non_nullable
as Map<String, Set<String>>,coreStatus: null == coreStatus ? _self.coreStatus : coreStatus // ignore: cast_nullable_to_non_nullable
as SystemUiOverlayStyle,coreStatus: null == coreStatus ? _self.coreStatus : coreStatus // ignore: cast_nullable_to_non_nullable
as CoreStatus,
));
}
@@ -103,18 +99,6 @@ $TrafficCopyWith<$Res> get totalTraffic {
return $TrafficCopyWith<$Res>(_self.totalTraffic, (value) {
return _then(_self.copyWith(totalTraffic: value));
});
}/// Create a copy of AppState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$ProfileOverrideModelCopyWith<$Res>? get profileOverrideModel {
if (_self.profileOverrideModel == null) {
return null;
}
return $ProfileOverrideModelCopyWith<$Res>(_self.profileOverrideModel!, (value) {
return _then(_self.copyWith(profileOverrideModel: value));
});
}
}
@@ -197,10 +181,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, bool realTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, ProfileOverrideModel? profileOverrideModel, Map<QueryTag, String> queryMap, Map<String, String> selectedItemMap, Map<String, Set<String>> selectedItemsMap, CoreStatus coreStatus)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, bool realTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _AppState() when $default != null:
return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_that.sortNum,_that.viewSize,_that.sideWidth,_that.delayMap,_that.groups,_that.checkIpNum,_that.brightness,_that.runTime,_that.providers,_that.localIp,_that.requests,_that.version,_that.logs,_that.traffics,_that.totalTraffic,_that.realTunEnable,_that.loading,_that.systemUiOverlayStyle,_that.profileOverrideModel,_that.queryMap,_that.selectedItemMap,_that.selectedItemsMap,_that.coreStatus);case _:
return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_that.sortNum,_that.viewSize,_that.sideWidth,_that.delayMap,_that.groups,_that.checkIpNum,_that.brightness,_that.runTime,_that.providers,_that.localIp,_that.requests,_that.version,_that.logs,_that.traffics,_that.totalTraffic,_that.realTunEnable,_that.loading,_that.systemUiOverlayStyle,_that.coreStatus);case _:
return orElse();
}
@@ -218,10 +202,10 @@ return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_tha
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, bool realTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, ProfileOverrideModel? profileOverrideModel, Map<QueryTag, String> queryMap, Map<String, String> selectedItemMap, Map<String, Set<String>> selectedItemsMap, CoreStatus coreStatus) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, bool realTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus) $default,) {final _that = this;
switch (_that) {
case _AppState():
return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_that.sortNum,_that.viewSize,_that.sideWidth,_that.delayMap,_that.groups,_that.checkIpNum,_that.brightness,_that.runTime,_that.providers,_that.localIp,_that.requests,_that.version,_that.logs,_that.traffics,_that.totalTraffic,_that.realTunEnable,_that.loading,_that.systemUiOverlayStyle,_that.profileOverrideModel,_that.queryMap,_that.selectedItemMap,_that.selectedItemsMap,_that.coreStatus);case _:
return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_that.sortNum,_that.viewSize,_that.sideWidth,_that.delayMap,_that.groups,_that.checkIpNum,_that.brightness,_that.runTime,_that.providers,_that.localIp,_that.requests,_that.version,_that.logs,_that.traffics,_that.totalTraffic,_that.realTunEnable,_that.loading,_that.systemUiOverlayStyle,_that.coreStatus);case _:
throw StateError('Unexpected subclass');
}
@@ -238,10 +222,10 @@ return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_tha
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, bool realTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, ProfileOverrideModel? profileOverrideModel, Map<QueryTag, String> queryMap, Map<String, String> selectedItemMap, Map<String, Set<String>> selectedItemsMap, CoreStatus coreStatus)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, bool realTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus)? $default,) {final _that = this;
switch (_that) {
case _AppState() when $default != null:
return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_that.sortNum,_that.viewSize,_that.sideWidth,_that.delayMap,_that.groups,_that.checkIpNum,_that.brightness,_that.runTime,_that.providers,_that.localIp,_that.requests,_that.version,_that.logs,_that.traffics,_that.totalTraffic,_that.realTunEnable,_that.loading,_that.systemUiOverlayStyle,_that.profileOverrideModel,_that.queryMap,_that.selectedItemMap,_that.selectedItemsMap,_that.coreStatus);case _:
return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_that.sortNum,_that.viewSize,_that.sideWidth,_that.delayMap,_that.groups,_that.checkIpNum,_that.brightness,_that.runTime,_that.providers,_that.localIp,_that.requests,_that.version,_that.logs,_that.traffics,_that.totalTraffic,_that.realTunEnable,_that.loading,_that.systemUiOverlayStyle,_that.coreStatus);case _:
return null;
}
@@ -253,7 +237,7 @@ return $default(_that.isInit,_that.backBlock,_that.pageLabel,_that.packages,_tha
class _AppState implements AppState {
const _AppState({this.isInit = false, this.backBlock = false, this.pageLabel = PageLabel.dashboard, final List<Package> packages = const [], this.sortNum = 0, required this.viewSize, this.sideWidth = 0, final DelayMap delayMap = const {}, final List<Group> groups = const [], this.checkIpNum = 0, required this.brightness, this.runTime, final List<ExternalProvider> providers = const [], this.localIp, required this.requests, required this.version, required this.logs, required this.traffics, required this.totalTraffic, this.realTunEnable = false, this.loading = false, required this.systemUiOverlayStyle, this.profileOverrideModel, final Map<QueryTag, String> queryMap = const {}, final Map<String, String> selectedItemMap = const {}, final Map<String, Set<String>> selectedItemsMap = const {}, this.coreStatus = CoreStatus.connecting}): _packages = packages,_delayMap = delayMap,_groups = groups,_providers = providers,_queryMap = queryMap,_selectedItemMap = selectedItemMap,_selectedItemsMap = selectedItemsMap;
const _AppState({this.isInit = false, this.backBlock = false, this.pageLabel = PageLabel.dashboard, final List<Package> packages = const [], this.sortNum = 0, required this.viewSize, this.sideWidth = 0, final DelayMap delayMap = const {}, final List<Group> groups = const [], this.checkIpNum = 0, required this.brightness, this.runTime, final List<ExternalProvider> providers = const [], this.localIp, required this.requests, required this.version, required this.logs, required this.traffics, required this.totalTraffic, this.realTunEnable = false, this.loading = false, required this.systemUiOverlayStyle, this.coreStatus = CoreStatus.connecting}): _packages = packages,_delayMap = delayMap,_groups = groups,_providers = providers;
@override@JsonKey() final bool isInit;
@@ -302,28 +286,6 @@ class _AppState implements AppState {
@override@JsonKey() final bool realTunEnable;
@override@JsonKey() final bool loading;
@override final SystemUiOverlayStyle systemUiOverlayStyle;
@override final ProfileOverrideModel? profileOverrideModel;
final Map<QueryTag, String> _queryMap;
@override@JsonKey() Map<QueryTag, String> get queryMap {
if (_queryMap is EqualUnmodifiableMapView) return _queryMap;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_queryMap);
}
final Map<String, String> _selectedItemMap;
@override@JsonKey() Map<String, String> get selectedItemMap {
if (_selectedItemMap is EqualUnmodifiableMapView) return _selectedItemMap;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_selectedItemMap);
}
final Map<String, Set<String>> _selectedItemsMap;
@override@JsonKey() Map<String, Set<String>> get selectedItemsMap {
if (_selectedItemsMap is EqualUnmodifiableMapView) return _selectedItemsMap;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_selectedItemsMap);
}
@override@JsonKey() final CoreStatus coreStatus;
/// Create a copy of AppState
@@ -336,16 +298,16 @@ _$AppStateCopyWith<_AppState> get copyWith => __$AppStateCopyWithImpl<_AppState>
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppState&&(identical(other.isInit, isInit) || other.isInit == isInit)&&(identical(other.backBlock, backBlock) || other.backBlock == backBlock)&&(identical(other.pageLabel, pageLabel) || other.pageLabel == pageLabel)&&const DeepCollectionEquality().equals(other._packages, _packages)&&(identical(other.sortNum, sortNum) || other.sortNum == sortNum)&&(identical(other.viewSize, viewSize) || other.viewSize == viewSize)&&(identical(other.sideWidth, sideWidth) || other.sideWidth == sideWidth)&&const DeepCollectionEquality().equals(other._delayMap, _delayMap)&&const DeepCollectionEquality().equals(other._groups, _groups)&&(identical(other.checkIpNum, checkIpNum) || other.checkIpNum == checkIpNum)&&(identical(other.brightness, brightness) || other.brightness == brightness)&&(identical(other.runTime, runTime) || other.runTime == runTime)&&const DeepCollectionEquality().equals(other._providers, _providers)&&(identical(other.localIp, localIp) || other.localIp == localIp)&&(identical(other.requests, requests) || other.requests == requests)&&(identical(other.version, version) || other.version == version)&&(identical(other.logs, logs) || other.logs == logs)&&(identical(other.traffics, traffics) || other.traffics == traffics)&&(identical(other.totalTraffic, totalTraffic) || other.totalTraffic == totalTraffic)&&(identical(other.realTunEnable, realTunEnable) || other.realTunEnable == realTunEnable)&&(identical(other.loading, loading) || other.loading == loading)&&(identical(other.systemUiOverlayStyle, systemUiOverlayStyle) || other.systemUiOverlayStyle == systemUiOverlayStyle)&&(identical(other.profileOverrideModel, profileOverrideModel) || other.profileOverrideModel == profileOverrideModel)&&const DeepCollectionEquality().equals(other._queryMap, _queryMap)&&const DeepCollectionEquality().equals(other._selectedItemMap, _selectedItemMap)&&const DeepCollectionEquality().equals(other._selectedItemsMap, _selectedItemsMap)&&(identical(other.coreStatus, coreStatus) || other.coreStatus == coreStatus));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppState&&(identical(other.isInit, isInit) || other.isInit == isInit)&&(identical(other.backBlock, backBlock) || other.backBlock == backBlock)&&(identical(other.pageLabel, pageLabel) || other.pageLabel == pageLabel)&&const DeepCollectionEquality().equals(other._packages, _packages)&&(identical(other.sortNum, sortNum) || other.sortNum == sortNum)&&(identical(other.viewSize, viewSize) || other.viewSize == viewSize)&&(identical(other.sideWidth, sideWidth) || other.sideWidth == sideWidth)&&const DeepCollectionEquality().equals(other._delayMap, _delayMap)&&const DeepCollectionEquality().equals(other._groups, _groups)&&(identical(other.checkIpNum, checkIpNum) || other.checkIpNum == checkIpNum)&&(identical(other.brightness, brightness) || other.brightness == brightness)&&(identical(other.runTime, runTime) || other.runTime == runTime)&&const DeepCollectionEquality().equals(other._providers, _providers)&&(identical(other.localIp, localIp) || other.localIp == localIp)&&(identical(other.requests, requests) || other.requests == requests)&&(identical(other.version, version) || other.version == version)&&(identical(other.logs, logs) || other.logs == logs)&&(identical(other.traffics, traffics) || other.traffics == traffics)&&(identical(other.totalTraffic, totalTraffic) || other.totalTraffic == totalTraffic)&&(identical(other.realTunEnable, realTunEnable) || other.realTunEnable == realTunEnable)&&(identical(other.loading, loading) || other.loading == loading)&&(identical(other.systemUiOverlayStyle, systemUiOverlayStyle) || other.systemUiOverlayStyle == systemUiOverlayStyle)&&(identical(other.coreStatus, coreStatus) || other.coreStatus == coreStatus));
}
@override
int get hashCode => Object.hashAll([runtimeType,isInit,backBlock,pageLabel,const DeepCollectionEquality().hash(_packages),sortNum,viewSize,sideWidth,const DeepCollectionEquality().hash(_delayMap),const DeepCollectionEquality().hash(_groups),checkIpNum,brightness,runTime,const DeepCollectionEquality().hash(_providers),localIp,requests,version,logs,traffics,totalTraffic,realTunEnable,loading,systemUiOverlayStyle,profileOverrideModel,const DeepCollectionEquality().hash(_queryMap),const DeepCollectionEquality().hash(_selectedItemMap),const DeepCollectionEquality().hash(_selectedItemsMap),coreStatus]);
int get hashCode => Object.hashAll([runtimeType,isInit,backBlock,pageLabel,const DeepCollectionEquality().hash(_packages),sortNum,viewSize,sideWidth,const DeepCollectionEquality().hash(_delayMap),const DeepCollectionEquality().hash(_groups),checkIpNum,brightness,runTime,const DeepCollectionEquality().hash(_providers),localIp,requests,version,logs,traffics,totalTraffic,realTunEnable,loading,systemUiOverlayStyle,coreStatus]);
@override
String toString() {
return 'AppState(isInit: $isInit, backBlock: $backBlock, pageLabel: $pageLabel, packages: $packages, sortNum: $sortNum, viewSize: $viewSize, sideWidth: $sideWidth, delayMap: $delayMap, groups: $groups, checkIpNum: $checkIpNum, brightness: $brightness, runTime: $runTime, providers: $providers, localIp: $localIp, requests: $requests, version: $version, logs: $logs, traffics: $traffics, totalTraffic: $totalTraffic, realTunEnable: $realTunEnable, loading: $loading, systemUiOverlayStyle: $systemUiOverlayStyle, profileOverrideModel: $profileOverrideModel, queryMap: $queryMap, selectedItemMap: $selectedItemMap, selectedItemsMap: $selectedItemsMap, coreStatus: $coreStatus)';
return 'AppState(isInit: $isInit, backBlock: $backBlock, pageLabel: $pageLabel, packages: $packages, sortNum: $sortNum, viewSize: $viewSize, sideWidth: $sideWidth, delayMap: $delayMap, groups: $groups, checkIpNum: $checkIpNum, brightness: $brightness, runTime: $runTime, providers: $providers, localIp: $localIp, requests: $requests, version: $version, logs: $logs, traffics: $traffics, totalTraffic: $totalTraffic, realTunEnable: $realTunEnable, loading: $loading, systemUiOverlayStyle: $systemUiOverlayStyle, coreStatus: $coreStatus)';
}
@@ -356,11 +318,11 @@ abstract mixin class _$AppStateCopyWith<$Res> implements $AppStateCopyWith<$Res>
factory _$AppStateCopyWith(_AppState value, $Res Function(_AppState) _then) = __$AppStateCopyWithImpl;
@override @useResult
$Res call({
bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, bool realTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, ProfileOverrideModel? profileOverrideModel, Map<QueryTag, String> queryMap, Map<String, String> selectedItemMap, Map<String, Set<String>> selectedItemsMap, CoreStatus coreStatus
bool isInit, bool backBlock, PageLabel pageLabel, List<Package> packages, int sortNum, Size viewSize, double sideWidth, DelayMap delayMap, List<Group> groups, int checkIpNum, Brightness brightness, int? runTime, List<ExternalProvider> providers, String? localIp, FixedList<TrackerInfo> requests, int version, FixedList<Log> logs, FixedList<Traffic> traffics, Traffic totalTraffic, bool realTunEnable, bool loading, SystemUiOverlayStyle systemUiOverlayStyle, CoreStatus coreStatus
});
@override $TrafficCopyWith<$Res> get totalTraffic;@override $ProfileOverrideModelCopyWith<$Res>? get profileOverrideModel;
@override $TrafficCopyWith<$Res> get totalTraffic;
}
/// @nodoc
@@ -373,7 +335,7 @@ class __$AppStateCopyWithImpl<$Res>
/// Create a copy of AppState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? isInit = null,Object? backBlock = null,Object? pageLabel = null,Object? packages = null,Object? sortNum = null,Object? viewSize = null,Object? sideWidth = null,Object? delayMap = null,Object? groups = null,Object? checkIpNum = null,Object? brightness = null,Object? runTime = freezed,Object? providers = null,Object? localIp = freezed,Object? requests = null,Object? version = null,Object? logs = null,Object? traffics = null,Object? totalTraffic = null,Object? realTunEnable = null,Object? loading = null,Object? systemUiOverlayStyle = null,Object? profileOverrideModel = freezed,Object? queryMap = null,Object? selectedItemMap = null,Object? selectedItemsMap = null,Object? coreStatus = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? isInit = null,Object? backBlock = null,Object? pageLabel = null,Object? packages = null,Object? sortNum = null,Object? viewSize = null,Object? sideWidth = null,Object? delayMap = null,Object? groups = null,Object? checkIpNum = null,Object? brightness = null,Object? runTime = freezed,Object? providers = null,Object? localIp = freezed,Object? requests = null,Object? version = null,Object? logs = null,Object? traffics = null,Object? totalTraffic = null,Object? realTunEnable = null,Object? loading = null,Object? systemUiOverlayStyle = null,Object? coreStatus = null,}) {
return _then(_AppState(
isInit: null == isInit ? _self.isInit : isInit // ignore: cast_nullable_to_non_nullable
as bool,backBlock: null == backBlock ? _self.backBlock : backBlock // ignore: cast_nullable_to_non_nullable
@@ -397,11 +359,7 @@ as FixedList<Traffic>,totalTraffic: null == totalTraffic ? _self.totalTraffic :
as Traffic,realTunEnable: null == realTunEnable ? _self.realTunEnable : realTunEnable // ignore: cast_nullable_to_non_nullable
as bool,loading: null == loading ? _self.loading : loading // ignore: cast_nullable_to_non_nullable
as bool,systemUiOverlayStyle: null == systemUiOverlayStyle ? _self.systemUiOverlayStyle : systemUiOverlayStyle // ignore: cast_nullable_to_non_nullable
as SystemUiOverlayStyle,profileOverrideModel: freezed == profileOverrideModel ? _self.profileOverrideModel : profileOverrideModel // ignore: cast_nullable_to_non_nullable
as ProfileOverrideModel?,queryMap: null == queryMap ? _self._queryMap : queryMap // ignore: cast_nullable_to_non_nullable
as Map<QueryTag, String>,selectedItemMap: null == selectedItemMap ? _self._selectedItemMap : selectedItemMap // ignore: cast_nullable_to_non_nullable
as Map<String, String>,selectedItemsMap: null == selectedItemsMap ? _self._selectedItemsMap : selectedItemsMap // ignore: cast_nullable_to_non_nullable
as Map<String, Set<String>>,coreStatus: null == coreStatus ? _self.coreStatus : coreStatus // ignore: cast_nullable_to_non_nullable
as SystemUiOverlayStyle,coreStatus: null == coreStatus ? _self.coreStatus : coreStatus // ignore: cast_nullable_to_non_nullable
as CoreStatus,
));
}
@@ -415,18 +373,6 @@ $TrafficCopyWith<$Res> get totalTraffic {
return $TrafficCopyWith<$Res>(_self.totalTraffic, (value) {
return _then(_self.copyWith(totalTraffic: value));
});
}/// Create a copy of AppState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$ProfileOverrideModelCopyWith<$Res>? get profileOverrideModel {
if (_self.profileOverrideModel == null) {
return null;
}
return $ProfileOverrideModelCopyWith<$Res>(_self.profileOverrideModel!, (value) {
return _then(_self.copyWith(profileOverrideModel: value));
});
}
}

View File

@@ -2698,7 +2698,7 @@ as bool,
/// @nodoc
mixin _$Rule {
String get id; String get value;
int get id; String get value; String? get order;
/// Create a copy of Rule
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -2711,16 +2711,16 @@ $RuleCopyWith<Rule> get copyWith => _$RuleCopyWithImpl<Rule>(this as Rule, _$ide
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is Rule&&(identical(other.id, id) || other.id == id)&&(identical(other.value, value) || other.value == value));
return identical(this, other) || (other.runtimeType == runtimeType&&other is Rule&&(identical(other.id, id) || other.id == id)&&(identical(other.value, value) || other.value == value)&&(identical(other.order, order) || other.order == order));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,value);
int get hashCode => Object.hash(runtimeType,id,value,order);
@override
String toString() {
return 'Rule(id: $id, value: $value)';
return 'Rule(id: $id, value: $value, order: $order)';
}
@@ -2731,7 +2731,7 @@ abstract mixin class $RuleCopyWith<$Res> {
factory $RuleCopyWith(Rule value, $Res Function(Rule) _then) = _$RuleCopyWithImpl;
@useResult
$Res call({
String id, String value
int id, String value, String? order
});
@@ -2748,11 +2748,12 @@ class _$RuleCopyWithImpl<$Res>
/// Create a copy of Rule
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? value = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? value = null,Object? order = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,value: null == value ? _self.value : value // ignore: cast_nullable_to_non_nullable
as String,
as int,value: null == value ? _self.value : value // ignore: cast_nullable_to_non_nullable
as String,order: freezed == order ? _self.order : order // ignore: cast_nullable_to_non_nullable
as String?,
));
}
@@ -2837,10 +2838,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String value)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int id, String value, String? order)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _Rule() when $default != null:
return $default(_that.id,_that.value);case _:
return $default(_that.id,_that.value,_that.order);case _:
return orElse();
}
@@ -2858,10 +2859,10 @@ return $default(_that.id,_that.value);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String value) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int id, String value, String? order) $default,) {final _that = this;
switch (_that) {
case _Rule():
return $default(_that.id,_that.value);case _:
return $default(_that.id,_that.value,_that.order);case _:
throw StateError('Unexpected subclass');
}
@@ -2878,10 +2879,10 @@ return $default(_that.id,_that.value);case _:
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String value)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int id, String value, String? order)? $default,) {final _that = this;
switch (_that) {
case _Rule() when $default != null:
return $default(_that.id,_that.value);case _:
return $default(_that.id,_that.value,_that.order);case _:
return null;
}
@@ -2893,11 +2894,12 @@ return $default(_that.id,_that.value);case _:
@JsonSerializable()
class _Rule implements Rule {
const _Rule({required this.id, required this.value});
const _Rule({required this.id, required this.value, this.order});
factory _Rule.fromJson(Map<String, dynamic> json) => _$RuleFromJson(json);
@override final String id;
@override final int id;
@override final String value;
@override final String? order;
/// Create a copy of Rule
/// with the given fields replaced by the non-null parameter values.
@@ -2912,16 +2914,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Rule&&(identical(other.id, id) || other.id == id)&&(identical(other.value, value) || other.value == value));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Rule&&(identical(other.id, id) || other.id == id)&&(identical(other.value, value) || other.value == value)&&(identical(other.order, order) || other.order == order));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,value);
int get hashCode => Object.hash(runtimeType,id,value,order);
@override
String toString() {
return 'Rule(id: $id, value: $value)';
return 'Rule(id: $id, value: $value, order: $order)';
}
@@ -2932,7 +2934,7 @@ abstract mixin class _$RuleCopyWith<$Res> implements $RuleCopyWith<$Res> {
factory _$RuleCopyWith(_Rule value, $Res Function(_Rule) _then) = __$RuleCopyWithImpl;
@override @useResult
$Res call({
String id, String value
int id, String value, String? order
});
@@ -2949,11 +2951,12 @@ class __$RuleCopyWithImpl<$Res>
/// Create a copy of Rule
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? value = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? value = null,Object? order = freezed,}) {
return _then(_Rule(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,value: null == value ? _self.value : value // ignore: cast_nullable_to_non_nullable
as String,
as int,value: null == value ? _self.value : value // ignore: cast_nullable_to_non_nullable
as String,order: freezed == order ? _self.order : order // ignore: cast_nullable_to_non_nullable
as String?,
));
}

View File

@@ -285,12 +285,16 @@ Map<String, dynamic> _$GeoXUrlToJson(_GeoXUrl instance) => <String, dynamic>{
'geosite': instance.geosite,
};
_Rule _$RuleFromJson(Map<String, dynamic> json) =>
_Rule(id: json['id'] as String, value: json['value'] as String);
_Rule _$RuleFromJson(Map<String, dynamic> json) => _Rule(
id: (json['id'] as num).toInt(),
value: json['value'] as String,
order: json['order'] as String?,
);
Map<String, dynamic> _$RuleToJson(_Rule instance) => <String, dynamic>{
'id': instance.id,
'value': instance.value,
'order': instance.order,
};
_SubRule _$SubRuleFromJson(Map<String, dynamic> json) =>

View File

@@ -2033,22 +2033,22 @@ as bool,
/// @nodoc
mixin _$DAV {
mixin _$DAVProps {
String get uri; String get user; String get password; String get fileName;
/// Create a copy of DAV
/// Create a copy of DAVProps
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$DAVCopyWith<DAV> get copyWith => _$DAVCopyWithImpl<DAV>(this as DAV, _$identity);
$DAVPropsCopyWith<DAVProps> get copyWith => _$DAVPropsCopyWithImpl<DAVProps>(this as DAVProps, _$identity);
/// Serializes this DAV to a JSON map.
/// Serializes this DAVProps to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is DAV&&(identical(other.uri, uri) || other.uri == uri)&&(identical(other.user, user) || other.user == user)&&(identical(other.password, password) || other.password == password)&&(identical(other.fileName, fileName) || other.fileName == fileName));
return identical(this, other) || (other.runtimeType == runtimeType&&other is DAVProps&&(identical(other.uri, uri) || other.uri == uri)&&(identical(other.user, user) || other.user == user)&&(identical(other.password, password) || other.password == password)&&(identical(other.fileName, fileName) || other.fileName == fileName));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -2057,15 +2057,15 @@ int get hashCode => Object.hash(runtimeType,uri,user,password,fileName);
@override
String toString() {
return 'DAV(uri: $uri, user: $user, password: $password, fileName: $fileName)';
return 'DAVProps(uri: $uri, user: $user, password: $password, fileName: $fileName)';
}
}
/// @nodoc
abstract mixin class $DAVCopyWith<$Res> {
factory $DAVCopyWith(DAV value, $Res Function(DAV) _then) = _$DAVCopyWithImpl;
abstract mixin class $DAVPropsCopyWith<$Res> {
factory $DAVPropsCopyWith(DAVProps value, $Res Function(DAVProps) _then) = _$DAVPropsCopyWithImpl;
@useResult
$Res call({
String uri, String user, String password, String fileName
@@ -2076,14 +2076,14 @@ $Res call({
}
/// @nodoc
class _$DAVCopyWithImpl<$Res>
implements $DAVCopyWith<$Res> {
_$DAVCopyWithImpl(this._self, this._then);
class _$DAVPropsCopyWithImpl<$Res>
implements $DAVPropsCopyWith<$Res> {
_$DAVPropsCopyWithImpl(this._self, this._then);
final DAV _self;
final $Res Function(DAV) _then;
final DAVProps _self;
final $Res Function(DAVProps) _then;
/// Create a copy of DAV
/// Create a copy of DAVProps
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? uri = null,Object? user = null,Object? password = null,Object? fileName = null,}) {
return _then(_self.copyWith(
@@ -2098,8 +2098,8 @@ as String,
}
/// Adds pattern-matching-related methods to [DAV].
extension DAVPatterns on DAV {
/// Adds pattern-matching-related methods to [DAVProps].
extension DAVPropsPatterns on DAVProps {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
@@ -2112,10 +2112,10 @@ extension DAVPatterns on DAV {
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _DAV value)? $default,{required TResult orElse(),}){
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _DAVProps value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _DAV() when $default != null:
case _DAVProps() when $default != null:
return $default(_that);case _:
return orElse();
@@ -2134,10 +2134,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _DAV value) $default,){
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _DAVProps value) $default,){
final _that = this;
switch (_that) {
case _DAV():
case _DAVProps():
return $default(_that);case _:
throw StateError('Unexpected subclass');
@@ -2155,10 +2155,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _DAV value)? $default,){
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _DAVProps value)? $default,){
final _that = this;
switch (_that) {
case _DAV() when $default != null:
case _DAVProps() when $default != null:
return $default(_that);case _:
return null;
@@ -2178,7 +2178,7 @@ return $default(_that);case _:
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String uri, String user, String password, String fileName)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _DAV() when $default != null:
case _DAVProps() when $default != null:
return $default(_that.uri,_that.user,_that.password,_that.fileName);case _:
return orElse();
@@ -2199,7 +2199,7 @@ return $default(_that.uri,_that.user,_that.password,_that.fileName);case _:
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String uri, String user, String password, String fileName) $default,) {final _that = this;
switch (_that) {
case _DAV():
case _DAVProps():
return $default(_that.uri,_that.user,_that.password,_that.fileName);case _:
throw StateError('Unexpected subclass');
@@ -2219,7 +2219,7 @@ return $default(_that.uri,_that.user,_that.password,_that.fileName);case _:
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String uri, String user, String password, String fileName)? $default,) {final _that = this;
switch (_that) {
case _DAV() when $default != null:
case _DAVProps() when $default != null:
return $default(_that.uri,_that.user,_that.password,_that.fileName);case _:
return null;
@@ -2231,29 +2231,29 @@ return $default(_that.uri,_that.user,_that.password,_that.fileName);case _:
/// @nodoc
@JsonSerializable()
class _DAV implements DAV {
const _DAV({required this.uri, required this.user, required this.password, this.fileName = defaultDavFileName});
factory _DAV.fromJson(Map<String, dynamic> json) => _$DAVFromJson(json);
class _DAVProps implements DAVProps {
const _DAVProps({required this.uri, required this.user, required this.password, this.fileName = defaultDavFileName});
factory _DAVProps.fromJson(Map<String, dynamic> json) => _$DAVPropsFromJson(json);
@override final String uri;
@override final String user;
@override final String password;
@override@JsonKey() final String fileName;
/// Create a copy of DAV
/// Create a copy of DAVProps
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$DAVCopyWith<_DAV> get copyWith => __$DAVCopyWithImpl<_DAV>(this, _$identity);
_$DAVPropsCopyWith<_DAVProps> get copyWith => __$DAVPropsCopyWithImpl<_DAVProps>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$DAVToJson(this, );
return _$DAVPropsToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DAV&&(identical(other.uri, uri) || other.uri == uri)&&(identical(other.user, user) || other.user == user)&&(identical(other.password, password) || other.password == password)&&(identical(other.fileName, fileName) || other.fileName == fileName));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DAVProps&&(identical(other.uri, uri) || other.uri == uri)&&(identical(other.user, user) || other.user == user)&&(identical(other.password, password) || other.password == password)&&(identical(other.fileName, fileName) || other.fileName == fileName));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -2262,15 +2262,15 @@ int get hashCode => Object.hash(runtimeType,uri,user,password,fileName);
@override
String toString() {
return 'DAV(uri: $uri, user: $user, password: $password, fileName: $fileName)';
return 'DAVProps(uri: $uri, user: $user, password: $password, fileName: $fileName)';
}
}
/// @nodoc
abstract mixin class _$DAVCopyWith<$Res> implements $DAVCopyWith<$Res> {
factory _$DAVCopyWith(_DAV value, $Res Function(_DAV) _then) = __$DAVCopyWithImpl;
abstract mixin class _$DAVPropsCopyWith<$Res> implements $DAVPropsCopyWith<$Res> {
factory _$DAVPropsCopyWith(_DAVProps value, $Res Function(_DAVProps) _then) = __$DAVPropsCopyWithImpl;
@override @useResult
$Res call({
String uri, String user, String password, String fileName
@@ -2281,17 +2281,17 @@ $Res call({
}
/// @nodoc
class __$DAVCopyWithImpl<$Res>
implements _$DAVCopyWith<$Res> {
__$DAVCopyWithImpl(this._self, this._then);
class __$DAVPropsCopyWithImpl<$Res>
implements _$DAVPropsCopyWith<$Res> {
__$DAVPropsCopyWithImpl(this._self, this._then);
final _DAV _self;
final $Res Function(_DAV) _then;
final _DAVProps _self;
final $Res Function(_DAVProps) _then;
/// Create a copy of DAV
/// Create a copy of DAVProps
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? uri = null,Object? user = null,Object? password = null,Object? fileName = null,}) {
return _then(_DAV(
return _then(_DAVProps(
uri: null == uri ? _self.uri : uri // ignore: cast_nullable_to_non_nullable
as String,user: null == user ? _self.user : user // ignore: cast_nullable_to_non_nullable
as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
@@ -4967,278 +4967,6 @@ as Validator?,
}
}
/// @nodoc
mixin _$AndroidState {
String get currentProfileName; String get stopText; bool get onlyStatisticsProxy; bool get crashlytics;
/// Create a copy of AndroidState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$AndroidStateCopyWith<AndroidState> get copyWith => _$AndroidStateCopyWithImpl<AndroidState>(this as AndroidState, _$identity);
/// Serializes this AndroidState to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is AndroidState&&(identical(other.currentProfileName, currentProfileName) || other.currentProfileName == currentProfileName)&&(identical(other.stopText, stopText) || other.stopText == stopText)&&(identical(other.onlyStatisticsProxy, onlyStatisticsProxy) || other.onlyStatisticsProxy == onlyStatisticsProxy)&&(identical(other.crashlytics, crashlytics) || other.crashlytics == crashlytics));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,currentProfileName,stopText,onlyStatisticsProxy,crashlytics);
@override
String toString() {
return 'AndroidState(currentProfileName: $currentProfileName, stopText: $stopText, onlyStatisticsProxy: $onlyStatisticsProxy, crashlytics: $crashlytics)';
}
}
/// @nodoc
abstract mixin class $AndroidStateCopyWith<$Res> {
factory $AndroidStateCopyWith(AndroidState value, $Res Function(AndroidState) _then) = _$AndroidStateCopyWithImpl;
@useResult
$Res call({
String currentProfileName, String stopText, bool onlyStatisticsProxy, bool crashlytics
});
}
/// @nodoc
class _$AndroidStateCopyWithImpl<$Res>
implements $AndroidStateCopyWith<$Res> {
_$AndroidStateCopyWithImpl(this._self, this._then);
final AndroidState _self;
final $Res Function(AndroidState) _then;
/// Create a copy of AndroidState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? currentProfileName = null,Object? stopText = null,Object? onlyStatisticsProxy = null,Object? crashlytics = null,}) {
return _then(_self.copyWith(
currentProfileName: null == currentProfileName ? _self.currentProfileName : currentProfileName // ignore: cast_nullable_to_non_nullable
as String,stopText: null == stopText ? _self.stopText : stopText // ignore: cast_nullable_to_non_nullable
as String,onlyStatisticsProxy: null == onlyStatisticsProxy ? _self.onlyStatisticsProxy : onlyStatisticsProxy // ignore: cast_nullable_to_non_nullable
as bool,crashlytics: null == crashlytics ? _self.crashlytics : crashlytics // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// Adds pattern-matching-related methods to [AndroidState].
extension AndroidStatePatterns on AndroidState {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _AndroidState value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _AndroidState() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _AndroidState value) $default,){
final _that = this;
switch (_that) {
case _AndroidState():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _AndroidState value)? $default,){
final _that = this;
switch (_that) {
case _AndroidState() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String currentProfileName, String stopText, bool onlyStatisticsProxy, bool crashlytics)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _AndroidState() when $default != null:
return $default(_that.currentProfileName,_that.stopText,_that.onlyStatisticsProxy,_that.crashlytics);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String currentProfileName, String stopText, bool onlyStatisticsProxy, bool crashlytics) $default,) {final _that = this;
switch (_that) {
case _AndroidState():
return $default(_that.currentProfileName,_that.stopText,_that.onlyStatisticsProxy,_that.crashlytics);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String currentProfileName, String stopText, bool onlyStatisticsProxy, bool crashlytics)? $default,) {final _that = this;
switch (_that) {
case _AndroidState() when $default != null:
return $default(_that.currentProfileName,_that.stopText,_that.onlyStatisticsProxy,_that.crashlytics);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _AndroidState implements AndroidState {
const _AndroidState({required this.currentProfileName, required this.stopText, required this.onlyStatisticsProxy, required this.crashlytics});
factory _AndroidState.fromJson(Map<String, dynamic> json) => _$AndroidStateFromJson(json);
@override final String currentProfileName;
@override final String stopText;
@override final bool onlyStatisticsProxy;
@override final bool crashlytics;
/// Create a copy of AndroidState
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$AndroidStateCopyWith<_AndroidState> get copyWith => __$AndroidStateCopyWithImpl<_AndroidState>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$AndroidStateToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AndroidState&&(identical(other.currentProfileName, currentProfileName) || other.currentProfileName == currentProfileName)&&(identical(other.stopText, stopText) || other.stopText == stopText)&&(identical(other.onlyStatisticsProxy, onlyStatisticsProxy) || other.onlyStatisticsProxy == onlyStatisticsProxy)&&(identical(other.crashlytics, crashlytics) || other.crashlytics == crashlytics));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,currentProfileName,stopText,onlyStatisticsProxy,crashlytics);
@override
String toString() {
return 'AndroidState(currentProfileName: $currentProfileName, stopText: $stopText, onlyStatisticsProxy: $onlyStatisticsProxy, crashlytics: $crashlytics)';
}
}
/// @nodoc
abstract mixin class _$AndroidStateCopyWith<$Res> implements $AndroidStateCopyWith<$Res> {
factory _$AndroidStateCopyWith(_AndroidState value, $Res Function(_AndroidState) _then) = __$AndroidStateCopyWithImpl;
@override @useResult
$Res call({
String currentProfileName, String stopText, bool onlyStatisticsProxy, bool crashlytics
});
}
/// @nodoc
class __$AndroidStateCopyWithImpl<$Res>
implements _$AndroidStateCopyWith<$Res> {
__$AndroidStateCopyWithImpl(this._self, this._then);
final _AndroidState _self;
final $Res Function(_AndroidState) _then;
/// Create a copy of AndroidState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? currentProfileName = null,Object? stopText = null,Object? onlyStatisticsProxy = null,Object? crashlytics = null,}) {
return _then(_AndroidState(
currentProfileName: null == currentProfileName ? _self.currentProfileName : currentProfileName // ignore: cast_nullable_to_non_nullable
as String,stopText: null == stopText ? _self.stopText : stopText // ignore: cast_nullable_to_non_nullable
as String,onlyStatisticsProxy: null == onlyStatisticsProxy ? _self.onlyStatisticsProxy : onlyStatisticsProxy // ignore: cast_nullable_to_non_nullable
as bool,crashlytics: null == crashlytics ? _self.crashlytics : crashlytics // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// @nodoc
@@ -5508,7 +5236,7 @@ as String,
/// @nodoc
mixin _$Script {
String get id; String get label; String get content;
int get id; String get label; DateTime get lastUpdateTime;
/// Create a copy of Script
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -5521,16 +5249,16 @@ $ScriptCopyWith<Script> get copyWith => _$ScriptCopyWithImpl<Script>(this as Scr
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is Script&&(identical(other.id, id) || other.id == id)&&(identical(other.label, label) || other.label == label)&&(identical(other.content, content) || other.content == content));
return identical(this, other) || (other.runtimeType == runtimeType&&other is Script&&(identical(other.id, id) || other.id == id)&&(identical(other.label, label) || other.label == label)&&(identical(other.lastUpdateTime, lastUpdateTime) || other.lastUpdateTime == lastUpdateTime));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,label,content);
int get hashCode => Object.hash(runtimeType,id,label,lastUpdateTime);
@override
String toString() {
return 'Script(id: $id, label: $label, content: $content)';
return 'Script(id: $id, label: $label, lastUpdateTime: $lastUpdateTime)';
}
@@ -5541,7 +5269,7 @@ abstract mixin class $ScriptCopyWith<$Res> {
factory $ScriptCopyWith(Script value, $Res Function(Script) _then) = _$ScriptCopyWithImpl;
@useResult
$Res call({
String id, String label, String content
int id, String label, DateTime lastUpdateTime
});
@@ -5558,12 +5286,12 @@ class _$ScriptCopyWithImpl<$Res>
/// Create a copy of Script
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? label = null,Object? content = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? label = null,Object? lastUpdateTime = null,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,label: null == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as String,content: null == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
as String,
as int,label: null == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as String,lastUpdateTime: null == lastUpdateTime ? _self.lastUpdateTime : lastUpdateTime // ignore: cast_nullable_to_non_nullable
as DateTime,
));
}
@@ -5648,10 +5376,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String label, String content)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int id, String label, DateTime lastUpdateTime)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _Script() when $default != null:
return $default(_that.id,_that.label,_that.content);case _:
return $default(_that.id,_that.label,_that.lastUpdateTime);case _:
return orElse();
}
@@ -5669,10 +5397,10 @@ return $default(_that.id,_that.label,_that.content);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String label, String content) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int id, String label, DateTime lastUpdateTime) $default,) {final _that = this;
switch (_that) {
case _Script():
return $default(_that.id,_that.label,_that.content);case _:
return $default(_that.id,_that.label,_that.lastUpdateTime);case _:
throw StateError('Unexpected subclass');
}
@@ -5689,10 +5417,10 @@ return $default(_that.id,_that.label,_that.content);case _:
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String label, String content)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int id, String label, DateTime lastUpdateTime)? $default,) {final _that = this;
switch (_that) {
case _Script() when $default != null:
return $default(_that.id,_that.label,_that.content);case _:
return $default(_that.id,_that.label,_that.lastUpdateTime);case _:
return null;
}
@@ -5704,12 +5432,12 @@ return $default(_that.id,_that.label,_that.content);case _:
@JsonSerializable()
class _Script implements Script {
const _Script({required this.id, required this.label, required this.content});
const _Script({required this.id, required this.label, required this.lastUpdateTime});
factory _Script.fromJson(Map<String, dynamic> json) => _$ScriptFromJson(json);
@override final String id;
@override final int id;
@override final String label;
@override final String content;
@override final DateTime lastUpdateTime;
/// Create a copy of Script
/// with the given fields replaced by the non-null parameter values.
@@ -5724,16 +5452,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Script&&(identical(other.id, id) || other.id == id)&&(identical(other.label, label) || other.label == label)&&(identical(other.content, content) || other.content == content));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Script&&(identical(other.id, id) || other.id == id)&&(identical(other.label, label) || other.label == label)&&(identical(other.lastUpdateTime, lastUpdateTime) || other.lastUpdateTime == lastUpdateTime));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,label,content);
int get hashCode => Object.hash(runtimeType,id,label,lastUpdateTime);
@override
String toString() {
return 'Script(id: $id, label: $label, content: $content)';
return 'Script(id: $id, label: $label, lastUpdateTime: $lastUpdateTime)';
}
@@ -5744,7 +5472,7 @@ abstract mixin class _$ScriptCopyWith<$Res> implements $ScriptCopyWith<$Res> {
factory _$ScriptCopyWith(_Script value, $Res Function(_Script) _then) = __$ScriptCopyWithImpl;
@override @useResult
$Res call({
String id, String label, String content
int id, String label, DateTime lastUpdateTime
});
@@ -5761,12 +5489,12 @@ class __$ScriptCopyWithImpl<$Res>
/// Create a copy of Script
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? label = null,Object? content = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? label = null,Object? lastUpdateTime = null,}) {
return _then(_Script(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,label: null == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as String,content: null == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
as String,
as int,label: null == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as String,lastUpdateTime: null == lastUpdateTime ? _self.lastUpdateTime : lastUpdateTime // ignore: cast_nullable_to_non_nullable
as DateTime,
));
}
@@ -6031,6 +5759,266 @@ as bool,
}
}
/// @nodoc
mixin _$UpdatingMessage {
String get label; String get message;
/// Create a copy of UpdatingMessage
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$UpdatingMessageCopyWith<UpdatingMessage> get copyWith => _$UpdatingMessageCopyWithImpl<UpdatingMessage>(this as UpdatingMessage, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is UpdatingMessage&&(identical(other.label, label) || other.label == label)&&(identical(other.message, message) || other.message == message));
}
@override
int get hashCode => Object.hash(runtimeType,label,message);
@override
String toString() {
return 'UpdatingMessage(label: $label, message: $message)';
}
}
/// @nodoc
abstract mixin class $UpdatingMessageCopyWith<$Res> {
factory $UpdatingMessageCopyWith(UpdatingMessage value, $Res Function(UpdatingMessage) _then) = _$UpdatingMessageCopyWithImpl;
@useResult
$Res call({
String label, String message
});
}
/// @nodoc
class _$UpdatingMessageCopyWithImpl<$Res>
implements $UpdatingMessageCopyWith<$Res> {
_$UpdatingMessageCopyWithImpl(this._self, this._then);
final UpdatingMessage _self;
final $Res Function(UpdatingMessage) _then;
/// Create a copy of UpdatingMessage
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? label = null,Object? message = null,}) {
return _then(_self.copyWith(
label: null == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as String,message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// Adds pattern-matching-related methods to [UpdatingMessage].
extension UpdatingMessagePatterns on UpdatingMessage {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _UpdatingMessage value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _UpdatingMessage() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _UpdatingMessage value) $default,){
final _that = this;
switch (_that) {
case _UpdatingMessage():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _UpdatingMessage value)? $default,){
final _that = this;
switch (_that) {
case _UpdatingMessage() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String label, String message)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _UpdatingMessage() when $default != null:
return $default(_that.label,_that.message);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String label, String message) $default,) {final _that = this;
switch (_that) {
case _UpdatingMessage():
return $default(_that.label,_that.message);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String label, String message)? $default,) {final _that = this;
switch (_that) {
case _UpdatingMessage() when $default != null:
return $default(_that.label,_that.message);case _:
return null;
}
}
}
/// @nodoc
class _UpdatingMessage implements UpdatingMessage {
const _UpdatingMessage({required this.label, required this.message});
@override final String label;
@override final String message;
/// Create a copy of UpdatingMessage
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$UpdatingMessageCopyWith<_UpdatingMessage> get copyWith => __$UpdatingMessageCopyWithImpl<_UpdatingMessage>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _UpdatingMessage&&(identical(other.label, label) || other.label == label)&&(identical(other.message, message) || other.message == message));
}
@override
int get hashCode => Object.hash(runtimeType,label,message);
@override
String toString() {
return 'UpdatingMessage(label: $label, message: $message)';
}
}
/// @nodoc
abstract mixin class _$UpdatingMessageCopyWith<$Res> implements $UpdatingMessageCopyWith<$Res> {
factory _$UpdatingMessageCopyWith(_UpdatingMessage value, $Res Function(_UpdatingMessage) _then) = __$UpdatingMessageCopyWithImpl;
@override @useResult
$Res call({
String label, String message
});
}
/// @nodoc
class __$UpdatingMessageCopyWithImpl<$Res>
implements _$UpdatingMessageCopyWith<$Res> {
__$UpdatingMessageCopyWithImpl(this._self, this._then);
final _UpdatingMessage _self;
final $Res Function(_UpdatingMessage) _then;
/// Create a copy of UpdatingMessage
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? label = null,Object? message = null,}) {
return _then(_UpdatingMessage(
label: null == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as String,message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
// dart format on

View File

@@ -125,14 +125,14 @@ const _$LogLevelEnumMap = {
LogLevel.silent: 'silent',
};
_DAV _$DAVFromJson(Map<String, dynamic> json) => _DAV(
_DAVProps _$DAVPropsFromJson(Map<String, dynamic> json) => _DAVProps(
uri: json['uri'] as String,
user: json['user'] as String,
password: json['password'] as String,
fileName: json['fileName'] as String? ?? defaultDavFileName,
);
Map<String, dynamic> _$DAVToJson(_DAV instance) => <String, dynamic>{
Map<String, dynamic> _$DAVPropsToJson(_DAVProps instance) => <String, dynamic>{
'uri': instance.uri,
'user': instance.user,
'password': instance.password,
@@ -239,30 +239,14 @@ const _$KeyboardModifierEnumMap = {
KeyboardModifier.shift: 'shift',
};
_AndroidState _$AndroidStateFromJson(Map<String, dynamic> json) =>
_AndroidState(
currentProfileName: json['currentProfileName'] as String,
stopText: json['stopText'] as String,
onlyStatisticsProxy: json['onlyStatisticsProxy'] as bool,
crashlytics: json['crashlytics'] as bool,
);
Map<String, dynamic> _$AndroidStateToJson(_AndroidState instance) =>
<String, dynamic>{
'currentProfileName': instance.currentProfileName,
'stopText': instance.stopText,
'onlyStatisticsProxy': instance.onlyStatisticsProxy,
'crashlytics': instance.crashlytics,
};
_Script _$ScriptFromJson(Map<String, dynamic> json) => _Script(
id: json['id'] as String,
id: (json['id'] as num).toInt(),
label: json['label'] as String,
content: json['content'] as String,
lastUpdateTime: DateTime.parse(json['lastUpdateTime'] as String),
);
Map<String, dynamic> _$ScriptToJson(_Script instance) => <String, dynamic>{
'id': instance.id,
'label': instance.label,
'content': instance.content,
'lastUpdateTime': instance.lastUpdateTime.toIso8601String(),
};

File diff suppressed because it is too large Load Diff

View File

@@ -28,12 +28,12 @@ _AppSettingProps _$AppSettingPropsFromJson(Map<String, dynamic> json) =>
minimizeOnExit: json['minimizeOnExit'] as bool? ?? true,
hidden: json['hidden'] as bool? ?? false,
developerMode: json['developerMode'] as bool? ?? false,
recoveryStrategy:
restoreStrategy:
$enumDecodeNullable(
_$RecoveryStrategyEnumMap,
json['recoveryStrategy'],
_$RestoreStrategyEnumMap,
json['restoreStrategy'],
) ??
RecoveryStrategy.compatible,
RestoreStrategy.compatible,
showTrayTitle: json['showTrayTitle'] as bool? ?? true,
);
@@ -59,13 +59,13 @@ Map<String, dynamic> _$AppSettingPropsToJson(_AppSettingProps instance) =>
'minimizeOnExit': instance.minimizeOnExit,
'hidden': instance.hidden,
'developerMode': instance.developerMode,
'recoveryStrategy': _$RecoveryStrategyEnumMap[instance.recoveryStrategy]!,
'restoreStrategy': _$RestoreStrategyEnumMap[instance.restoreStrategy]!,
'showTrayTitle': instance.showTrayTitle,
};
const _$RecoveryStrategyEnumMap = {
RecoveryStrategy.compatible: 'compatible',
RecoveryStrategy.override: 'override',
const _$RestoreStrategyEnumMap = {
RestoreStrategy.compatible: 'compatible',
RestoreStrategy.override: 'override',
};
const _$DashboardWidgetEnumMap = {
@@ -81,8 +81,8 @@ const _$DashboardWidgetEnumMap = {
DashboardWidget.memoryInfo: 'memoryInfo',
};
_AccessControl _$AccessControlFromJson(Map<String, dynamic> json) =>
_AccessControl(
_AccessControlProps _$AccessControlPropsFromJson(Map<String, dynamic> json) =>
_AccessControlProps(
enable: json['enable'] as bool? ?? false,
mode:
$enumDecodeNullable(_$AccessControlModeEnumMap, json['mode']) ??
@@ -104,7 +104,7 @@ _AccessControl _$AccessControlFromJson(Map<String, dynamic> json) =>
isFilterNonInternetApp: json['isFilterNonInternetApp'] as bool? ?? true,
);
Map<String, dynamic> _$AccessControlToJson(_AccessControl instance) =>
Map<String, dynamic> _$AccessControlPropsToJson(_AccessControlProps instance) =>
<String, dynamic>{
'enable': instance.enable,
'mode': _$AccessControlModeEnumMap[instance.mode]!,
@@ -147,9 +147,11 @@ _VpnProps _$VpnPropsFromJson(Map<String, dynamic> json) => _VpnProps(
ipv6: json['ipv6'] as bool? ?? false,
allowBypass: json['allowBypass'] as bool? ?? true,
dnsHijacking: json['dnsHijacking'] as bool? ?? false,
accessControl: json['accessControl'] == null
? defaultAccessControl
: AccessControl.fromJson(json['accessControl'] as Map<String, dynamic>),
accessControlProps: json['accessControlProps'] == null
? defaultAccessControlProps
: AccessControlProps.fromJson(
json['accessControlProps'] as Map<String, dynamic>,
),
);
Map<String, dynamic> _$VpnPropsToJson(_VpnProps instance) => <String, dynamic>{
@@ -158,7 +160,7 @@ Map<String, dynamic> _$VpnPropsToJson(_VpnProps instance) => <String, dynamic>{
'ipv6': instance.ipv6,
'allowBypass': instance.allowBypass,
'dnsHijacking': instance.dnsHijacking,
'accessControl': instance.accessControl,
'accessControlProps': instance.accessControlProps,
};
_NetworkProps _$NetworkPropsFromJson(Map<String, dynamic> json) =>
@@ -190,8 +192,8 @@ const _$RouteModeEnumMap = {
RouteMode.config: 'config',
};
_ProxiesStyle _$ProxiesStyleFromJson(Map<String, dynamic> json) =>
_ProxiesStyle(
_ProxiesStyleProps _$ProxiesStylePropsFromJson(Map<String, dynamic> json) =>
_ProxiesStyleProps(
type:
$enumDecodeNullable(_$ProxiesTypeEnumMap, json['type']) ??
ProxiesType.tab,
@@ -209,7 +211,7 @@ _ProxiesStyle _$ProxiesStyleFromJson(Map<String, dynamic> json) =>
ProxyCardType.expand,
);
Map<String, dynamic> _$ProxiesStyleToJson(_ProxiesStyle instance) =>
Map<String, dynamic> _$ProxiesStylePropsToJson(_ProxiesStyleProps instance) =>
<String, dynamic>{
'type': _$ProxiesTypeEnumMap[instance.type]!,
'sortType': _$ProxiesSortTypeEnumMap[instance.sortType]!,
@@ -302,42 +304,22 @@ const _$DynamicSchemeVariantEnumMap = {
DynamicSchemeVariant.fruitSalad: 'fruitSalad',
};
_ScriptProps _$ScriptPropsFromJson(Map<String, dynamic> json) => _ScriptProps(
currentId: json['currentId'] as String?,
scripts:
(json['scripts'] as List<dynamic>?)
?.map((e) => Script.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
);
Map<String, dynamic> _$ScriptPropsToJson(_ScriptProps instance) =>
<String, dynamic>{
'currentId': instance.currentId,
'scripts': instance.scripts,
};
_Config _$ConfigFromJson(Map<String, dynamic> json) => _Config(
appSetting: json['appSetting'] == null
? defaultAppSettingProps
: AppSettingProps.safeFromJson(
json['appSetting'] as Map<String, Object?>?,
),
profiles:
(json['profiles'] as List<dynamic>?)
?.map((e) => Profile.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
currentProfileId: (json['currentProfileId'] as num?)?.toInt(),
overrideDns: json['overrideDns'] as bool? ?? false,
hotKeyActions:
(json['hotKeyActions'] as List<dynamic>?)
?.map((e) => HotKeyAction.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
currentProfileId: json['currentProfileId'] as String?,
overrideDns: json['overrideDns'] as bool? ?? false,
dav: json['dav'] == null
appSettingProps: json['appSettingProps'] == null
? defaultAppSettingProps
: AppSettingProps.safeFromJson(
json['appSettingProps'] as Map<String, Object?>?,
),
davProps: json['davProps'] == null
? null
: DAV.fromJson(json['dav'] as Map<String, dynamic>),
: DAVProps.fromJson(json['davProps'] as Map<String, dynamic>),
networkProps: json['networkProps'] == null
? defaultNetworkProps
: NetworkProps.fromJson(json['networkProps'] as Map<String, dynamic>?),
@@ -347,40 +329,29 @@ _Config _$ConfigFromJson(Map<String, dynamic> json) => _Config(
themeProps: ThemeProps.safeFromJson(
json['themeProps'] as Map<String, Object?>?,
),
proxiesStyle: json['proxiesStyle'] == null
? defaultProxiesStyle
: ProxiesStyle.fromJson(json['proxiesStyle'] as Map<String, dynamic>?),
proxiesStyleProps: json['proxiesStyleProps'] == null
? defaultProxiesStyleProps
: ProxiesStyleProps.fromJson(
json['proxiesStyleProps'] as Map<String, dynamic>?,
),
windowProps: json['windowProps'] == null
? defaultWindowProps
: WindowProps.fromJson(json['windowProps'] as Map<String, dynamic>?),
patchClashConfig: json['patchClashConfig'] == null
? defaultClashConfig
: ClashConfig.fromJson(json['patchClashConfig'] as Map<String, dynamic>),
scripts:
(json['scripts'] as List<dynamic>?)
?.map((e) => Script.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
rules:
(json['rules'] as List<dynamic>?)
?.map((e) => Rule.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
);
Map<String, dynamic> _$ConfigToJson(_Config instance) => <String, dynamic>{
'appSetting': instance.appSetting,
'profiles': instance.profiles,
'hotKeyActions': instance.hotKeyActions,
'currentProfileId': instance.currentProfileId,
'overrideDns': instance.overrideDns,
'dav': instance.dav,
'hotKeyActions': instance.hotKeyActions,
'appSettingProps': instance.appSettingProps,
'davProps': instance.davProps,
'networkProps': instance.networkProps,
'vpnProps': instance.vpnProps,
'themeProps': instance.themeProps,
'proxiesStyle': instance.proxiesStyle,
'proxiesStyleProps': instance.proxiesStyleProps,
'windowProps': instance.windowProps,
'patchClashConfig': instance.patchClashConfig,
'scripts': instance.scripts,
'rules': instance.rules,
};

View File

@@ -595,7 +595,7 @@ $TunCopyWith<$Res> get tun {
/// @nodoc
mixin _$VpnOptions {
bool get enable; int get port; bool get ipv6; bool get dnsHijacking; AccessControl get accessControl; bool get allowBypass; bool get systemProxy; List<String> get bypassDomain; String get stack; List<String> get routeAddress;
bool get enable; int get port; bool get ipv6; bool get dnsHijacking; AccessControlProps get accessControlProps; bool get allowBypass; bool get systemProxy; List<String> get bypassDomain; String get stack; List<String> get routeAddress;
/// Create a copy of VpnOptions
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -608,16 +608,16 @@ $VpnOptionsCopyWith<VpnOptions> get copyWith => _$VpnOptionsCopyWithImpl<VpnOpti
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is VpnOptions&&(identical(other.enable, enable) || other.enable == enable)&&(identical(other.port, port) || other.port == port)&&(identical(other.ipv6, ipv6) || other.ipv6 == ipv6)&&(identical(other.dnsHijacking, dnsHijacking) || other.dnsHijacking == dnsHijacking)&&(identical(other.accessControl, accessControl) || other.accessControl == accessControl)&&(identical(other.allowBypass, allowBypass) || other.allowBypass == allowBypass)&&(identical(other.systemProxy, systemProxy) || other.systemProxy == systemProxy)&&const DeepCollectionEquality().equals(other.bypassDomain, bypassDomain)&&(identical(other.stack, stack) || other.stack == stack)&&const DeepCollectionEquality().equals(other.routeAddress, routeAddress));
return identical(this, other) || (other.runtimeType == runtimeType&&other is VpnOptions&&(identical(other.enable, enable) || other.enable == enable)&&(identical(other.port, port) || other.port == port)&&(identical(other.ipv6, ipv6) || other.ipv6 == ipv6)&&(identical(other.dnsHijacking, dnsHijacking) || other.dnsHijacking == dnsHijacking)&&(identical(other.accessControlProps, accessControlProps) || other.accessControlProps == accessControlProps)&&(identical(other.allowBypass, allowBypass) || other.allowBypass == allowBypass)&&(identical(other.systemProxy, systemProxy) || other.systemProxy == systemProxy)&&const DeepCollectionEquality().equals(other.bypassDomain, bypassDomain)&&(identical(other.stack, stack) || other.stack == stack)&&const DeepCollectionEquality().equals(other.routeAddress, routeAddress));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,enable,port,ipv6,dnsHijacking,accessControl,allowBypass,systemProxy,const DeepCollectionEquality().hash(bypassDomain),stack,const DeepCollectionEquality().hash(routeAddress));
int get hashCode => Object.hash(runtimeType,enable,port,ipv6,dnsHijacking,accessControlProps,allowBypass,systemProxy,const DeepCollectionEquality().hash(bypassDomain),stack,const DeepCollectionEquality().hash(routeAddress));
@override
String toString() {
return 'VpnOptions(enable: $enable, port: $port, ipv6: $ipv6, dnsHijacking: $dnsHijacking, accessControl: $accessControl, allowBypass: $allowBypass, systemProxy: $systemProxy, bypassDomain: $bypassDomain, stack: $stack, routeAddress: $routeAddress)';
return 'VpnOptions(enable: $enable, port: $port, ipv6: $ipv6, dnsHijacking: $dnsHijacking, accessControlProps: $accessControlProps, allowBypass: $allowBypass, systemProxy: $systemProxy, bypassDomain: $bypassDomain, stack: $stack, routeAddress: $routeAddress)';
}
@@ -628,11 +628,11 @@ abstract mixin class $VpnOptionsCopyWith<$Res> {
factory $VpnOptionsCopyWith(VpnOptions value, $Res Function(VpnOptions) _then) = _$VpnOptionsCopyWithImpl;
@useResult
$Res call({
bool enable, int port, bool ipv6, bool dnsHijacking, AccessControl accessControl, bool allowBypass, bool systemProxy, List<String> bypassDomain, String stack, List<String> routeAddress
bool enable, int port, bool ipv6, bool dnsHijacking, AccessControlProps accessControlProps, bool allowBypass, bool systemProxy, List<String> bypassDomain, String stack, List<String> routeAddress
});
$AccessControlCopyWith<$Res> get accessControl;
$AccessControlPropsCopyWith<$Res> get accessControlProps;
}
/// @nodoc
@@ -645,14 +645,14 @@ class _$VpnOptionsCopyWithImpl<$Res>
/// Create a copy of VpnOptions
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? enable = null,Object? port = null,Object? ipv6 = null,Object? dnsHijacking = null,Object? accessControl = null,Object? allowBypass = null,Object? systemProxy = null,Object? bypassDomain = null,Object? stack = null,Object? routeAddress = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? enable = null,Object? port = null,Object? ipv6 = null,Object? dnsHijacking = null,Object? accessControlProps = null,Object? allowBypass = null,Object? systemProxy = null,Object? bypassDomain = null,Object? stack = null,Object? routeAddress = null,}) {
return _then(_self.copyWith(
enable: null == enable ? _self.enable : enable // ignore: cast_nullable_to_non_nullable
as bool,port: null == port ? _self.port : port // ignore: cast_nullable_to_non_nullable
as int,ipv6: null == ipv6 ? _self.ipv6 : ipv6 // ignore: cast_nullable_to_non_nullable
as bool,dnsHijacking: null == dnsHijacking ? _self.dnsHijacking : dnsHijacking // ignore: cast_nullable_to_non_nullable
as bool,accessControl: null == accessControl ? _self.accessControl : accessControl // ignore: cast_nullable_to_non_nullable
as AccessControl,allowBypass: null == allowBypass ? _self.allowBypass : allowBypass // ignore: cast_nullable_to_non_nullable
as bool,accessControlProps: null == accessControlProps ? _self.accessControlProps : accessControlProps // ignore: cast_nullable_to_non_nullable
as AccessControlProps,allowBypass: null == allowBypass ? _self.allowBypass : allowBypass // ignore: cast_nullable_to_non_nullable
as bool,systemProxy: null == systemProxy ? _self.systemProxy : systemProxy // ignore: cast_nullable_to_non_nullable
as bool,bypassDomain: null == bypassDomain ? _self.bypassDomain : bypassDomain // ignore: cast_nullable_to_non_nullable
as List<String>,stack: null == stack ? _self.stack : stack // ignore: cast_nullable_to_non_nullable
@@ -664,10 +664,10 @@ as List<String>,
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$AccessControlCopyWith<$Res> get accessControl {
$AccessControlPropsCopyWith<$Res> get accessControlProps {
return $AccessControlCopyWith<$Res>(_self.accessControl, (value) {
return _then(_self.copyWith(accessControl: value));
return $AccessControlPropsCopyWith<$Res>(_self.accessControlProps, (value) {
return _then(_self.copyWith(accessControlProps: value));
});
}
}
@@ -751,10 +751,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool enable, int port, bool ipv6, bool dnsHijacking, AccessControl accessControl, bool allowBypass, bool systemProxy, List<String> bypassDomain, String stack, List<String> routeAddress)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool enable, int port, bool ipv6, bool dnsHijacking, AccessControlProps accessControlProps, bool allowBypass, bool systemProxy, List<String> bypassDomain, String stack, List<String> routeAddress)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _VpnOptions() when $default != null:
return $default(_that.enable,_that.port,_that.ipv6,_that.dnsHijacking,_that.accessControl,_that.allowBypass,_that.systemProxy,_that.bypassDomain,_that.stack,_that.routeAddress);case _:
return $default(_that.enable,_that.port,_that.ipv6,_that.dnsHijacking,_that.accessControlProps,_that.allowBypass,_that.systemProxy,_that.bypassDomain,_that.stack,_that.routeAddress);case _:
return orElse();
}
@@ -772,10 +772,10 @@ return $default(_that.enable,_that.port,_that.ipv6,_that.dnsHijacking,_that.acce
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool enable, int port, bool ipv6, bool dnsHijacking, AccessControl accessControl, bool allowBypass, bool systemProxy, List<String> bypassDomain, String stack, List<String> routeAddress) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool enable, int port, bool ipv6, bool dnsHijacking, AccessControlProps accessControlProps, bool allowBypass, bool systemProxy, List<String> bypassDomain, String stack, List<String> routeAddress) $default,) {final _that = this;
switch (_that) {
case _VpnOptions():
return $default(_that.enable,_that.port,_that.ipv6,_that.dnsHijacking,_that.accessControl,_that.allowBypass,_that.systemProxy,_that.bypassDomain,_that.stack,_that.routeAddress);case _:
return $default(_that.enable,_that.port,_that.ipv6,_that.dnsHijacking,_that.accessControlProps,_that.allowBypass,_that.systemProxy,_that.bypassDomain,_that.stack,_that.routeAddress);case _:
throw StateError('Unexpected subclass');
}
@@ -792,10 +792,10 @@ return $default(_that.enable,_that.port,_that.ipv6,_that.dnsHijacking,_that.acce
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool enable, int port, bool ipv6, bool dnsHijacking, AccessControl accessControl, bool allowBypass, bool systemProxy, List<String> bypassDomain, String stack, List<String> routeAddress)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool enable, int port, bool ipv6, bool dnsHijacking, AccessControlProps accessControlProps, bool allowBypass, bool systemProxy, List<String> bypassDomain, String stack, List<String> routeAddress)? $default,) {final _that = this;
switch (_that) {
case _VpnOptions() when $default != null:
return $default(_that.enable,_that.port,_that.ipv6,_that.dnsHijacking,_that.accessControl,_that.allowBypass,_that.systemProxy,_that.bypassDomain,_that.stack,_that.routeAddress);case _:
return $default(_that.enable,_that.port,_that.ipv6,_that.dnsHijacking,_that.accessControlProps,_that.allowBypass,_that.systemProxy,_that.bypassDomain,_that.stack,_that.routeAddress);case _:
return null;
}
@@ -807,14 +807,14 @@ return $default(_that.enable,_that.port,_that.ipv6,_that.dnsHijacking,_that.acce
@JsonSerializable()
class _VpnOptions implements VpnOptions {
const _VpnOptions({required this.enable, required this.port, required this.ipv6, required this.dnsHijacking, required this.accessControl, required this.allowBypass, required this.systemProxy, required final List<String> bypassDomain, required this.stack, final List<String> routeAddress = const []}): _bypassDomain = bypassDomain,_routeAddress = routeAddress;
const _VpnOptions({required this.enable, required this.port, required this.ipv6, required this.dnsHijacking, required this.accessControlProps, required this.allowBypass, required this.systemProxy, required final List<String> bypassDomain, required this.stack, final List<String> routeAddress = const []}): _bypassDomain = bypassDomain,_routeAddress = routeAddress;
factory _VpnOptions.fromJson(Map<String, dynamic> json) => _$VpnOptionsFromJson(json);
@override final bool enable;
@override final int port;
@override final bool ipv6;
@override final bool dnsHijacking;
@override final AccessControl accessControl;
@override final AccessControlProps accessControlProps;
@override final bool allowBypass;
@override final bool systemProxy;
final List<String> _bypassDomain;
@@ -846,16 +846,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _VpnOptions&&(identical(other.enable, enable) || other.enable == enable)&&(identical(other.port, port) || other.port == port)&&(identical(other.ipv6, ipv6) || other.ipv6 == ipv6)&&(identical(other.dnsHijacking, dnsHijacking) || other.dnsHijacking == dnsHijacking)&&(identical(other.accessControl, accessControl) || other.accessControl == accessControl)&&(identical(other.allowBypass, allowBypass) || other.allowBypass == allowBypass)&&(identical(other.systemProxy, systemProxy) || other.systemProxy == systemProxy)&&const DeepCollectionEquality().equals(other._bypassDomain, _bypassDomain)&&(identical(other.stack, stack) || other.stack == stack)&&const DeepCollectionEquality().equals(other._routeAddress, _routeAddress));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _VpnOptions&&(identical(other.enable, enable) || other.enable == enable)&&(identical(other.port, port) || other.port == port)&&(identical(other.ipv6, ipv6) || other.ipv6 == ipv6)&&(identical(other.dnsHijacking, dnsHijacking) || other.dnsHijacking == dnsHijacking)&&(identical(other.accessControlProps, accessControlProps) || other.accessControlProps == accessControlProps)&&(identical(other.allowBypass, allowBypass) || other.allowBypass == allowBypass)&&(identical(other.systemProxy, systemProxy) || other.systemProxy == systemProxy)&&const DeepCollectionEquality().equals(other._bypassDomain, _bypassDomain)&&(identical(other.stack, stack) || other.stack == stack)&&const DeepCollectionEquality().equals(other._routeAddress, _routeAddress));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,enable,port,ipv6,dnsHijacking,accessControl,allowBypass,systemProxy,const DeepCollectionEquality().hash(_bypassDomain),stack,const DeepCollectionEquality().hash(_routeAddress));
int get hashCode => Object.hash(runtimeType,enable,port,ipv6,dnsHijacking,accessControlProps,allowBypass,systemProxy,const DeepCollectionEquality().hash(_bypassDomain),stack,const DeepCollectionEquality().hash(_routeAddress));
@override
String toString() {
return 'VpnOptions(enable: $enable, port: $port, ipv6: $ipv6, dnsHijacking: $dnsHijacking, accessControl: $accessControl, allowBypass: $allowBypass, systemProxy: $systemProxy, bypassDomain: $bypassDomain, stack: $stack, routeAddress: $routeAddress)';
return 'VpnOptions(enable: $enable, port: $port, ipv6: $ipv6, dnsHijacking: $dnsHijacking, accessControlProps: $accessControlProps, allowBypass: $allowBypass, systemProxy: $systemProxy, bypassDomain: $bypassDomain, stack: $stack, routeAddress: $routeAddress)';
}
@@ -866,11 +866,11 @@ abstract mixin class _$VpnOptionsCopyWith<$Res> implements $VpnOptionsCopyWith<$
factory _$VpnOptionsCopyWith(_VpnOptions value, $Res Function(_VpnOptions) _then) = __$VpnOptionsCopyWithImpl;
@override @useResult
$Res call({
bool enable, int port, bool ipv6, bool dnsHijacking, AccessControl accessControl, bool allowBypass, bool systemProxy, List<String> bypassDomain, String stack, List<String> routeAddress
bool enable, int port, bool ipv6, bool dnsHijacking, AccessControlProps accessControlProps, bool allowBypass, bool systemProxy, List<String> bypassDomain, String stack, List<String> routeAddress
});
@override $AccessControlCopyWith<$Res> get accessControl;
@override $AccessControlPropsCopyWith<$Res> get accessControlProps;
}
/// @nodoc
@@ -883,14 +883,14 @@ class __$VpnOptionsCopyWithImpl<$Res>
/// Create a copy of VpnOptions
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? enable = null,Object? port = null,Object? ipv6 = null,Object? dnsHijacking = null,Object? accessControl = null,Object? allowBypass = null,Object? systemProxy = null,Object? bypassDomain = null,Object? stack = null,Object? routeAddress = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? enable = null,Object? port = null,Object? ipv6 = null,Object? dnsHijacking = null,Object? accessControlProps = null,Object? allowBypass = null,Object? systemProxy = null,Object? bypassDomain = null,Object? stack = null,Object? routeAddress = null,}) {
return _then(_VpnOptions(
enable: null == enable ? _self.enable : enable // ignore: cast_nullable_to_non_nullable
as bool,port: null == port ? _self.port : port // ignore: cast_nullable_to_non_nullable
as int,ipv6: null == ipv6 ? _self.ipv6 : ipv6 // ignore: cast_nullable_to_non_nullable
as bool,dnsHijacking: null == dnsHijacking ? _self.dnsHijacking : dnsHijacking // ignore: cast_nullable_to_non_nullable
as bool,accessControl: null == accessControl ? _self.accessControl : accessControl // ignore: cast_nullable_to_non_nullable
as AccessControl,allowBypass: null == allowBypass ? _self.allowBypass : allowBypass // ignore: cast_nullable_to_non_nullable
as bool,accessControlProps: null == accessControlProps ? _self.accessControlProps : accessControlProps // ignore: cast_nullable_to_non_nullable
as AccessControlProps,allowBypass: null == allowBypass ? _self.allowBypass : allowBypass // ignore: cast_nullable_to_non_nullable
as bool,systemProxy: null == systemProxy ? _self.systemProxy : systemProxy // ignore: cast_nullable_to_non_nullable
as bool,bypassDomain: null == bypassDomain ? _self._bypassDomain : bypassDomain // ignore: cast_nullable_to_non_nullable
as List<String>,stack: null == stack ? _self.stack : stack // ignore: cast_nullable_to_non_nullable
@@ -903,10 +903,10 @@ as List<String>,
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$AccessControlCopyWith<$Res> get accessControl {
$AccessControlPropsCopyWith<$Res> get accessControlProps {
return $AccessControlCopyWith<$Res>(_self.accessControl, (value) {
return _then(_self.copyWith(accessControl: value));
return $AccessControlPropsCopyWith<$Res>(_self.accessControlProps, (value) {
return _then(_self.copyWith(accessControlProps: value));
});
}
}
@@ -3052,7 +3052,7 @@ as int,
/// @nodoc
mixin _$ExternalProvider {
String get name; String get type; String? get path; int get count;@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) SubscriptionInfo? get subscriptionInfo; bool get isUpdating;@JsonKey(name: 'vehicle-type') String get vehicleType;@JsonKey(name: 'update-at') DateTime get updateAt;
String get name; String get type; String? get path; int get count;@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) SubscriptionInfo? get subscriptionInfo;@JsonKey(name: 'vehicle-type') String get vehicleType;@JsonKey(name: 'update-at') DateTime get updateAt;
/// Create a copy of ExternalProvider
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -3065,16 +3065,16 @@ $ExternalProviderCopyWith<ExternalProvider> get copyWith => _$ExternalProviderCo
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is ExternalProvider&&(identical(other.name, name) || other.name == name)&&(identical(other.type, type) || other.type == type)&&(identical(other.path, path) || other.path == path)&&(identical(other.count, count) || other.count == count)&&(identical(other.subscriptionInfo, subscriptionInfo) || other.subscriptionInfo == subscriptionInfo)&&(identical(other.isUpdating, isUpdating) || other.isUpdating == isUpdating)&&(identical(other.vehicleType, vehicleType) || other.vehicleType == vehicleType)&&(identical(other.updateAt, updateAt) || other.updateAt == updateAt));
return identical(this, other) || (other.runtimeType == runtimeType&&other is ExternalProvider&&(identical(other.name, name) || other.name == name)&&(identical(other.type, type) || other.type == type)&&(identical(other.path, path) || other.path == path)&&(identical(other.count, count) || other.count == count)&&(identical(other.subscriptionInfo, subscriptionInfo) || other.subscriptionInfo == subscriptionInfo)&&(identical(other.vehicleType, vehicleType) || other.vehicleType == vehicleType)&&(identical(other.updateAt, updateAt) || other.updateAt == updateAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,name,type,path,count,subscriptionInfo,isUpdating,vehicleType,updateAt);
int get hashCode => Object.hash(runtimeType,name,type,path,count,subscriptionInfo,vehicleType,updateAt);
@override
String toString() {
return 'ExternalProvider(name: $name, type: $type, path: $path, count: $count, subscriptionInfo: $subscriptionInfo, isUpdating: $isUpdating, vehicleType: $vehicleType, updateAt: $updateAt)';
return 'ExternalProvider(name: $name, type: $type, path: $path, count: $count, subscriptionInfo: $subscriptionInfo, vehicleType: $vehicleType, updateAt: $updateAt)';
}
@@ -3085,7 +3085,7 @@ abstract mixin class $ExternalProviderCopyWith<$Res> {
factory $ExternalProviderCopyWith(ExternalProvider value, $Res Function(ExternalProvider) _then) = _$ExternalProviderCopyWithImpl;
@useResult
$Res call({
String name, String type, String? path, int count,@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) SubscriptionInfo? subscriptionInfo, bool isUpdating,@JsonKey(name: 'vehicle-type') String vehicleType,@JsonKey(name: 'update-at') DateTime updateAt
String name, String type, String? path, int count,@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) SubscriptionInfo? subscriptionInfo,@JsonKey(name: 'vehicle-type') String vehicleType,@JsonKey(name: 'update-at') DateTime updateAt
});
@@ -3102,15 +3102,14 @@ class _$ExternalProviderCopyWithImpl<$Res>
/// Create a copy of ExternalProvider
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? name = null,Object? type = null,Object? path = freezed,Object? count = null,Object? subscriptionInfo = freezed,Object? isUpdating = null,Object? vehicleType = null,Object? updateAt = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? name = null,Object? type = null,Object? path = freezed,Object? count = null,Object? subscriptionInfo = freezed,Object? vehicleType = null,Object? updateAt = null,}) {
return _then(_self.copyWith(
name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as String,path: freezed == path ? _self.path : path // ignore: cast_nullable_to_non_nullable
as String?,count: null == count ? _self.count : count // ignore: cast_nullable_to_non_nullable
as int,subscriptionInfo: freezed == subscriptionInfo ? _self.subscriptionInfo : subscriptionInfo // ignore: cast_nullable_to_non_nullable
as SubscriptionInfo?,isUpdating: null == isUpdating ? _self.isUpdating : isUpdating // ignore: cast_nullable_to_non_nullable
as bool,vehicleType: null == vehicleType ? _self.vehicleType : vehicleType // ignore: cast_nullable_to_non_nullable
as SubscriptionInfo?,vehicleType: null == vehicleType ? _self.vehicleType : vehicleType // ignore: cast_nullable_to_non_nullable
as String,updateAt: null == updateAt ? _self.updateAt : updateAt // ignore: cast_nullable_to_non_nullable
as DateTime,
));
@@ -3209,10 +3208,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String name, String type, String? path, int count, @JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) SubscriptionInfo? subscriptionInfo, bool isUpdating, @JsonKey(name: 'vehicle-type') String vehicleType, @JsonKey(name: 'update-at') DateTime updateAt)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String name, String type, String? path, int count, @JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) SubscriptionInfo? subscriptionInfo, @JsonKey(name: 'vehicle-type') String vehicleType, @JsonKey(name: 'update-at') DateTime updateAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _ExternalProvider() when $default != null:
return $default(_that.name,_that.type,_that.path,_that.count,_that.subscriptionInfo,_that.isUpdating,_that.vehicleType,_that.updateAt);case _:
return $default(_that.name,_that.type,_that.path,_that.count,_that.subscriptionInfo,_that.vehicleType,_that.updateAt);case _:
return orElse();
}
@@ -3230,10 +3229,10 @@ return $default(_that.name,_that.type,_that.path,_that.count,_that.subscriptionI
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String name, String type, String? path, int count, @JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) SubscriptionInfo? subscriptionInfo, bool isUpdating, @JsonKey(name: 'vehicle-type') String vehicleType, @JsonKey(name: 'update-at') DateTime updateAt) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String name, String type, String? path, int count, @JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) SubscriptionInfo? subscriptionInfo, @JsonKey(name: 'vehicle-type') String vehicleType, @JsonKey(name: 'update-at') DateTime updateAt) $default,) {final _that = this;
switch (_that) {
case _ExternalProvider():
return $default(_that.name,_that.type,_that.path,_that.count,_that.subscriptionInfo,_that.isUpdating,_that.vehicleType,_that.updateAt);case _:
return $default(_that.name,_that.type,_that.path,_that.count,_that.subscriptionInfo,_that.vehicleType,_that.updateAt);case _:
throw StateError('Unexpected subclass');
}
@@ -3250,10 +3249,10 @@ return $default(_that.name,_that.type,_that.path,_that.count,_that.subscriptionI
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String name, String type, String? path, int count, @JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) SubscriptionInfo? subscriptionInfo, bool isUpdating, @JsonKey(name: 'vehicle-type') String vehicleType, @JsonKey(name: 'update-at') DateTime updateAt)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String name, String type, String? path, int count, @JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) SubscriptionInfo? subscriptionInfo, @JsonKey(name: 'vehicle-type') String vehicleType, @JsonKey(name: 'update-at') DateTime updateAt)? $default,) {final _that = this;
switch (_that) {
case _ExternalProvider() when $default != null:
return $default(_that.name,_that.type,_that.path,_that.count,_that.subscriptionInfo,_that.isUpdating,_that.vehicleType,_that.updateAt);case _:
return $default(_that.name,_that.type,_that.path,_that.count,_that.subscriptionInfo,_that.vehicleType,_that.updateAt);case _:
return null;
}
@@ -3265,7 +3264,7 @@ return $default(_that.name,_that.type,_that.path,_that.count,_that.subscriptionI
@JsonSerializable()
class _ExternalProvider implements ExternalProvider {
const _ExternalProvider({required this.name, required this.type, this.path, required this.count, @JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) this.subscriptionInfo, this.isUpdating = false, @JsonKey(name: 'vehicle-type') required this.vehicleType, @JsonKey(name: 'update-at') required this.updateAt});
const _ExternalProvider({required this.name, required this.type, this.path, required this.count, @JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) this.subscriptionInfo, @JsonKey(name: 'vehicle-type') required this.vehicleType, @JsonKey(name: 'update-at') required this.updateAt});
factory _ExternalProvider.fromJson(Map<String, dynamic> json) => _$ExternalProviderFromJson(json);
@override final String name;
@@ -3273,7 +3272,6 @@ class _ExternalProvider implements ExternalProvider {
@override final String? path;
@override final int count;
@override@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) final SubscriptionInfo? subscriptionInfo;
@override@JsonKey() final bool isUpdating;
@override@JsonKey(name: 'vehicle-type') final String vehicleType;
@override@JsonKey(name: 'update-at') final DateTime updateAt;
@@ -3290,16 +3288,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ExternalProvider&&(identical(other.name, name) || other.name == name)&&(identical(other.type, type) || other.type == type)&&(identical(other.path, path) || other.path == path)&&(identical(other.count, count) || other.count == count)&&(identical(other.subscriptionInfo, subscriptionInfo) || other.subscriptionInfo == subscriptionInfo)&&(identical(other.isUpdating, isUpdating) || other.isUpdating == isUpdating)&&(identical(other.vehicleType, vehicleType) || other.vehicleType == vehicleType)&&(identical(other.updateAt, updateAt) || other.updateAt == updateAt));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ExternalProvider&&(identical(other.name, name) || other.name == name)&&(identical(other.type, type) || other.type == type)&&(identical(other.path, path) || other.path == path)&&(identical(other.count, count) || other.count == count)&&(identical(other.subscriptionInfo, subscriptionInfo) || other.subscriptionInfo == subscriptionInfo)&&(identical(other.vehicleType, vehicleType) || other.vehicleType == vehicleType)&&(identical(other.updateAt, updateAt) || other.updateAt == updateAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,name,type,path,count,subscriptionInfo,isUpdating,vehicleType,updateAt);
int get hashCode => Object.hash(runtimeType,name,type,path,count,subscriptionInfo,vehicleType,updateAt);
@override
String toString() {
return 'ExternalProvider(name: $name, type: $type, path: $path, count: $count, subscriptionInfo: $subscriptionInfo, isUpdating: $isUpdating, vehicleType: $vehicleType, updateAt: $updateAt)';
return 'ExternalProvider(name: $name, type: $type, path: $path, count: $count, subscriptionInfo: $subscriptionInfo, vehicleType: $vehicleType, updateAt: $updateAt)';
}
@@ -3310,7 +3308,7 @@ abstract mixin class _$ExternalProviderCopyWith<$Res> implements $ExternalProvid
factory _$ExternalProviderCopyWith(_ExternalProvider value, $Res Function(_ExternalProvider) _then) = __$ExternalProviderCopyWithImpl;
@override @useResult
$Res call({
String name, String type, String? path, int count,@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) SubscriptionInfo? subscriptionInfo, bool isUpdating,@JsonKey(name: 'vehicle-type') String vehicleType,@JsonKey(name: 'update-at') DateTime updateAt
String name, String type, String? path, int count,@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore) SubscriptionInfo? subscriptionInfo,@JsonKey(name: 'vehicle-type') String vehicleType,@JsonKey(name: 'update-at') DateTime updateAt
});
@@ -3327,15 +3325,14 @@ class __$ExternalProviderCopyWithImpl<$Res>
/// Create a copy of ExternalProvider
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? name = null,Object? type = null,Object? path = freezed,Object? count = null,Object? subscriptionInfo = freezed,Object? isUpdating = null,Object? vehicleType = null,Object? updateAt = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? name = null,Object? type = null,Object? path = freezed,Object? count = null,Object? subscriptionInfo = freezed,Object? vehicleType = null,Object? updateAt = null,}) {
return _then(_ExternalProvider(
name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as String,path: freezed == path ? _self.path : path // ignore: cast_nullable_to_non_nullable
as String?,count: null == count ? _self.count : count // ignore: cast_nullable_to_non_nullable
as int,subscriptionInfo: freezed == subscriptionInfo ? _self.subscriptionInfo : subscriptionInfo // ignore: cast_nullable_to_non_nullable
as SubscriptionInfo?,isUpdating: null == isUpdating ? _self.isUpdating : isUpdating // ignore: cast_nullable_to_non_nullable
as bool,vehicleType: null == vehicleType ? _self.vehicleType : vehicleType // ignore: cast_nullable_to_non_nullable
as SubscriptionInfo?,vehicleType: null == vehicleType ? _self.vehicleType : vehicleType // ignore: cast_nullable_to_non_nullable
as String,updateAt: null == updateAt ? _self.updateAt : updateAt // ignore: cast_nullable_to_non_nullable
as DateTime,
));
@@ -3626,6 +3623,284 @@ as String,
}
/// @nodoc
mixin _$ProxiesData {
Map<String, dynamic> get proxies; List<String> get all;
/// Create a copy of ProxiesData
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$ProxiesDataCopyWith<ProxiesData> get copyWith => _$ProxiesDataCopyWithImpl<ProxiesData>(this as ProxiesData, _$identity);
/// Serializes this ProxiesData to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is ProxiesData&&const DeepCollectionEquality().equals(other.proxies, proxies)&&const DeepCollectionEquality().equals(other.all, all));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(proxies),const DeepCollectionEquality().hash(all));
@override
String toString() {
return 'ProxiesData(proxies: $proxies, all: $all)';
}
}
/// @nodoc
abstract mixin class $ProxiesDataCopyWith<$Res> {
factory $ProxiesDataCopyWith(ProxiesData value, $Res Function(ProxiesData) _then) = _$ProxiesDataCopyWithImpl;
@useResult
$Res call({
Map<String, dynamic> proxies, List<String> all
});
}
/// @nodoc
class _$ProxiesDataCopyWithImpl<$Res>
implements $ProxiesDataCopyWith<$Res> {
_$ProxiesDataCopyWithImpl(this._self, this._then);
final ProxiesData _self;
final $Res Function(ProxiesData) _then;
/// Create a copy of ProxiesData
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? proxies = null,Object? all = null,}) {
return _then(_self.copyWith(
proxies: null == proxies ? _self.proxies : proxies // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>,all: null == all ? _self.all : all // ignore: cast_nullable_to_non_nullable
as List<String>,
));
}
}
/// Adds pattern-matching-related methods to [ProxiesData].
extension ProxiesDataPatterns on ProxiesData {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _ProxiesData value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _ProxiesData() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _ProxiesData value) $default,){
final _that = this;
switch (_that) {
case _ProxiesData():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _ProxiesData value)? $default,){
final _that = this;
switch (_that) {
case _ProxiesData() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( Map<String, dynamic> proxies, List<String> all)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _ProxiesData() when $default != null:
return $default(_that.proxies,_that.all);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( Map<String, dynamic> proxies, List<String> all) $default,) {final _that = this;
switch (_that) {
case _ProxiesData():
return $default(_that.proxies,_that.all);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( Map<String, dynamic> proxies, List<String> all)? $default,) {final _that = this;
switch (_that) {
case _ProxiesData() when $default != null:
return $default(_that.proxies,_that.all);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _ProxiesData implements ProxiesData {
const _ProxiesData({required final Map<String, dynamic> proxies, required final List<String> all}): _proxies = proxies,_all = all;
factory _ProxiesData.fromJson(Map<String, dynamic> json) => _$ProxiesDataFromJson(json);
final Map<String, dynamic> _proxies;
@override Map<String, dynamic> get proxies {
if (_proxies is EqualUnmodifiableMapView) return _proxies;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_proxies);
}
final List<String> _all;
@override List<String> get all {
if (_all is EqualUnmodifiableListView) return _all;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_all);
}
/// Create a copy of ProxiesData
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$ProxiesDataCopyWith<_ProxiesData> get copyWith => __$ProxiesDataCopyWithImpl<_ProxiesData>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$ProxiesDataToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ProxiesData&&const DeepCollectionEquality().equals(other._proxies, _proxies)&&const DeepCollectionEquality().equals(other._all, _all));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_proxies),const DeepCollectionEquality().hash(_all));
@override
String toString() {
return 'ProxiesData(proxies: $proxies, all: $all)';
}
}
/// @nodoc
abstract mixin class _$ProxiesDataCopyWith<$Res> implements $ProxiesDataCopyWith<$Res> {
factory _$ProxiesDataCopyWith(_ProxiesData value, $Res Function(_ProxiesData) _then) = __$ProxiesDataCopyWithImpl;
@override @useResult
$Res call({
Map<String, dynamic> proxies, List<String> all
});
}
/// @nodoc
class __$ProxiesDataCopyWithImpl<$Res>
implements _$ProxiesDataCopyWith<$Res> {
__$ProxiesDataCopyWithImpl(this._self, this._then);
final _ProxiesData _self;
final $Res Function(_ProxiesData) _then;
/// Create a copy of ProxiesData
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? proxies = null,Object? all = null,}) {
return _then(_ProxiesData(
proxies: null == proxies ? _self._proxies : proxies // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>,all: null == all ? _self._all : all // ignore: cast_nullable_to_non_nullable
as List<String>,
));
}
}
/// @nodoc
mixin _$ActionResult {

View File

@@ -81,8 +81,8 @@ _VpnOptions _$VpnOptionsFromJson(Map<String, dynamic> json) => _VpnOptions(
port: (json['port'] as num).toInt(),
ipv6: json['ipv6'] as bool,
dnsHijacking: json['dnsHijacking'] as bool,
accessControl: AccessControl.fromJson(
json['accessControl'] as Map<String, dynamic>,
accessControlProps: AccessControlProps.fromJson(
json['accessControlProps'] as Map<String, dynamic>,
),
allowBypass: json['allowBypass'] as bool,
systemProxy: json['systemProxy'] as bool,
@@ -103,7 +103,7 @@ Map<String, dynamic> _$VpnOptionsToJson(_VpnOptions instance) =>
'port': instance.port,
'ipv6': instance.ipv6,
'dnsHijacking': instance.dnsHijacking,
'accessControl': instance.accessControl,
'accessControlProps': instance.accessControlProps,
'allowBypass': instance.allowBypass,
'systemProxy': instance.systemProxy,
'bypassDomain': instance.bypassDomain,
@@ -230,7 +230,6 @@ _ExternalProvider _$ExternalProviderFromJson(Map<String, dynamic> json) =>
subscriptionInfo: subscriptionInfoFormCore(
json['subscription-info'] as Map<String, Object?>?,
),
isUpdating: json['isUpdating'] as bool? ?? false,
vehicleType: json['vehicle-type'] as String,
updateAt: DateTime.parse(json['update-at'] as String),
);
@@ -242,7 +241,6 @@ Map<String, dynamic> _$ExternalProviderToJson(_ExternalProvider instance) =>
'path': instance.path,
'count': instance.count,
'subscription-info': instance.subscriptionInfo,
'isUpdating': instance.isUpdating,
'vehicle-type': instance.vehicleType,
'update-at': instance.updateAt.toIso8601String(),
};
@@ -301,6 +299,14 @@ const _$ActionMethodEnumMap = {
ActionMethod.getCurrentProfileName: 'getCurrentProfileName',
};
_ProxiesData _$ProxiesDataFromJson(Map<String, dynamic> json) => _ProxiesData(
proxies: json['proxies'] as Map<String, dynamic>,
all: (json['all'] as List<dynamic>).map((e) => e as String).toList(),
);
Map<String, dynamic> _$ProxiesDataToJson(_ProxiesData instance) =>
<String, dynamic>{'proxies': instance.proxies, 'all': instance.all};
_ActionResult _$ActionResultFromJson(Map<String, dynamic> json) =>
_ActionResult(
method: $enumDecode(_$ActionMethodEnumMap, json['method']),

File diff suppressed because it is too large Load Diff

View File

@@ -23,8 +23,8 @@ Map<String, dynamic> _$SubscriptionInfoToJson(_SubscriptionInfo instance) =>
};
_Profile _$ProfileFromJson(Map<String, dynamic> json) => _Profile(
id: json['id'] as String,
label: json['label'] as String?,
id: (json['id'] as num).toInt(),
label: json['label'] as String? ?? '',
currentGroupName: json['currentGroupName'] as String?,
url: json['url'] as String? ?? '',
lastUpdateDate: json['lastUpdateDate'] == null
@@ -47,12 +47,11 @@ _Profile _$ProfileFromJson(Map<String, dynamic> json) => _Profile(
unfoldSet:
(json['unfoldSet'] as List<dynamic>?)?.map((e) => e as String).toSet() ??
const {},
overrideData: json['overrideData'] == null
? const OverrideData()
: OverrideData.fromJson(json['overrideData'] as Map<String, dynamic>),
overwrite: json['overwrite'] == null
? const Overwrite()
: Overwrite.fromJson(json['overwrite'] as Map<String, dynamic>),
overwriteType:
$enumDecodeNullable(_$OverwriteTypeEnumMap, json['overwriteType']) ??
OverwriteType.standard,
scriptId: (json['scriptId'] as num?)?.toInt(),
order: (json['order'] as num?)?.toInt(),
);
Map<String, dynamic> _$ProfileToJson(_Profile instance) => <String, dynamic>{
@@ -66,33 +65,11 @@ Map<String, dynamic> _$ProfileToJson(_Profile instance) => <String, dynamic>{
'autoUpdate': instance.autoUpdate,
'selectedMap': instance.selectedMap,
'unfoldSet': instance.unfoldSet.toList(),
'overrideData': instance.overrideData,
'overwrite': instance.overwrite,
'overwriteType': _$OverwriteTypeEnumMap[instance.overwriteType]!,
'scriptId': instance.scriptId,
'order': instance.order,
};
_Overwrite _$OverwriteFromJson(Map<String, dynamic> json) => _Overwrite(
type:
$enumDecodeNullable(_$OverwriteTypeEnumMap, json['type']) ??
OverwriteType.standard,
standardOverwrite: json['standardOverwrite'] == null
? const StandardOverwrite()
: StandardOverwrite.fromJson(
json['standardOverwrite'] as Map<String, dynamic>,
),
scriptOverwrite: json['scriptOverwrite'] == null
? const ScriptOverwrite()
: ScriptOverwrite.fromJson(
json['scriptOverwrite'] as Map<String, dynamic>,
),
);
Map<String, dynamic> _$OverwriteToJson(_Overwrite instance) =>
<String, dynamic>{
'type': _$OverwriteTypeEnumMap[instance.type]!,
'standardOverwrite': instance.standardOverwrite,
'scriptOverwrite': instance.scriptOverwrite,
};
const _$OverwriteTypeEnumMap = {
OverwriteType.standard: 'standard',
OverwriteType.script: 'script',
@@ -107,7 +84,7 @@ _StandardOverwrite _$StandardOverwriteFromJson(Map<String, dynamic> json) =>
const [],
disabledRuleIds:
(json['disabledRuleIds'] as List<dynamic>?)
?.map((e) => e as String)
?.map((e) => (e as num).toInt())
.toList() ??
const [],
);
@@ -119,47 +96,7 @@ Map<String, dynamic> _$StandardOverwriteToJson(_StandardOverwrite instance) =>
};
_ScriptOverwrite _$ScriptOverwriteFromJson(Map<String, dynamic> json) =>
_ScriptOverwrite(scriptId: json['scriptId'] as String?);
_ScriptOverwrite(scriptId: (json['scriptId'] as num?)?.toInt());
Map<String, dynamic> _$ScriptOverwriteToJson(_ScriptOverwrite instance) =>
<String, dynamic>{'scriptId': instance.scriptId};
_OverrideData _$OverrideDataFromJson(Map<String, dynamic> json) =>
_OverrideData(
enable: json['enable'] as bool? ?? false,
rule: json['rule'] == null
? const OverrideRule()
: OverrideRule.fromJson(json['rule'] as Map<String, dynamic>),
);
Map<String, dynamic> _$OverrideDataToJson(_OverrideData instance) =>
<String, dynamic>{'enable': instance.enable, 'rule': instance.rule};
_OverrideRule _$OverrideRuleFromJson(Map<String, dynamic> json) =>
_OverrideRule(
type:
$enumDecodeNullable(_$OverrideRuleTypeEnumMap, json['type']) ??
OverrideRuleType.added,
overrideRules:
(json['overrideRules'] as List<dynamic>?)
?.map((e) => Rule.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
addedRules:
(json['addedRules'] as List<dynamic>?)
?.map((e) => Rule.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
);
Map<String, dynamic> _$OverrideRuleToJson(_OverrideRule instance) =>
<String, dynamic>{
'type': _$OverrideRuleTypeEnumMap[instance.type]!,
'overrideRules': instance.overrideRules,
'addedRules': instance.addedRules,
};
const _$OverrideRuleTypeEnumMap = {
OverrideRuleType.override: 'override',
OverrideRuleType.added: 'added',
};

View File

@@ -0,0 +1,34 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of '../state.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_SharedState _$SharedStateFromJson(Map<String, dynamic> json) => _SharedState(
setupParams: json['setupParams'] == null
? null
: SetupParams.fromJson(json['setupParams'] as Map<String, dynamic>),
vpnOptions: json['vpnOptions'] == null
? null
: VpnOptions.fromJson(json['vpnOptions'] as Map<String, dynamic>),
stopTip: json['stopTip'] as String,
startTip: json['startTip'] as String,
currentProfileName: json['currentProfileName'] as String,
stopText: json['stopText'] as String,
onlyStatisticsProxy: json['onlyStatisticsProxy'] as bool,
crashlytics: json['crashlytics'] as bool,
);
Map<String, dynamic> _$SharedStateToJson(_SharedState instance) =>
<String, dynamic>{
'setupParams': instance.setupParams,
'vpnOptions': instance.vpnOptions,
'stopTip': instance.stopTip,
'startTip': instance.startTip,
'currentProfileName': instance.currentProfileName,
'stopText': instance.stopText,
'onlyStatisticsProxy': instance.onlyStatisticsProxy,
'crashlytics': instance.crashlytics,
};

File diff suppressed because it is too large Load Diff

View File

@@ -4,5 +4,4 @@ export 'common.dart';
export 'config.dart';
export 'core.dart';
export 'profile.dart';
export 'selector.dart';
export 'widget.dart';
export 'state.dart';

View File

@@ -1,5 +1,4 @@
import 'dart:io';
import 'dart:isolate';
import 'dart:typed_data';
import 'package:fl_clash/common/common.dart';
@@ -8,6 +7,7 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'clash_config.dart';
import 'state.dart';
part 'generated/profile.freezed.dart';
part 'generated/profile.g.dart';
@@ -44,8 +44,8 @@ abstract class SubscriptionInfo with _$SubscriptionInfo {
@freezed
abstract class Profile with _$Profile {
const factory Profile({
required String id,
String? label,
required int id,
@Default('') String label,
String? currentGroupName,
@Default('') String url,
DateTime? lastUpdateDate,
@@ -54,43 +54,63 @@ abstract class Profile with _$Profile {
@Default(true) bool autoUpdate,
@Default({}) Map<String, String> selectedMap,
@Default({}) Set<String> unfoldSet,
@Default(OverrideData()) OverrideData overrideData,
@Default(Overwrite()) Overwrite overwrite,
@JsonKey(includeToJson: false, includeFromJson: false)
@Default(false)
bool isUpdating,
@Default(OverwriteType.standard) OverwriteType overwriteType,
int? scriptId,
int? order,
}) = _Profile;
factory Profile.fromJson(Map<String, Object?> json) =>
_$ProfileFromJson(json);
factory Profile.normal({String? label, String url = ''}) {
final id = snowflake.id;
return Profile(
label: label,
label: label ?? '',
url: url,
id: DateTime.now().millisecondsSinceEpoch.toString(),
id: id,
autoUpdateDuration: defaultUpdateDuration,
);
}
}
@freezed
abstract class Overwrite with _$Overwrite {
const factory Overwrite({
@Default(OverwriteType.standard) OverwriteType type,
@Default(StandardOverwrite()) StandardOverwrite standardOverwrite,
@Default(ScriptOverwrite()) ScriptOverwrite scriptOverwrite,
}) = _Overwrite;
factory Overwrite.fromJson(Map<String, Object?> json) =>
_$OverwriteFromJson(json);
abstract class ProfileRuleLink with _$ProfileRuleLink {
const factory ProfileRuleLink({
int? profileId,
required int ruleId,
RuleScene? scene,
String? order,
}) = _ProfileRuleLink;
}
extension ProfileRuleLinkExt on ProfileRuleLink {
String get key {
final splits = <String?>[
profileId?.toString(),
ruleId.toString(),
scene?.name,
];
return splits.where((item) => item != null).join('_');
}
}
// @freezed
// abstract class Overwrite with _$Overwrite {
// const factory Overwrite({
// @Default(OverwriteType.standard) OverwriteType type,
// @Default(StandardOverwrite()) StandardOverwrite standardOverwrite,
// @Default(ScriptOverwrite()) ScriptOverwrite scriptOverwrite,
// }) = _Overwrite;
//
// factory Overwrite.fromJson(Map<String, Object?> json) =>
// _$OverwriteFromJson(json);
// }
@freezed
abstract class StandardOverwrite with _$StandardOverwrite {
const factory StandardOverwrite({
@Default([]) List<Rule> addedRules,
@Default([]) List<String> disabledRuleIds,
@Default([]) List<int> disabledRuleIds,
}) = _StandardOverwrite;
factory StandardOverwrite.fromJson(Map<String, Object?> json) =>
@@ -99,63 +119,47 @@ abstract class StandardOverwrite with _$StandardOverwrite {
@freezed
abstract class ScriptOverwrite with _$ScriptOverwrite {
const factory ScriptOverwrite({String? scriptId}) = _ScriptOverwrite;
const factory ScriptOverwrite({int? scriptId}) = _ScriptOverwrite;
factory ScriptOverwrite.fromJson(Map<String, Object?> json) =>
_$ScriptOverwriteFromJson(json);
}
@freezed
abstract class OverrideData with _$OverrideData {
const factory OverrideData({
@Default(false) bool enable,
@Default(OverrideRule()) OverrideRule rule,
}) = _OverrideData;
factory OverrideData.fromJson(Map<String, Object?> json) =>
_$OverrideDataFromJson(json);
}
@freezed
abstract class OverrideRule with _$OverrideRule {
const factory OverrideRule({
@Default(OverrideRuleType.added) OverrideRuleType type,
@Default([]) List<Rule> overrideRules,
@Default([]) List<Rule> addedRules,
}) = _OverrideRule;
factory OverrideRule.fromJson(Map<String, Object?> json) =>
_$OverrideRuleFromJson(json);
}
extension OverrideDataExt on OverrideData {
List<String> get runningRule {
if (!enable) {
return [];
}
return rule.rules.map((item) => item.value).toList();
}
}
extension OverrideRuleExt on OverrideRule {
List<Rule> get rules => switch (type == OverrideRuleType.override) {
true => overrideRules,
false => addedRules,
};
OverrideRule updateRules(List<Rule> Function(List<Rule> rules) builder) {
if (type == OverrideRuleType.added) {
return copyWith(addedRules: builder(addedRules));
}
return copyWith(overrideRules: builder(overrideRules));
}
}
extension ProfilesExt on List<Profile> {
Profile? getProfile(String? profileId) {
Profile? getProfile(int? profileId) {
final index = indexWhere((profile) => profile.id == profileId);
return index == -1 ? null : this[index];
}
String _getLabel(String label, int id) {
final realLabel = label.takeFirstValid([id.toString()]);
final hasDup =
indexWhere(
(element) => element.label == realLabel && element.id != id,
) !=
-1;
if (hasDup) {
return _getLabel(utils.getOverwriteLabel(realLabel), id);
} else {
return label;
}
}
VM2<List<Profile>, Profile> copyAndAddProfile(Profile profile) {
final List<Profile> profilesTemp = List.from(this);
final index = profilesTemp.indexWhere(
(element) => element.id == profile.id,
);
final updateProfile = profile.copyWith(
label: _getLabel(profile.label, profile.id),
);
if (index == -1) {
profilesTemp.add(updateProfile);
} else {
profilesTemp[index] = updateProfile;
}
return VM2(profilesTemp, updateProfile);
}
}
extension ProfileExtension on Profile {
@@ -164,33 +168,46 @@ extension ProfileExtension on Profile {
bool get realAutoUpdate => url.isEmpty == true ? false : autoUpdate;
Future<void> checkAndUpdate() async {
final isExists = await check();
if (!isExists) {
if (url.isNotEmpty) {
await update();
}
String get realLabel => label.takeFirstValid([id.toString()]);
String get fileName => '$id.yaml';
String get updatingKey => 'profile_$id';
Future<Profile?> checkAndUpdateAndCopy() async {
final mFile = await _getFile(false);
final isExists = await mFile.exists();
if (isExists || url.isEmpty) {
return null;
}
return update();
}
Future<bool> check() async {
final profilePath = await appPath.getProfilePath(id);
return await File(profilePath).exists();
}
Future<File> getFile() async {
final path = await appPath.getProfilePath(id);
Future<File> _getFile([bool autoCreate = true]) async {
final path = await appPath.getProfilePath(id.toString());
final file = File(path);
final isExists = await file.exists();
if (!isExists) {
await file.create(recursive: true);
if (!isExists && autoCreate) {
return await file.create(recursive: true);
}
return file;
// final oldPath = await appPath.getProfilePath(id);
// final newPath = await appPath.getProfilePath(fileName);
// final oldFile = oldPath == newPath ? null : File(oldPath);
// final oldIsExists = await oldFile?.exists() ?? false;
// if (oldIsExists) {
// return await oldFile!.rename(newPath);
// }
// final file = File(newPath);
// final isExists = await file.exists();
// if (!isExists && autoCreate) {
// return await file.create(recursive: true);
// }
// return file;
}
Future<int> get profileLastModified async {
final file = await getFile();
return (await file.lastModified()).microsecondsSinceEpoch;
Future<File> get file async {
return _getFile();
}
Future<Profile> update() async {
@@ -198,20 +215,35 @@ extension ProfileExtension on Profile {
final disposition = response.headers.value('content-disposition');
final userinfo = response.headers.value('subscription-userinfo');
return await copyWith(
label: label ?? utils.getFileNameForDisposition(disposition) ?? id,
label: label.takeFirstValid([
utils.getFileNameForDisposition(disposition),
id.toString(),
]),
subscriptionInfo: SubscriptionInfo.formHString(userinfo),
).saveFile(response.data ?? Uint8List.fromList([]));
}
Future<Profile> saveFile(Uint8List bytes) async {
final message = await coreController.validateConfigFormBytes(bytes);
final path = await appPath.tempFilePath;
final tempFile = File(path);
await tempFile.safeWriteAsBytes(bytes);
final message = await coreController.validateConfig(path);
if (message.isNotEmpty) {
throw message;
}
final file = await getFile();
await Isolate.run(() async {
return await file.writeAsBytes(bytes);
});
final mFile = await file;
await tempFile.copy(mFile.path);
await tempFile.safeDelete();
return copyWith(lastUpdateDate: DateTime.now());
}
Future<Profile> saveFileWithPath(String path) async {
final message = await coreController.validateConfig(path);
if (message.isNotEmpty) {
throw message;
}
final mFile = await file;
await File(path).copy(mFile.path);
return copyWith(lastUpdateDate: DateTime.now());
}
}

View File

@@ -1,20 +1,27 @@
import 'package:collection/collection.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'generated/selector.freezed.dart';
import 'app.dart';
import 'clash_config.dart';
import 'common.dart';
import 'config.dart';
import 'core.dart';
import 'profile.dart';
part 'generated/state.freezed.dart';
part 'generated/state.g.dart';
@freezed
abstract class VM2<A, B> with _$VM2<A, B> {
const factory VM2({required A a, required B b}) = _VM2;
const factory VM2(A a, B b) = _VM2;
}
@freezed
abstract class VM3<A, B, C> with _$VM3<A, B, C> {
const factory VM3({required A a, required B b, required C c}) = _VM3;
const factory VM3(A a, B b, C c) = _VM3;
}
@freezed
@@ -24,30 +31,81 @@ abstract class VM4<A, B, C, D> with _$VM4<A, B, C, D> {
@freezed
abstract class VM5<A, B, C, D, E> with _$VM5<A, B, C, D, E> {
const factory VM5({
required A a,
required B b,
required C c,
required D d,
required E e,
}) = _VM5;
const factory VM5(A a, B b, C c, D d, E e) = _VM5;
}
@freezed
abstract class StartButtonSelectorState with _$StartButtonSelectorState {
const factory StartButtonSelectorState({
required bool isInit,
required bool hasProfile,
}) = _StartButtonSelectorState;
abstract class ActivateState with _$ActivateState {
const factory ActivateState({required bool active}) = _ActivateState;
}
@freezed
abstract class ProfilesSelectorState with _$ProfilesSelectorState {
const factory ProfilesSelectorState({
abstract class InitState with _$InitState {
const factory InitState({
required Config config,
required List<Profile> profiles,
required String? currentProfileId,
}) = _InitState;
}
@freezed
abstract class CommonMessage with _$CommonMessage {
const factory CommonMessage({
required String id,
required String text,
@Default(Duration(seconds: 3)) Duration duration,
MessageActionState? actionState,
}) = _CommonMessage;
}
@freezed
abstract class MessageActionState with _$MessageActionState {
const factory MessageActionState({
required String actionText,
required VoidCallback action,
}) = _MessageActionState;
}
@freezed
abstract class AppBarState with _$AppBarState {
const factory AppBarState({
@Default([]) List<Widget> actions,
AppBarSearchState? searchState,
AppBarEditState? editState,
}) = _AppBarState;
}
@freezed
abstract class AppBarSearchState with _$AppBarSearchState {
const factory AppBarSearchState({
required Function(String) onSearch,
@Default(true) bool autoAddSearch,
@Default(null) String? query,
}) = _AppBarSearchState;
}
@freezed
abstract class AppBarEditState with _$AppBarEditState {
const factory AppBarEditState({
@Default(0) int editCount,
required Function() onExit,
}) = _AppBarEditState;
}
@freezed
abstract class StartButtonState with _$StartButtonState {
const factory StartButtonState({
required bool isPreload,
required bool hasProfile,
}) = _StartButtonState;
}
@freezed
abstract class ProfilesState with _$ProfilesState {
const factory ProfilesState({
required List<Profile> profiles,
required int? currentProfileId,
required int columns,
}) = _ProfilesSelectorState;
}) = _ProfilesState;
}
@freezed
@@ -149,14 +207,14 @@ abstract class MoreToolsSelectorState with _$MoreToolsSelectorState {
abstract class PackageListSelectorState with _$PackageListSelectorState {
const factory PackageListSelectorState({
required List<Package> packages,
required AccessControl accessControl,
required AccessControlProps accessControlProps,
}) = _PackageListSelectorState;
}
extension PackageListSelectorStateExt on PackageListSelectorState {
List<Package> get list {
final isFilterSystemApp = accessControl.isFilterSystemApp;
final isFilterNonInternetApp = accessControl.isFilterNonInternetApp;
final isFilterSystemApp = accessControlProps.isFilterSystemApp;
final isFilterNonInternetApp = accessControlProps.isFilterNonInternetApp;
return packages
.where(
(item) =>
@@ -167,7 +225,7 @@ extension PackageListSelectorStateExt on PackageListSelectorState {
}
List<Package> getSortList(List<String> selectedList) {
final sort = accessControl.sort;
final sort = accessControlProps.sort;
return list.sorted((a, b) {
final isSelectA = selectedList.contains(a.packageName);
@@ -218,7 +276,6 @@ abstract class ClashConfigState with _$ClashConfigState {
const factory ClashConfigState({
required bool overrideDns,
required ClashConfig clashConfig,
required OverrideData overrideData,
required RouteMode routeMode,
}) = _ClashConfigState;
}
@@ -249,22 +306,70 @@ abstract class VpnState with _$VpnState {
}
@freezed
abstract class ProfileOverrideModel with _$ProfileOverrideModel {
const factory ProfileOverrideModel({
@Default(ClashConfigSnippet()) ClashConfigSnippet snippet,
@Default({}) Set<String> selectedRules,
OverrideData? overrideData,
}) = _ProfileOverrideModel;
abstract class SharedState with _$SharedState {
const factory SharedState({
SetupParams? setupParams,
VpnOptions? vpnOptions,
required String stopTip,
required String startTip,
required String currentProfileName,
required String stopText,
required bool onlyStatisticsProxy,
required bool crashlytics,
}) = _SharedState;
factory SharedState.fromJson(Map<String, Object?> json) =>
_$SharedStateFromJson(json);
}
extension SharedStateExt on SharedState {
SharedState get needSyncSharedState => copyWith(setupParams: null);
}
@freezed
abstract class ComputeGroupsState with _$ComputeGroupsState {
const factory ComputeGroupsState({
required ProxiesData proxiesData,
required ProxiesSortType sortType,
required DelayMap delayMap,
required Map<String, String> selectedMap,
required String defaultTestUrl,
}) = _ComputeGroupsState;
}
@freezed
abstract class MakeRealProfileState with _$MakeRealProfileState {
const factory MakeRealProfileState({
required String profilesPath,
required int profileId,
required Map<String, dynamic> rawConfig,
required ClashConfig realPatchConfig,
required bool overrideDns,
required bool appendSystemDns,
required List<Rule> addedRules,
required String defaultUA,
}) = _MakeRealProfileState;
}
@freezed
abstract class MigrationData with _$MigrationData {
const factory MigrationData({
Map<String, Object?>? configMap,
@Default([]) List<Rule> rules,
@Default([]) List<Script> scripts,
@Default([]) List<Profile> profiles,
@Default([]) List<ProfileRuleLink> links,
}) = _MigrationData;
}
@freezed
abstract class SetupState with _$SetupState {
const factory SetupState({
required String? profileId,
required int? profileId,
required int? profileLastUpdateDate,
required OverwriteType overwriteType,
required List<Rule> addedRules,
required String? scriptContent,
required Script? script,
required bool overrideDns,
required Dns dns,
}) = _SetupState;
@@ -273,7 +378,7 @@ abstract class SetupState with _$SetupState {
extension SetupStateExt on SetupState {
bool needSetup(SetupState? lastSetupState) {
if (lastSetupState == null) {
return true;
return false;
}
if (profileId != lastSetupState.profileId) {
return true;
@@ -281,14 +386,15 @@ extension SetupStateExt on SetupState {
if (profileLastUpdateDate != lastSetupState.profileLastUpdateDate) {
return true;
}
final scriptIsChange = script != lastSetupState.script;
if (overwriteType != lastSetupState.overwriteType) {
if (!ruleListEquality.equals(addedRules, lastSetupState.addedRules) ||
scriptContent != lastSetupState.scriptContent) {
scriptIsChange) {
return true;
}
} else {
if (overwriteType == OverwriteType.script) {
if (scriptContent != lastSetupState.scriptContent) {
if (scriptIsChange) {
return true;
}
}

View File

@@ -1,53 +0,0 @@
import 'package:flutter/widgets.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'generated/widget.freezed.dart';
@freezed
abstract class ActivateState with _$ActivateState {
const factory ActivateState({required bool active}) = _ActivateState;
}
@freezed
abstract class CommonMessage with _$CommonMessage {
const factory CommonMessage({
required String id,
required String text,
@Default(Duration(seconds: 3)) Duration duration,
MessageActionState? actionState,
}) = _CommonMessage;
}
@freezed
abstract class MessageActionState with _$MessageActionState {
const factory MessageActionState({
required String actionText,
required VoidCallback action,
}) = _MessageActionState;
}
@freezed
abstract class AppBarState with _$AppBarState {
const factory AppBarState({
@Default([]) List<Widget> actions,
AppBarSearchState? searchState,
AppBarEditState? editState,
}) = _AppBarState;
}
@freezed
abstract class AppBarSearchState with _$AppBarSearchState {
const factory AppBarSearchState({
required Function(String) onSearch,
@Default(true) bool autoAddSearch,
@Default(null) String? query,
}) = _AppBarSearchState;
}
@freezed
abstract class AppBarEditState with _$AppBarEditState {
const factory AppBarEditState({
@Default(0) int editCount,
required Function() onExit,
}) = _AppBarEditState;
}

View File

@@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/common.dart';
@@ -125,7 +127,7 @@ class _EditorPageState extends ConsumerState<EditorPage> {
if (file == null) {
return;
}
final res = String.fromCharCodes(file.bytes?.toList() ?? []);
final res = utf8.decode(file.bytes?.toList() ?? []);
_controller.text = res;
}

121
lib/pages/error.dart Normal file
View File

@@ -0,0 +1,121 @@
import 'package:fl_clash/common/color.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class InitErrorScreen extends StatelessWidget {
final Object error;
final StackTrace stack;
const InitErrorScreen({super.key, required this.error, required this.stack});
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Scaffold(
appBar: AppBar(
title: const Text('Init Failed'),
backgroundColor: colorScheme.error,
foregroundColor: colorScheme.onError,
elevation: 0,
),
body: SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
Icons.report_problem,
color: colorScheme.error,
size: 32,
),
const SizedBox(width: 12),
const Expanded(
child: Text(
'The application encountered a critical error during startup and cannot continue.',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
],
),
const SizedBox(height: 24),
_buildSectionLabel('Error Details:'),
Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: colorScheme.errorContainer.opacity50,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: colorScheme.error.opacity50),
),
child: SelectableText(
error.toString(),
style: TextStyle(
color: colorScheme.onErrorContainer,
fontWeight: FontWeight.w600,
),
),
),
const SizedBox(height: 24),
_buildSectionLabel('Stack Trace:'),
Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Theme.of(context).brightness == Brightness.dark
? Colors.grey[900]
: Colors.grey[200],
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey.opacity50),
),
child: SelectableText(
stack.toString(),
style: const TextStyle(
fontFamily: 'monospace', // Makes code easier to read
fontSize: 12,
),
),
),
const SizedBox(height: 80),
],
),
),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () => _copyToClipboard(context),
label: const Text('Copy Details'),
icon: const Icon(Icons.copy),
backgroundColor: colorScheme.error,
foregroundColor: colorScheme.onError,
),
);
}
Widget _buildSectionLabel(String text) {
return Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
text,
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
);
}
void _copyToClipboard(BuildContext context) {
final text = '=== ERROR ===\n$error\n\n=== STACK TRACE ===\n$stack';
Clipboard.setData(ClipboardData(text: text));
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Error details copied to clipboard'),
duration: Duration(seconds: 2),
),
);
}
}

View File

@@ -1,8 +1,9 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/manager/app_manager.dart';
import 'package:fl_clash/models/common.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -21,26 +22,13 @@ class HomePage extends StatelessWidget {
child: Material(
color: context.colorScheme.surface,
child: Consumer(
builder: (context, ref, _) {
builder: (context, ref, child) {
final state = ref.watch(navigationStateProvider);
final systemUiOverlayStyle = ref.read(
systemUiOverlayStyleStateProvider,
);
final isMobile = state.viewMode == ViewMode.mobile;
final navigationItems = state.navigationItems;
final pageView = _HomePageView(
pageBuilder: (_, index) {
final navigationItem = state.navigationItems[index];
final navigationView = navigationItem.builder(context);
final view = KeepScope(
keep: navigationItem.keep,
child: isMobile
? navigationView
: Navigator(
pages: [MaterialPage(child: navigationView)],
onDidRemovePage: (_) {},
),
);
return view;
},
);
final currentIndex = state.currentIndex;
final bottomNavigationBar = NavigationBarTheme(
data: _NavigationBarDefaultsM3(context),
@@ -54,16 +42,14 @@ class HomePage extends StatelessWidget {
)
.toList(),
onDestinationSelected: (index) {
globalState.appController.toPage(
navigationItems[index].label,
);
appController.toPage(navigationItems[index].label);
},
selectedIndex: currentIndex,
),
);
if (isMobile) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: globalState.appState.systemUiOverlayStyle.copyWith(
value: systemUiOverlayStyle.copyWith(
systemNavigationBarColor:
context.colorScheme.surfaceContainer,
),
@@ -77,7 +63,7 @@ class HomePage extends StatelessWidget {
removeLeft: true,
removeRight: true,
context: context,
child: pageView,
child: child!,
),
),
MediaQuery.removePadding(
@@ -92,9 +78,34 @@ class HomePage extends StatelessWidget {
),
);
} else {
return pageView;
return child!;
}
},
child: Consumer(
builder: (_, ref, _) {
final navigationItems = ref
.watch(currentNavigationItemsStateProvider)
.value;
final isMobile = ref.watch(isMobileViewProvider);
return _HomePageView(
navigationItems: navigationItems,
pageBuilder: (_, index) {
final navigationItem = navigationItems[index];
final navigationView = navigationItem.builder(context);
final view = KeepScope(
keep: navigationItem.keep,
child: isMobile
? navigationView
: Navigator(
pages: [MaterialPage(child: navigationView)],
onDidRemovePage: (_) {},
),
);
return view;
},
);
},
),
),
),
),
@@ -104,8 +115,12 @@ class HomePage extends StatelessWidget {
class _HomePageView extends ConsumerStatefulWidget {
final IndexedWidgetBuilder pageBuilder;
final List<NavigationItem> navigationItems;
const _HomePageView({required this.pageBuilder});
const _HomePageView({
required this.pageBuilder,
required this.navigationItems,
});
@override
ConsumerState createState() => _HomePageViewState();
@@ -123,18 +138,19 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
_toPage(next);
}
});
ref.listenManual(currentNavigationItemsStateProvider, (prev, next) {
if (prev?.value.length != next.value.length) {
_updatePageController();
}
});
}
@override
void didUpdateWidget(covariant _HomePageView oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.navigationItems.length != widget.navigationItems.length) {
_updatePageController();
}
}
int get _pageIndex {
final navigationItems = ref.read(currentNavigationItemsStateProvider).value;
return navigationItems.indexWhere(
(item) => item.label == globalState.appState.pageLabel,
);
final pageLabel = ref.read(currentPageLabelProvider);
return widget.navigationItems.indexWhere((item) => item.label == pageLabel);
}
Future<void> _toPage(
@@ -144,8 +160,9 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
if (!mounted) {
return;
}
final navigationItems = ref.read(currentNavigationItemsStateProvider).value;
final index = navigationItems.indexWhere((item) => item.label == pageLabel);
final index = widget.navigationItems.indexWhere(
(item) => item.label == pageLabel,
);
if (index == -1) {
return;
}
@@ -163,7 +180,7 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
}
void _updatePageController() {
final pageLabel = globalState.appState.pageLabel;
final pageLabel = ref.read(currentPageLabelProvider);
_toPage(pageLabel, true);
}
@@ -262,7 +279,7 @@ class HomeBackScopeContainer extends ConsumerWidget {
if (canPop) {
Navigator.of(realContext).pop();
} else {
await globalState.appController.handleBackOrExit();
await appController.handleBackOrExit();
}
return false;
},

View File

@@ -1,3 +1,4 @@
export 'editor.dart';
export 'error.dart';
export 'home.dart';
export 'scan.dart';
export 'editor.dart';

View File

@@ -2,7 +2,7 @@ import 'dart:async';
import 'dart:math';
import 'package:fl_clash/common/color.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/widgets/activate_box.dart';
import 'package:flutter/material.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
@@ -139,7 +139,7 @@ class _ScanPageState extends State<ScanPage> with WidgetsBindingObserver {
),
padding: const EdgeInsets.all(16),
iconSize: 32.0,
onPressed: globalState.appController.addProfileFormQrCode,
onPressed: appController.addProfileFormQrCode,
icon: const Icon(Icons.photo_camera_back),
),
),

View File

@@ -1,11 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'package:fl_clash/common/app_localizations.dart';
import 'package:fl_clash/common/constant.dart';
import 'package:fl_clash/common/system.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/models/models.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -42,24 +38,18 @@ class App {
final packagesString = await methodChannel.invokeMethod<String>(
'getPackages',
);
return Isolate.run<List<Package>>(() {
final List<dynamic> packagesRaw = packagesString != null
? json.decode(packagesString)
: [];
return packagesRaw.map((e) => Package.fromJson(e)).toSet().toList();
});
List<dynamic> packagesRaw =
(await packagesString?.commonToJSON<List<dynamic>>()) ?? [];
return packagesRaw.map((e) => Package.fromJson(e)).toSet().toList();
}
Future<List<String>> getChinaPackageNames() async {
final packageNamesString = await methodChannel.invokeMethod<String>(
'getChinaPackageNames',
);
return Isolate.run<List<String>>(() {
final List<dynamic> packageNamesRaw = packageNamesString != null
? json.decode(packageNamesString)
: [];
return packageNamesRaw.map((e) => e.toString()).toList();
});
List<dynamic> packageNamesRaw =
await packageNamesString?.commonToJSON<List<dynamic>>() ?? [];
return packageNamesRaw.map((e) => e.toString()).toList();
}
Future<bool?> requestNotificationsPermission() async {

View File

@@ -2,11 +2,8 @@ import 'dart:async';
import 'dart:convert';
import 'dart:isolate';
import 'package:fl_clash/common/constant.dart';
import 'package:fl_clash/common/system.dart';
import 'package:fl_clash/models/common.dart';
import 'package:fl_clash/models/core.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/models/models.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
@@ -33,8 +30,6 @@ class Service {
methodChannel = const MethodChannel('$packageName/service');
methodChannel.setMethodCallHandler((call) async {
switch (call.method) {
case 'getVpnOptions':
return handleGetVpnOptions();
case 'event':
final data = call.arguments as String? ?? '';
final result = ActionResult.fromJson(json.decode(data));
@@ -62,11 +57,8 @@ class Service {
if (data == null) {
return null;
}
return ActionResult.fromJson(json.decode(data));
}
String handleGetVpnOptions() {
return json.encode(globalState.getVpnOptions());
final dataJson = await data.commonToJSON<dynamic>();
return ActionResult.fromJson(dataJson);
}
Future<bool> start() async {
@@ -77,7 +69,11 @@ class Service {
return await methodChannel.invokeMethod<bool>('stop') ?? false;
}
Future<String> syncAndroidState(AndroidState state) async {
Future<String> init() async {
return await methodChannel.invokeMethod<String>('init') ?? '';
}
Future<String> syncState(SharedState state) async {
return await methodChannel.invokeMethod<String>(
'syncState',
json.encode(state),
@@ -85,14 +81,6 @@ class Service {
'';
}
Future<String> init() async {
return await methodChannel.invokeMethod<String>(
'init',
!globalState.isService,
) ??
'';
}
Future<bool> shutdown() async {
return await methodChannel.invokeMethod<bool>('shutdown') ?? true;
}

View File

@@ -1,9 +1,10 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:flutter/services.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -13,42 +14,27 @@ part 'generated/app.g.dart';
class RealTunEnable extends _$RealTunEnable with AutoDisposeNotifierMixin {
@override
bool build() {
return globalState.appState.realTunEnable;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(realTunEnable: value);
return false;
}
}
@riverpod
@Riverpod(keepAlive: true)
class Logs extends _$Logs with AutoDisposeNotifierMixin {
@override
FixedList<Log> build() {
return globalState.appState.logs;
return FixedList(0);
}
void addLog(Log value) {
this.value = state.copyWith()..add(value);
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(logs: value);
}
}
@riverpod
@Riverpod(keepAlive: true)
class Requests extends _$Requests with AutoDisposeNotifierMixin {
@override
FixedList<TrackerInfo> build() {
return globalState.appState.requests;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(requests: value);
return FixedList(0);
}
void addRequest(TrackerInfo value) {
@@ -56,25 +42,14 @@ class Requests extends _$Requests with AutoDisposeNotifierMixin {
}
}
@riverpod
class Providers extends _$Providers with AnyNotifierMixin {
@override
List<ExternalProvider> get value => globalState.appState.providers;
@Riverpod(keepAlive: true)
class Providers extends _$Providers with AutoDisposeNotifierMixin {
@override
List<ExternalProvider> build() {
return globalState.appState.providers;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(providers: value);
return [];
}
void setProvider(ExternalProvider? provider) {
if (!ref.mounted) {
return;
}
if (provider == null) return;
final index = value.indexWhere((item) => item.name == provider.name);
if (index == -1) return;
@@ -83,47 +58,28 @@ class Providers extends _$Providers with AnyNotifierMixin {
}
}
@riverpod
@Riverpod(keepAlive: true)
class Packages extends _$Packages with AutoDisposeNotifierMixin {
@override
List<Package> build() {
return globalState.appState.packages;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(packages: value);
return [];
}
}
@riverpod
@Riverpod(keepAlive: true)
class SystemBrightness extends _$SystemBrightness
with AutoDisposeNotifierMixin {
@override
Brightness build() {
return globalState.appState.brightness;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(brightness: value);
}
void setState(Brightness value) {
this.value = value;
return Brightness.dark;
}
}
@riverpod
@Riverpod(keepAlive: true)
class Traffics extends _$Traffics with AutoDisposeNotifierMixin {
@override
FixedList<Traffic> build() {
return globalState.appState.traffics;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(traffics: value);
return FixedList(0);
}
void addTraffic(Traffic value) {
@@ -135,169 +91,179 @@ class Traffics extends _$Traffics with AutoDisposeNotifierMixin {
}
}
@riverpod
@Riverpod(keepAlive: true)
class TotalTraffic extends _$TotalTraffic with AutoDisposeNotifierMixin {
@override
Traffic build() {
return globalState.appState.totalTraffic;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(totalTraffic: value);
return Traffic();
}
}
@riverpod
@Riverpod(keepAlive: true)
class LocalIp extends _$LocalIp with AutoDisposeNotifierMixin {
@override
String? build() {
return globalState.appState.localIp;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(localIp: value);
return null;
}
}
@riverpod
@Riverpod(keepAlive: true)
class RunTime extends _$RunTime with AutoDisposeNotifierMixin {
@override
int? build() {
return globalState.appState.runTime;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(runTime: value);
return null;
}
}
@riverpod
@Riverpod(keepAlive: true)
class ViewSize extends _$ViewSize with AutoDisposeNotifierMixin {
@override
Size build() {
return globalState.appState.viewSize;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(viewSize: value);
return Size.zero;
}
}
@riverpod
@Riverpod(keepAlive: true)
class SideWidth extends _$SideWidth with AutoDisposeNotifierMixin {
@override
double build() {
return globalState.appState.sideWidth;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(sideWidth: value);
return 0;
}
}
@riverpod
@Riverpod(keepAlive: true)
double viewWidth(Ref ref) {
return ref.watch(viewSizeProvider).width;
}
@riverpod
@Riverpod(keepAlive: true)
ViewMode viewMode(Ref ref) {
return utils.getViewMode(ref.watch(viewWidthProvider));
}
@riverpod
@Riverpod(keepAlive: true)
bool isMobileView(Ref ref) {
return ref.watch(viewModeProvider) == ViewMode.mobile;
}
@riverpod
@Riverpod(keepAlive: true)
double viewHeight(Ref ref) {
return ref.watch(viewSizeProvider).height;
}
@riverpod
@Riverpod(keepAlive: true)
class Init extends _$Init with AutoDisposeNotifierMixin {
@override
bool build() {
return globalState.appState.isInit;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(isInit: value);
return false;
}
}
@riverpod
@Riverpod(keepAlive: true)
class CurrentPageLabel extends _$CurrentPageLabel
with AutoDisposeNotifierMixin {
@override
PageLabel build() {
return globalState.appState.pageLabel;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(pageLabel: value);
return PageLabel.dashboard;
}
}
@riverpod
@Riverpod(keepAlive: true)
class SortNum extends _$SortNum with AutoDisposeNotifierMixin {
@override
int build() {
return globalState.appState.sortNum;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(sortNum: value);
return 0;
}
int add() => state++;
}
@riverpod
@Riverpod(keepAlive: true)
class CheckIpNum extends _$CheckIpNum with AutoDisposeNotifierMixin {
@override
int build() {
return globalState.appState.checkIpNum;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(checkIpNum: value);
return 0;
}
int add() => state++;
}
@riverpod
@Riverpod(keepAlive: true)
class BackBlock extends _$BackBlock with AutoDisposeNotifierMixin {
@override
bool build() {
return globalState.appState.backBlock;
return false;
}
}
@Riverpod(keepAlive: true)
class Version extends _$Version with AutoDisposeNotifierMixin {
@override
int build() {
return 0;
}
}
@Riverpod(keepAlive: true)
class Groups extends _$Groups with AutoDisposeNotifierMixin {
@override
List<Group> build() {
return [];
}
}
@Riverpod(keepAlive: true)
class DelayDataSource extends _$DelayDataSource with AutoDisposeNotifierMixin {
@override
DelayMap build() {
return {};
}
void setDelay(Delay delay) {
if (state[delay.url]?[delay.name] != delay.value) {
final DelayMap newDelayMap = Map.from(state);
if (newDelayMap[delay.url] == null) {
newDelayMap[delay.url] = {};
}
newDelayMap[delay.url]![delay.name] = delay.value;
value = newDelayMap;
}
}
}
@Riverpod(keepAlive: true)
class SystemUiOverlayStyleState extends _$SystemUiOverlayStyleState
with AutoDisposeNotifierMixin {
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(backBlock: value);
SystemUiOverlayStyle build() {
return SystemUiOverlayStyle();
}
}
@Riverpod(name: 'coreStatusProvider', keepAlive: true)
class _CoreStatus extends _$CoreStatus with AutoDisposeNotifierMixin {
@override
CoreStatus build() {
return CoreStatus.disconnected;
}
}
@riverpod
class Query extends _$Query with AutoDisposeNotifierMixin {
@override
String build(QueryTag tag) {
return '';
}
}
@Riverpod(keepAlive: true)
class Loading extends _$Loading with AutoDisposeNotifierMixin {
DateTime? _start;
Timer? _timer;
@override
bool build() {
return globalState.appState.loading;
bool build(LoadingTag tag) {
return false;
}
void start() {
@@ -326,176 +292,106 @@ class Loading extends _$Loading with AutoDisposeNotifierMixin {
value = false;
});
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(loading: value);
}
}
@riverpod
class Version extends _$Version with AutoDisposeNotifierMixin {
@override
int build() {
return globalState.appState.version;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(version: value);
}
}
@riverpod
class Groups extends _$Groups with AutoDisposeNotifierMixin {
@override
List<Group> build() {
return globalState.appState.groups;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(groups: value);
}
}
@riverpod
class DelayDataSource extends _$DelayDataSource with AutoDisposeNotifierMixin {
@override
DelayMap build() {
return globalState.appState.delayMap;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(delayMap: value);
}
void setDelay(Delay delay) {
if (state[delay.url]?[delay.name] != delay.value) {
final DelayMap newDelayMap = Map.from(state);
if (newDelayMap[delay.url] == null) {
newDelayMap[delay.url] = {};
}
newDelayMap[delay.url]![delay.name] = delay.value;
value = newDelayMap;
}
}
}
@riverpod
class SystemUiOverlayStyleState extends _$SystemUiOverlayStyleState
with AutoDisposeNotifierMixin {
@override
SystemUiOverlayStyle build() {
return globalState.appState.systemUiOverlayStyle;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(
systemUiOverlayStyle: value,
);
}
}
@riverpod
class ProfileOverrideState extends _$ProfileOverrideState
with AutoDisposeNotifierMixin {
@override
ProfileOverrideModel? build() {
return globalState.appState.profileOverrideModel;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(
profileOverrideModel: value,
);
}
void updateState(
ProfileOverrideModel? Function(ProfileOverrideModel? state) builder,
) {
final value = builder(state);
if (value == null) {
return;
}
this.value = value;
}
}
@Riverpod(name: 'coreStatusProvider')
class _CoreStatus extends _$CoreStatus with AutoDisposeNotifierMixin {
@override
CoreStatus build() {
return globalState.appState.coreStatus;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(coreStatus: value);
}
}
@riverpod
class Query extends _$Query with AutoDisposeNotifierMixin {
late final QueryTag _tag;
@override
String build(QueryTag tag) {
_tag = tag;
return globalState.appState.queryMap[tag] ?? '';
}
@override
onUpdate(value) {
final newMap = Map<QueryTag, String>.from(globalState.appState.queryMap)
..[_tag] = value;
globalState.appState = globalState.appState.copyWith(queryMap: newMap);
}
}
@riverpod
class SelectedItems extends _$SelectedItems with AutoDisposeNotifierMixin {
late final String _key;
@override
Set<String> build(String key) {
_key = key;
return globalState.appState.selectedItemsMap[_key] ?? {};
}
@override
onUpdate(value) {
final newMap = globalState.appState.selectedItemsMap.copyWitUpdate(
key,
value.isEmpty ? null : value,
);
globalState.appState = globalState.appState.copyWith(
selectedItemsMap: newMap,
);
Set<dynamic> build(String key) {
return {};
}
}
@riverpod
class SelectedItem extends _$SelectedItem with AutoDisposeNotifierMixin {
late final String _key;
@override
String build(String key) {
_key = key;
return globalState.appState.selectedItemMap[_key] ?? '';
}
@override
onUpdate(value) {
final newMap = globalState.appState.selectedItemMap.copyWitUpdate(
key,
value.isEmpty ? null : value,
);
globalState.appState = globalState.appState.copyWith(
selectedItemMap: newMap,
);
dynamic build(String key) {
return null;
}
}
@riverpod
class IsUpdating extends _$IsUpdating with AutoDisposeNotifierMixin {
@override
bool build(String name) {
return false;
}
}
@Riverpod(keepAlive: true)
class NetworkDetection extends _$NetworkDetection
with AutoDisposeNotifierMixin {
bool? _preIsStart;
CancelToken? _cancelToken;
int _startMillisecondsEpoch = 0;
@override
NetworkDetectionState build() {
return NetworkDetectionState(isLoading: true, ipInfo: null);
}
void startCheck() {
debouncer.call(FunctionTag.checkIp, () {
_checkIp();
}, duration: commonDuration);
}
Future<void> _checkIp() async {
final isInit = ref.read(initProvider);
if (!isInit) {
return;
}
final isStart = ref.read(isStartProvider);
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');
state = state.copyWith(isLoading: true, ipInfo: null);
_preIsStart = isStart;
final res = await request.checkIp(cancelToken: _cancelToken);
commonPrint.log('checkIp res: $res');
if (res.isError && runTime > _startMillisecondsEpoch) {
state = state.copyWith(isLoading: true, ipInfo: null);
return;
}
final ipInfo = res.data;
if (ipInfo == null) {
return;
}
state = state.copyWith(isLoading: false, ipInfo: ipInfo);
}
}
List<Override> buildAppStateOverrides(AppState appState) {
return [
initProvider.overrideWithBuild((_, _) => appState.isInit),
backBlockProvider.overrideWithBuild((_, _) => appState.backBlock),
currentPageLabelProvider.overrideWithBuild((_, _) => appState.pageLabel),
packagesProvider.overrideWithBuild((_, _) => appState.packages),
sortNumProvider.overrideWithBuild((_, _) => appState.sortNum),
viewSizeProvider.overrideWithBuild((_, _) => appState.viewSize),
sideWidthProvider.overrideWithBuild((_, _) => appState.sideWidth),
delayDataSourceProvider.overrideWithBuild((_, _) => appState.delayMap),
groupsProvider.overrideWithBuild((_, _) => appState.groups),
checkIpNumProvider.overrideWithBuild((_, _) => appState.checkIpNum),
systemBrightnessProvider.overrideWithBuild((_, _) => appState.brightness),
runTimeProvider.overrideWithBuild((_, _) => appState.runTime),
providersProvider.overrideWithBuild((_, _) => appState.providers),
localIpProvider.overrideWithBuild((_, _) => appState.localIp),
requestsProvider.overrideWithBuild((_, _) => appState.requests),
versionProvider.overrideWithBuild((_, _) => appState.version),
logsProvider.overrideWithBuild((_, _) => appState.logs),
trafficsProvider.overrideWithBuild((_, _) => appState.traffics),
totalTrafficProvider.overrideWithBuild((_, _) => appState.totalTraffic),
realTunEnableProvider.overrideWithBuild((_, _) => appState.realTunEnable),
systemUiOverlayStyleStateProvider.overrideWithBuild(
(_, _) => appState.systemUiOverlayStyle,
),
coreStatusProvider.overrideWithBuild((_, _) => appState.coreStatus),
];
}

View File

@@ -1,6 +1,5 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/state.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'generated/config.g.dart';
@@ -9,46 +8,25 @@ part 'generated/config.g.dart';
class AppSetting extends _$AppSetting with AutoDisposeNotifierMixin {
@override
AppSettingProps build() {
return globalState.config.appSetting;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(appSetting: value);
}
void updateState(AppSettingProps Function(AppSettingProps state) builder) {
value = builder(state);
return AppSettingProps();
}
}
@riverpod
@Riverpod(keepAlive: true)
class WindowSetting extends _$WindowSetting with AutoDisposeNotifierMixin {
@override
WindowProps build() {
return globalState.config.windowProps;
return WindowProps();
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(windowProps: value);
}
void updateState(WindowProps Function(WindowProps state) builder) {
value = builder(state);
}
void hello() {}
}
@riverpod
class VpnSetting extends _$VpnSetting with AutoDisposeNotifierMixin {
@override
VpnProps build() {
return globalState.config.vpnProps;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(vpnProps: value);
return VpnProps();
}
}
@@ -56,16 +34,7 @@ class VpnSetting extends _$VpnSetting with AutoDisposeNotifierMixin {
class NetworkSetting extends _$NetworkSetting with AutoDisposeNotifierMixin {
@override
NetworkProps build() {
return globalState.config.networkProps;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(networkProps: value);
}
void updateState(NetworkProps Function(NetworkProps state) builder) {
value = builder(state);
return NetworkProps();
}
}
@@ -73,75 +42,7 @@ class NetworkSetting extends _$NetworkSetting with AutoDisposeNotifierMixin {
class ThemeSetting extends _$ThemeSetting with AutoDisposeNotifierMixin {
@override
ThemeProps build() {
return globalState.config.themeProps;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(themeProps: value);
}
void updateState(ThemeProps Function(ThemeProps state) builder) {
value = builder(state);
}
}
@riverpod
class Profiles extends _$Profiles with AutoDisposeNotifierMixin {
@override
List<Profile> build() {
return globalState.config.profiles;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(profiles: value);
}
String? _getLabel(String? label, String id) {
final realLabel = label ?? id;
final hasDup =
state.indexWhere(
(element) => element.label == realLabel && element.id != id,
) !=
-1;
if (hasDup) {
return _getLabel(utils.getOverwriteLabel(realLabel), id);
} else {
return label;
}
}
void setProfile(Profile profile) {
final List<Profile> profilesTemp = List.from(state);
final index = profilesTemp.indexWhere(
(element) => element.id == profile.id,
);
final updateProfile = profile.copyWith(
label: _getLabel(profile.label, profile.id),
);
if (index == -1) {
profilesTemp.add(updateProfile);
} else {
profilesTemp[index] = updateProfile;
}
value = profilesTemp;
}
void updateProfile(
String profileId,
Profile Function(Profile profile) builder,
) {
final List<Profile> profilesTemp = List.from(state);
final index = profilesTemp.indexWhere((element) => element.id == profileId);
if (index != -1) {
profilesTemp[index] = builder(profilesTemp[index]);
}
value = profilesTemp;
}
void deleteProfileById(String id) {
value = state.where((element) => element.id != id).toList();
return ThemeProps();
}
}
@@ -149,30 +50,16 @@ class Profiles extends _$Profiles with AutoDisposeNotifierMixin {
class CurrentProfileId extends _$CurrentProfileId
with AutoDisposeNotifierMixin {
@override
String? build() {
return globalState.config.currentProfileId;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(currentProfileId: value);
int? build() {
return null;
}
}
@riverpod
class AppDAVSetting extends _$AppDAVSetting with AutoDisposeNotifierMixin {
class DavSetting extends _$DavSetting with AutoDisposeNotifierMixin {
@override
DAV? build() {
return globalState.config.dav;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(dav: value);
}
void updateState(DAV? Function(DAV? state) builder) {
value = builder(state);
DAVProps? build() {
return null;
}
}
@@ -180,12 +67,7 @@ class AppDAVSetting extends _$AppDAVSetting with AutoDisposeNotifierMixin {
class OverrideDns extends _$OverrideDns with AutoDisposeNotifierMixin {
@override
bool build() {
return globalState.config.overrideDns;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(overrideDns: value);
return false;
}
}
@@ -193,12 +75,7 @@ class OverrideDns extends _$OverrideDns with AutoDisposeNotifierMixin {
class HotKeyActions extends _$HotKeyActions with AutoDisposeNotifierMixin {
@override
List<HotKeyAction> build() {
return globalState.config.hotKeyActions;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(hotKeyActions: value);
return [];
}
}
@@ -206,67 +83,8 @@ class HotKeyActions extends _$HotKeyActions with AutoDisposeNotifierMixin {
class ProxiesStyleSetting extends _$ProxiesStyleSetting
with AutoDisposeNotifierMixin {
@override
ProxiesStyle build() {
return globalState.config.proxiesStyle;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(proxiesStyle: value);
}
void updateState(ProxiesStyle Function(ProxiesStyle state) builder) {
value = builder(state);
}
}
@riverpod
class Scripts extends _$Scripts with AutoDisposeNotifierMixin {
@override
List<Script> build() {
return globalState.config.scripts;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(scripts: value);
}
void setScript(Script script) {
final list = List<Script>.from(state);
final index = list.indexWhere((item) => item.id == script.id);
if (index != -1) {
list[index] = script;
} else {
list.add(script);
}
value = list;
}
void del(String id) {
final list = List<Script>.from(state);
final index = list.indexWhere((item) => item.id == id);
if (index != -1) {
list.removeAt(index);
}
state = list;
}
bool isExits(String label) {
return state.indexWhere((item) => item.label == label) != -1;
}
}
@riverpod
class Rules extends _$Rules with AutoDisposeNotifierMixin {
@override
List<Rule> build() {
return globalState.config.rules;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(rules: value);
ProxiesStyleProps build() {
return ProxiesStyleProps();
}
}
@@ -275,19 +93,56 @@ class PatchClashConfig extends _$PatchClashConfig
with AutoDisposeNotifierMixin {
@override
ClashConfig build() {
return globalState.config.patchClashConfig;
}
void updateState(ClashConfig? Function(ClashConfig state) builder) {
final newState = builder(state);
if (newState == null) {
return;
}
value = newState;
}
@override
onUpdate(value) {
globalState.config = globalState.config.copyWith(patchClashConfig: value);
return ClashConfig();
}
}
@Riverpod(name: 'configProvider')
Config _config(Ref ref) {
final appSettingProps = ref.watch(appSettingProvider);
final windowProps = ref.watch(windowSettingProvider);
final vpnProps = ref.watch(vpnSettingProvider);
final networkProps = ref.watch(networkSettingProvider);
final themeProps = ref.watch(themeSettingProvider);
final currentProfileId = ref.watch(currentProfileIdProvider);
final davProps = ref.watch(davSettingProvider);
final overrideDns = ref.watch(overrideDnsProvider);
final hotKeyActions = ref.watch(hotKeyActionsProvider);
final proxiesStyleProps = ref.watch(proxiesStyleSettingProvider);
final patchClashConfig = ref.watch(patchClashConfigProvider);
return Config(
appSettingProps: appSettingProps,
windowProps: windowProps,
vpnProps: vpnProps,
networkProps: networkProps,
themeProps: themeProps,
currentProfileId: currentProfileId,
davProps: davProps,
overrideDns: overrideDns,
hotKeyActions: hotKeyActions,
proxiesStyleProps: proxiesStyleProps,
patchClashConfig: patchClashConfig,
);
}
List<Override> buildConfigOverrides(Config config) {
return [
appSettingProvider.overrideWithBuild((_, _) => config.appSettingProps),
windowSettingProvider.overrideWithBuild((_, _) => config.windowProps),
vpnSettingProvider.overrideWithBuild((_, _) => config.vpnProps),
networkSettingProvider.overrideWithBuild((_, _) => config.networkProps),
themeSettingProvider.overrideWithBuild((_, _) => config.themeProps),
currentProfileIdProvider.overrideWithBuild(
(_, _) => config.currentProfileId,
),
davSettingProvider.overrideWithBuild((_, _) => config.davProps),
overrideDnsProvider.overrideWithBuild((_, _) => config.overrideDns),
hotKeyActionsProvider.overrideWithBuild((_, _) => config.hotKeyActions),
proxiesStyleSettingProvider.overrideWithBuild(
(_, _) => config.proxiesStyleProps,
),
patchClashConfigProvider.overrideWithBuild(
(_, _) => config.patchClashConfig,
),
];
}

250
lib/providers/database.dart Normal file
View File

@@ -0,0 +1,250 @@
import 'package:collection/collection.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/database/database.dart';
import 'package:fl_clash/models/models.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'generated/database.g.dart';
@riverpod
Stream<List<Profile>> profilesStream(Ref ref) {
return database.profilesDao.all().watch();
}
@riverpod
Stream<List<Rule>> addedRuleStream(Ref ref, int profileId) {
return database.rulesDao.allAddedRules(profileId).watch();
}
@Riverpod(keepAlive: true)
class Profiles extends _$Profiles {
@override
List<Profile> build() {
return ref.watch(profilesStreamProvider).value ?? [];
}
void put(Profile profile) {
final vm2 = state.copyAndAddProfile(profile);
final nextProfiles = vm2.a;
final newProfile = vm2.b;
state = nextProfiles;
database.profiles.put(newProfile.toCompanion());
}
void del(int id) {
final newProfiles = state.where((element) => element.id != id).toList();
state = newProfiles;
database.profiles.remove((t) => t.id.equals(id));
}
void updateProfile(int profileId, Profile Function(Profile profile) builder) {
final index = state.indexWhere((element) => element.id == profileId);
if (index == -1) {
return;
}
final List<Profile> profilesTemp = List.from(state);
final newProfile = builder(profilesTemp[index]);
profilesTemp[index] = newProfile;
state = profilesTemp;
database.profiles.put(newProfile.toCompanion());
}
void setAndReorder(List<Profile> profiles) {
final newProfiles = List<Profile>.from(profiles);
state = newProfiles;
database.profilesDao.setAll(profiles);
}
void reorder(List<Profile> profiles) {
final newProfiles = List<Profile>.from(profiles);
state = newProfiles;
final List<ProfilesCompanion> needUpdateProfiles = [];
newProfiles.forEachIndexed((index, item) {
if (item.order != index) {
needUpdateProfiles.add(item.toCompanion(index));
}
});
database.profilesDao.putAll(needUpdateProfiles);
}
@override
bool updateShouldNotify(List<Profile> previous, List<Profile> next) {
return !profileListEquality.equals(previous, next);
}
}
@riverpod
class Scripts extends _$Scripts with AsyncNotifierMixin {
@override
Stream<List<Script>> build() {
return database.scriptsDao.all().watch();
}
@override
List<Script> get value => state.value ?? [];
void put(Script script) {
final list = List<Script>.from(value);
final index = value.indexWhere((item) => item.id == script.id);
if (index != -1) {
list[index] = script;
} else {
list.add(script);
}
value = list;
database.scripts.put(script.toCompanion());
}
void del(int id) {
final index = value.indexWhere((item) => item.id == id);
if (index == -1) {
return;
}
final list = List<Script>.from(value);
list.removeAt(index);
value = list;
database.scripts.remove((t) => t.id.equals(id));
}
bool isExits(String label) {
return value.indexWhere((item) => item.label == label) != -1;
}
@override
bool updateShouldNotify(
AsyncValue<List<Script>> previous,
AsyncValue<List<Script>> next,
) {
return !scriptListEquality.equals(previous.value, next.value);
}
}
@riverpod
class GlobalRules extends _$GlobalRules with AsyncNotifierMixin {
@override
Stream<List<Rule>> build() {
return database.rulesDao.allGlobalAddedRules().watch();
}
@override
List<Rule> get value => state.value ?? [];
@override
bool updateShouldNotify(
AsyncValue<List<Rule>> previous,
AsyncValue<List<Rule>> next,
) {
return !ruleListEquality.equals(previous.value, next.value);
}
void delAll(Iterable<int> ruleIds) {
value = List<Rule>.from(value.where((item) => !ruleIds.contains(item.id)));
database.rulesDao.delRules(ruleIds);
}
void put(Rule rule) {
value = value.copyAndPut(rule);
database.rulesDao.putGlobalRule(rule);
}
void order(int oldIndex, int newIndex) {
int insertIndex = newIndex;
if (oldIndex < newIndex) {
insertIndex -= 1;
}
final nextItems = List<Rule>.from(value);
final item = nextItems.removeAt(oldIndex);
nextItems.insert(insertIndex, item);
value = nextItems;
final preOrder = nextItems.safeGet(insertIndex - 1)?.order;
final nextOrder = nextItems.safeGet(insertIndex + 1)?.order;
final newOrder = indexing.generateKeyBetween(nextOrder, preOrder)!;
database.rulesDao.orderGlobalRule(ruleId: item.id, order: newOrder);
}
}
@riverpod
class ProfileAddedRules extends _$ProfileAddedRules with AsyncNotifierMixin {
@override
Stream<List<Rule>> build(int profileId) {
return database.rulesDao.allProfileAddedRules(profileId).watch();
}
@override
List<Rule> get value => state.value ?? [];
@override
bool updateShouldNotify(
AsyncValue<List<Rule>> previous,
AsyncValue<List<Rule>> next,
) {
return !ruleListEquality.equals(previous.value, next.value);
}
void put(Rule rule) {
value = value.copyAndPut(rule);
database.rulesDao.putProfileAddedRule(profileId, rule);
}
void delAll(Iterable<int> ruleIds) {
value = List<Rule>.from(value.where((item) => !ruleIds.contains(item.id)));
database.rulesDao.delRules(ruleIds);
}
void order(int oldIndex, int newIndex) {
int insertIndex = newIndex;
if (oldIndex < newIndex) {
insertIndex -= 1;
}
final nextItems = List<Rule>.from(value);
final item = nextItems.removeAt(oldIndex);
nextItems.insert(insertIndex, item);
value = nextItems;
final preOrder = nextItems.safeGet(insertIndex - 1)?.order;
final nextOrder = nextItems.safeGet(insertIndex + 1)?.order;
final newOrder = indexing.generateKeyBetween(nextOrder, preOrder)!;
database.rulesDao.orderProfileAddedRule(
profileId,
ruleId: item.id,
order: newOrder,
);
}
}
@riverpod
class ProfileDisabledRuleIds extends _$ProfileDisabledRuleIds
with AsyncNotifierMixin {
@override
List<int> get value => state.value ?? [];
@override
Stream<List<int>> build(int profileId) {
return database.rulesDao
.allProfileDisabledRules(profileId)
.map((item) => item.id)
.watch();
}
void _put(int ruleId) {
var newList = List<int>.from(value);
final index = newList.indexWhere((item) => item == ruleId);
if (index != -1) {
newList[index] = ruleId;
} else {
newList.insert(0, ruleId);
}
value = newList;
}
void del(int ruleId) {
List<int> newList = List.from(value);
newList = newList.where((item) => item != ruleId).toList();
value = newList;
database.rulesDao.delDisabledLink(profileId, ruleId);
}
void put(int ruleId) {
_put(ruleId);
database.rulesDao.putDisabledLink(profileId, ruleId);
}
}

View File

@@ -41,7 +41,7 @@ final class RealTunEnableProvider
}
}
String _$realTunEnableHash() => r'a4e995c86deca4c8307966470e69d93d64a40df6';
String _$realTunEnableHash() => r'f2c88f5031d1f97665c10f70121082c4f6d6c99d';
abstract class _$RealTunEnable extends $Notifier<bool> {
bool build();
@@ -72,7 +72,7 @@ final class LogsProvider extends $NotifierProvider<Logs, FixedList<Log>> {
argument: null,
retry: null,
name: r'logsProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -93,7 +93,7 @@ final class LogsProvider extends $NotifierProvider<Logs, FixedList<Log>> {
}
}
String _$logsHash() => r'a671cf70f13d38cae75dc51841b651fe2d2dad9a';
String _$logsHash() => r'f327fa8d05527172a647adf07771c797fb436bfd';
abstract class _$Logs extends $Notifier<FixedList<Log>> {
FixedList<Log> build();
@@ -125,7 +125,7 @@ final class RequestsProvider
argument: null,
retry: null,
name: r'requestsProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -146,7 +146,7 @@ final class RequestsProvider
}
}
String _$requestsHash() => r'8642621b8b5f2e56f3abb04554c058fb30389795';
String _$requestsHash() => r'32e4f0141a66b27732f8156a55a6fb23d74cfc07';
abstract class _$Requests extends $Notifier<FixedList<TrackerInfo>> {
FixedList<TrackerInfo> build();
@@ -179,7 +179,7 @@ final class ProvidersProvider
argument: null,
retry: null,
name: r'providersProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -200,7 +200,7 @@ final class ProvidersProvider
}
}
String _$providersHash() => r'9cb491314be6dca0d9ff2d09aa276d19a92895af';
String _$providersHash() => r'8752fd5059f1ff767a7dabd0a4ab92effe2f2651';
abstract class _$Providers extends $Notifier<List<ExternalProvider>> {
List<ExternalProvider> build();
@@ -233,7 +233,7 @@ final class PackagesProvider
argument: null,
retry: null,
name: r'packagesProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -254,7 +254,7 @@ final class PackagesProvider
}
}
String _$packagesHash() => r'84bff9f5271622ed4199ecafacda8e74fa444fe2';
String _$packagesHash() => r'93c92438ed777ec4c3017b90c22f4ddd1c02e931';
abstract class _$Packages extends $Notifier<List<Package>> {
List<Package> build();
@@ -286,7 +286,7 @@ final class SystemBrightnessProvider
argument: null,
retry: null,
name: r'systemBrightnessProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -307,7 +307,7 @@ final class SystemBrightnessProvider
}
}
String _$systemBrightnessHash() => r'2fb112459d5f505768f8c33b314aa62cf1fb0a0a';
String _$systemBrightnessHash() => r'5b8c93dc20f048b12cdad42b301afe8b9aa864cf';
abstract class _$SystemBrightness extends $Notifier<Brightness> {
Brightness build();
@@ -339,7 +339,7 @@ final class TrafficsProvider
argument: null,
retry: null,
name: r'trafficsProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -360,7 +360,7 @@ final class TrafficsProvider
}
}
String _$trafficsHash() => r'7df7d01f39e9fa1bf629221c9f73273757fa535a';
String _$trafficsHash() => r'00b83d393175b51abcef277417fb3d9b70cc247f';
abstract class _$Traffics extends $Notifier<FixedList<Traffic>> {
FixedList<Traffic> build();
@@ -392,7 +392,7 @@ final class TotalTrafficProvider
argument: null,
retry: null,
name: r'totalTrafficProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -413,7 +413,7 @@ final class TotalTrafficProvider
}
}
String _$totalTrafficHash() => r'cc993ec58fa4c8ee0dbbf2e8a146f7039e818d7e';
String _$totalTrafficHash() => r'00c5b34834882c4db0eacf948121ddbe9921728a';
abstract class _$TotalTraffic extends $Notifier<Traffic> {
Traffic build();
@@ -444,7 +444,7 @@ final class LocalIpProvider extends $NotifierProvider<LocalIp, String?> {
argument: null,
retry: null,
name: r'localIpProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -465,7 +465,7 @@ final class LocalIpProvider extends $NotifierProvider<LocalIp, String?> {
}
}
String _$localIpHash() => r'25ff07ff9ae316eac7ef39c29d9ae2714b7ba323';
String _$localIpHash() => r'7daf4c498425db64db4e33b10c870d8fa10695d8';
abstract class _$LocalIp extends $Notifier<String?> {
String? build();
@@ -496,7 +496,7 @@ final class RunTimeProvider extends $NotifierProvider<RunTime, int?> {
argument: null,
retry: null,
name: r'runTimeProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -517,7 +517,7 @@ final class RunTimeProvider extends $NotifierProvider<RunTime, int?> {
}
}
String _$runTimeHash() => r'8d792a969f68de037ee46f271e7f04a25924e6a6';
String _$runTimeHash() => r'665a3a58487bb59aa54c3f797db0627986aa878f';
abstract class _$RunTime extends $Notifier<int?> {
int? build();
@@ -548,7 +548,7 @@ final class ViewSizeProvider extends $NotifierProvider<ViewSize, Size> {
argument: null,
retry: null,
name: r'viewSizeProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -569,7 +569,7 @@ final class ViewSizeProvider extends $NotifierProvider<ViewSize, Size> {
}
}
String _$viewSizeHash() => r'8f7e485a3a2ec7cade8577c737cf7ead14868081';
String _$viewSizeHash() => r'3f355412237dc1234cca0d97972ac2eef1eb4792';
abstract class _$ViewSize extends $Notifier<Size> {
Size build();
@@ -600,7 +600,7 @@ final class SideWidthProvider extends $NotifierProvider<SideWidth, double> {
argument: null,
retry: null,
name: r'sideWidthProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -621,7 +621,7 @@ final class SideWidthProvider extends $NotifierProvider<SideWidth, double> {
}
}
String _$sideWidthHash() => r'380c2ae2136dc75346259d3c1d0dd3325e41fe49';
String _$sideWidthHash() => r'2f849d52dab271831bad68b07c1f90b5c18c0cc4';
abstract class _$SideWidth extends $Notifier<double> {
double build();
@@ -654,7 +654,7 @@ final class ViewWidthProvider
argument: null,
retry: null,
name: r'viewWidthProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -681,7 +681,7 @@ final class ViewWidthProvider
}
}
String _$viewWidthHash() => r'a469c3414170a6616ff3264962e7f160b2edceca';
String _$viewWidthHash() => r'5ee8f1bdebe44760f7333f88127108f5ffd70214';
@ProviderFor(viewMode)
const viewModeProvider = ViewModeProvider._();
@@ -695,7 +695,7 @@ final class ViewModeProvider
argument: null,
retry: null,
name: r'viewModeProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -722,7 +722,7 @@ final class ViewModeProvider
}
}
String _$viewModeHash() => r'736e2acc7e7d98ee30132de1990bf85f9506b47a';
String _$viewModeHash() => r'6822e9dc28c813afe1ed743feea464f0d33c805c';
@ProviderFor(isMobileView)
const isMobileViewProvider = IsMobileViewProvider._();
@@ -735,7 +735,7 @@ final class IsMobileViewProvider extends $FunctionalProvider<bool, bool, bool>
argument: null,
retry: null,
name: r'isMobileViewProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -762,7 +762,7 @@ final class IsMobileViewProvider extends $FunctionalProvider<bool, bool, bool>
}
}
String _$isMobileViewHash() => r'554c9ed269a02af001e623e596622e2bb2d658e7';
String _$isMobileViewHash() => r'1d75bccb4f50ae206bf43b68df869a5d95e5ea5f';
@ProviderFor(viewHeight)
const viewHeightProvider = ViewHeightProvider._();
@@ -776,7 +776,7 @@ final class ViewHeightProvider
argument: null,
retry: null,
name: r'viewHeightProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -803,7 +803,7 @@ final class ViewHeightProvider
}
}
String _$viewHeightHash() => r'410aee5b41388226ab16737f0e85a56f7e9fe801';
String _$viewHeightHash() => r'dc3fc18337b5ce9fc953d994c380e8f1fa49f352';
@ProviderFor(Init)
const initProvider = InitProvider._();
@@ -815,7 +815,7 @@ final class InitProvider extends $NotifierProvider<Init, bool> {
argument: null,
retry: null,
name: r'initProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -836,7 +836,7 @@ final class InitProvider extends $NotifierProvider<Init, bool> {
}
}
String _$initHash() => r'7d3f11c8aff7a1924c5ec8886b2cd2cbdda57c3f';
String _$initHash() => r'0fcded1ed3c62f2658898dee845455e412b171b1';
abstract class _$Init extends $Notifier<bool> {
bool build();
@@ -868,7 +868,7 @@ final class CurrentPageLabelProvider
argument: null,
retry: null,
name: r'currentPageLabelProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -889,7 +889,7 @@ final class CurrentPageLabelProvider
}
}
String _$currentPageLabelHash() => r'a4ed13348bcd406ec3be52138cf1083106d31215';
String _$currentPageLabelHash() => r'3a5fcd2d50e018ae379cdcd835cfa72ccf8720b8';
abstract class _$CurrentPageLabel extends $Notifier<PageLabel> {
PageLabel build();
@@ -920,7 +920,7 @@ final class SortNumProvider extends $NotifierProvider<SortNum, int> {
argument: null,
retry: null,
name: r'sortNumProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -941,7 +941,7 @@ final class SortNumProvider extends $NotifierProvider<SortNum, int> {
}
}
String _$sortNumHash() => r'b67bee9fdfbb74b484190fbc6e5c3da7d773bed0';
String _$sortNumHash() => r'6682f00d1f87cb17f294ad181ac96bf4dc6edb52';
abstract class _$SortNum extends $Notifier<int> {
int build();
@@ -972,7 +972,7 @@ final class CheckIpNumProvider extends $NotifierProvider<CheckIpNum, int> {
argument: null,
retry: null,
name: r'checkIpNumProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -993,7 +993,7 @@ final class CheckIpNumProvider extends $NotifierProvider<CheckIpNum, int> {
}
}
String _$checkIpNumHash() => r'4d8b32ed9c0013c056f90c9d5483f11fa5fddec5';
String _$checkIpNumHash() => r'e66b46fae31f3683698dc55533fbdd240aff44fe';
abstract class _$CheckIpNum extends $Notifier<int> {
int build();
@@ -1024,7 +1024,7 @@ final class BackBlockProvider extends $NotifierProvider<BackBlock, bool> {
argument: null,
retry: null,
name: r'backBlockProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -1045,7 +1045,7 @@ final class BackBlockProvider extends $NotifierProvider<BackBlock, bool> {
}
}
String _$backBlockHash() => r'c0223e0776b72d3a8c8842fc32fdb5287353999f';
String _$backBlockHash() => r'76e821bab72717698f0a5f10e9d2a8909918ae0d';
abstract class _$BackBlock extends $Notifier<bool> {
bool build();
@@ -1066,58 +1066,6 @@ abstract class _$BackBlock extends $Notifier<bool> {
}
}
@ProviderFor(Loading)
const loadingProvider = LoadingProvider._();
final class LoadingProvider extends $NotifierProvider<Loading, bool> {
const LoadingProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'loadingProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$loadingHash();
@$internal
@override
Loading create() => Loading();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(bool value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<bool>(value),
);
}
}
String _$loadingHash() => r'd3d9e6b203fecbef89d468b6ecf173a98a6a26a9';
abstract class _$Loading extends $Notifier<bool> {
bool build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<bool, bool>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<bool, bool>,
bool,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(Version)
const versionProvider = VersionProvider._();
@@ -1128,7 +1076,7 @@ final class VersionProvider extends $NotifierProvider<Version, int> {
argument: null,
retry: null,
name: r'versionProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -1149,7 +1097,7 @@ final class VersionProvider extends $NotifierProvider<Version, int> {
}
}
String _$versionHash() => r'8c0ee019d20df3f112c38ae4dc4abd61148d3809';
String _$versionHash() => r'00b43faa4061121d30a0612ed275644a402ce3fa';
abstract class _$Version extends $Notifier<int> {
int build();
@@ -1180,7 +1128,7 @@ final class GroupsProvider extends $NotifierProvider<Groups, List<Group>> {
argument: null,
retry: null,
name: r'groupsProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -1201,7 +1149,7 @@ final class GroupsProvider extends $NotifierProvider<Groups, List<Group>> {
}
}
String _$groupsHash() => r'fbff504e0bcdb5a2770a902f2867aabd921fbadc';
String _$groupsHash() => r'180ede48880a239add201c111ae45b2a6d98f3a5';
abstract class _$Groups extends $Notifier<List<Group>> {
List<Group> build();
@@ -1233,7 +1181,7 @@ final class DelayDataSourceProvider
argument: null,
retry: null,
name: r'delayDataSourceProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -1254,7 +1202,7 @@ final class DelayDataSourceProvider
}
}
String _$delayDataSourceHash() => r'0cc7064c6e7e7a1823df1c5b339001ae49ee54f1';
String _$delayDataSourceHash() => r'9737cf2d943cb9b5504a5ec8ace20b0a9380b197';
abstract class _$DelayDataSource extends $Notifier<DelayMap> {
DelayMap build();
@@ -1286,7 +1234,7 @@ final class SystemUiOverlayStyleStateProvider
argument: null,
retry: null,
name: r'systemUiOverlayStyleStateProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -1308,7 +1256,7 @@ final class SystemUiOverlayStyleStateProvider
}
String _$systemUiOverlayStyleStateHash() =>
r'4420d92227ae617ce685c8943dda64f29f57d5d1';
r'c5ba11d1c6eceef95f80b129e4d2a8ab7ecb7916';
abstract class _$SystemUiOverlayStyleState
extends $Notifier<SystemUiOverlayStyle> {
@@ -1330,60 +1278,6 @@ abstract class _$SystemUiOverlayStyleState
}
}
@ProviderFor(ProfileOverrideState)
const profileOverrideStateProvider = ProfileOverrideStateProvider._();
final class ProfileOverrideStateProvider
extends $NotifierProvider<ProfileOverrideState, ProfileOverrideModel?> {
const ProfileOverrideStateProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'profileOverrideStateProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$profileOverrideStateHash();
@$internal
@override
ProfileOverrideState create() => ProfileOverrideState();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(ProfileOverrideModel? value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<ProfileOverrideModel?>(value),
);
}
}
String _$profileOverrideStateHash() =>
r'6bcf739e034cc39623dc63bf304189d63fc19404';
abstract class _$ProfileOverrideState extends $Notifier<ProfileOverrideModel?> {
ProfileOverrideModel? build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<ProfileOverrideModel?, ProfileOverrideModel?>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<ProfileOverrideModel?, ProfileOverrideModel?>,
ProfileOverrideModel?,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(_CoreStatus)
const coreStatusProvider = _CoreStatusProvider._();
@@ -1395,7 +1289,7 @@ final class _CoreStatusProvider
argument: null,
retry: null,
name: r'coreStatusProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -1416,7 +1310,7 @@ final class _CoreStatusProvider
}
}
String _$_coreStatusHash() => r'795bee66f41f4fbafe14249263356ade03950aa5';
String _$_coreStatusHash() => r'e2e7fe37f66b906877e678149d09c656993e1405';
abstract class _$CoreStatus extends $Notifier<CoreStatus> {
CoreStatus build();
@@ -1485,7 +1379,7 @@ final class QueryProvider extends $NotifierProvider<Query, String> {
}
}
String _$queryHash() => r'da8d34ef86df1366e8607df2ef9155cc9473c959';
String _$queryHash() => r'b6be53823f3351ee2bf1c0d147c0ccf5f31bb8b5';
final class QueryFamily extends $Family
with $ClassFamilyOverride<Query, String, String, String, QueryTag> {
@@ -1527,11 +1421,101 @@ abstract class _$Query extends $Notifier<String> {
}
}
@ProviderFor(Loading)
const loadingProvider = LoadingFamily._();
final class LoadingProvider extends $NotifierProvider<Loading, bool> {
const LoadingProvider._({
required LoadingFamily super.from,
required LoadingTag super.argument,
}) : super(
retry: null,
name: r'loadingProvider',
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$loadingHash();
@override
String toString() {
return r'loadingProvider'
''
'($argument)';
}
@$internal
@override
Loading create() => Loading();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(bool value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<bool>(value),
);
}
@override
bool operator ==(Object other) {
return other is LoadingProvider && other.argument == argument;
}
@override
int get hashCode {
return argument.hashCode;
}
}
String _$loadingHash() => r'f4c58da7e5869c3e114b76439f3169b31d2e5b71';
final class LoadingFamily extends $Family
with $ClassFamilyOverride<Loading, bool, bool, bool, LoadingTag> {
const LoadingFamily._()
: super(
retry: null,
name: r'loadingProvider',
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: false,
);
LoadingProvider call(LoadingTag tag) =>
LoadingProvider._(argument: tag, from: this);
@override
String toString() => r'loadingProvider';
}
abstract class _$Loading extends $Notifier<bool> {
late final _$args = ref.$arg as LoadingTag;
LoadingTag get tag => _$args;
bool build(LoadingTag tag);
@$mustCallSuper
@override
void runBuild() {
final created = build(_$args);
final ref = this.ref as $Ref<bool, bool>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<bool, bool>,
bool,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(SelectedItems)
const selectedItemsProvider = SelectedItemsFamily._();
final class SelectedItemsProvider
extends $NotifierProvider<SelectedItems, Set<String>> {
extends $NotifierProvider<SelectedItems, Set<dynamic>> {
const SelectedItemsProvider._({
required SelectedItemsFamily super.from,
required String super.argument,
@@ -1558,10 +1542,10 @@ final class SelectedItemsProvider
SelectedItems create() => SelectedItems();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(Set<String> value) {
Override overrideWithValue(Set<dynamic> value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<Set<String>>(value),
providerOverride: $SyncValueProvider<Set<dynamic>>(value),
);
}
@@ -1576,15 +1560,15 @@ final class SelectedItemsProvider
}
}
String _$selectedItemsHash() => r'9a13ee78fdc100c8708af9de46e2861652d68e77';
String _$selectedItemsHash() => r'05ef5c5584cbac90d416e5c4fe53ec9e29604020';
final class SelectedItemsFamily extends $Family
with
$ClassFamilyOverride<
SelectedItems,
Set<String>,
Set<String>,
Set<String>,
Set<dynamic>,
Set<dynamic>,
Set<dynamic>,
String
> {
const SelectedItemsFamily._()
@@ -1603,21 +1587,21 @@ final class SelectedItemsFamily extends $Family
String toString() => r'selectedItemsProvider';
}
abstract class _$SelectedItems extends $Notifier<Set<String>> {
abstract class _$SelectedItems extends $Notifier<Set<dynamic>> {
late final _$args = ref.$arg as String;
String get key => _$args;
Set<String> build(String key);
Set<dynamic> build(String key);
@$mustCallSuper
@override
void runBuild() {
final created = build(_$args);
final ref = this.ref as $Ref<Set<String>, Set<String>>;
final ref = this.ref as $Ref<Set<dynamic>, Set<dynamic>>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<Set<String>, Set<String>>,
Set<String>,
AnyNotifier<Set<dynamic>, Set<dynamic>>,
Set<dynamic>,
Object?,
Object?
>;
@@ -1629,7 +1613,7 @@ abstract class _$SelectedItems extends $Notifier<Set<String>> {
const selectedItemProvider = SelectedItemFamily._();
final class SelectedItemProvider
extends $NotifierProvider<SelectedItem, String> {
extends $NotifierProvider<SelectedItem, dynamic> {
const SelectedItemProvider._({
required SelectedItemFamily super.from,
required String super.argument,
@@ -1656,10 +1640,10 @@ final class SelectedItemProvider
SelectedItem create() => SelectedItem();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(String value) {
Override overrideWithValue(dynamic value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<String>(value),
providerOverride: $SyncValueProvider<dynamic>(value),
);
}
@@ -1674,10 +1658,10 @@ final class SelectedItemProvider
}
}
String _$selectedItemHash() => r'374202f309d7a786190706fb0a2ac4945de94213';
String _$selectedItemHash() => r'b50be0386d53ee8441c37d1a2a4c25640ce10766';
final class SelectedItemFamily extends $Family
with $ClassFamilyOverride<SelectedItem, String, String, String, String> {
with $ClassFamilyOverride<SelectedItem, dynamic, dynamic, dynamic, String> {
const SelectedItemFamily._()
: super(
retry: null,
@@ -1694,21 +1678,164 @@ final class SelectedItemFamily extends $Family
String toString() => r'selectedItemProvider';
}
abstract class _$SelectedItem extends $Notifier<String> {
abstract class _$SelectedItem extends $Notifier<dynamic> {
late final _$args = ref.$arg as String;
String get key => _$args;
String build(String key);
dynamic build(String key);
@$mustCallSuper
@override
void runBuild() {
final created = build(_$args);
final ref = this.ref as $Ref<String, String>;
final ref = this.ref as $Ref<dynamic, dynamic>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<String, String>,
String,
AnyNotifier<dynamic, dynamic>,
dynamic,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(IsUpdating)
const isUpdatingProvider = IsUpdatingFamily._();
final class IsUpdatingProvider extends $NotifierProvider<IsUpdating, bool> {
const IsUpdatingProvider._({
required IsUpdatingFamily super.from,
required String super.argument,
}) : super(
retry: null,
name: r'isUpdatingProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$isUpdatingHash();
@override
String toString() {
return r'isUpdatingProvider'
''
'($argument)';
}
@$internal
@override
IsUpdating create() => IsUpdating();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(bool value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<bool>(value),
);
}
@override
bool operator ==(Object other) {
return other is IsUpdatingProvider && other.argument == argument;
}
@override
int get hashCode {
return argument.hashCode;
}
}
String _$isUpdatingHash() => r'934cc96cbf8cf6909d27867455a31bf3008470e6';
final class IsUpdatingFamily extends $Family
with $ClassFamilyOverride<IsUpdating, bool, bool, bool, String> {
const IsUpdatingFamily._()
: super(
retry: null,
name: r'isUpdatingProvider',
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
);
IsUpdatingProvider call(String name) =>
IsUpdatingProvider._(argument: name, from: this);
@override
String toString() => r'isUpdatingProvider';
}
abstract class _$IsUpdating extends $Notifier<bool> {
late final _$args = ref.$arg as String;
String get name => _$args;
bool build(String name);
@$mustCallSuper
@override
void runBuild() {
final created = build(_$args);
final ref = this.ref as $Ref<bool, bool>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<bool, bool>,
bool,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(NetworkDetection)
const networkDetectionProvider = NetworkDetectionProvider._();
final class NetworkDetectionProvider
extends $NotifierProvider<NetworkDetection, NetworkDetectionState> {
const NetworkDetectionProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'networkDetectionProvider',
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$networkDetectionHash();
@$internal
@override
NetworkDetection create() => NetworkDetection();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(NetworkDetectionState value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<NetworkDetectionState>(value),
);
}
}
String _$networkDetectionHash() => r'501babec2bbf2a38e4fef96cf20c76e9352bc5ee';
abstract class _$NetworkDetection extends $Notifier<NetworkDetectionState> {
NetworkDetectionState build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<NetworkDetectionState, NetworkDetectionState>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<NetworkDetectionState, NetworkDetectionState>,
NetworkDetectionState,
Object?,
Object?
>;

View File

@@ -41,7 +41,7 @@ final class AppSettingProvider
}
}
String _$appSettingHash() => r'7ec7fbf146e690dea42cf854fa4452b2652d8a46';
String _$appSettingHash() => r'0efd340a05a5be1b1190b3f2e9465bdfc6182046';
abstract class _$AppSetting extends $Notifier<AppSettingProps> {
AppSettingProps build();
@@ -73,7 +73,7 @@ final class WindowSettingProvider
argument: null,
retry: null,
name: r'windowSettingProvider',
isAutoDispose: true,
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@@ -94,7 +94,7 @@ final class WindowSettingProvider
}
}
String _$windowSettingHash() => r'fc0e5c4ec95a57a24e0e656fc2fab6f31add31e7';
String _$windowSettingHash() => r'd245796233fec671722ebed58e39c967d9a12142';
abstract class _$WindowSetting extends $Notifier<WindowProps> {
WindowProps build();
@@ -146,7 +146,7 @@ final class VpnSettingProvider extends $NotifierProvider<VpnSetting, VpnProps> {
}
}
String _$vpnSettingHash() => r'e6fab5a735fe518f9d4e5619254b0cea0006f318';
String _$vpnSettingHash() => r'051f90f388a52678052b655827c48947150b7ca1';
abstract class _$VpnSetting extends $Notifier<VpnProps> {
VpnProps build();
@@ -199,7 +199,7 @@ final class NetworkSettingProvider
}
}
String _$networkSettingHash() => r'6ac5959ad478247fd60329221743cccc7a7d010b';
String _$networkSettingHash() => r'54bd68084a1eb1b68650e353089c240d4a07f3a5';
abstract class _$NetworkSetting extends $Notifier<NetworkProps> {
NetworkProps build();
@@ -252,7 +252,7 @@ final class ThemeSettingProvider
}
}
String _$themeSettingHash() => r'0ddad89cb63fc2b2094dd82262c76d972c2def5c';
String _$themeSettingHash() => r'5b64a2e3968a60967534805b4bef3adf3712e77a';
abstract class _$ThemeSetting extends $Notifier<ThemeProps> {
ThemeProps build();
@@ -273,64 +273,11 @@ abstract class _$ThemeSetting extends $Notifier<ThemeProps> {
}
}
@ProviderFor(Profiles)
const profilesProvider = ProfilesProvider._();
final class ProfilesProvider
extends $NotifierProvider<Profiles, List<Profile>> {
const ProfilesProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'profilesProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$profilesHash();
@$internal
@override
Profiles create() => Profiles();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(List<Profile> value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<List<Profile>>(value),
);
}
}
String _$profilesHash() => r'aad57222a4a0bd16f2c70f9eb8ba0053d1a26d0f';
abstract class _$Profiles extends $Notifier<List<Profile>> {
List<Profile> build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<List<Profile>, List<Profile>>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<List<Profile>, List<Profile>>,
List<Profile>,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(CurrentProfileId)
const currentProfileIdProvider = CurrentProfileIdProvider._();
final class CurrentProfileIdProvider
extends $NotifierProvider<CurrentProfileId, String?> {
extends $NotifierProvider<CurrentProfileId, int?> {
const CurrentProfileIdProvider._()
: super(
from: null,
@@ -350,28 +297,28 @@ final class CurrentProfileIdProvider
CurrentProfileId create() => CurrentProfileId();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(String? value) {
Override overrideWithValue(int? value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<String?>(value),
providerOverride: $SyncValueProvider<int?>(value),
);
}
}
String _$currentProfileIdHash() => r'0c3e324e751aac1164da479e1796e826615bdcbe';
String _$currentProfileIdHash() => r'98ff7a3a0b8ed420d086993839f4d629df7590a6';
abstract class _$CurrentProfileId extends $Notifier<String?> {
String? build();
abstract class _$CurrentProfileId extends $Notifier<int?> {
int? build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<String?, String?>;
final ref = this.ref as $Ref<int?, int?>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<String?, String?>,
String?,
AnyNotifier<int?, int?>,
int?,
Object?,
Object?
>;
@@ -379,52 +326,52 @@ abstract class _$CurrentProfileId extends $Notifier<String?> {
}
}
@ProviderFor(AppDAVSetting)
const appDAVSettingProvider = AppDAVSettingProvider._();
@ProviderFor(DavSetting)
const davSettingProvider = DavSettingProvider._();
final class AppDAVSettingProvider
extends $NotifierProvider<AppDAVSetting, DAV?> {
const AppDAVSettingProvider._()
final class DavSettingProvider
extends $NotifierProvider<DavSetting, DAVProps?> {
const DavSettingProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'appDAVSettingProvider',
name: r'davSettingProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$appDAVSettingHash();
String debugGetCreateSourceHash() => _$davSettingHash();
@$internal
@override
AppDAVSetting create() => AppDAVSetting();
DavSetting create() => DavSetting();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(DAV? value) {
Override overrideWithValue(DAVProps? value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<DAV?>(value),
providerOverride: $SyncValueProvider<DAVProps?>(value),
);
}
}
String _$appDAVSettingHash() => r'fa8de5d89d7a11f34f3f8e20b71cf164e5e11888';
String _$davSettingHash() => r'5c85725b0d988c8f44ef6ba373953e551e09e857';
abstract class _$AppDAVSetting extends $Notifier<DAV?> {
DAV? build();
abstract class _$DavSetting extends $Notifier<DAVProps?> {
DAVProps? build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<DAV?, DAV?>;
final ref = this.ref as $Ref<DAVProps?, DAVProps?>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<DAV?, DAV?>,
DAV?,
AnyNotifier<DAVProps?, DAVProps?>,
DAVProps?,
Object?,
Object?
>;
@@ -463,7 +410,7 @@ final class OverrideDnsProvider extends $NotifierProvider<OverrideDns, bool> {
}
}
String _$overrideDnsHash() => r'1fc914de471319bf1e003edf9627b8c646b641bf';
String _$overrideDnsHash() => r'3d49994fa23389530643e8c80e588a58f14eec92';
abstract class _$OverrideDns extends $Notifier<bool> {
bool build();
@@ -516,7 +463,7 @@ final class HotKeyActionsProvider
}
}
String _$hotKeyActionsHash() => r'1d308d61b74accebbb11b1771a55975760503691';
String _$hotKeyActionsHash() => r'5512b83196646a49fa7307282315d9dccc658dc8';
abstract class _$HotKeyActions extends $Notifier<List<HotKeyAction>> {
List<HotKeyAction> build();
@@ -541,7 +488,7 @@ abstract class _$HotKeyActions extends $Notifier<List<HotKeyAction>> {
const proxiesStyleSettingProvider = ProxiesStyleSettingProvider._();
final class ProxiesStyleSettingProvider
extends $NotifierProvider<ProxiesStyleSetting, ProxiesStyle> {
extends $NotifierProvider<ProxiesStyleSetting, ProxiesStyleProps> {
const ProxiesStyleSettingProvider._()
: super(
from: null,
@@ -561,133 +508,29 @@ final class ProxiesStyleSettingProvider
ProxiesStyleSetting create() => ProxiesStyleSetting();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(ProxiesStyle value) {
Override overrideWithValue(ProxiesStyleProps value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<ProxiesStyle>(value),
providerOverride: $SyncValueProvider<ProxiesStyleProps>(value),
);
}
}
String _$proxiesStyleSettingHash() =>
r'4ff62951ddc8289220191850516b6751ee69d642';
r'b785ed2e71d74384150d80456d2b852e80629b8e';
abstract class _$ProxiesStyleSetting extends $Notifier<ProxiesStyle> {
ProxiesStyle build();
abstract class _$ProxiesStyleSetting extends $Notifier<ProxiesStyleProps> {
ProxiesStyleProps build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<ProxiesStyle, ProxiesStyle>;
final ref = this.ref as $Ref<ProxiesStyleProps, ProxiesStyleProps>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<ProxiesStyle, ProxiesStyle>,
ProxiesStyle,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(Scripts)
const scriptsProvider = ScriptsProvider._();
final class ScriptsProvider extends $NotifierProvider<Scripts, List<Script>> {
const ScriptsProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'scriptsProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$scriptsHash();
@$internal
@override
Scripts create() => Scripts();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(List<Script> value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<List<Script>>(value),
);
}
}
String _$scriptsHash() => r'67dfdff76fc16b47c2300011afb5952a8857bad5';
abstract class _$Scripts extends $Notifier<List<Script>> {
List<Script> build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<List<Script>, List<Script>>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<List<Script>, List<Script>>,
List<Script>,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(Rules)
const rulesProvider = RulesProvider._();
final class RulesProvider extends $NotifierProvider<Rules, List<Rule>> {
const RulesProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'rulesProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$rulesHash();
@$internal
@override
Rules create() => Rules();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(List<Rule> value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<List<Rule>>(value),
);
}
}
String _$rulesHash() => r'ca7fdb6c8b9c5071002ac950494ec7c20937aa1b';
abstract class _$Rules extends $Notifier<List<Rule>> {
List<Rule> build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<List<Rule>, List<Rule>>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<List<Rule>, List<Rule>>,
List<Rule>,
AnyNotifier<ProxiesStyleProps, ProxiesStyleProps>,
ProxiesStyleProps,
Object?,
Object?
>;
@@ -727,7 +570,7 @@ final class PatchClashConfigProvider
}
}
String _$patchClashConfigHash() => r'b355bd89969d4d119631fdf117df230a71493fa8';
String _$patchClashConfigHash() => r'ff92f991ccb3a3d13a938affc006d7e2cb85fecd';
abstract class _$PatchClashConfig extends $Notifier<ClashConfig> {
ClashConfig build();
@@ -747,3 +590,43 @@ abstract class _$PatchClashConfig extends $Notifier<ClashConfig> {
element.handleValue(ref, created);
}
}
@ProviderFor(_config)
const configProvider = _ConfigProvider._();
final class _ConfigProvider extends $FunctionalProvider<Config, Config, Config>
with $Provider<Config> {
const _ConfigProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'configProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$_configHash();
@$internal
@override
$ProviderElement<Config> $createElement($ProviderPointer pointer) =>
$ProviderElement(pointer);
@override
Config create(Ref ref) {
return _config(ref);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(Config value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<Config>(value),
);
}
}
String _$_configHash() => r'17dad8563f5727690a7fd484815e7344e6a46ffa';

View File

@@ -0,0 +1,448 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of '../database.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
@ProviderFor(profilesStream)
const profilesStreamProvider = ProfilesStreamProvider._();
final class ProfilesStreamProvider
extends
$FunctionalProvider<
AsyncValue<List<Profile>>,
List<Profile>,
Stream<List<Profile>>
>
with $FutureModifier<List<Profile>>, $StreamProvider<List<Profile>> {
const ProfilesStreamProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'profilesStreamProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$profilesStreamHash();
@$internal
@override
$StreamProviderElement<List<Profile>> $createElement(
$ProviderPointer pointer,
) => $StreamProviderElement(pointer);
@override
Stream<List<Profile>> create(Ref ref) {
return profilesStream(ref);
}
}
String _$profilesStreamHash() => r'483907aa6c324209b5202369300a4a53230f83db';
@ProviderFor(addedRuleStream)
const addedRuleStreamProvider = AddedRuleStreamFamily._();
final class AddedRuleStreamProvider
extends
$FunctionalProvider<
AsyncValue<List<Rule>>,
List<Rule>,
Stream<List<Rule>>
>
with $FutureModifier<List<Rule>>, $StreamProvider<List<Rule>> {
const AddedRuleStreamProvider._({
required AddedRuleStreamFamily super.from,
required int super.argument,
}) : super(
retry: null,
name: r'addedRuleStreamProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$addedRuleStreamHash();
@override
String toString() {
return r'addedRuleStreamProvider'
''
'($argument)';
}
@$internal
@override
$StreamProviderElement<List<Rule>> $createElement($ProviderPointer pointer) =>
$StreamProviderElement(pointer);
@override
Stream<List<Rule>> create(Ref ref) {
final argument = this.argument as int;
return addedRuleStream(ref, argument);
}
@override
bool operator ==(Object other) {
return other is AddedRuleStreamProvider && other.argument == argument;
}
@override
int get hashCode {
return argument.hashCode;
}
}
String _$addedRuleStreamHash() => r'491968ce795e56d4516a95676fcf46d575b3495f';
final class AddedRuleStreamFamily extends $Family
with $FunctionalFamilyOverride<Stream<List<Rule>>, int> {
const AddedRuleStreamFamily._()
: super(
retry: null,
name: r'addedRuleStreamProvider',
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
);
AddedRuleStreamProvider call(int profileId) =>
AddedRuleStreamProvider._(argument: profileId, from: this);
@override
String toString() => r'addedRuleStreamProvider';
}
@ProviderFor(Profiles)
const profilesProvider = ProfilesProvider._();
final class ProfilesProvider
extends $NotifierProvider<Profiles, List<Profile>> {
const ProfilesProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'profilesProvider',
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$profilesHash();
@$internal
@override
Profiles create() => Profiles();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(List<Profile> value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<List<Profile>>(value),
);
}
}
String _$profilesHash() => r'9ba0fedd671eab4aa809eb2ce7962f8a7a71665d';
abstract class _$Profiles extends $Notifier<List<Profile>> {
List<Profile> build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<List<Profile>, List<Profile>>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<List<Profile>, List<Profile>>,
List<Profile>,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(Scripts)
const scriptsProvider = ScriptsProvider._();
final class ScriptsProvider
extends $StreamNotifierProvider<Scripts, List<Script>> {
const ScriptsProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'scriptsProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$scriptsHash();
@$internal
@override
Scripts create() => Scripts();
}
String _$scriptsHash() => r'a784e9986eae864229a1035cc28ce4f3ec4644a0';
abstract class _$Scripts extends $StreamNotifier<List<Script>> {
Stream<List<Script>> build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<AsyncValue<List<Script>>, List<Script>>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<AsyncValue<List<Script>>, List<Script>>,
AsyncValue<List<Script>>,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(GlobalRules)
const globalRulesProvider = GlobalRulesProvider._();
final class GlobalRulesProvider
extends $StreamNotifierProvider<GlobalRules, List<Rule>> {
const GlobalRulesProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'globalRulesProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$globalRulesHash();
@$internal
@override
GlobalRules create() => GlobalRules();
}
String _$globalRulesHash() => r'3ed947f389649a86d5c6d78d8c02ba5b8d0f7119';
abstract class _$GlobalRules extends $StreamNotifier<List<Rule>> {
Stream<List<Rule>> build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<AsyncValue<List<Rule>>, List<Rule>>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<AsyncValue<List<Rule>>, List<Rule>>,
AsyncValue<List<Rule>>,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(ProfileAddedRules)
const profileAddedRulesProvider = ProfileAddedRulesFamily._();
final class ProfileAddedRulesProvider
extends $StreamNotifierProvider<ProfileAddedRules, List<Rule>> {
const ProfileAddedRulesProvider._({
required ProfileAddedRulesFamily super.from,
required int super.argument,
}) : super(
retry: null,
name: r'profileAddedRulesProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$profileAddedRulesHash();
@override
String toString() {
return r'profileAddedRulesProvider'
''
'($argument)';
}
@$internal
@override
ProfileAddedRules create() => ProfileAddedRules();
@override
bool operator ==(Object other) {
return other is ProfileAddedRulesProvider && other.argument == argument;
}
@override
int get hashCode {
return argument.hashCode;
}
}
String _$profileAddedRulesHash() => r'4155448335cf14a8928db6adf68e59572aa4ce47';
final class ProfileAddedRulesFamily extends $Family
with
$ClassFamilyOverride<
ProfileAddedRules,
AsyncValue<List<Rule>>,
List<Rule>,
Stream<List<Rule>>,
int
> {
const ProfileAddedRulesFamily._()
: super(
retry: null,
name: r'profileAddedRulesProvider',
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
);
ProfileAddedRulesProvider call(int profileId) =>
ProfileAddedRulesProvider._(argument: profileId, from: this);
@override
String toString() => r'profileAddedRulesProvider';
}
abstract class _$ProfileAddedRules extends $StreamNotifier<List<Rule>> {
late final _$args = ref.$arg as int;
int get profileId => _$args;
Stream<List<Rule>> build(int profileId);
@$mustCallSuper
@override
void runBuild() {
final created = build(_$args);
final ref = this.ref as $Ref<AsyncValue<List<Rule>>, List<Rule>>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<AsyncValue<List<Rule>>, List<Rule>>,
AsyncValue<List<Rule>>,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(ProfileDisabledRuleIds)
const profileDisabledRuleIdsProvider = ProfileDisabledRuleIdsFamily._();
final class ProfileDisabledRuleIdsProvider
extends $StreamNotifierProvider<ProfileDisabledRuleIds, List<int>> {
const ProfileDisabledRuleIdsProvider._({
required ProfileDisabledRuleIdsFamily super.from,
required int super.argument,
}) : super(
retry: null,
name: r'profileDisabledRuleIdsProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$profileDisabledRuleIdsHash();
@override
String toString() {
return r'profileDisabledRuleIdsProvider'
''
'($argument)';
}
@$internal
@override
ProfileDisabledRuleIds create() => ProfileDisabledRuleIds();
@override
bool operator ==(Object other) {
return other is ProfileDisabledRuleIdsProvider &&
other.argument == argument;
}
@override
int get hashCode {
return argument.hashCode;
}
}
String _$profileDisabledRuleIdsHash() =>
r'22d6e68bcee55b42fbb909e7f66e5c7095935224';
final class ProfileDisabledRuleIdsFamily extends $Family
with
$ClassFamilyOverride<
ProfileDisabledRuleIds,
AsyncValue<List<int>>,
List<int>,
Stream<List<int>>,
int
> {
const ProfileDisabledRuleIdsFamily._()
: super(
retry: null,
name: r'profileDisabledRuleIdsProvider',
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
);
ProfileDisabledRuleIdsProvider call(int profileId) =>
ProfileDisabledRuleIdsProvider._(argument: profileId, from: this);
@override
String toString() => r'profileDisabledRuleIdsProvider';
}
abstract class _$ProfileDisabledRuleIds extends $StreamNotifier<List<int>> {
late final _$args = ref.$arg as int;
int get profileId => _$args;
Stream<List<int>> build(int profileId);
@$mustCallSuper
@override
void runBuild() {
final created = build(_$args);
final ref = this.ref as $Ref<AsyncValue<List<int>>, List<int>>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<AsyncValue<List<int>>, List<int>>,
AsyncValue<List<int>>,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}

View File

@@ -9,47 +9,6 @@ part of '../state.dart';
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
@ProviderFor(configState)
const configStateProvider = ConfigStateProvider._();
final class ConfigStateProvider
extends $FunctionalProvider<Config, Config, Config>
with $Provider<Config> {
const ConfigStateProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'configStateProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$configStateHash();
@$internal
@override
$ProviderElement<Config> $createElement($ProviderPointer pointer) =>
$ProviderElement(pointer);
@override
Config create(Ref ref) {
return configState(ref);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(Config value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<Config>(value),
);
}
}
String _$configStateHash() => r'0eb72e2cf30d1d0de694d28a3ec3c7658e825e92';
@ProviderFor(currentGroupsState)
const currentGroupsStateProvider = CurrentGroupsStateProvider._();
@@ -269,7 +228,7 @@ final class ProxyStateProvider
}
}
String _$proxyStateHash() => r'22478fb593aaca11dfe2cf64472013190475a5bc';
String _$proxyStateHash() => r'3df11daa70bd06de32da43e9b3e09a74389264b2';
@ProviderFor(trayState)
const trayStateProvider = TrayStateProvider._();
@@ -310,7 +269,7 @@ final class TrayStateProvider
}
}
String _$trayStateHash() => r'f5057cc600a13dfc3bc7a45de7452febd18b2293';
String _$trayStateHash() => r'b03770ae2eb7fe1a73372f1128af3b38fdebb818';
@ProviderFor(trayTitleState)
const trayTitleStateProvider = TrayTitleStateProvider._();
@@ -566,101 +525,46 @@ final class ProxiesActionsStateProvider
String _$proxiesActionsStateHash() =>
r'84f8a94706233ff5d4b8a456291a4e66c1381c62';
@ProviderFor(startButtonSelectorState)
const startButtonSelectorStateProvider = StartButtonSelectorStateProvider._();
@ProviderFor(profilesState)
const profilesStateProvider = ProfilesStateProvider._();
final class StartButtonSelectorStateProvider
extends
$FunctionalProvider<
StartButtonSelectorState,
StartButtonSelectorState,
StartButtonSelectorState
>
with $Provider<StartButtonSelectorState> {
const StartButtonSelectorStateProvider._()
final class ProfilesStateProvider
extends $FunctionalProvider<ProfilesState, ProfilesState, ProfilesState>
with $Provider<ProfilesState> {
const ProfilesStateProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'startButtonSelectorStateProvider',
name: r'profilesStateProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$startButtonSelectorStateHash();
String debugGetCreateSourceHash() => _$profilesStateHash();
@$internal
@override
$ProviderElement<StartButtonSelectorState> $createElement(
$ProviderPointer pointer,
) => $ProviderElement(pointer);
$ProviderElement<ProfilesState> $createElement($ProviderPointer pointer) =>
$ProviderElement(pointer);
@override
StartButtonSelectorState create(Ref ref) {
return startButtonSelectorState(ref);
ProfilesState create(Ref ref) {
return profilesState(ref);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(StartButtonSelectorState value) {
Override overrideWithValue(ProfilesState value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<StartButtonSelectorState>(value),
providerOverride: $SyncValueProvider<ProfilesState>(value),
);
}
}
String _$startButtonSelectorStateHash() =>
r'537aff93c98b0a689cf8cabd080c610c9c58e611';
@ProviderFor(profilesSelectorState)
const profilesSelectorStateProvider = ProfilesSelectorStateProvider._();
final class ProfilesSelectorStateProvider
extends
$FunctionalProvider<
ProfilesSelectorState,
ProfilesSelectorState,
ProfilesSelectorState
>
with $Provider<ProfilesSelectorState> {
const ProfilesSelectorStateProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'profilesSelectorStateProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$profilesSelectorStateHash();
@$internal
@override
$ProviderElement<ProfilesSelectorState> $createElement(
$ProviderPointer pointer,
) => $ProviderElement(pointer);
@override
ProfilesSelectorState create(Ref ref) {
return profilesSelectorState(ref);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(ProfilesSelectorState value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<ProfilesSelectorState>(value),
);
}
}
String _$profilesSelectorStateHash() =>
r'da4a4382d7054dfe4010e44e55368d31ec805536';
String _$profilesStateHash() => r'8b07eeacb83b9002ba7e6283ff7a7f451a0845a6';
@ProviderFor(filterGroupsState)
const filterGroupsStateProvider = FilterGroupsStateFamily._();
@@ -913,7 +817,7 @@ final class ProxiesTabControllerStateProvider
}
String _$proxiesTabControllerStateHash() =>
r'05dba6f9b7fe99b84234540f56ba1bf53a2a5228';
r'd9c4eb6771262b2a989b053ce6ad94c307cf43fb';
@ProviderFor(proxyGroupSelectorState)
const proxyGroupSelectorStateProvider = ProxyGroupSelectorStateFamily._();
@@ -1049,7 +953,7 @@ final class PackageListSelectorStateProvider
}
String _$packageListSelectorStateHash() =>
r'26ad58fec2cb0136ece373c7f3ec89b5aafd9324';
r'1fa2bebbd8ee07910aa8d6e9c5d5d6128df5c13b';
@ProviderFor(moreToolsSelectorState)
const moreToolsSelectorStateProvider = MoreToolsSelectorStateProvider._();
@@ -1196,29 +1100,29 @@ final class IsCurrentPageFamily extends $Family
String toString() => r'isCurrentPageProvider';
}
@ProviderFor(getRealTestUrl)
const getRealTestUrlProvider = GetRealTestUrlFamily._();
@ProviderFor(realTestUrl)
const realTestUrlProvider = RealTestUrlFamily._();
final class GetRealTestUrlProvider
final class RealTestUrlProvider
extends $FunctionalProvider<String, String, String>
with $Provider<String> {
const GetRealTestUrlProvider._({
required GetRealTestUrlFamily super.from,
const RealTestUrlProvider._({
required RealTestUrlFamily super.from,
required String? super.argument,
}) : super(
retry: null,
name: r'getRealTestUrlProvider',
name: r'realTestUrlProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$getRealTestUrlHash();
String debugGetCreateSourceHash() => _$realTestUrlHash();
@override
String toString() {
return r'getRealTestUrlProvider'
return r'realTestUrlProvider'
''
'($argument)';
}
@@ -1231,7 +1135,7 @@ final class GetRealTestUrlProvider
@override
String create(Ref ref) {
final argument = this.argument as String?;
return getRealTestUrl(ref, argument);
return realTestUrl(ref, argument);
}
/// {@macro riverpod.override_with_value}
@@ -1244,7 +1148,7 @@ final class GetRealTestUrlProvider
@override
bool operator ==(Object other) {
return other is GetRealTestUrlProvider && other.argument == argument;
return other is RealTestUrlProvider && other.argument == argument;
}
@override
@@ -1253,24 +1157,24 @@ final class GetRealTestUrlProvider
}
}
String _$getRealTestUrlHash() => r'5c6513cabb53e5e6689cba5919f49aeaeff90247';
String _$realTestUrlHash() => r'6d68caa7a526b6788e3e4899d3ec8ad1c065b15e';
final class GetRealTestUrlFamily extends $Family
final class RealTestUrlFamily extends $Family
with $FunctionalFamilyOverride<String, String?> {
const GetRealTestUrlFamily._()
const RealTestUrlFamily._()
: super(
retry: null,
name: r'getRealTestUrlProvider',
name: r'realTestUrlProvider',
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
);
GetRealTestUrlProvider call([String? testUrl]) =>
GetRealTestUrlProvider._(argument: testUrl, from: this);
RealTestUrlProvider call([String? testUrl]) =>
RealTestUrlProvider._(argument: testUrl, from: this);
@override
String toString() => r'getRealTestUrlProvider';
String toString() => r'realTestUrlProvider';
}
@ProviderFor(getDelay)
@@ -1333,7 +1237,7 @@ final class GetDelayProvider extends $FunctionalProvider<int?, int?, int?>
}
}
String _$getDelayHash() => r'15df90fb31665501b21ea671a72e35beaf32141b';
String _$getDelayHash() => r'ee2df2db2b12d599794f77519a9ac518f42245a7';
final class GetDelayFamily extends $Family
with
@@ -1920,138 +1824,17 @@ final class GetProxyDescFamily extends $Family
String toString() => r'getProxyDescProvider';
}
@ProviderFor(getProfileOverrideData)
const getProfileOverrideDataProvider = GetProfileOverrideDataFamily._();
final class GetProfileOverrideDataProvider
extends $FunctionalProvider<OverrideData?, OverrideData?, OverrideData?>
with $Provider<OverrideData?> {
const GetProfileOverrideDataProvider._({
required GetProfileOverrideDataFamily super.from,
required String super.argument,
}) : super(
retry: null,
name: r'getProfileOverrideDataProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$getProfileOverrideDataHash();
@override
String toString() {
return r'getProfileOverrideDataProvider'
''
'($argument)';
}
@$internal
@override
$ProviderElement<OverrideData?> $createElement($ProviderPointer pointer) =>
$ProviderElement(pointer);
@override
OverrideData? create(Ref ref) {
final argument = this.argument as String;
return getProfileOverrideData(ref, argument);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(OverrideData? value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<OverrideData?>(value),
);
}
@override
bool operator ==(Object other) {
return other is GetProfileOverrideDataProvider &&
other.argument == argument;
}
@override
int get hashCode {
return argument.hashCode;
}
}
String _$getProfileOverrideDataHash() =>
r'a17ec085f1733b63b123ac08aa7737588c048c5f';
final class GetProfileOverrideDataFamily extends $Family
with $FunctionalFamilyOverride<OverrideData?, String> {
const GetProfileOverrideDataFamily._()
: super(
retry: null,
name: r'getProfileOverrideDataProvider',
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
);
GetProfileOverrideDataProvider call(String profileId) =>
GetProfileOverrideDataProvider._(argument: profileId, from: this);
@override
String toString() => r'getProfileOverrideDataProvider';
}
@ProviderFor(layoutChange)
const layoutChangeProvider = LayoutChangeProvider._();
final class LayoutChangeProvider
extends
$FunctionalProvider<
VM2<dynamic, dynamic>?,
VM2<dynamic, dynamic>?,
VM2<dynamic, dynamic>?
>
with $Provider<VM2<dynamic, dynamic>?> {
const LayoutChangeProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'layoutChangeProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$layoutChangeHash();
@$internal
@override
$ProviderElement<VM2<dynamic, dynamic>?> $createElement(
$ProviderPointer pointer,
) => $ProviderElement(pointer);
@override
VM2<dynamic, dynamic>? create(Ref ref) {
return layoutChange(ref);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(VM2<dynamic, dynamic>? value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<VM2<dynamic, dynamic>?>(value),
);
}
}
String _$layoutChangeHash() => r'f25182e1dfaf3c70000404d7635bb1e1db09efbb';
@ProviderFor(checkIp)
const checkIpProvider = CheckIpProvider._();
final class CheckIpProvider
extends $FunctionalProvider<VM2<int, bool>, VM2<int, bool>, VM2<int, bool>>
with $Provider<VM2<int, bool>> {
extends
$FunctionalProvider<
VM3<bool, int, bool>,
VM3<bool, int, bool>,
VM3<bool, int, bool>
>
with $Provider<VM3<bool, int, bool>> {
const CheckIpProvider._()
: super(
from: null,
@@ -2068,24 +1851,25 @@ final class CheckIpProvider
@$internal
@override
$ProviderElement<VM2<int, bool>> $createElement($ProviderPointer pointer) =>
$ProviderElement(pointer);
$ProviderElement<VM3<bool, int, bool>> $createElement(
$ProviderPointer pointer,
) => $ProviderElement(pointer);
@override
VM2<int, bool> create(Ref ref) {
VM3<bool, int, bool> create(Ref ref) {
return checkIp(ref);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(VM2<int, bool> value) {
Override overrideWithValue(VM3<bool, int, bool> value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<VM2<int, bool>>(value),
providerOverride: $SyncValueProvider<VM3<bool, int, bool>>(value),
);
}
}
String _$checkIpHash() => r'07ebf8d032349e2b3adda483e68b1936ffbed68d';
String _$checkIpHash() => r'7d8be66f0e8164bcf20c32659da2a4bea9893596';
@ProviderFor(genColorScheme)
const genColorSchemeProvider = GenColorSchemeFamily._();
@@ -2150,7 +1934,7 @@ final class GenColorSchemeProvider
}
}
String _$genColorSchemeHash() => r'b18f15c938a8132ee4ed02cdfc02f3b9f01724e2';
String _$genColorSchemeHash() => r'25f648db7c33ac00e7152f3d304da372a4de9fdd';
final class GenColorSchemeFamily extends $Family
with
@@ -2180,54 +1964,46 @@ final class GenColorSchemeFamily extends $Family
String toString() => r'genColorSchemeProvider';
}
@ProviderFor(needSetup)
const needSetupProvider = NeedSetupProvider._();
@ProviderFor(currentSetupState)
const currentSetupStateProvider = CurrentSetupStateProvider._();
final class NeedSetupProvider
extends
$FunctionalProvider<
VM4<String?, String?, Dns?, bool>,
VM4<String?, String?, Dns?, bool>,
VM4<String?, String?, Dns?, bool>
>
with $Provider<VM4<String?, String?, Dns?, bool>> {
const NeedSetupProvider._()
final class CurrentSetupStateProvider
extends $FunctionalProvider<SetupState?, SetupState?, SetupState?>
with $Provider<SetupState?> {
const CurrentSetupStateProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'needSetupProvider',
name: r'currentSetupStateProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$needSetupHash();
String debugGetCreateSourceHash() => _$currentSetupStateHash();
@$internal
@override
$ProviderElement<VM4<String?, String?, Dns?, bool>> $createElement(
$ProviderPointer pointer,
) => $ProviderElement(pointer);
$ProviderElement<SetupState?> $createElement($ProviderPointer pointer) =>
$ProviderElement(pointer);
@override
VM4<String?, String?, Dns?, bool> create(Ref ref) {
return needSetup(ref);
SetupState? create(Ref ref) {
return currentSetupState(ref);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(VM4<String?, String?, Dns?, bool> value) {
Override overrideWithValue(SetupState? value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<VM4<String?, String?, Dns?, bool>>(
value,
),
providerOverride: $SyncValueProvider<SetupState?>(value),
);
}
}
String _$needSetupHash() => r'6ea0d2be3df2046bbfa4e6c5d751727f06e7a4b3';
String _$currentSetupStateHash() => r'd687b0563ea8cc8eb1ca345fdfeee3411d67ad47';
@ProviderFor(currentBrightness)
const currentBrightnessProvider = CurrentBrightnessProvider._();
@@ -2311,7 +2087,7 @@ final class AutoSetSystemDnsStateProvider
}
String _$autoSetSystemDnsStateHash() =>
r'2e0976e079100325b1ca797285df48a94c2c066c';
r'a8805965efe78241613bfde55f4ea8fa12a6ea32';
@ProviderFor(needUpdateGroups)
const needUpdateGroupsProvider = NeedUpdateGroupsProvider._();
@@ -2360,48 +2136,48 @@ final class NeedUpdateGroupsProvider
}
}
String _$needUpdateGroupsHash() => r'1d1fbf135b4b5d2a2ee984e421ccffe7c4bb0a47';
String _$needUpdateGroupsHash() => r'7913b7b74caf9f2c72fd32729d52b7c6ac9258e8';
@ProviderFor(androidState)
const androidStateProvider = AndroidStateProvider._();
@ProviderFor(sharedState)
const sharedStateProvider = SharedStateProvider._();
final class AndroidStateProvider
extends $FunctionalProvider<AndroidState, AndroidState, AndroidState>
with $Provider<AndroidState> {
const AndroidStateProvider._()
final class SharedStateProvider
extends $FunctionalProvider<SharedState, SharedState, SharedState>
with $Provider<SharedState> {
const SharedStateProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'androidStateProvider',
name: r'sharedStateProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$androidStateHash();
String debugGetCreateSourceHash() => _$sharedStateHash();
@$internal
@override
$ProviderElement<AndroidState> $createElement($ProviderPointer pointer) =>
$ProviderElement<SharedState> $createElement($ProviderPointer pointer) =>
$ProviderElement(pointer);
@override
AndroidState create(Ref ref) {
return androidState(ref);
SharedState create(Ref ref) {
return sharedState(ref);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(AndroidState value) {
Override overrideWithValue(SharedState value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<AndroidState>(value),
providerOverride: $SyncValueProvider<SharedState>(value),
);
}
}
String _$androidStateHash() => r'9f527fbb00c7e0c177f023e77d2f23458543d72f';
String _$sharedStateHash() => r'864fdf3f750fb6d1beadcb5f9226a614a9cb2caa';
@ProviderFor(overlayTopOffset)
const overlayTopOffsetProvider = OverlayTopOffsetProvider._();
@@ -2452,7 +2228,7 @@ final class ProfileProvider
with $Provider<Profile?> {
const ProfileProvider._({
required ProfileFamily super.from,
required String super.argument,
required int? super.argument,
}) : super(
retry: null,
name: r'profileProvider',
@@ -2478,7 +2254,7 @@ final class ProfileProvider
@override
Profile? create(Ref ref) {
final argument = this.argument as String;
final argument = this.argument as int?;
return profile(ref, argument);
}
@@ -2501,10 +2277,10 @@ final class ProfileProvider
}
}
String _$profileHash() => r'6992b7e6f32b24f2a876e2a2cab24fcd8e39d30d';
String _$profileHash() => r'8de429dc0844c6b6155032ad3c9546231e08cead';
final class ProfileFamily extends $Family
with $FunctionalFamilyOverride<Profile?, String> {
with $FunctionalFamilyOverride<Profile?, int?> {
const ProfileFamily._()
: super(
retry: null,
@@ -2514,62 +2290,62 @@ final class ProfileFamily extends $Family
isAutoDispose: true,
);
ProfileProvider call(String profileId) =>
ProfileProvider call(int? profileId) =>
ProfileProvider._(argument: profileId, from: this);
@override
String toString() => r'profileProvider';
}
@ProviderFor(profileOverwrite)
const profileOverwriteProvider = ProfileOverwriteFamily._();
@ProviderFor(overwriteType)
const overwriteTypeProvider = OverwriteTypeFamily._();
final class ProfileOverwriteProvider
extends $FunctionalProvider<Overwrite?, Overwrite?, Overwrite?>
with $Provider<Overwrite?> {
const ProfileOverwriteProvider._({
required ProfileOverwriteFamily super.from,
required String super.argument,
final class OverwriteTypeProvider
extends $FunctionalProvider<OverwriteType, OverwriteType, OverwriteType>
with $Provider<OverwriteType> {
const OverwriteTypeProvider._({
required OverwriteTypeFamily super.from,
required int? super.argument,
}) : super(
retry: null,
name: r'profileOverwriteProvider',
name: r'overwriteTypeProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$profileOverwriteHash();
String debugGetCreateSourceHash() => _$overwriteTypeHash();
@override
String toString() {
return r'profileOverwriteProvider'
return r'overwriteTypeProvider'
''
'($argument)';
}
@$internal
@override
$ProviderElement<Overwrite?> $createElement($ProviderPointer pointer) =>
$ProviderElement<OverwriteType> $createElement($ProviderPointer pointer) =>
$ProviderElement(pointer);
@override
Overwrite? create(Ref ref) {
final argument = this.argument as String;
return profileOverwrite(ref, argument);
OverwriteType create(Ref ref) {
final argument = this.argument as int?;
return overwriteType(ref, argument);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(Overwrite? value) {
Override overrideWithValue(OverwriteType value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<Overwrite?>(value),
providerOverride: $SyncValueProvider<OverwriteType>(value),
);
}
@override
bool operator ==(Object other) {
return other is ProfileOverwriteProvider && other.argument == argument;
return other is OverwriteTypeProvider && other.argument == argument;
}
@override
@@ -2578,89 +2354,109 @@ final class ProfileOverwriteProvider
}
}
String _$profileOverwriteHash() => r'9d64c5546ff9236c7c9b0d6536bafdb57ffe40a5';
String _$overwriteTypeHash() => r'03a8ab8ddec76935da5fa231270b65baa70fd727';
final class ProfileOverwriteFamily extends $Family
with $FunctionalFamilyOverride<Overwrite?, String> {
const ProfileOverwriteFamily._()
final class OverwriteTypeFamily extends $Family
with $FunctionalFamilyOverride<OverwriteType, int?> {
const OverwriteTypeFamily._()
: super(
retry: null,
name: r'profileOverwriteProvider',
name: r'overwriteTypeProvider',
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
);
ProfileOverwriteProvider call(String profileId) =>
ProfileOverwriteProvider._(argument: profileId, from: this);
OverwriteTypeProvider call(int? profileId) =>
OverwriteTypeProvider._(argument: profileId, from: this);
@override
String toString() => r'profileOverwriteProvider';
String toString() => r'overwriteTypeProvider';
}
@ProviderFor(AccessControlState)
const accessControlStateProvider = AccessControlStateProvider._();
@ProviderFor(script)
const scriptProvider = ScriptFamily._();
final class AccessControlStateProvider
extends $NotifierProvider<AccessControlState, AccessControl> {
const AccessControlStateProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'accessControlStateProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
final class ScriptProvider
extends $FunctionalProvider<AsyncValue<Script?>, Script?, FutureOr<Script?>>
with $FutureModifier<Script?>, $FutureProvider<Script?> {
const ScriptProvider._({
required ScriptFamily super.from,
required int? super.argument,
}) : super(
retry: null,
name: r'scriptProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$accessControlStateHash();
String debugGetCreateSourceHash() => _$scriptHash();
@override
String toString() {
return r'scriptProvider'
''
'($argument)';
}
@$internal
@override
AccessControlState create() => AccessControlState();
$FutureProviderElement<Script?> $createElement($ProviderPointer pointer) =>
$FutureProviderElement(pointer);
/// {@macro riverpod.override_with_value}
Override overrideWithValue(AccessControl value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<AccessControl>(value),
);
@override
FutureOr<Script?> create(Ref ref) {
final argument = this.argument as int?;
return script(ref, argument);
}
@override
bool operator ==(Object other) {
return other is ScriptProvider && other.argument == argument;
}
@override
int get hashCode {
return argument.hashCode;
}
}
String _$accessControlStateHash() =>
r'f7e23637439b8b6c80744d8fa83498edf15acc11';
String _$scriptHash() => r'b12a6dbe34e08cb1232afafa8b0b0f5363d28bc0';
final class ScriptFamily extends $Family
with $FunctionalFamilyOverride<FutureOr<Script?>, int?> {
const ScriptFamily._()
: super(
retry: null,
name: r'scriptProvider',
dependencies: null,
$allTransitiveDependencies: null,
isAutoDispose: true,
);
ScriptProvider call(int? scriptId) =>
ScriptProvider._(argument: scriptId, from: this);
abstract class _$AccessControlState extends $Notifier<AccessControl> {
AccessControl build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<AccessControl, AccessControl>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<AccessControl, AccessControl>,
AccessControl,
Object?,
Object?
>;
element.handleValue(ref, created);
}
String toString() => r'scriptProvider';
}
@ProviderFor(setupState)
const setupStateProvider = SetupStateFamily._();
final class SetupStateProvider
extends $FunctionalProvider<SetupState, SetupState, SetupState>
with $Provider<SetupState> {
extends
$FunctionalProvider<
AsyncValue<SetupState>,
SetupState,
FutureOr<SetupState>
>
with $FutureModifier<SetupState>, $FutureProvider<SetupState> {
const SetupStateProvider._({
required SetupStateFamily super.from,
required String super.argument,
required int? super.argument,
}) : super(
retry: null,
name: r'setupStateProvider',
@@ -2681,23 +2477,15 @@ final class SetupStateProvider
@$internal
@override
$ProviderElement<SetupState> $createElement($ProviderPointer pointer) =>
$ProviderElement(pointer);
$FutureProviderElement<SetupState> $createElement($ProviderPointer pointer) =>
$FutureProviderElement(pointer);
@override
SetupState create(Ref ref) {
final argument = this.argument as String;
FutureOr<SetupState> create(Ref ref) {
final argument = this.argument as int?;
return setupState(ref, argument);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(SetupState value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<SetupState>(value),
);
}
@override
bool operator ==(Object other) {
return other is SetupStateProvider && other.argument == argument;
@@ -2709,10 +2497,10 @@ final class SetupStateProvider
}
}
String _$setupStateHash() => r'f4a7cd47c996bb6de04ee84716d59feca6bb7bc9';
String _$setupStateHash() => r'8e0c849fa1a51ee15f8b40be94e3094182325b58';
final class SetupStateFamily extends $Family
with $FunctionalFamilyOverride<SetupState, String> {
with $FunctionalFamilyOverride<FutureOr<SetupState>, int?> {
const SetupStateFamily._()
: super(
retry: null,
@@ -2722,9 +2510,63 @@ final class SetupStateFamily extends $Family
isAutoDispose: true,
);
SetupStateProvider call(String profileId) =>
SetupStateProvider call(int? profileId) =>
SetupStateProvider._(argument: profileId, from: this);
@override
String toString() => r'setupStateProvider';
}
@ProviderFor(AccessControlState)
const accessControlStateProvider = AccessControlStateProvider._();
final class AccessControlStateProvider
extends $NotifierProvider<AccessControlState, AccessControlProps> {
const AccessControlStateProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'accessControlStateProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$accessControlStateHash();
@$internal
@override
AccessControlState create() => AccessControlState();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(AccessControlProps value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<AccessControlProps>(value),
);
}
}
String _$accessControlStateHash() =>
r'08fda2e342d027c1bdd49c1ef9a13f2e775db204';
abstract class _$AccessControlState extends $Notifier<AccessControlProps> {
AccessControlProps build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<AccessControlProps, AccessControlProps>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<AccessControlProps, AccessControlProps>,
AccessControlProps,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}

View File

@@ -9,43 +9,10 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'app.dart';
import 'config.dart';
import 'database.dart';
part 'generated/state.g.dart';
@riverpod
Config configState(Ref ref) {
final themeProps = ref.watch(themeSettingProvider);
final patchClashConfig = ref.watch(patchClashConfigProvider);
final appSetting = ref.watch(appSettingProvider);
final profiles = ref.watch(profilesProvider);
final currentProfileId = ref.watch(currentProfileIdProvider);
final overrideDns = ref.watch(overrideDnsProvider);
final networkProps = ref.watch(networkSettingProvider);
final vpnProps = ref.watch(vpnSettingProvider);
final proxiesStyle = ref.watch(proxiesStyleSettingProvider);
final scripts = ref.watch(scriptsProvider);
final hotKeyActions = ref.watch(hotKeyActionsProvider);
final dav = ref.watch(appDAVSettingProvider);
final windowProps = ref.watch(windowSettingProvider);
final rules = ref.watch(rulesProvider);
return Config(
dav: dav,
windowProps: windowProps,
hotKeyActions: hotKeyActions,
proxiesStyle: proxiesStyle,
vpnProps: vpnProps,
networkProps: networkProps,
overrideDns: overrideDns,
currentProfileId: currentProfileId,
profiles: profiles,
appSetting: appSetting,
themeProps: themeProps,
patchClashConfig: patchClashConfig,
scripts: scripts,
rules: rules,
);
}
@riverpod
GroupsState currentGroupsState(Ref ref) {
final mode = ref.watch(
@@ -135,7 +102,7 @@ ProxyState proxyState(Ref ref) {
final isStart = ref.watch(runTimeProvider.select((state) => state != null));
final vm2 = ref.watch(
networkSettingProvider.select(
(state) => VM2(a: state.systemProxy, b: state.bypassDomain),
(state) => VM2(state.systemProxy, state.bypassDomain),
),
);
final mixedPort = ref.watch(
@@ -157,13 +124,12 @@ TrayState trayState(Ref ref) {
);
final clashConfigVm3 = ref.watch(
patchClashConfigProvider.select(
(state) => VM3(a: state.mode, b: state.mixedPort, c: state.tun.enable),
(state) => VM3(state.mode, state.mixedPort, state.tun.enable),
),
);
final appSettingVm3 = ref.watch(
appSettingProvider.select(
(state) =>
VM3(a: state.autoLaunch, b: state.locale, c: state.showTrayTitle),
(state) => VM3(state.autoLaunch, state.locale, state.showTrayTitle),
),
);
final groups = ref.watch(currentGroupsStateProvider).value;
@@ -260,22 +226,13 @@ ProxiesActionsState proxiesActionsState(Ref ref) {
}
@riverpod
StartButtonSelectorState startButtonSelectorState(Ref ref) {
final isInit = ref.watch(initProvider);
final hasProfile = ref.watch(
profilesProvider.select((state) => state.isNotEmpty),
);
return StartButtonSelectorState(isInit: isInit, hasProfile: hasProfile);
}
@riverpod
ProfilesSelectorState profilesSelectorState(Ref ref) {
ProfilesState profilesState(Ref ref) {
final currentProfileId = ref.watch(currentProfileIdProvider);
final profiles = ref.watch(profilesProvider);
final columns = ref.watch(
contentWidthProvider.select((state) => utils.getProfilesColumns(state)),
);
return ProfilesSelectorState(
return ProfilesState(
profiles: profiles,
currentProfileId: currentProfileId,
columns: columns,
@@ -349,8 +306,8 @@ VM2<List<String>, String?> proxiesTabControllerState(Ref ref) {
return ref.watch(
proxiesTabStateProvider.select(
(state) => VM2(
a: state.groups.map((group) => group.name).toList(),
b: state.currentGroupName,
state.groups.map((group) => group.name).toList(),
state.currentGroupName,
),
),
);
@@ -390,12 +347,12 @@ ProxyGroupSelectorState proxyGroupSelectorState(
@riverpod
PackageListSelectorState packageListSelectorState(Ref ref) {
final packages = ref.watch(packagesProvider);
final accessControl = ref.watch(
vpnSettingProvider.select((state) => state.accessControl),
final accessControlProps = ref.watch(
vpnSettingProvider.select((state) => state.accessControlProps),
);
return PackageListSelectorState(
packages: packages,
accessControl: accessControl,
accessControlProps: accessControlProps,
);
}
@@ -437,18 +394,19 @@ bool isCurrentPage(
}
@riverpod
String getRealTestUrl(Ref ref, [String? testUrl]) {
String realTestUrl(Ref ref, [String? testUrl]) {
final currentTestUrl = ref.watch(appSettingProvider).testUrl;
return testUrl.getSafeValue(currentTestUrl);
return testUrl.takeFirstValid([currentTestUrl]);
}
@riverpod
int? getDelay(Ref ref, {required String proxyName, String? testUrl}) {
final currentTestUrl = ref.watch(getRealTestUrlProvider(testUrl));
final currentTestUrl = ref.watch(realTestUrlProvider(testUrl));
final proxyState = ref.watch(realSelectedProxyStateProvider(proxyName));
final delay = ref.watch(
delayDataSourceProvider.select((state) {
final delayMap = state[proxyState.testUrl.getSafeValue(currentTestUrl)];
final delayMap =
state[proxyState.testUrl.takeFirstValid([currentTestUrl])];
return delayMap?[proxyState.proxyName];
}),
);
@@ -542,25 +500,8 @@ String getProxyDesc(Ref ref, Proxy proxy) {
}
@riverpod
OverrideData? getProfileOverrideData(Ref ref, String profileId) {
return ref.watch(
profilesProvider.select(
(state) => state.getProfile(profileId)?.overrideData,
),
);
}
@riverpod
VM2? layoutChange(Ref ref) {
final viewWidth = ref.watch(viewWidthProvider);
final textScale = ref.watch(
themeSettingProvider.select((state) => state.textScale),
);
return VM2(a: viewWidth, b: textScale);
}
@riverpod
VM2<int, bool> checkIp(Ref ref) {
VM3<bool, int, bool> checkIp(Ref ref) {
final isInit = ref.watch(initProvider);
final checkIpNum = ref.watch(checkIpNumProvider);
final containsDetection = ref.watch(
dashboardStateProvider.select(
@@ -568,7 +509,7 @@ VM2<int, bool> checkIp(Ref ref) {
state.dashboardWidgets.contains(DashboardWidget.networkDetection),
),
);
return VM2(a: checkIpNum, b: containsDetection);
return VM3(isInit, checkIpNum, containsDetection);
}
@riverpod
@@ -580,7 +521,7 @@ ColorScheme genColorScheme(
}) {
final vm2 = ref.watch(
themeSettingProvider.select(
(state) => VM2(a: state.primaryColor, b: state.schemeVariant),
(state) => VM2(state.primaryColor, state.schemeVariant),
),
);
if (color == null && (ignoreConfig == true || vm2.a == null)) {
@@ -605,19 +546,9 @@ ColorScheme genColorScheme(
}
@riverpod
VM4<String?, String?, Dns?, bool> needSetup(Ref ref) {
SetupState? currentSetupState(Ref ref) {
final profileId = ref.watch(currentProfileIdProvider);
// final content = ref.watch(
// scriptsProvider.select((state) => state.currentScript?.content),
// );
final overrideDns = ref.watch(overrideDnsProvider);
final dns = overrideDns == true
? ref.watch(patchClashConfigProvider.select((state) => state.dns))
: null;
final appendSystemDns = ref.watch(
networkSettingProvider.select((state) => state.appendSystemDns),
);
return VM4(profileId, '', dns, appendSystemDns);
return ref.watch(setupStateProvider(profileId)).value;
}
@riverpod
@@ -640,7 +571,7 @@ VM2<bool, bool> autoSetSystemDnsState(Ref ref) {
final autoSetSystemDns = ref.watch(
networkSettingProvider.select((state) => state.autoSetSystemDns),
);
return VM2(a: isStart ? realTunEnable : false, b: autoSetSystemDns);
return VM2(isStart ? realTunEnable : false, autoSetSystemDns);
}
@riverpod
@@ -652,26 +583,58 @@ VM3<bool, int, ProxiesSortType> needUpdateGroups(Ref ref) {
final sortType = ref.watch(
proxiesStyleSettingProvider.select((state) => state.sortType),
);
return VM3(a: isProxies, b: sortNum, c: sortType);
return VM3(isProxies, sortNum, sortType);
}
@riverpod
AndroidState androidState(Ref ref) {
final currentProfileName = ref.watch(
currentProfileProvider.select((state) => state?.label ?? ''),
);
final onlyStatisticsProxy = ref.watch(
appSettingProvider.select((state) => state.onlyStatisticsProxy),
);
SharedState sharedState(Ref ref) {
ref.watch((appSettingProvider).select((state) => state.locale));
final crashlytics = ref.watch(
(appSettingProvider).select((state) => state.crashlytics),
final currentProfileVM2 = ref.watch(
currentProfileProvider.select(
(state) => VM2(state?.label ?? '', state?.selectedMap ?? {}),
),
);
return AndroidState(
final appSettingVM3 = ref.watch(
appSettingProvider.select(
(state) =>
VM3(state.onlyStatisticsProxy, state.crashlytics, state.testUrl),
),
);
final bypassDomain = ref.watch(
networkSettingProvider.select((state) => state.bypassDomain),
);
final clashConfigVM2 = ref.watch(
patchClashConfigProvider.select(
(state) => VM2(state.tun.stack.name, state.mixedPort),
),
);
final vpnSetting = ref.watch(vpnSettingProvider);
final currentProfileName = currentProfileVM2.a;
final selectedMap = currentProfileVM2.b;
final onlyStatisticsProxy = appSettingVM3.a;
final crashlytics = appSettingVM3.b;
final testUrl = appSettingVM3.c;
final stack = clashConfigVM2.a;
final port = clashConfigVM2.b;
return SharedState(
currentProfileName: currentProfileName,
onlyStatisticsProxy: onlyStatisticsProxy,
stopText: appLocalizations.stop,
crashlytics: crashlytics,
stopTip: appLocalizations.stopVpn,
startTip: appLocalizations.startVpn,
setupParams: SetupParams(selectedMap: selectedMap, testUrl: testUrl),
vpnOptions: VpnOptions(
enable: vpnSetting.enable,
stack: stack,
systemProxy: vpnSetting.systemProxy,
port: port,
ipv6: vpnSetting.ipv6,
dnsHijacking: vpnSetting.dnsHijacking,
accessControlProps: vpnSetting.accessControlProps,
allowBypass: vpnSetting.allowBypass,
bypassDomain: bypassDomain,
),
);
}
@@ -688,16 +651,52 @@ double overlayTopOffset(Ref ref) {
}
@riverpod
Profile? profile(Ref ref, String profileId) {
Profile? profile(Ref ref, int? profileId) {
return ref.watch(
profilesProvider.select((state) => state.getProfile(profileId)),
);
}
@riverpod
Overwrite? profileOverwrite(Ref ref, String profileId) {
OverwriteType overwriteType(Ref ref, int? profileId) {
return ref.watch(
profileProvider(profileId).select((state) => state?.overwrite),
profileProvider(
profileId,
).select((state) => state?.overwriteType ?? OverwriteType.standard),
);
}
@riverpod
Future<Script?> script(Ref ref, int? scriptId) async {
final script = await ref.watch(
(scriptsProvider.future.select((state) async {
final scripts = await state;
return scripts.get(scriptId);
})),
);
return script;
}
@riverpod
Future<SetupState> setupState(Ref ref, int? profileId) async {
final profile = ref.watch(profileProvider(profileId));
final scriptId = profile?.scriptId;
final profileLastUpdateDate = profile?.lastUpdateDate?.millisecondsSinceEpoch;
final overwriteType = profile?.overwriteType ?? OverwriteType.standard;
final dns = ref.watch(patchClashConfigProvider.select((state) => state.dns));
final script = await ref.watch(scriptProvider(scriptId).future);
final overrideDns = ref.watch(overrideDnsProvider);
final List<Rule> addedRules = profileId != null
? await ref.watch(addedRuleStreamProvider(profileId).future)
: [];
return SetupState(
profileId: profileId,
profileLastUpdateDate: profileLastUpdateDate,
overwriteType: overwriteType,
addedRules: addedRules,
script: script,
overrideDns: overrideDns,
dns: dns,
);
}
@@ -705,20 +704,5 @@ Overwrite? profileOverwrite(Ref ref, String profileId) {
class AccessControlState extends _$AccessControlState
with AutoDisposeNotifierMixin {
@override
AccessControl build() => AccessControl();
}
@riverpod
SetupState setupState(Ref ref, String profileId) {
ref.watch(
profileProvider(profileId).select(
(state) =>
VM3(a: state?.id, b: state?.lastUpdateDate, c: state?.overwrite),
),
);
ref.watch(patchClashConfigProvider.select((state) => state.dns));
ref.watch(overrideDnsProvider);
ref.watch(scriptsProvider);
ref.watch(rulesProvider);
return globalState.getSetupState(profileId);
AccessControlProps build() => AccessControlProps();
}

View File

@@ -1,66 +1,52 @@
import 'dart:async';
import 'dart:convert';
import 'dart:ffi' as ffi;
import 'dart:io';
import 'dart:isolate';
import 'package:animations/animations.dart';
import 'package:dio/dio.dart';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:fl_clash/common/theme.dart';
import 'package:fl_clash/core/core.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/l10n/l10n.dart';
import 'package:fl_clash/plugins/service.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/providers/database.dart';
import 'package:fl_clash/widgets/dialog.dart';
import 'package:fl_clash/widgets/list.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_js/flutter_js.dart';
import 'package:material_color_utilities/palettes/core_palette.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:path/path.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:url_launcher/url_launcher.dart';
import 'common/common.dart';
import 'controller.dart';
import 'database/database.dart';
import 'l10n/l10n.dart';
import 'models/models.dart';
typedef UpdateTasks = List<FutureOr Function()>;
class GlobalState {
static GlobalState? _instance;
Map<CacheTag, FixedMap<String, double>> computeHeightMapCache = {};
final navigatorKey = GlobalKey<NavigatorState>();
Timer? timer;
Timer? groupsUpdateTimer;
late Config config;
late AppState appState;
bool isPre = true;
String? coreSHA256;
late PackageInfo packageInfo;
late final String coreSHA256;
late final PackageInfo packageInfo;
Function? updateCurrentDelayDebounce;
late Measure measure;
late CommonTheme theme;
late Color accentColor;
bool needInitStatus = true;
CorePalette? corePalette;
DateTime? startTime;
UpdateTasks tasks = [];
final navigatorKey = GlobalKey<NavigatorState>();
AppController? _appController;
bool isInit = false;
bool isUserDisconnected = false;
bool isService = false;
SetupState? lastSetupState;
VpnState? lastVpnState;
bool get isStart => startTime != null && startTime!.isBeforeNow;
AppController get appController => _appController!;
set appController(AppController appController) {
_appController = appController;
isInit = true;
}
GlobalState._internal();
factory GlobalState() {
@@ -68,55 +54,11 @@ class GlobalState {
return _instance!;
}
Future<void> initApp(int version) async {
Future<ProviderContainer> init(int version) async {
coreSHA256 = const String.fromEnvironment('CORE_SHA256');
isPre = const String.fromEnvironment('APP_ENV') != 'stable';
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(),
);
await _initDynamicColor();
await init();
await window?.init(version);
_shakingStore();
}
Future<void> _shakingStore() async {
final profileIds = config.profiles.map((item) => item.id);
final providersRootPath = await appPath.getProvidersRootPath();
final profilesRootPath = await appPath.profilesPath;
final entities = await Isolate.run<List<FileSystemEntity>>(() async {
final profilesDir = Directory(profilesRootPath);
final providersDir = Directory(providersRootPath);
final List<FileSystemEntity> entities = [];
if (await profilesDir.exists()) {
entities.addAll(
profilesDir.listSync().where(
(item) => !item.path.contains('providers'),
),
);
}
if (await providersDir.exists()) {
entities.addAll(providersDir.listSync());
}
return entities;
});
final deleteFutures = entities.map((entity) async {
if (!profileIds.contains(basenameWithoutExtension(entity.path))) {
final res = await coreController.deleteFile(entity.path);
if (res.isNotEmpty) {
throw res;
}
}
return true;
});
await Future.wait(deleteFutures);
return await _initData(version);
}
Future<void> _initDynamicColor() async {
@@ -128,19 +70,46 @@ class GlobalState {
} catch (_) {}
}
Future<void> init() async {
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();
config =
await preferences.getConfig() ?? Config(themeProps: defaultThemeProps);
await globalState.migrateOldData(config);
final configMap = await preferences.getConfigMap();
final config = await migration.migrationIfNeeded(
configMap,
sync: (data) async {
final newConfigMap = data.configMap;
final config = Config.realFromJson(newConfigMap);
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.appSetting.locale) ??
utils.getLocaleForString(config.appSettingProps.locale) ??
WidgetsBinding.instance.platformDispatcher.locale,
);
await window?.init(version, config.windowProps);
return container;
}
String get ua => config.patchClashConfig.globalUa ?? packageInfo.ua;
Future<void> startUpdateTasks([UpdateTasks? tasks]) async {
if (timer != null && timer!.isActive == true) return;
if (tasks != null) {
@@ -236,20 +205,42 @@ class GlobalState {
);
}
VpnOptions getVpnOptions() {
final vpnProps = config.vpnProps;
final networkProps = config.networkProps;
final port = config.patchClashConfig.mixedPort;
return VpnOptions(
stack: config.patchClashConfig.tun.stack.name,
enable: vpnProps.enable,
systemProxy: vpnProps.systemProxy,
port: port,
ipv6: vpnProps.ipv6,
dnsHijacking: vpnProps.dnsHijacking,
accessControl: vpnProps.accessControl,
allowBypass: vpnProps.allowBypass,
bypassDomain: networkProps.bypassDomain,
Future<bool?> showAllUpdatingMessagesDialog(
List<UpdatingMessage> messages,
) async {
return await showCommonDialog<bool>(
child: Builder(
builder: (context) {
return CommonDialog(
padding: EdgeInsets.zero,
title: appLocalizations.tip,
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: Text(appLocalizations.confirm),
),
],
child: Container(
padding: EdgeInsets.symmetric(vertical: 4),
constraints: const BoxConstraints(maxHeight: 200),
child: ListView.separated(
itemBuilder: (_, index) {
final message = messages[index];
return ListItem(
padding: EdgeInsets.symmetric(horizontal: 24),
title: Text(message.label),
subtitle: Text(message.message),
);
},
itemCount: messages.length,
separatorBuilder: (_, _) => Divider(height: 0),
),
),
);
},
),
);
}
@@ -290,313 +281,6 @@ class GlobalState {
launchUrl(Uri.parse(url));
}
Future<void> migrateOldData(Config config) async {
final clashConfig = await preferences.getClashConfig();
if (clashConfig != null) {
config = config.copyWith(patchClashConfig: clashConfig);
preferences.clearClashConfig();
preferences.saveConfig(config);
}
}
Future<SetupParams> getSetupParams() async {
final params = SetupParams(
selectedMap: config.currentProfile?.selectedMap ?? {},
testUrl: config.appSetting.testUrl,
);
return params;
}
Future<Map> getConfigMap(String profileId) async {
var res = {};
try {
final setupState = globalState.getSetupState(profileId);
res = await makeRealConfig(
setupState: setupState,
patchConfig: config.patchClashConfig,
);
} catch (e) {
globalState.showNotifier(e.toString());
res = {};
}
return res;
}
Future<void> genValidateFile(String path, String data) async {
final res = await Isolate.run<String>(() async {
try {
final file = File(path);
if (!await file.exists()) {
await file.create(recursive: true);
}
await file.writeAsString(data);
return '';
} catch (e) {
return e.toString();
}
});
if (res.isNotEmpty) {
throw res;
}
}
Future<void> genValidateFileFormBytes(String path, Uint8List bytes) async {
final res = await Isolate.run<String>(() async {
try {
final file = File(path);
if (!await file.exists()) {
await file.create(recursive: true);
}
await file.writeAsBytes(bytes);
return '';
} catch (e) {
return e.toString();
}
});
if (res.isNotEmpty) {
throw res;
}
}
AndroidState getAndroidState() {
return AndroidState(
currentProfileName: config.currentProfile?.label ?? '',
onlyStatisticsProxy: config.appSetting.onlyStatisticsProxy,
stopText: appLocalizations.stop,
crashlytics: config.appSetting.crashlytics,
);
}
String getSelectedProxyName(String groupName) {
final group = appState.groups.getGroup(groupName);
final proxyName = config.currentProfile?.selectedMap[groupName];
return group?.getCurrentSelectedName(proxyName ?? '') ?? '';
}
Future<String> setupConfig({
required SetupState setupState,
required ClashConfig patchConfig,
VoidCallback? preloadInvoke,
}) async {
final config = await makeRealConfig(
setupState: setupState,
patchConfig: patchConfig,
);
final configFilePath = await appPath.configFilePath;
final res = await Isolate.run<String>(() async {
try {
final res = yaml.encode(config);
final file = File(configFilePath);
if (!await file.exists()) {
await file.create(recursive: true);
}
await file.writeAsString(res);
return '';
} catch (e) {
return e.toString();
}
});
if (res.isNotEmpty) {
throw res;
}
final params = await globalState.getSetupParams();
return await coreController.setupConfig(
params: params,
setupState: setupState,
preloadInvoke: preloadInvoke,
);
}
Future<Map<String, dynamic>> makeRealConfig({
required SetupState setupState,
required ClashConfig patchConfig,
}) async {
final profileId = setupState.profileId;
if (profileId?.isNotEmpty != true) {
return {};
}
final configMap = await getProfileConfig(profileId!);
String? scriptContent;
final List<Rule> addedRules = [];
if (setupState.overwriteType == OverwriteType.script) {
scriptContent = setupState.scriptContent;
} else {
addedRules.addAll(setupState.addedRules);
}
final defaultUA = packageInfo.ua;
final appendSystemDns = config.networkProps.appendSystemDns;
final realPatchConfig = patchConfig.copyWith(
tun: patchConfig.tun.getRealTun(config.networkProps.routeMode),
);
final overrideDns = globalState.config.overrideDns;
Map<String, dynamic> rawConfig = configMap;
if (scriptContent?.isNotEmpty == true) {
rawConfig = await handleEvaluate(scriptContent!, rawConfig);
}
final directory = await appPath.profilesPath;
String getProvidersFilePathInner(String type, String url) {
return join(directory, 'providers', profileId, type, url.toMd5());
}
final res = await Isolate.run<Map<String, dynamic>>(() async {
rawConfig['external-controller'] =
realPatchConfig.externalController.value;
rawConfig['external-ui'] = '';
rawConfig['interface-name'] = '';
rawConfig['external-ui-url'] = '';
rawConfig['tcp-concurrent'] = realPatchConfig.tcpConcurrent;
rawConfig['unified-delay'] = realPatchConfig.unifiedDelay;
rawConfig['ipv6'] = realPatchConfig.ipv6;
rawConfig['log-level'] = realPatchConfig.logLevel.name;
rawConfig['port'] = 0;
rawConfig['socks-port'] = 0;
rawConfig['keep-alive-interval'] = realPatchConfig.keepAliveInterval;
rawConfig['mixed-port'] = realPatchConfig.mixedPort;
rawConfig['port'] = realPatchConfig.port;
rawConfig['socks-port'] = realPatchConfig.socksPort;
rawConfig['redir-port'] = realPatchConfig.redirPort;
rawConfig['tproxy-port'] = realPatchConfig.tproxyPort;
rawConfig['find-process-mode'] = realPatchConfig.findProcessMode.name;
rawConfig['allow-lan'] = realPatchConfig.allowLan;
rawConfig['mode'] = realPatchConfig.mode.name;
if (rawConfig['tun'] == null) {
rawConfig['tun'] = {};
}
rawConfig['tun']['enable'] = realPatchConfig.tun.enable;
rawConfig['tun']['device'] = realPatchConfig.tun.device;
rawConfig['tun']['dns-hijack'] = realPatchConfig.tun.dnsHijack;
rawConfig['tun']['stack'] = realPatchConfig.tun.stack.name;
rawConfig['tun']['route-address'] = realPatchConfig.tun.routeAddress;
rawConfig['tun']['auto-route'] = realPatchConfig.tun.autoRoute;
rawConfig['geodata-loader'] = realPatchConfig.geodataLoader.name;
if (rawConfig['sniffer']?['sniff'] != null) {
for (final value in (rawConfig['sniffer']?['sniff'] as Map).values) {
if (value['ports'] != null && value['ports'] is List) {
value['ports'] =
value['ports']?.map((item) => item.toString()).toList() ?? [];
}
}
}
if (rawConfig['profile'] == null) {
rawConfig['profile'] = {};
}
if (rawConfig['proxy-providers'] != null) {
final proxyProviders = rawConfig['proxy-providers'] as Map;
for (final key in proxyProviders.keys) {
final proxyProvider = proxyProviders[key];
if (proxyProvider['type'] != 'http') {
continue;
}
if (proxyProvider['url'] != null) {
proxyProvider['path'] = getProvidersFilePathInner(
'proxies',
proxyProvider['url'],
);
}
}
}
if (rawConfig['rule-providers'] != null) {
final ruleProviders = rawConfig['rule-providers'] as Map;
for (final key in ruleProviders.keys) {
final ruleProvider = ruleProviders[key];
if (ruleProvider['type'] != 'http') {
continue;
}
if (ruleProvider['url'] != null) {
ruleProvider['path'] = getProvidersFilePathInner(
'rules',
ruleProvider['url'],
);
}
}
}
rawConfig['profile']['store-selected'] = false;
rawConfig['geox-url'] = realPatchConfig.geoXUrl.toJson();
rawConfig['global-ua'] = realPatchConfig.globalUa ?? defaultUA;
if (rawConfig['hosts'] == null) {
rawConfig['hosts'] = {};
}
for (final host in realPatchConfig.hosts.entries) {
rawConfig['hosts'][host.key] = host.value.splitByMultipleSeparators;
}
if (rawConfig['dns'] == null) {
rawConfig['dns'] = {};
}
final isEnableDns = rawConfig['dns']['enable'] == true;
final systemDns = 'system://';
if (overrideDns || !isEnableDns) {
final dns = switch (!isEnableDns) {
true => realPatchConfig.dns.copyWith(
nameserver: [...realPatchConfig.dns.nameserver, systemDns],
),
false => realPatchConfig.dns,
};
rawConfig['dns'] = dns.toJson();
rawConfig['dns']['nameserver-policy'] = {};
for (final entry in dns.nameserverPolicy.entries) {
rawConfig['dns']['nameserver-policy'][entry.key] =
entry.value.splitByMultipleSeparators;
}
}
if (appendSystemDns) {
final List<String> nameserver = List<String>.from(
rawConfig['dns']['nameserver'] ?? [],
);
if (!nameserver.contains(systemDns)) {
rawConfig['dns']['nameserver'] = [...nameserver, systemDns];
}
}
List<String> rules = [];
if (rawConfig['rules'] != null) {
rules = List<String>.from(rawConfig['rules']);
}
rawConfig.remove('rules');
if (addedRules.isNotEmpty) {
final parsedNewRules = addedRules
.map((item) => ParsedRule.parseString(item.value))
.toList();
final hasMatchPlaceholder = parsedNewRules.any(
(item) => item.ruleTarget?.toUpperCase() == 'MATCH',
);
String? replacementTarget;
if (hasMatchPlaceholder) {
for (int i = rules.length - 1; i >= 0; i--) {
final parsed = ParsedRule.parseString(rules[i]);
if (parsed.ruleAction == RuleAction.MATCH) {
final target = parsed.ruleTarget;
if (target != null && target.isNotEmpty) {
replacementTarget = target;
break;
}
}
}
}
final List<String> finalAddedRules;
if (replacementTarget?.isNotEmpty == true) {
finalAddedRules = [];
for (int i = 0; i < parsedNewRules.length; i++) {
final parsed = parsedNewRules[i];
if (parsed.ruleTarget?.toUpperCase() == 'MATCH') {
finalAddedRules.add(
parsed.copyWith(ruleTarget: replacementTarget).value,
);
} else {
finalAddedRules.add(addedRules[i].value);
}
}
} else {
finalAddedRules = addedRules.map((e) => e.value).toList();
}
rules = [...finalAddedRules, ...rules];
}
rawConfig['rules'] = rules;
return rawConfig;
});
return res;
}
Future<Map<String, dynamic>> handleEvaluate(
String scriptContent,
Map<String, dynamic> config,
@@ -619,117 +303,6 @@ class GlobalState {
};
return value ?? config;
}
SetupState getSetupState(String? profileId) {
final profile = config.profiles.getProfile(profileId);
final profileState = VM3(
a: profile?.id,
b: profile?.lastUpdateDate,
c: profile?.overwrite,
);
final overwrite = profileState.c;
final scriptContent = config.scripts
.get(overwrite?.scriptOverwrite.scriptId)
?.content;
final standardOverwrite =
overwrite?.standardOverwrite ?? StandardOverwrite();
final rules = config.rules;
final globalAddedRules = rules.where(
(item) => !standardOverwrite.disabledRuleIds.contains(item.id),
);
final addedRules = [...standardOverwrite.addedRules, ...globalAddedRules];
return SetupState(
profileId: profileId,
profileLastUpdateDate: profile?.lastUpdateDate?.millisecondsSinceEpoch,
overwriteType: profile?.overwrite.type ?? OverwriteType.standard,
addedRules: addedRules,
scriptContent: scriptContent,
overrideDns: config.overrideDns,
dns: config.patchClashConfig.dns,
);
}
Future<Map<String, dynamic>> getProfileConfig(String profileId) async {
final configMap = await coreController.getConfig(profileId);
configMap['rules'] = configMap['rule'];
configMap.remove('rule');
return configMap;
}
}
final globalState = GlobalState();
class DetectionState {
static DetectionState? _instance;
bool? _preIsStart;
Timer? _setTimeoutTimer;
CancelToken? cancelToken;
final state = ValueNotifier<NetworkDetectionState>(
const NetworkDetectionState(isLoading: true, ipInfo: null),
);
DetectionState._internal();
factory DetectionState() {
_instance ??= DetectionState._internal();
return _instance!;
}
void startCheck() {
debouncer.call(
FunctionTag.checkIp,
_checkIp,
duration: Duration(milliseconds: 1200),
);
}
void tryStartCheck() {
if (state.value.isLoading == false && state.value.ipInfo == null) {
startCheck();
}
}
Future<void> _checkIp() async {
final appState = globalState.appState;
final isInit = appState.isInit;
if (!isInit) return;
final isStart = appState.runTime != null;
if (_preIsStart == false &&
_preIsStart == isStart &&
state.value.ipInfo != null) {
return;
}
_clearSetTimeoutTimer();
state.value = state.value.copyWith(isLoading: true, ipInfo: null);
_preIsStart = isStart;
if (cancelToken != null) {
cancelToken!.cancel();
cancelToken = null;
}
cancelToken = CancelToken();
final res = await request.checkIp(cancelToken: cancelToken);
if (res.isError) {
state.value = state.value.copyWith(isLoading: true, ipInfo: null);
return;
}
final ipInfo = res.data;
if (ipInfo != null) {
state.value = state.value.copyWith(isLoading: false, ipInfo: ipInfo);
return;
}
_clearSetTimeoutTimer();
_setTimeoutTimer = Timer(const Duration(milliseconds: 300), () {
state.value = state.value.copyWith(isLoading: false, ipInfo: null);
});
}
void _clearSetTimeoutTimer() {
if (_setTimeoutTimer != null) {
_setTimeoutTimer?.cancel();
_setTimeoutTimer = null;
}
}
}
final detectionState = DetectionState();

View File

@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/list.dart';
@@ -25,12 +26,11 @@ class AboutView extends StatelessWidget {
const AboutView({super.key});
Future<void> _checkUpdate(BuildContext context) async {
final data = await globalState.appController.safeRun<Map<String, dynamic>?>(
final data = await appController.safeRun<Map<String, dynamic>?>(
request.checkForUpdate,
title: appLocalizations.checkUpdate,
needLoading: true,
);
globalState.appController.checkUpdateResultHandle(data: data, isUser: true);
appController.checkUpdateResultHandle(data: data, isUser: true);
}
List<Widget> _buildMoreSection(BuildContext context) {
@@ -144,9 +144,7 @@ class AboutView extends StatelessWidget {
onEnterDeveloperMode: () {
ref
.read(appSettingProvider.notifier)
.updateState(
(state) => state.copyWith(developerMode: true),
);
.update((state) => state.copyWith(developerMode: true));
context.showNotifier(
appLocalizations.developerModeEnableTip,
);

View File

@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/plugins/app.dart';
@@ -31,9 +32,9 @@ class _AccessViewState extends ConsumerState<AccessView> {
void initState() {
super.initState();
_controller = ScrollController();
_completer.complete(globalState.appController.getPackages());
_completer.complete(appController.getPackages());
final accessControl = ref
.read(vpnSettingProvider.select((state) => state.accessControl))
.read(vpnSettingProvider.select((state) => state.accessControlProps))
.copyWith();
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(accessControlStateProvider.notifier).value = accessControl;
@@ -91,12 +92,9 @@ class _AccessViewState extends ConsumerState<AccessView> {
return;
}
final selectedPackageNames =
(await globalState.appController.safeRun<List<String>>(
needLoading: true,
() async {
return await app?.getChinaPackageNames() ?? [];
},
))?.toSet() ??
(await appController.loadingRun<List<String>>(() async {
return await app?.getChinaPackageNames() ?? [];
}, tag: LoadingTag.access))?.toSet() ??
{};
final acceptList = packageNames
.where((item) => !selectedPackageNames.contains(item))
@@ -157,7 +155,9 @@ class _AccessViewState extends ConsumerState<AccessView> {
}
}
AccessControl _getRealAccessControl(AccessControl accessControl) {
AccessControlProps _getRealAccessControlProps(
AccessControlProps accessControl,
) {
final packages = ref.read(packagesProvider);
if (packages.isEmpty) {
return accessControl;
@@ -183,7 +183,7 @@ class _AccessViewState extends ConsumerState<AccessView> {
.read(vpnSettingProvider.notifier)
.update(
(state) => state.copyWith(
accessControl: _getRealAccessControl(accessControl),
accessControlProps: _getRealAccessControlProps(accessControl),
),
);
}
@@ -195,7 +195,8 @@ class _AccessViewState extends ConsumerState<AccessView> {
final noSave = ref.watch(
vpnSettingProvider.select(
(state) =>
state.accessControl == _getRealAccessControl(accessControl),
state.accessControlProps ==
_getRealAccessControlProps(accessControl),
),
);
if (noSave) {
@@ -219,7 +220,7 @@ class _AccessViewState extends ConsumerState<AccessView> {
}
Future<void> _exportToClipboard() async {
await globalState.appController.safeRun(() {
await appController.safeRun(() {
final currentList = ref.read(
accessControlStateProvider.select((state) => state.currentList),
);
@@ -228,7 +229,7 @@ class _AccessViewState extends ConsumerState<AccessView> {
}
Future<void> _importFormClipboard() async {
await globalState.appController.safeRun(() async {
await appController.safeRun(() async {
final data = await Clipboard.getData('text/plain');
final text = data?.text;
if (text == null) return;
@@ -371,6 +372,7 @@ class _AccessViewState extends ConsumerState<AccessView> {
@override
Widget build(BuildContext context) {
final isLoading = ref.watch(loadingProvider(LoadingTag.access));
final query = ref.watch(queryProvider(QueryTag.access));
final packages = ref.watch(packagesProvider);
final accessControl = ref.watch(accessControlStateProvider);
@@ -401,6 +403,7 @@ class _AccessViewState extends ConsumerState<AccessView> {
final valueList = currentList.intersection(viewPackageNameList);
return CommonScaffold(
key: _scaffoldKey,
isLoading: isLoading,
searchState: AppBarSearchState(onSearch: _onSearch, autoAddSearch: false),
title: appLocalizations.appAccessControl,
actions: _buildActions(enable: accessControl.enable),
@@ -602,8 +605,8 @@ class _AccessControlPanelState extends ConsumerState<AccessControlPanel> {
final vm2 = ref.watch(
accessControlStateProvider.select(
(state) => VM2(
a: state.isFilterSystemApp,
b: state.isFilterNonInternetApp,
state.isFilterSystemApp,
state.isFilterNonInternetApp,
),
),
);

View File

@@ -21,7 +21,7 @@ class CloseConnectionsItem extends ConsumerWidget {
onChanged: (value) async {
ref
.read(appSettingProvider.notifier)
.updateState((state) => state.copyWith(closeConnections: value));
.update((state) => state.copyWith(closeConnections: value));
},
),
);
@@ -44,9 +44,7 @@ class UsageItem extends ConsumerWidget {
onChanged: (bool value) async {
ref
.read(appSettingProvider.notifier)
.updateState(
(state) => state.copyWith(onlyStatisticsProxy: value),
);
.update((state) => state.copyWith(onlyStatisticsProxy: value));
},
),
);
@@ -69,7 +67,7 @@ class MinimizeItem extends ConsumerWidget {
onChanged: (bool value) {
ref
.read(appSettingProvider.notifier)
.updateState((state) => state.copyWith(minimizeOnExit: value));
.update((state) => state.copyWith(minimizeOnExit: value));
},
),
);
@@ -92,7 +90,7 @@ class AutoLaunchItem extends ConsumerWidget {
onChanged: (bool value) {
ref
.read(appSettingProvider.notifier)
.updateState((state) => state.copyWith(autoLaunch: value));
.update((state) => state.copyWith(autoLaunch: value));
},
),
);
@@ -115,7 +113,7 @@ class SilentLaunchItem extends ConsumerWidget {
onChanged: (bool value) {
ref
.read(appSettingProvider.notifier)
.updateState((state) => state.copyWith(silentLaunch: value));
.update((state) => state.copyWith(silentLaunch: value));
},
),
);
@@ -138,7 +136,7 @@ class AutoRunItem extends ConsumerWidget {
onChanged: (bool value) {
ref
.read(appSettingProvider.notifier)
.updateState((state) => state.copyWith(autoRun: value));
.update((state) => state.copyWith(autoRun: value));
},
),
);
@@ -161,7 +159,7 @@ class HiddenItem extends ConsumerWidget {
onChanged: (value) {
ref
.read(appSettingProvider.notifier)
.updateState((state) => state.copyWith(hidden: value));
.update((state) => state.copyWith(hidden: value));
},
),
);
@@ -184,7 +182,7 @@ class AnimateTabItem extends ConsumerWidget {
onChanged: (value) {
ref
.read(appSettingProvider.notifier)
.updateState((state) => state.copyWith(isAnimateToPage: value));
.update((state) => state.copyWith(isAnimateToPage: value));
},
),
);
@@ -207,7 +205,7 @@ class OpenLogsItem extends ConsumerWidget {
onChanged: (bool value) {
ref
.read(appSettingProvider.notifier)
.updateState((state) => state.copyWith(openLogs: value));
.update((state) => state.copyWith(openLogs: value));
},
),
);
@@ -230,7 +228,7 @@ class CrashlyticsItem extends ConsumerWidget {
onChanged: (bool value) {
ref
.read(appSettingProvider.notifier)
.updateState((state) => state.copyWith(crashlytics: value));
.update((state) => state.copyWith(crashlytics: value));
},
),
);
@@ -253,7 +251,7 @@ class AutoCheckUpdateItem extends ConsumerWidget {
onChanged: (bool value) {
ref
.read(appSettingProvider.notifier)
.updateState((state) => state.copyWith(autoCheckUpdate: value));
.update((state) => state.copyWith(autoCheckUpdate: value));
},
),
);

Some files were not shown because too many files have changed in this diff Show More