Optimize desktop view

Optimize logs, requests, connection pages

Optimize windows tray auto hide

Optimize some details

Update core
This commit is contained in:
chen08209
2025-06-07 01:48:34 +08:00
parent adb890d763
commit 1154e7b245
169 changed files with 6484 additions and 5230 deletions

View File

@@ -62,7 +62,7 @@ class ApplicationState extends ConsumerState<Application> {
});
}
_autoUpdateGroupTask() {
void _autoUpdateGroupTask() {
_autoUpdateGroupTaskTimer = Timer(const Duration(milliseconds: 20000), () {
WidgetsBinding.instance.addPostFrameCallback((_) {
globalState.appController.updateGroupsDebounce();
@@ -71,14 +71,14 @@ class ApplicationState extends ConsumerState<Application> {
});
}
_autoUpdateProfilesTask() {
void _autoUpdateProfilesTask() {
_autoUpdateProfilesTaskTimer = Timer(const Duration(minutes: 20), () async {
await globalState.appController.autoUpdateProfiles();
_autoUpdateProfilesTask();
});
}
_buildPlatformState(Widget child) {
Widget _buildPlatformState(Widget child) {
if (system.isDesktop) {
return WindowManager(
child: TrayManager(
@@ -97,13 +97,13 @@ class ApplicationState extends ConsumerState<Application> {
);
}
_buildState(Widget child) {
Widget _buildState(Widget child) {
return AppStateManager(
child: ClashManager(
child: ConnectivityManager(
onConnectivityChanged: (results) async {
if (!results.contains(ConnectivityResult.vpn)) {
await clashCore.closeConnections();
clashCore.closeConnections();
}
globalState.appController.updateLocalIp();
globalState.appController.addCheckIpNumDebounce();
@@ -114,7 +114,7 @@ class ApplicationState extends ConsumerState<Application> {
);
}
_buildPlatformApp(Widget child) {
Widget _buildPlatformApp(Widget child) {
if (system.isDesktop) {
return WindowHeaderContainer(
child: child,
@@ -125,7 +125,7 @@ class ApplicationState extends ConsumerState<Application> {
);
}
_buildApp(Widget child) {
Widget _buildApp(Widget child) {
return MessageManager(
child: ThemeManager(
child: child,
@@ -153,8 +153,12 @@ class ApplicationState extends ConsumerState<Application> {
],
builder: (_, child) {
return AppEnvManager(
child: _buildPlatformApp(
_buildApp(child!),
child: _buildApp(
AppSidebarContainer(
child: _buildPlatformApp(
child!,
),
),
),
);
},
@@ -179,7 +183,7 @@ class ApplicationState extends ConsumerState<Application> {
primaryColor: themeProps.primaryColor,
).toPureBlack(themeProps.pureBlack),
),
home: child,
home: child!,
);
},
child: const HomePage(),

View File

@@ -17,7 +17,7 @@ class ClashCore {
late ClashHandlerInterface clashInterface;
ClashCore._internal() {
if (Platform.isAndroid) {
if (system.isAndroid) {
clashInterface = clashLib!;
} else {
clashInterface = clashService!;
@@ -84,7 +84,7 @@ class ClashCore {
return await clashInterface.setState(state);
}
shutdown() async {
Future<void> shutdown() async {
await clashInterface.shutdown();
}
@@ -107,14 +107,14 @@ class ClashCore {
if (proxies.isEmpty) return [];
final groupNames = [
UsedProxy.GLOBAL.name,
...(proxies[UsedProxy.GLOBAL.name]["all"] as List).where((e) {
...(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)
group['all'] = ((group['all'] ?? []) as List)
.map(
(name) => proxies[name],
)
@@ -133,22 +133,22 @@ class ClashCore {
return await clashInterface.changeProxy(changeProxyParams);
}
Future<List<Connection>> getConnections() async {
Future<List<TrackerInfo>> getConnections() async {
final res = await clashInterface.getConnections();
final connectionsData = json.decode(res) as Map;
final connectionsRaw = connectionsData['connections'] as List? ?? [];
return connectionsRaw.map((e) => Connection.fromJson(e)).toList();
return connectionsRaw.map((e) => TrackerInfo.fromJson(e)).toList();
}
closeConnection(String id) {
void closeConnection(String id) {
clashInterface.closeConnection(id);
}
closeConnections() {
void closeConnections() {
clashInterface.closeConnections();
}
resetConnections() {
void resetConnections() {
clashInterface.resetConnections();
}
@@ -202,11 +202,11 @@ class ClashCore {
return clashInterface.updateExternalProvider(providerName);
}
startListener() async {
Future<void> startListener() async {
await clashInterface.startListener();
}
stopListener() async {
Future<void> stopListener() async {
await clashInterface.stopListener();
}
@@ -260,23 +260,23 @@ class ClashCore {
return int.parse(value);
}
resetTraffic() {
void resetTraffic() {
clashInterface.resetTraffic();
}
startLog() {
void startLog() {
clashInterface.startLog();
}
stopLog() {
void stopLog() {
clashInterface.stopLog();
}
requestGc() {
clashInterface.forceGc();
Future<void> requestGc() async {
await clashInterface.forceGc();
}
destroy() async {
Future<void> destroy() async {
await clashInterface.destroy();
}
}

View File

@@ -57,11 +57,11 @@ mixin ClashInterface {
FutureOr<String> getMemory();
resetTraffic();
FutureOr<void> resetTraffic();
startLog();
FutureOr<void> startLog();
stopLog();
FutureOr<void> stopLog();
Future<bool> crash();
@@ -89,7 +89,7 @@ mixin AndroidClashInterface {
abstract class ClashHandlerInterface with ClashInterface {
Map<String, Completer> callbackCompleterMap = {};
handleResult(ActionResult result) async {
Future<void> handleResult(ActionResult result) async {
final completer = callbackCompleterMap[result.id];
try {
switch (result.method) {
@@ -105,13 +105,13 @@ abstract class ClashHandlerInterface with ClashInterface {
return;
}
} catch (e) {
commonPrint.log("${result.id} error $e");
commonPrint.log('${result.id} error $e');
}
}
sendMessage(String message);
void sendMessage(String message);
reStart();
FutureOr<void> reStart();
FutureOr<bool> destroy();
@@ -122,14 +122,14 @@ abstract class ClashHandlerInterface with ClashInterface {
FutureOr<T> Function()? onTimeout,
T? defaultValue,
}) async {
final id = "${method.name}#${utils.id}";
final id = '${method.name}#${utils.id}';
callbackCompleterMap[id] = Completer<T>();
dynamic mDefaultValue = defaultValue;
if (mDefaultValue == null) {
if (T == String) {
mDefaultValue = "";
mDefaultValue = '';
} else if (T == bool) {
mDefaultValue = false;
} else if (T == Map) {
@@ -290,8 +290,8 @@ abstract class ClashHandlerInterface with ClashInterface {
return invoke<String>(
method: ActionMethod.sideLoadExternalProvider,
data: json.encode({
"providerName": providerName,
"data": data,
'providerName': providerName,
'data': data,
}),
);
}
@@ -382,9 +382,9 @@ abstract class ClashHandlerInterface with ClashInterface {
@override
Future<String> asyncTestDelay(String url, String proxyName) {
final delayParams = {
"proxy-name": proxyName,
"timeout": httpTimeoutDuration.inMilliseconds,
"test-url": url,
'proxy-name': proxyName,
'timeout': httpTimeoutDuration.inMilliseconds,
'test-url': url,
};
return invoke<String>(
method: ActionMethod.asyncTestDelay,

View File

@@ -1,7 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'dart:isolate';
import 'dart:ui';
@@ -30,7 +29,7 @@ class ClashLib extends ClashHandlerInterface with AndroidClashInterface {
return _canSendCompleter.future;
}
_initService() async {
Future<void> _initService() async {
await service?.destroy();
_registerMainPort(receiverPort.sendPort);
receiverPort.listen((message) {
@@ -52,7 +51,7 @@ class ClashLib extends ClashHandlerInterface with AndroidClashInterface {
await service?.init();
}
_registerMainPort(SendPort sendPort) {
void _registerMainPort(SendPort sendPort) {
IsolateNameServer.removePortNameMapping(mainIsolate);
IsolateNameServer.registerPortWithName(sendPort, mainIsolate);
}
@@ -139,7 +138,7 @@ class ClashLibHandler {
late final DynamicLibrary lib;
ClashLibHandler._internal() {
lib = DynamicLibrary.open("libclash.so");
lib = DynamicLibrary.open('libclash.so');
clashFFI = ClashFFI(lib);
clashFFI.initNativeApiBridge(
NativeApi.initializeApiDLData,
@@ -169,19 +168,19 @@ class ClashLibHandler {
return completer.future;
}
attachMessagePort(int messagePort) {
void attachMessagePort(int messagePort) {
clashFFI.attachMessagePort(
messagePort,
);
}
updateDns(String dns) {
void updateDns(String dns) {
final dnsChar = dns.toNativeUtf8().cast<Char>();
clashFFI.updateDns(dnsChar);
malloc.free(dnsChar);
}
setState(CoreState state) {
void setState(CoreState state) {
final stateChar = json.encode(state).toNativeUtf8().cast<Char>();
clashFFI.setState(stateChar);
malloc.free(stateChar);
@@ -221,12 +220,12 @@ class ClashLibHandler {
return Traffic.fromMap(json.decode(trafficString));
}
startListener() async {
Future<bool> startListener() async {
clashFFI.startListener();
return true;
}
stopListener() async {
Future<bool> stopListener() async {
clashFFI.stopListener();
return true;
}
@@ -287,7 +286,7 @@ class ClashLibHandler {
}
ClashLib? get clashLib =>
Platform.isAndroid && !globalState.isService ? ClashLib() : null;
system.isAndroid && !globalState.isService ? ClashLib() : null;
ClashLibHandler? get clashLibHandler =>
Platform.isAndroid && globalState.isService ? ClashLibHandler() : null;
system.isAndroid && globalState.isService ? ClashLibHandler() : null;

View File

@@ -23,7 +23,7 @@ class ClashMessage {
listener.onDelay(Delay.fromJson(m.data));
break;
case AppMessageType.request:
listener.onRequest(Connection.fromJson(m.data));
listener.onRequest(TrackerInfo.fromJson(m.data));
break;
case AppMessageType.loaded:
listener.onLoaded(m.data);

View File

@@ -28,9 +28,9 @@ class ClashService extends ClashHandlerInterface {
reStart();
}
_initServer() async {
Future<void> _initServer() async {
runZonedGuarded(() async {
final address = !Platform.isWindows
final address = !system.isWindows
? InternetAddress(
unixSocketPath,
type: InternetAddressType.unix,
@@ -83,10 +83,10 @@ class ClashService extends ClashHandlerInterface {
await shutdown();
}
final serverSocket = await serverCompleter.future;
final arg = Platform.isWindows
? "${serverSocket.port}"
final arg = system.isWindows
? '${serverSocket.port}'
: serverSocket.address.address;
if (Platform.isWindows && await system.checkIsAdmin()) {
if (system.isWindows && await system.checkIsAdmin()) {
final isSuccess = await request.startCoreByHelper(arg);
if (isSuccess) {
return;
@@ -122,8 +122,8 @@ class ClashService extends ClashHandlerInterface {
socket.writeln(message);
}
_deleteSocketFile() async {
if (!Platform.isWindows) {
Future<void> _deleteSocketFile() async {
if (!system.isWindows) {
final file = File(unixSocketPath);
if (await file.exists()) {
await file.delete();
@@ -131,7 +131,7 @@ class ClashService extends ClashHandlerInterface {
}
}
_destroySocket() async {
Future<void> _destroySocket() async {
if (socketCompleter.isCompleted) {
final lastSocket = await socketCompleter.future;
await lastSocket.close();
@@ -141,7 +141,7 @@ class ClashService extends ClashHandlerInterface {
@override
shutdown() async {
if (Platform.isWindows) {
if (system.isWindows) {
await request.stopCoreByHelper();
}
await _destroySocket();

View File

@@ -1,14 +1,14 @@
import 'dart:io';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/state.dart';
import 'system.dart';
class Android {
init() async {
Future<void> init() async {
app?.onExit = () async {
await globalState.appController.savePreferences();
};
}
}
final android = Platform.isAndroid ? Android() : null;
final android = system.isAndroid ? Android() : null;

View File

@@ -1,10 +1,11 @@
import 'dart:convert';
import 'dart:io';
import 'package:archive/archive_io.dart';
import 'package:path/path.dart';
extension ArchiveExt on Archive {
addDirectoryToArchive(String dirPath, String parentPath) {
void addDirectoryToArchive(String dirPath, String parentPath) {
final dir = Directory(dirPath);
final entities = dir.listSync(recursive: false);
for (final entity in entities) {
@@ -19,7 +20,7 @@ extension ArchiveExt on Archive {
}
}
add<T>(String name, T raw) {
void add<T>(String name, T raw) {
final data = json.encode(raw);
addFile(
ArchiveFile(name, data.length, data),

View File

@@ -23,6 +23,10 @@ extension ColorExtension on Color {
return withAlpha(77);
}
Color get opacity12 {
return withAlpha(31);
}
Color get opacity15 {
return withAlpha(38);
}

View File

@@ -37,4 +37,3 @@ export 'text.dart';
export 'tray.dart';
export 'utils.dart';
export 'window.dart';
export 'windows.dart';

View File

@@ -1,4 +1,3 @@
import 'dart:io';
import 'dart:math';
import 'dart:ui';
@@ -8,13 +7,13 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:flutter/material.dart';
const appName = "FlClash";
const appHelperService = "FlClashHelperService";
const coreName = "clash.meta";
const appName = 'FlClash';
const appHelperService = 'FlClashHelperService';
const coreName = 'clash.meta';
const browserUa =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
const packageName = "com.follow.clash";
final unixSocketPath = "/tmp/FlClashSocket_${Random().nextInt(10000)}.sock";
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
const packageName = 'com.follow.clash';
final unixSocketPath = '/tmp/FlClashSocket_${Random().nextInt(10000)}.sock';
const helperPort = 47890;
const maxTextScale = 1.4;
const minTextScale = 0.8;
@@ -31,25 +30,25 @@ const animateDuration = Duration(milliseconds: 100);
const midDuration = Duration(milliseconds: 200);
const commonDuration = Duration(milliseconds: 300);
const defaultUpdateDuration = Duration(days: 1);
const mmdbFileName = "geoip.metadb";
const asnFileName = "ASN.mmdb";
const geoIpFileName = "GeoIP.dat";
const geoSiteFileName = "GeoSite.dat";
const mmdbFileName = 'geoip.metadb';
const asnFileName = 'ASN.mmdb';
const geoIpFileName = 'GeoIP.dat';
const geoSiteFileName = 'GeoSite.dat';
final double kHeaderHeight = system.isDesktop
? !Platform.isMacOS
? !system.isMacOS
? 40
: 28
: 0;
const profilesDirectoryName = "profiles";
const localhost = "127.0.0.1";
const clashConfigKey = "clash_config";
const configKey = "config";
const profilesDirectoryName = 'profiles';
const localhost = '127.0.0.1';
const clashConfigKey = 'clash_config';
const configKey = 'config';
const double dialogCommonWidth = 300;
const repository = "chen08209/FlClash";
const defaultExternalController = "127.0.0.1:9090";
const repository = 'chen08209/FlClash';
const defaultExternalController = '127.0.0.1:9090';
const maxMobileWidth = 600;
const maxLaptopWidth = 840;
const defaultTestUrl = "https://www.gstatic.com/generate_204";
const defaultTestUrl = 'https://www.gstatic.com/generate_204';
final commonFilter = ImageFilter.blur(
sigmaX: 5,
sigmaY: 5,
@@ -57,7 +56,7 @@ final commonFilter = ImageFilter.blur(
);
const navigationItemListEquality = ListEquality<NavigationItem>();
const connectionListEquality = ListEquality<Connection>();
const trackerInfoListEquality = ListEquality<TrackerInfo>();
const stringListEquality = ListEquality<String>();
const intListEquality = ListEquality<int>();
const logListEquality = ListEquality<Log>();
@@ -78,9 +77,9 @@ const viewModeColumnsMap = {
ViewMode.desktop: [4, 3],
};
// const proxiesStoreKey = PageStorageKey<String>('proxies');
// const toolsStoreKey = PageStorageKey<String>('tools');
// const profilesStoreKey = PageStorageKey<String>('profiles');
const proxiesListStoreKey = PageStorageKey<String>('proxies_list');
const toolsStoreKey = PageStorageKey<String>('tools');
const profilesStoreKey = PageStorageKey<String>('profiles');
const defaultPrimaryColor = 0XFFD8C0C3;
@@ -88,11 +87,11 @@ double getWidgetHeight(num lines) {
return max(lines * 84 + (lines - 1) * 16, 0).ap;
}
const maxLength = 150;
const maxLength = 1000;
final mainIsolate = "FlClashMainIsolate";
final mainIsolate = 'FlClashMainIsolate';
final serviceIsolate = "FlClashServiceIsolate";
final serviceIsolate = 'FlClashServiceIsolate';
const defaultPrimaryColors = [
0xFF795548,
@@ -104,7 +103,7 @@ const defaultPrimaryColors = [
0XFF665390,
];
const scriptTemplate = """
const scriptTemplate = '''
const main = (config) => {
return config;
}""";
}''';

View File

@@ -7,11 +7,11 @@ extension BuildContextExtension on BuildContext {
return findAncestorStateOfType<CommonScaffoldState>();
}
showNotifier(String text) {
Future<void>? showNotifier(String text) {
return findAncestorStateOfType<MessageManagerState>()?.message(text);
}
showSnackBar(
void showSnackBar(
String message, {
SnackBarAction? action,
}) {
@@ -72,3 +72,18 @@ extension BuildContextExtension on BuildContext {
return state;
}
}
class BackHandleInherited extends InheritedWidget {
final Function handleBack;
const BackHandleInherited(
{super.key, required this.handleBack, required super.child});
static BackHandleInherited? of(BuildContext context) =>
context.dependOnInheritedWidgetOfExactType<BackHandleInherited>();
@override
bool updateShouldNotify(BackHandleInherited oldWidget) {
return handleBack != oldWidget.handleBack;
}
}

View File

@@ -17,26 +17,34 @@ extension DateTimeExtension on DateTime {
final difference = currentDateTime.difference(this);
final days = difference.inDays;
if (days >= 365) {
return "${(days / 365).floor()} ${appLocalizations.years}${appLocalizations.ago}";
return '${(days / 365).floor()} ${appLocalizations.years}${appLocalizations.ago}';
}
if (days >= 30) {
return "${(days / 30).floor()} ${appLocalizations.months}${appLocalizations.ago}";
return '${(days / 30).floor()} ${appLocalizations.months}${appLocalizations.ago}';
}
if (days >= 1) {
return "$days ${appLocalizations.days}${appLocalizations.ago}";
return '$days ${appLocalizations.days}${appLocalizations.ago}';
}
final hours = difference.inHours;
if (hours >= 1) {
return "$hours ${appLocalizations.hours}${appLocalizations.ago}";
return '$hours ${appLocalizations.hours}${appLocalizations.ago}';
}
final minutes = difference.inMinutes;
if (minutes >= 1) {
return "$minutes ${appLocalizations.minutes}${appLocalizations.ago}";
return '$minutes ${appLocalizations.minutes}${appLocalizations.ago}';
}
return appLocalizations.just;
}
String get show {
return toIso8601String().substring(0, 10);
return toString().substring(0, 10);
}
String get showFull {
return toString().substring(0, 19);
}
String get showTime {
return toString().substring(10, 19);
}
}

View File

@@ -38,18 +38,18 @@ class DAVClient {
}
}
get root => "/$appName";
String get root => '/$appName';
get backupFile => "$root/$fileName";
String get backupFile => '$root/$fileName';
backup(Uint8List data) async {
await client.mkdir("$root");
await client.write("$backupFile", data);
Future<bool> backup(Uint8List data) async {
await client.mkdir(root);
await client.write(backupFile, data);
return true;
}
Future<List<int>> recovery() async {
await client.mkdir("$root");
await client.mkdir(root);
final data = await client.read(backupFile);
return data;
}

View File

@@ -1,5 +1,7 @@
import 'iterable.dart';
typedef ValueCallback<T> = T Function();
class FixedList<T> {
final int maxLength;
final List<T> _list;
@@ -7,12 +9,12 @@ class FixedList<T> {
FixedList(this.maxLength, {List<T>? list})
: _list = (list ?? [])..truncate(maxLength);
add(T item) {
void add(T item) {
_list.add(item);
_list.truncate(maxLength);
}
clear() {
void clear() {
_list.clear();
}
@@ -38,7 +40,7 @@ class FixedMap<K, V> {
_map = map ?? {};
}
updateCacheValue(K key, V Function() callback) {
V updateCacheValue(K key, ValueCallback<V> callback) {
final realValue = _map.updateCacheValue(
key,
callback,
@@ -47,21 +49,21 @@ class FixedMap<K, V> {
return realValue;
}
clear() {
void clear() {
_map.clear();
}
updateMaxLength(int size) {
void updateMaxLength(int size) {
maxLength = size;
_adjustMap();
}
updateMap(Map<K, V> map) {
void updateMap(Map<K, V> map) {
_map = map;
_adjustMap();
}
_adjustMap() {
void _adjustMap() {
if (_map.length > maxLength) {
_map = Map.fromEntries(
map.entries.toList()..truncate(maxLength),

View File

@@ -5,7 +5,7 @@ import 'package:fl_clash/enum/enum.dart';
class Debouncer {
final Map<FunctionTag, Timer?> _operations = {};
call(
void call(
FunctionTag tag,
Function func, {
List<dynamic>? args,
@@ -28,7 +28,7 @@ class Debouncer {
);
}
cancel(dynamic tag) {
void cancel(dynamic tag) {
_operations[tag]?.cancel();
_operations[tag] = null;
}
@@ -37,7 +37,7 @@ class Debouncer {
class Throttler {
final Map<FunctionTag, Timer?> _operations = {};
call(
bool call(
FunctionTag tag,
Function func, {
List<dynamic>? args,
@@ -61,7 +61,7 @@ class Throttler {
return false;
}
cancel(dynamic tag) {
void cancel(dynamic tag) {
_operations[tag]?.cancel();
_operations[tag] = null;
}
@@ -81,7 +81,7 @@ Future<T> retry<T>({
}
attempts++;
}
throw "unknown error";
throw 'unknown error';
}
final debouncer = Debouncer();

View File

@@ -4,7 +4,7 @@ import 'dart:ui';
import 'package:fl_clash/common/common.dart';
extension CompleterExt<T> on Completer<T> {
safeFuture({
Future<T> safeFuture({
Duration? timeout,
VoidCallback? onLast,
FutureOr<T> Function()? onTimeout,

View File

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

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
class IconsExt{
static const IconData target =
IconData(0xe900, fontFamily: "Icons");
}
class IconsExt {
static const IconData target = IconData(0xe900, fontFamily: 'Icons');
}

View File

@@ -47,7 +47,9 @@ extension IterableExt<T> on Iterable<T> {
extension ListExt<T> on List<T> {
void truncate(int maxLength) {
assert(maxLength > 0);
if (maxLength == 0) {
return;
}
if (length > maxLength) {
removeRange(0, length - maxLength);
}
@@ -70,11 +72,19 @@ extension ListExt<T> on List<T> {
return res;
}
List<T> safeSublist(int start) {
List<T> safeSublist(int start, [int? end]) {
if (start <= 0) return this;
if (start > length) return [];
if (end != null) {
return sublist(start, end.clamp(start, length));
}
return sublist(start);
}
T safeGet(int index) {
if (length > index) return this[index];
return last;
}
}
extension DoubleListExt on List<double> {
@@ -104,10 +114,10 @@ extension DoubleListExt on List<double> {
}
extension MapExt<K, V> on Map<K, V> {
updateCacheValue(K key, V Function() callback) {
V updateCacheValue(K key, V Function() callback) {
if (this[key] == null) {
this[key] = callback();
}
return this[key];
return this[key]!;
}
}

View File

@@ -1,8 +1,8 @@
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:uni_platform/uni_platform.dart';
import 'system.dart';
final Map<PhysicalKeyboardKey, String> _knownKeyLabels =
<PhysicalKeyboardKey, String>{
PhysicalKeyboardKey.keyA: 'A',
@@ -79,14 +79,14 @@ final Map<PhysicalKeyboardKey, String> _knownKeyLabels =
PhysicalKeyboardKey.arrowLeft: '',
PhysicalKeyboardKey.arrowDown: '',
PhysicalKeyboardKey.arrowUp: '',
PhysicalKeyboardKey.controlLeft: "CTRL",
PhysicalKeyboardKey.controlLeft: 'CTRL',
PhysicalKeyboardKey.shiftLeft: 'SHIFT',
PhysicalKeyboardKey.altLeft: "ALT",
PhysicalKeyboardKey.metaLeft: Platform.isMacOS ? '' : 'WIN',
PhysicalKeyboardKey.controlRight: "CTRL",
PhysicalKeyboardKey.altLeft: 'ALT',
PhysicalKeyboardKey.metaLeft: system.isMacOS ? '' : 'WIN',
PhysicalKeyboardKey.controlRight: 'CTRL',
PhysicalKeyboardKey.shiftRight: 'SHIFT',
PhysicalKeyboardKey.altRight: "ALT",
PhysicalKeyboardKey.metaRight: Platform.isMacOS ? '' : 'WIN',
PhysicalKeyboardKey.altRight: 'ALT',
PhysicalKeyboardKey.metaRight: system.isMacOS ? '' : 'WIN',
PhysicalKeyboardKey.fn: 'FN',
};
@@ -101,6 +101,3 @@ extension KeyboardKeyExt on KeyboardKey {
return _knownKeyLabels[physicalKey] ?? physicalKey?.debugName ?? 'Unknown';
}
}

View File

@@ -34,8 +34,8 @@ class AutoLaunch {
return await launchAtStartup.disable();
}
updateStatus(bool isAutoLaunch) async {
if(kDebugMode){
Future<void> updateStatus(bool isAutoLaunch) async {
if (kDebugMode) {
return;
}
if (await isEnable == isAutoLaunch) return;

View File

@@ -15,8 +15,9 @@ class LinkManager {
_appLinks = AppLinks();
}
initAppLinksListen(installConfigCallBack) async {
commonPrint.log("initAppLinksListen");
Future<void> initAppLinksListen(
Function(String url) installConfigCallBack) async {
commonPrint.log('initAppLinksListen');
destroy();
subscription = _appLinks.uriLinkStream.listen(
(uri) {
@@ -32,7 +33,7 @@ class LinkManager {
);
}
destroy() {
void destroy() {
if (subscription != null) {
subscription?.cancel();
subscription = null;

View File

@@ -33,10 +33,10 @@ class Measure {
double get bodyMediumHeight {
return _measureMap.updateCacheValue(
"bodyMediumHeight",
'bodyMediumHeight',
() => computeTextSize(
Text(
"X",
'X',
style: context.textTheme.bodyMedium,
),
).height,
@@ -45,10 +45,10 @@ class Measure {
double get bodyLargeHeight {
return _measureMap.updateCacheValue(
"bodyLargeHeight",
'bodyLargeHeight',
() => computeTextSize(
Text(
"X",
'X',
style: context.textTheme.bodyLarge,
),
).height,
@@ -57,10 +57,10 @@ class Measure {
double get bodySmallHeight {
return _measureMap.updateCacheValue(
"bodySmallHeight",
'bodySmallHeight',
() => computeTextSize(
Text(
"X",
'X',
style: context.textTheme.bodySmall,
),
).height,
@@ -69,10 +69,10 @@ class Measure {
double get labelSmallHeight {
return _measureMap.updateCacheValue(
"labelSmallHeight",
'labelSmallHeight',
() => computeTextSize(
Text(
"X",
'X',
style: context.textTheme.labelSmall,
),
).height,
@@ -81,10 +81,10 @@ class Measure {
double get labelMediumHeight {
return _measureMap.updateCacheValue(
"labelMediumHeight",
'labelMediumHeight',
() => computeTextSize(
Text(
"X",
'X',
style: context.textTheme.labelMedium,
),
).height,
@@ -93,10 +93,10 @@ class Measure {
double get titleLargeHeight {
return _measureMap.updateCacheValue(
"titleLargeHeight",
'titleLargeHeight',
() => computeTextSize(
Text(
"X",
'X',
style: context.textTheme.titleLarge,
),
).height,
@@ -105,10 +105,10 @@ class Measure {
double get titleMediumHeight {
return _measureMap.updateCacheValue(
"titleMediumHeight",
'titleMediumHeight',
() => computeTextSize(
Text(
"X",
'X',
style: context.textTheme.titleMedium,
),
).height,

View File

@@ -1,7 +1,4 @@
import 'package:fl_clash/models/models.dart';
import 'package:flutter/material.dart';
import 'package:riverpod/riverpod.dart';
import 'context.dart';
mixin AutoDisposeNotifierMixin<T> on AutoDisposeNotifier<T> {
set value(T value) {
@@ -17,37 +14,31 @@ mixin AutoDisposeNotifierMixin<T> on AutoDisposeNotifier<T> {
return res;
}
onUpdate(T value) {}
void onUpdate(T value) {}
}
mixin PageMixin<T extends StatefulWidget> on State<T> {
void onPageShow() {
initPageState();
}
initPageState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
final commonScaffoldState = context.commonScaffoldState;
commonScaffoldState?.actions = actions;
commonScaffoldState?.floatingActionButton = floatingActionButton;
commonScaffoldState?.onKeywordsUpdate = onKeywordsUpdate;
commonScaffoldState?.updateSearchState(
(_) => onSearch != null
? AppBarSearchState(
onSearch: onSearch!,
)
: null,
);
});
}
void onPageHidden() {}
List<Widget> get actions => [];
Widget? get floatingActionButton => null;
Function(String)? get onSearch => null;
Function(List<String>)? get onKeywordsUpdate => null;
}
// mixin PageMixin<T extends StatefulWidget> on State<T> {
// initPageState() {
// WidgetsBinding.instance.addPostFrameCallback((_) {
// final commonScaffoldState = context.commonScaffoldState;
// commonScaffoldState?.actions = actions;
// commonScaffoldState?.floatingActionButton = floatingActionButton;
// commonScaffoldState?.onKeywordsUpdate = onKeywordsUpdate;
// commonScaffoldState?.updateSearchState(
// (_) => onSearch != null
// ? AppBarSearchState(
// onSearch: onSearch!,
// )
// : null,
// );
// });
// }
//
// List<Widget> get actions => [];
//
// Widget? get floatingActionButton => null;
//
// Function(String)? get onSearch => null;
//
// Function(List<String>)? get onKeywordsUpdate => null;
// }

View File

@@ -1,7 +1,9 @@
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/views/views.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class Navigation {
static Navigation? _instance;
@@ -11,62 +13,69 @@ class Navigation {
bool hasProxies = false,
}) {
return [
const NavigationItem(
NavigationItem(
keep: false,
icon: Icon(Icons.space_dashboard),
label: PageLabel.dashboard,
view: DashboardView(
builder: (_) => const DashboardView(
key: GlobalObjectKey(PageLabel.dashboard),
),
),
NavigationItem(
icon: const Icon(Icons.article),
label: PageLabel.proxies,
view: const ProxiesView(
key: GlobalObjectKey(
PageLabel.proxies,
builder: (_) => ProviderScope(
overrides: [
queryProvider.overrideWith(
() => Query(),
),
],
child: const ProxiesView(
key: GlobalObjectKey(
PageLabel.proxies,
),
),
),
modes: hasProxies
? [NavigationItemMode.mobile, NavigationItemMode.desktop]
: [],
),
const NavigationItem(
NavigationItem(
icon: Icon(Icons.folder),
label: PageLabel.profiles,
view: ProfilesView(
builder: (_) => const ProfilesView(
key: GlobalObjectKey(
PageLabel.profiles,
),
),
),
const NavigationItem(
NavigationItem(
icon: Icon(Icons.view_timeline),
label: PageLabel.requests,
view: RequestsView(
builder: (_) => const RequestsView(
key: GlobalObjectKey(
PageLabel.requests,
),
),
description: "requestsDesc",
description: 'requestsDesc',
modes: [NavigationItemMode.desktop, NavigationItemMode.more],
),
const NavigationItem(
NavigationItem(
icon: Icon(Icons.ballot),
label: PageLabel.connections,
view: ConnectionsView(
builder: (_) => const ConnectionsView(
key: GlobalObjectKey(
PageLabel.connections,
),
),
description: "connectionsDesc",
description: 'connectionsDesc',
modes: [NavigationItemMode.desktop, NavigationItemMode.more],
),
const NavigationItem(
NavigationItem(
icon: Icon(Icons.storage),
label: PageLabel.resources,
description: "resourcesDesc",
view: ResourcesView(
description: 'resourcesDesc',
builder: (_) => const ResourcesView(
key: GlobalObjectKey(
PageLabel.resources,
),
@@ -76,20 +85,20 @@ class Navigation {
NavigationItem(
icon: const Icon(Icons.adb),
label: PageLabel.logs,
view: const LogsView(
builder: (_) => const LogsView(
key: GlobalObjectKey(
PageLabel.logs,
),
),
description: "logsDesc",
description: 'logsDesc',
modes: openLogs
? [NavigationItemMode.desktop, NavigationItemMode.more]
: [],
),
const NavigationItem(
NavigationItem(
icon: Icon(Icons.construction),
label: PageLabel.tools,
view: ToolsView(
builder: (_) => const ToolsView(
key: GlobalObjectKey(
PageLabel.tools,
),

View File

@@ -2,7 +2,6 @@ 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/widgets/dialog.dart';
import 'package:flutter/material.dart';
class BaseNavigator {
@@ -21,20 +20,20 @@ class BaseNavigator {
);
}
static Future<T?> modal<T>(BuildContext context, Widget child) async {
if (globalState.appState.viewMode != ViewMode.mobile) {
return await globalState.showCommonDialog<T>(
child: CommonModal(
child: child,
),
);
}
return await Navigator.of(context).push<T>(
CommonRoute(
builder: (context) => child,
),
);
}
// static Future<T?> modal<T>(BuildContext context, Widget child) async {
// if (globalState.appState.viewMode != ViewMode.mobile) {
// return await globalState.showCommonDialog<T>(
// child: CommonModal(
// child: child,
// ),
// );
// }
// return await Navigator.of(context).push<T>(
// CommonRoute(
// builder: (context) => child,
// ),
// );
// }
}
class CommonDesktopRoute<T> extends PageRoute<T> {

View File

@@ -3,7 +3,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
extension NumExt on num {
String fixed({decimals = 2}) {
String fixed({int decimals = 2}) {
String formatted = toStringAsFixed(decimals);
if (formatted.contains('.')) {
formatted = formatted.replaceAll(RegExp(r'0*$'), '');
@@ -20,7 +20,7 @@ extension NumExt on num {
}
extension DoubleExt on double {
moreOrEqual(double value) {
bool moreOrEqual(double value) {
return this > value || (value - this).abs() < precisionErrorTolerance + 1;
}
}
@@ -46,7 +46,7 @@ extension OffsetExt on Offset {
}
extension RectExt on Rect {
doRectIntersect(Rect rect) {
bool doRectIntersect(Rect rect) {
return left < rect.right &&
right > rect.left &&
top < rect.bottom &&

View File

@@ -6,8 +6,8 @@ import 'common.dart';
extension PackageInfoExtension on PackageInfo {
String get ua => [
"$appName/v$version",
"clash-verge",
"Platform/${Platform.operatingSystem}",
].join(" ");
'$appName/v$version',
'clash-verge',
'Platform/${Platform.operatingSystem}',
].join(' ');
}

View File

@@ -31,7 +31,7 @@ class AppPath {
}
String get executableExtension {
return Platform.isWindows ? ".exe" : "";
return system.isWindows ? '.exe' : '';
}
String get executableDirPath {
@@ -40,11 +40,11 @@ class AppPath {
}
String get corePath {
return join(executableDirPath, "FlClashCore$executableExtension");
return join(executableDirPath, 'FlClashCore$executableExtension');
}
String get helperPath {
return join(executableDirPath, "$appHelperService$executableExtension");
return join(executableDirPath, '$appHelperService$executableExtension');
}
Future<String> get downloadDirPath async {
@@ -59,12 +59,12 @@ class AppPath {
Future<String> get lockFilePath async {
final directory = await dataDir.future;
return join(directory.path, "FlClash.lock");
return join(directory.path, 'FlClash.lock');
}
Future<String> get sharedPreferencesPath async {
final directory = await dataDir.future;
return join(directory.path, "shared_preferences.json");
return join(directory.path, 'shared_preferences.json');
}
Future<String> get profilesPath async {
@@ -74,14 +74,14 @@ class AppPath {
Future<String> getProfilePath(String id) async {
final directory = await profilesPath;
return join(directory, "$id.yaml");
return join(directory, '$id.yaml');
}
Future<String> getProvidersDirPath(String id) async {
final directory = await profilesPath;
return join(
directory,
"providers",
'providers',
id,
);
}
@@ -94,7 +94,7 @@ class AppPath {
final directory = await profilesPath;
return join(
directory,
"providers",
'providers',
id,
type,
url.toMd5(),

View File

@@ -20,9 +20,9 @@ class Picker {
final path = await FilePicker.platform.saveFile(
fileName: fileName,
initialDirectory: await appPath.downloadDirPath,
bytes: Platform.isAndroid ? bytes : null,
bytes: system.isAndroid ? bytes : null,
);
if (!Platform.isAndroid && path != null) {
if (!system.isAndroid && path != null) {
final file = await File(path).create(recursive: true);
await file.writeAsBytes(bytes);
}

View File

@@ -49,12 +49,12 @@ class Preferences {
false;
}
clearClashConfig() async {
Future<void> clearClashConfig() async {
final preferences = await sharedPreferencesCompleter.future;
preferences?.remove(clashConfigKey);
}
clearPreferences() async {
Future<void> clearPreferences() async {
final sharedPreferencesIns = await sharedPreferencesCompleter.future;
sharedPreferencesIns?.clear();
}

View File

@@ -12,8 +12,8 @@ class CommonPrint {
return _instance!;
}
log(String? text) {
final payload = "[FlClash] $text";
void log(String? text) {
final payload = '[APP] $text';
debugPrint(payload);
if (!globalState.isInit) {
return;

View File

@@ -16,12 +16,12 @@ class Render {
return _instance!;
}
active() {
void active() {
resume();
pause();
}
pause() {
void pause() {
throttler.call(
FunctionTag.renderPause,
_pause,
@@ -29,7 +29,7 @@ class Render {
);
}
resume() {
void resume() {
throttler.cancel(FunctionTag.renderPause);
_resume();
}
@@ -41,7 +41,7 @@ class Render {
_drawFrame = _dispatcher.onDrawFrame;
_dispatcher.onBeginFrame = null;
_dispatcher.onDrawFrame = null;
commonPrint.log("pause");
commonPrint.log('pause');
}
void _resume() {
@@ -50,7 +50,7 @@ class Render {
_dispatcher.onBeginFrame = _beginFrame;
_dispatcher.onDrawFrame = _drawFrame;
_dispatcher.scheduleFrame();
commonPrint.log("resume");
commonPrint.log('resume');
}
}

View File

@@ -19,7 +19,7 @@ class Request {
_dio = Dio(
BaseOptions(
headers: {
"User-Agent": browserUa,
'User-Agent': browserUa,
},
),
);
@@ -69,7 +69,7 @@ class Request {
Future<Map<String, dynamic>?> checkForUpdate() async {
final response = await _dio.get(
"https://api.github.com/repos/$repository/releases/latest",
'https://api.github.com/repos/$repository/releases/latest',
options: Options(
responseType: ResponseType.json,
),
@@ -85,16 +85,22 @@ class Request {
}
final Map<String, IpInfo Function(Map<String, dynamic>)> _ipInfoSources = {
"https://ipwho.is/": IpInfo.fromIpwhoIsJson,
"https://api.ip.sb/geoip/": IpInfo.fromIpSbJson,
"https://ipapi.co/json/": IpInfo.fromIpApiCoJson,
"https://ipinfo.io/json/": IpInfo.fromIpInfoIoJson,
'https://ipwho.is/': IpInfo.fromIpwhoIsJson,
'https://api.ip.sb/geoip/': IpInfo.fromIpSbJson,
'https://ipapi.co/json/': IpInfo.fromIpApiCoJson,
'https://ipinfo.io/json/': IpInfo.fromIpInfoIoJson,
};
Future<Result<IpInfo?>> checkIp({CancelToken? cancelToken}) async {
var failureCount = 0;
final futures = _ipInfoSources.entries.map((source) async {
final Completer<Result<IpInfo?>> completer = Completer();
handleFailRes() {
if (!completer.isCompleted && failureCount == _ipInfoSources.length) {
completer.complete(Result.success(null));
}
}
final future = Dio().get<Map<String, dynamic>>(
source.key,
cancelToken: cancelToken,
@@ -107,15 +113,14 @@ class Request {
completer.complete(Result.success(source.value(res.data!)));
} else {
failureCount++;
if (failureCount == _ipInfoSources.length) {
completer.complete(Result.success(null));
}
handleFailRes();
}
}).catchError((e) {
failureCount++;
if (e == DioExceptionType.cancel) {
completer.complete(Result.error("cancelled"));
if (e is DioException && e.type == DioExceptionType.cancel) {
completer.complete(Result.error('cancelled'));
}
handleFailRes();
});
return completer.future;
});
@@ -128,7 +133,7 @@ class Request {
try {
final response = await _dio
.get(
"http://$localhost:$helperPort/ping",
'http://$localhost:$helperPort/ping',
options: Options(
responseType: ResponseType.plain,
),
@@ -151,10 +156,10 @@ class Request {
try {
final response = await _dio
.post(
"http://$localhost:$helperPort/start",
'http://$localhost:$helperPort/start',
data: json.encode({
"path": appPath.corePath,
"arg": arg,
'path': appPath.corePath,
'arg': arg,
}),
options: Options(
responseType: ResponseType.plain,
@@ -179,7 +184,7 @@ class Request {
try {
final response = await _dio
.post(
"http://$localhost:$helperPort/stop",
'http://$localhost:$helperPort/stop',
options: Options(
responseType: ResponseType.plain,
),

View File

@@ -35,7 +35,7 @@ class ShowBarScrollBehavior extends BaseScrollBehavior {
Widget child,
ScrollableDetails details,
) {
return CommonAutoHiddenScrollBar(
return CommonScrollBar(
controller: details.controller,
child: child,
);
@@ -88,6 +88,54 @@ class NextClampingScrollPhysics extends ClampingScrollPhysics {
}
}
// class CacheScrollPositionController extends ScrollController {
// final String key;
//
// CacheScrollPositionController({
// required this.key,
// double initialScrollOffset = 0.0,
// super.keepScrollOffset = true,
// super.debugLabel,
// super.onAttach,
// super.onDetach,
// });
//
// @override
// ScrollPosition createScrollPosition(
// ScrollPhysics physics,
// ScrollContext context,
// ScrollPosition? oldPosition,
// ) {
// return ScrollPositionWithSingleContext(
// physics: physics,
// context: context,
// initialPixels:
// globalState.scrollPositionCache[key] ?? initialScrollOffset,
// keepScrollOffset: keepScrollOffset,
// oldPosition: oldPosition,
// debugLabel: debugLabel,
// );
// }
//
// double? get cacheOffset => globalState.scrollPositionCache[key];
//
// _handleScroll() {
// globalState.scrollPositionCache[key] = position.pixels;
// }
//
// @override
// void attach(ScrollPosition position) {
// super.attach(position);
// addListener(_handleScroll);
// }
//
// @override
// void detach(ScrollPosition position) {
// removeListener(_handleScroll);
// super.detach(position);
// }
// }
class ReverseScrollController extends ScrollController {
ReverseScrollController({
super.initialScrollOffset,

View File

@@ -48,7 +48,7 @@ extension StringExtension on String {
}
bool get isSvg {
return endsWith(".svg");
return endsWith('.svg');
}
bool get isRegex {

View File

@@ -1,16 +1,18 @@
import 'dart:ffi';
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:ffi/ffi.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/input.dart';
import 'package:flutter/services.dart';
import 'package:path/path.dart';
class System {
static System? _instance;
List<String>? originDns;
System._internal();
@@ -19,25 +21,32 @@ class System {
return _instance!;
}
bool get isDesktop =>
Platform.isWindows || Platform.isMacOS || Platform.isLinux;
bool get isDesktop => isWindows || isMacOS || isLinux;
bool get isWindows => Platform.isWindows;
bool get isMacOS => Platform.isMacOS;
bool get isAndroid => Platform.isAndroid;
bool get isLinux => Platform.isLinux;
Future<int> get version async {
final deviceInfo = await DeviceInfoPlugin().deviceInfo;
return switch (Platform.operatingSystem) {
"macos" => (deviceInfo as MacOsDeviceInfo).majorVersion,
"android" => (deviceInfo as AndroidDeviceInfo).version.sdkInt,
"windows" => (deviceInfo as WindowsDeviceInfo).majorVersion,
'macos' => (deviceInfo as MacOsDeviceInfo).majorVersion,
'android' => (deviceInfo as AndroidDeviceInfo).version.sdkInt,
'windows' => (deviceInfo as WindowsDeviceInfo).majorVersion,
String() => 0
};
}
Future<bool> checkIsAdmin() async {
final corePath = appPath.corePath.replaceAll(' ', '\\\\ ');
if (Platform.isWindows) {
if (system.isWindows) {
final result = await windows?.checkService();
return result == WindowsHelperServiceStatus.running;
} else if (Platform.isMacOS) {
} else if (system.isMacOS) {
final result = await Process.run('stat', ['-f', '%Su:%Sg %Sp', corePath]);
final output = result.stdout.trim();
if (output.startsWith('root:admin') && output.contains('rws')) {
@@ -56,7 +65,7 @@ class System {
}
Future<AuthorizeCode> authorizeCore() async {
if (Platform.isAndroid) {
if (system.isAndroid) {
return AuthorizeCode.error;
}
final corePath = appPath.corePath.replaceAll(' ', '\\\\ ');
@@ -65,7 +74,7 @@ class System {
return AuthorizeCode.none;
}
if (Platform.isWindows) {
if (system.isWindows) {
final result = await windows?.registerService();
if (result == true) {
return AuthorizeCode.success;
@@ -73,13 +82,13 @@ class System {
return AuthorizeCode.error;
}
if (Platform.isMacOS) {
if (system.isMacOS) {
final shell = 'chown root:admin $corePath; chmod +sx $corePath';
final arguments = [
"-e",
'-e',
'do shell script "$shell" with administrator privileges',
];
final result = await Process.run("osascript", arguments);
final result = await Process.run('osascript', arguments);
if (result.exitCode != 0) {
return AuthorizeCode.error;
}
@@ -88,12 +97,13 @@ class System {
final shell = Platform.environment['SHELL'] ?? 'bash';
final password = await globalState.showCommonDialog<String>(
child: InputDialog(
obscureText: true,
title: appLocalizations.pleaseInputAdminPassword,
value: '',
),
);
final arguments = [
"-c",
'-c',
'echo "$password" | sudo -S chown root:root "$corePath" && echo "$password" | sudo -S chmod +sx "$corePath"'
];
final result = await Process.run(shell, arguments);
@@ -105,15 +115,223 @@ class System {
return AuthorizeCode.error;
}
Future<String?> getMacOSDefaultServiceName() async {
if (!Platform.isMacOS) {
return null;
Future<void> back() async {
await app?.moveTaskToBack();
await window?.hide();
}
Future<void> exit() async {
if (system.isAndroid) {
await SystemNavigator.pop();
}
await window?.close();
}
}
final system = System();
class Windows {
static Windows? _instance;
late DynamicLibrary _shell32;
Windows._internal() {
_shell32 = DynamicLibrary.open('shell32.dll');
}
factory Windows() {
_instance ??= Windows._internal();
return _instance!;
}
bool runas(String command, String arguments) {
final commandPtr = command.toNativeUtf16();
final argumentsPtr = arguments.toNativeUtf16();
final operationPtr = 'runas'.toNativeUtf16();
final shellExecute = _shell32.lookupFunction<
Int32 Function(
Pointer<Utf16> hwnd,
Pointer<Utf16> lpOperation,
Pointer<Utf16> lpFile,
Pointer<Utf16> lpParameters,
Pointer<Utf16> lpDirectory,
Int32 nShowCmd),
int Function(
Pointer<Utf16> hwnd,
Pointer<Utf16> lpOperation,
Pointer<Utf16> lpFile,
Pointer<Utf16> lpParameters,
Pointer<Utf16> lpDirectory,
int nShowCmd)>('ShellExecuteW');
final result = shellExecute(
nullptr,
operationPtr,
commandPtr,
argumentsPtr,
nullptr,
1,
);
calloc.free(commandPtr);
calloc.free(argumentsPtr);
calloc.free(operationPtr);
commonPrint.log('windows runas: $command $arguments resultCode:$result');
if (result < 42) {
return false;
}
return true;
}
Future<void> _killProcess(int port) async {
final result = await Process.run('netstat', ['-ano']);
final lines = result.stdout.toString().trim().split('\n');
for (final line in lines) {
if (!line.contains(':$port') || !line.contains('LISTENING')) {
continue;
}
final parts = line.trim().split(RegExp(r'\s+'));
final pid = int.tryParse(parts.last);
if (pid != null) {
await Process.run('taskkill', ['/PID', pid.toString(), '/F']);
}
}
}
Future<WindowsHelperServiceStatus> checkService() async {
// final qcResult = await Process.run('sc', ['qc', appHelperService]);
// final qcOutput = qcResult.stdout.toString();
// if (qcResult.exitCode != 0 || !qcOutput.contains(appPath.helperPath)) {
// return WindowsHelperServiceStatus.none;
// }
final result = await Process.run('sc', ['query', appHelperService]);
if (result.exitCode != 0) {
return WindowsHelperServiceStatus.none;
}
final output = result.stdout.toString();
if (output.contains('RUNNING') && await request.pingHelper()) {
return WindowsHelperServiceStatus.running;
}
return WindowsHelperServiceStatus.presence;
}
Future<bool> registerService() async {
final status = await checkService();
if (status == WindowsHelperServiceStatus.running) {
return true;
}
await _killProcess(helperPort);
final command = [
'/c',
if (status == WindowsHelperServiceStatus.presence) ...[
'sc',
'delete',
appHelperService,
'/force',
'&&',
],
'sc',
'create',
appHelperService,
'binPath= "${appPath.helperPath}"',
'start= auto',
'&&',
'sc',
'start',
appHelperService,
].join(' ');
final res = runas('cmd.exe', command);
await Future.delayed(
Duration(milliseconds: 300),
);
return res;
}
Future<bool> registerTask(String appName) async {
final taskXml = '''
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<Principals>
<Principal id="Author">
<LogonType>InteractiveToken</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Triggers>
<LogonTrigger/>
</Triggers>
<Settings>
<MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>false</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>false</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>"${Platform.resolvedExecutable}"</Command>
</Exec>
</Actions>
</Task>''';
final taskPath = join(await appPath.tempPath, 'task.xml');
await File(taskPath).create(recursive: true);
await File(taskPath)
.writeAsBytes(taskXml.encodeUtf16LeWithBom, flush: true);
final commandLine = [
'/Create',
'/TN',
appName,
'/XML',
'%s',
'/F',
].join(' ');
return runas(
'schtasks',
commandLine.replaceFirst('%s', taskPath),
);
}
}
final windows = system.isWindows ? Windows() : null;
class MacOS {
static MacOS? _instance;
List<String>? originDns;
MacOS._internal();
factory MacOS() {
_instance ??= MacOS._internal();
return _instance!;
}
Future<String?> get defaultServiceName async {
final result = await Process.run('route', ['-n', 'get', 'default']);
final output = result.stdout.toString();
final deviceLine = output
.split('\n')
.firstWhere((s) => s.contains('interface:'), orElse: () => "");
.firstWhere((s) => s.contains('interface:'), orElse: () => '');
final lineSplits = deviceLine.trim().split(' ');
if (lineSplits.length != 2) {
return null;
@@ -125,15 +343,15 @@ class System {
);
final serviceResultOutput = serviceResult.stdout.toString();
final currentService = serviceResultOutput.split('\n\n').firstWhere(
(s) => s.contains("Device: $device"),
orElse: () => "",
(s) => s.contains('Device: $device'),
orElse: () => '',
);
if (currentService.isEmpty) {
return null;
}
final currentServiceNameLine = currentService.split("\n").firstWhere(
final currentServiceNameLine = currentService.split('\n').firstWhere(
(line) => RegExp(r'^\(\d+\).*').hasMatch(line),
orElse: () => "");
orElse: () => '');
final currentServiceNameLineSplits =
currentServiceNameLine.trim().split(' ');
if (currentServiceNameLineSplits.length < 2) {
@@ -142,11 +360,8 @@ class System {
return currentServiceNameLineSplits[1];
}
Future<List<String>?> getMacOSOriginDns() async {
if (!Platform.isMacOS) {
return null;
}
final deviceServiceName = await getMacOSDefaultServiceName();
Future<List<String>?> get systemDns async {
final deviceServiceName = await defaultServiceName;
if (deviceServiceName == null) {
return null;
}
@@ -158,16 +373,13 @@ class System {
if (output.startsWith("There aren't any DNS Servers set on")) {
originDns = [];
} else {
originDns = output.split("\n");
originDns = output.split('\n');
}
return originDns;
}
setMacOSDns(bool restore) async {
if (!Platform.isMacOS) {
return;
}
final serviceName = await getMacOSDefaultServiceName();
Future<void> updateDns(bool restore) async {
final serviceName = await defaultServiceName;
if (serviceName == null) {
return;
}
@@ -175,11 +387,11 @@ class System {
if (restore) {
nextDns = originDns;
} else {
final originDns = await system.getMacOSOriginDns();
final originDns = await systemDns;
if (originDns == null) {
return;
}
final needAddDns = "223.5.5.5";
final needAddDns = '223.5.5.5';
if (originDns.contains(needAddDns)) {
return;
}
@@ -194,22 +406,10 @@ class System {
'-setdnsservers',
serviceName,
if (nextDns.isNotEmpty) ...nextDns,
if (nextDns.isEmpty) "Empty",
if (nextDns.isEmpty) 'Empty',
],
);
}
back() async {
await app?.moveTaskToBack();
await window?.hide();
}
exit() async {
if (Platform.isAndroid) {
await SystemNavigator.pop();
}
await window?.close();
}
}
final system = System();
final macOS = system.isMacOS ? MacOS() : null;

View File

@@ -13,7 +13,7 @@ class CommonTheme {
Color get darkenSecondaryContainer {
return _colorMap.updateCacheValue(
"darkenSecondaryContainer",
'darkenSecondaryContainer',
() => context.colorScheme.secondaryContainer
.blendDarken(context, factor: 0.1),
);
@@ -21,7 +21,7 @@ class CommonTheme {
Color get darkenSecondaryContainerLighter {
return _colorMap.updateCacheValue(
"darkenSecondaryContainerLighter",
'darkenSecondaryContainerLighter',
() => context.colorScheme.secondaryContainer
.blendDarken(context, factor: 0.1)
.opacity60,
@@ -30,7 +30,7 @@ class CommonTheme {
Color get darken2SecondaryContainer {
return _colorMap.updateCacheValue(
"darken2SecondaryContainer",
'darken2SecondaryContainer',
() => context.colorScheme.secondaryContainer
.blendDarken(context, factor: 0.2),
);
@@ -38,7 +38,7 @@ class CommonTheme {
Color get darken3PrimaryContainer {
return _colorMap.updateCacheValue(
"darken3PrimaryContainer",
'darken3PrimaryContainer',
() => context.colorScheme.primaryContainer
.blendDarken(context, factor: 0.3),
);

View File

@@ -11,6 +11,7 @@ import 'package:tray_manager/tray_manager.dart';
import 'app_localizations.dart';
import 'constant.dart';
import 'system.dart';
import 'window.dart';
class Tray {
@@ -18,7 +19,7 @@ class Tray {
required Brightness? brightness,
bool force = false,
}) async {
if (Platform.isAndroid) {
if (system.isAndroid) {
return;
}
if (Platform.isLinux || force) {
@@ -38,11 +39,11 @@ class Tray {
}
}
update({
Future<void> update({
required TrayState trayState,
bool focus = false,
}) async {
if (Platform.isAndroid) {
if (system.isAndroid) {
return;
}
if (!Platform.isLinux) {
@@ -80,7 +81,7 @@ class Tray {
);
}
menuItems.add(MenuItem.separator());
if (Platform.isMacOS) {
if (system.isMacOS) {
for (final group in trayState.groups) {
List<MenuItem> subMenuItems = [];
for (final proxy in group.all) {
@@ -169,8 +170,8 @@ class Tray {
}
}
updateTrayTitle([Traffic? traffic]) async {
// if (!Platform.isMacOS) {
Future<void> updateTrayTitle([Traffic? traffic]) async {
// if (!system.isMacOS) {
// return;
// }
// if (traffic == null) {
@@ -183,11 +184,10 @@ class Tray {
}
Future<void> _copyEnv(int port) async {
final url = "http://127.0.0.1:$port";
final url = 'http://127.0.0.1:$port';
final cmdline = Platform.isWindows
? "set \$env:all_proxy=$url"
: "export all_proxy=$url";
final cmdline =
system.isWindows ? 'set \$env:all_proxy=$url' : 'export all_proxy=$url';
await Clipboard.setData(
ClipboardData(

View File

@@ -23,11 +23,11 @@ class Utils {
final random = Random();
final randomStr =
String.fromCharCodes(List.generate(8, (_) => random.nextInt(26) + 97));
return "$timestamp$randomStr";
return '$timestamp$randomStr';
}
String getDateStringLast2(int value) {
var valueRaw = "0$value";
var valueRaw = '0$value';
return valueRaw.substring(
valueRaw.length - 2,
);
@@ -73,7 +73,7 @@ class Utils {
var inMinutes = difference.inMinutes;
var inSeconds = difference.inSeconds;
return "${getDateStringLast2(inHours)}:${getDateStringLast2(inMinutes)}:${getDateStringLast2(inSeconds)}";
return '${getDateStringLast2(inHours)}:${getDateStringLast2(inMinutes)}:${getDateStringLast2(inSeconds)}';
}
String getTimeText(int? timeStamp) {
@@ -83,17 +83,17 @@ class Utils {
final diff = timeStamp / 1000;
final inHours = (diff / 3600).floor();
if (inHours > 99) {
return "99:59:59";
return '99:59:59';
}
final inMinutes = (diff / 60 % 60).floor();
final inSeconds = (diff % 60).floor();
return "${getDateStringLast2(inHours)}:${getDateStringLast2(inMinutes)}:${getDateStringLast2(inSeconds)}";
return '${getDateStringLast2(inHours)}:${getDateStringLast2(inMinutes)}:${getDateStringLast2(inSeconds)}';
}
Locale? getLocaleForString(String? localString) {
if (localString == null) return null;
var localSplit = localString.split("_");
var localSplit = localString.split('_');
if (localSplit.length == 1) {
return Locale(localSplit[0]);
}
@@ -137,18 +137,18 @@ class Utils {
final number = int.parse(match[1] ?? '0') + 1;
return label.replaceFirst(reg, '($number)', label.length - 3 - 1);
} else {
return "$label(1)";
return '$label(1)';
}
}
String getTrayIconPath({
required Brightness brightness,
}) {
if (Platform.isMacOS) {
return "assets/images/icon_white.png";
if (system.isMacOS) {
return 'assets/images/icon_white.png';
}
final suffix = Platform.isWindows ? "ico" : "png";
return "assets/images/icon.$suffix";
final suffix = system.isWindows ? 'ico' : 'png';
return 'assets/images/icon.$suffix';
// return switch (brightness) {
// Brightness.dark => "assets/images/icon_white.$suffix",
// Brightness.light => "assets/images/icon_black.$suffix",
@@ -181,7 +181,7 @@ class Utils {
String getPinyin(String value) {
return value.isNotEmpty
? PinyinHelper.getFirstWordPinyin(value.substring(0, 1))
: "";
: '';
}
String? getFileNameForDisposition(String? disposition) {
@@ -189,7 +189,7 @@ class Utils {
final parseValue = HeaderValue.parse(disposition);
final parameters = parseValue.parameters;
final fileNamePointKey = parameters.keys
.firstWhere((key) => key == "filename*", orElse: () => "");
.firstWhere((key) => key == 'filename*', orElse: () => '');
if (fileNamePointKey.isNotEmpty) {
final res = parameters[fileNamePointKey]?.split("''") ?? [];
if (res.length >= 2) {
@@ -197,7 +197,7 @@ class Utils {
}
}
final fileNameKey = parameters.keys
.firstWhere((key) => key == "filename", orElse: () => "");
.firstWhere((key) => key == 'filename', orElse: () => '');
if (fileNameKey.isEmpty) return null;
return parameters[fileNameKey];
}
@@ -250,7 +250,7 @@ class Utils {
900,
];
_createPrimarySwatch(Color color) {
MaterialColor _createPrimarySwatch(Color color) {
final Map<int, Color> swatch = <int, Color>{};
final int a = color.alpha8bit;
final int r = color.red8bit;
@@ -294,11 +294,11 @@ class Utils {
}
String getBackupFileName() {
return "${appName}_backup_${DateTime.now().show}.zip";
return '${appName}_backup_${DateTime.now().show}.zip';
}
String get logFile {
return "${appName}_${DateTime.now().show}.log";
return '${appName}_${DateTime.now().show}.log';
}
Future<String?> getLocalIpAddress() async {
@@ -324,11 +324,11 @@ class Utils {
});
return addresses.first.address;
}
return "";
return '';
}
SingleActivator controlSingleActivator(LogicalKeyboardKey trigger) {
final control = Platform.isMacOS ? false : true;
final control = system.isMacOS ? false : true;
return SingleActivator(
trigger,
control: control,

View File

@@ -3,30 +3,34 @@ import 'dart:io';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_acrylic/flutter_acrylic.dart' as acrylic;
import 'package:screen_retriever/screen_retriever.dart';
import 'package:window_manager/window_manager.dart';
class Window {
init(int version) async {
Future<void> init(int version) async {
final props = globalState.config.windowProps;
final acquire = await singleInstanceLock.acquire();
if (!acquire) {
exit(0);
}
if (Platform.isWindows) {
protocol.register("clash");
protocol.register("clashmeta");
protocol.register("flclash");
if (system.isWindows) {
protocol.register('clash');
protocol.register('clashmeta');
protocol.register('flclash');
}
if ((version > 10 && system.isMacOS)) {
await acrylic.Window.initialize();
}
await windowManager.ensureInitialized();
WindowOptions windowOptions = WindowOptions(
size: Size(props.width, props.height),
minimumSize: const Size(380, 400),
);
if (!Platform.isMacOS || version > 10) {
if (!system.isMacOS || version > 10) {
await windowManager.setTitleBarStyle(TitleBarStyle.hidden);
}
if (!Platform.isMacOS) {
if (!system.isMacOS) {
final left = props.left ?? 0;
final top = props.top ?? 0;
final right = left + props.width;
@@ -62,7 +66,14 @@ class Window {
});
}
show() async {
void updateMacOSBrightness(Brightness brightness) {
if (!system.isMacOS) {
return;
}
acrylic.Window.overrideMacOSBrightness(dark: brightness == Brightness.dark);
}
Future<void> show() async {
render?.resume();
await windowManager.show();
await windowManager.focus();
@@ -71,15 +82,15 @@ class Window {
Future<bool> get isVisible async {
final value = await windowManager.isVisible();
commonPrint.log("window visible check: $value");
commonPrint.log('window visible check: $value');
return value;
}
close() async {
Future<void> close() async {
exit(0);
}
hide() async {
Future<void> hide() async {
render?.pause();
await windowManager.hide();
await windowManager.setSkipTaskbar(true);

View File

@@ -1,191 +0,0 @@
import 'dart:ffi';
import 'dart:io';
import 'package:ffi/ffi.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:path/path.dart';
class Windows {
static Windows? _instance;
late DynamicLibrary _shell32;
Windows._internal() {
_shell32 = DynamicLibrary.open('shell32.dll');
}
factory Windows() {
_instance ??= Windows._internal();
return _instance!;
}
bool runas(String command, String arguments) {
final commandPtr = command.toNativeUtf16();
final argumentsPtr = arguments.toNativeUtf16();
final operationPtr = 'runas'.toNativeUtf16();
final shellExecute = _shell32.lookupFunction<
Int32 Function(
Pointer<Utf16> hwnd,
Pointer<Utf16> lpOperation,
Pointer<Utf16> lpFile,
Pointer<Utf16> lpParameters,
Pointer<Utf16> lpDirectory,
Int32 nShowCmd),
int Function(
Pointer<Utf16> hwnd,
Pointer<Utf16> lpOperation,
Pointer<Utf16> lpFile,
Pointer<Utf16> lpParameters,
Pointer<Utf16> lpDirectory,
int nShowCmd)>('ShellExecuteW');
final result = shellExecute(
nullptr,
operationPtr,
commandPtr,
argumentsPtr,
nullptr,
1,
);
calloc.free(commandPtr);
calloc.free(argumentsPtr);
calloc.free(operationPtr);
commonPrint.log("windows runas: $command $arguments resultCode:$result");
if (result < 42) {
return false;
}
return true;
}
_killProcess(int port) async {
final result = await Process.run('netstat', ['-ano']);
final lines = result.stdout.toString().trim().split('\n');
for (final line in lines) {
if (!line.contains(":$port") || !line.contains("LISTENING")) {
continue;
}
final parts = line.trim().split(RegExp(r'\s+'));
final pid = int.tryParse(parts.last);
if (pid != null) {
await Process.run('taskkill', ['/PID', pid.toString(), '/F']);
}
}
}
Future<WindowsHelperServiceStatus> checkService() async {
// final qcResult = await Process.run('sc', ['qc', appHelperService]);
// final qcOutput = qcResult.stdout.toString();
// if (qcResult.exitCode != 0 || !qcOutput.contains(appPath.helperPath)) {
// return WindowsHelperServiceStatus.none;
// }
final result = await Process.run('sc', ['query', appHelperService]);
if(result.exitCode != 0){
return WindowsHelperServiceStatus.none;
}
final output = result.stdout.toString();
if (output.contains("RUNNING") && await request.pingHelper()) {
return WindowsHelperServiceStatus.running;
}
return WindowsHelperServiceStatus.presence;
}
Future<bool> registerService() async {
final status = await checkService();
if (status == WindowsHelperServiceStatus.running) {
return true;
}
await _killProcess(helperPort);
final command = [
"/c",
if (status == WindowsHelperServiceStatus.presence) ...[
"sc",
"delete",
appHelperService,
"/force",
"&&",
],
"sc",
"create",
appHelperService,
'binPath= "${appPath.helperPath}"',
'start= auto',
"&&",
"sc",
"start",
appHelperService,
].join(" ");
final res = runas("cmd.exe", command);
await Future.delayed(
Duration(milliseconds: 300),
);
return res;
}
Future<bool> registerTask(String appName) async {
final taskXml = '''
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<Principals>
<Principal id="Author">
<LogonType>InteractiveToken</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Triggers>
<LogonTrigger/>
</Triggers>
<Settings>
<MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>false</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>false</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>"${Platform.resolvedExecutable}"</Command>
</Exec>
</Actions>
</Task>''';
final taskPath = join(await appPath.tempPath, "task.xml");
await File(taskPath).create(recursive: true);
await File(taskPath)
.writeAsBytes(taskXml.encodeUtf16LeWithBom, flush: true);
final commandLine = [
'/Create',
'/TN',
appName,
'/XML',
"%s",
'/F',
].join(" ");
return runas(
'schtasks',
commandLine.replaceFirst("%s", taskPath),
);
}
}
final windows = Platform.isWindows ? Windows() : null;

View File

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

View File

@@ -2,8 +2,10 @@
import 'dart:io';
import 'package:fl_clash/common/system.dart';
import 'package:fl_clash/views/dashboard/widgets/widgets.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hotkey_manager/hotkey_manager.dart';
@@ -15,16 +17,16 @@ enum SupportPlatform {
Android;
static SupportPlatform get currentPlatform {
if (Platform.isWindows) {
if (system.isWindows) {
return SupportPlatform.Windows;
} else if (Platform.isMacOS) {
} else if (system.isMacOS) {
return SupportPlatform.MacOS;
} else if (Platform.isLinux) {
return SupportPlatform.Linux;
} else if (Platform.isAndroid) {
} else if (system.isAndroid) {
return SupportPlatform.Android;
}
throw "invalid platform";
throw 'invalid platform';
}
}
@@ -43,11 +45,11 @@ enum GroupType {
static GroupType parseProfileType(String type) {
return switch (type) {
"url-test" => URLTest,
"select" => Selector,
"fallback" => Fallback,
"load-balance" => LoadBalance,
"relay" => Relay,
'url-test' => URLTest,
'select' => Selector,
'fallback' => Fallback,
'load-balance' => LoadBalance,
'relay' => Relay,
String() => throw UnimplementedError(),
};
}
@@ -58,7 +60,7 @@ enum GroupName { GLOBAL, Proxy, Auto, Fallback }
extension GroupTypeExtension on GroupType {
static List<String> get valueList => GroupType.values
.map(
(e) => e.toString().split(".").last,
(e) => e.toString().split('.').last,
)
.toList();
@@ -80,7 +82,7 @@ enum UsedProxy { GLOBAL, DIRECT, REJECT }
extension UsedProxyExtension on UsedProxy {
static List<String> get valueList => UsedProxy.values
.map(
(e) => e.toString().split(".").last,
(e) => e.toString().split('.').last,
)
.toList();
@@ -97,7 +99,18 @@ enum LogLevel {
warning,
error,
silent,
app,
}
extension LogLevelExt on LogLevel {
Color? get color {
return switch (this) {
LogLevel.silent => Colors.grey.shade700,
LogLevel.debug => Colors.grey.shade400,
LogLevel.info => null,
LogLevel.warning => Colors.yellowAccent,
LogLevel.error => Colors.redAccent,
};
}
}
enum TransportProtocol { udp, tcp }
@@ -160,18 +173,18 @@ enum ProxyCardType { expand, shrink, min }
enum DnsMode {
normal,
@JsonValue("fake-ip")
@JsonValue('fake-ip')
fakeIp,
@JsonValue("redir-host")
@JsonValue('redir-host')
redirHost,
hosts
}
enum ExternalControllerStatus {
@JsonValue("")
close(""),
@JsonValue("127.0.0.1:9090")
open("127.0.0.1:9090");
@JsonValue('')
close(''),
@JsonValue('127.0.0.1:9090')
open('127.0.0.1:9090');
final String value;
@@ -235,9 +248,9 @@ enum ProxiesIconStyle {
}
enum FontFamily {
twEmoji("Twemoji"),
jetBrainsMono("JetBrainsMono"),
icon("Icons");
twEmoji('Twemoji'),
jetBrainsMono('JetBrainsMono'),
icon('Icons');
final String value;
@@ -320,6 +333,7 @@ enum FunctionTag {
proxiesTabChange,
logs,
requests,
autoScrollToEnd,
}
enum DashboardWidget {
@@ -423,39 +437,39 @@ enum PageLabel {
}
enum RuleAction {
DOMAIN("DOMAIN"),
DOMAIN_SUFFIX("DOMAIN-SUFFIX"),
DOMAIN_KEYWORD("DOMAIN-KEYWORD"),
DOMAIN_REGEX("DOMAIN-REGEX"),
GEOSITE("GEOSITE"),
IP_CIDR("IP-CIDR"),
IP_CIDR6("IP-CIDR6"),
IP_SUFFIX("IP-SUFFIX"),
IP_ASN("IP-ASN"),
GEOIP("GEOIP"),
SRC_GEOIP("SRC-GEOIP"),
SRC_IP_ASN("SRC-IP-ASN"),
SRC_IP_CIDR("SRC-IP-CIDR"),
SRC_IP_SUFFIX("SRC-IP-SUFFIX"),
DST_PORT("DST-PORT"),
SRC_PORT("SRC-PORT"),
IN_PORT("IN-PORT"),
IN_TYPE("IN-TYPE"),
IN_USER("IN-USER"),
IN_NAME("IN-NAME"),
PROCESS_PATH("PROCESS-PATH"),
PROCESS_PATH_REGEX("PROCESS-PATH-REGEX"),
PROCESS_NAME("PROCESS-NAME"),
PROCESS_NAME_REGEX("PROCESS-NAME-REGEX"),
UID("UID"),
NETWORK("NETWORK"),
DSCP("DSCP"),
RULE_SET("RULE-SET"),
AND("AND"),
OR("OR"),
NOT("NOT"),
SUB_RULE("SUB-RULE"),
MATCH("MATCH");
DOMAIN('DOMAIN'),
DOMAIN_SUFFIX('DOMAIN-SUFFIX'),
DOMAIN_KEYWORD('DOMAIN-KEYWORD'),
DOMAIN_REGEX('DOMAIN-REGEX'),
GEOSITE('GEOSITE'),
IP_CIDR('IP-CIDR'),
IP_CIDR6('IP-CIDR6'),
IP_SUFFIX('IP-SUFFIX'),
IP_ASN('IP-ASN'),
GEOIP('GEOIP'),
SRC_GEOIP('SRC-GEOIP'),
SRC_IP_ASN('SRC-IP-ASN'),
SRC_IP_CIDR('SRC-IP-CIDR'),
SRC_IP_SUFFIX('SRC-IP-SUFFIX'),
DST_PORT('DST-PORT'),
SRC_PORT('SRC-PORT'),
IN_PORT('IN-PORT'),
IN_TYPE('IN-TYPE'),
IN_USER('IN-USER'),
IN_NAME('IN-NAME'),
PROCESS_PATH('PROCESS-PATH'),
PROCESS_PATH_REGEX('PROCESS-PATH-REGEX'),
PROCESS_NAME('PROCESS-NAME'),
PROCESS_NAME_REGEX('PROCESS-NAME-REGEX'),
UID('UID'),
NETWORK('NETWORK'),
DSCP('DSCP'),
RULE_SET('RULE-SET'),
AND('AND'),
OR('OR'),
NOT('NOT'),
SUB_RULE('SUB-RULE'),
MATCH('MATCH');
final String value;
@@ -493,6 +507,7 @@ enum CacheTag {
logs,
rules,
requests,
proxiesList,
}
enum Language {
@@ -504,3 +519,10 @@ enum ImportOption {
file,
url,
}
enum ScrollPositionCacheKeys {
tools,
profiles,
proxiesList,
proxiesTabList,
}

View File

@@ -26,19 +26,21 @@ class MessageLookup extends MessageLookupByLibrary {
static String m1(label) =>
"Are you sure you want to delete the current ${label}?";
static String m2(label) => "${label} cannot be empty";
static String m2(label) => "${label} details";
static String m3(label) => "Current ${label} already exists";
static String m3(label) => "${label} cannot be empty";
static String m4(label) => "No ${label} at the moment";
static String m4(label) => "Current ${label} already exists";
static String m5(label) => "${label} must be a number";
static String m5(label) => "No ${label} at the moment";
static String m6(label) => "${label} must be between 1024 and 49151";
static String m6(label) => "${label} must be a number";
static String m7(count) => "${count} items have been selected";
static String m7(label) => "${label} must be between 1024 and 49151";
static String m8(label) => "${label} must be a url";
static String m8(count) => "${count} items have been selected";
static String m9(label) => "${label} must be a url";
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -175,6 +177,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Opening it will lose part of its application ability and gain the support of full amount of Clash.",
),
"confirm": MessageLookupByLibrary.simpleMessage("Confirm"),
"connection": MessageLookupByLibrary.simpleMessage("Connection"),
"connections": MessageLookupByLibrary.simpleMessage("Connections"),
"connectionsDesc": MessageLookupByLibrary.simpleMessage(
"View current connections data",
@@ -194,6 +197,7 @@ class MessageLookup extends MessageLookupByLibrary {
"country": MessageLookupByLibrary.simpleMessage("Country"),
"crashTest": MessageLookupByLibrary.simpleMessage("Crash test"),
"create": MessageLookupByLibrary.simpleMessage("Create"),
"creationTime": MessageLookupByLibrary.simpleMessage("Creation time"),
"cut": MessageLookupByLibrary.simpleMessage("Cut"),
"dark": MessageLookupByLibrary.simpleMessage("Dark"),
"dashboard": MessageLookupByLibrary.simpleMessage("Dashboard"),
@@ -214,6 +218,14 @@ class MessageLookup extends MessageLookupByLibrary {
"desc": MessageLookupByLibrary.simpleMessage(
"A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free.",
),
"destination": MessageLookupByLibrary.simpleMessage("Destination"),
"destinationGeoIP": MessageLookupByLibrary.simpleMessage(
"Destination GeoIP",
),
"destinationIPASN": MessageLookupByLibrary.simpleMessage(
"Destination IPASN",
),
"details": m2,
"detectionTip": MessageLookupByLibrary.simpleMessage(
"Relying on third-party api is for reference only",
),
@@ -242,7 +254,7 @@ class MessageLookup extends MessageLookupByLibrary {
"domain": MessageLookupByLibrary.simpleMessage("Domain"),
"download": MessageLookupByLibrary.simpleMessage("Download"),
"edit": MessageLookupByLibrary.simpleMessage("Edit"),
"emptyTip": m2,
"emptyTip": m3,
"en": MessageLookupByLibrary.simpleMessage("English"),
"enableOverride": MessageLookupByLibrary.simpleMessage("Enable override"),
"entries": MessageLookupByLibrary.simpleMessage(" entries"),
@@ -250,7 +262,7 @@ class MessageLookup extends MessageLookupByLibrary {
"excludeDesc": MessageLookupByLibrary.simpleMessage(
"When the app is in the background, the app is hidden from the recent task",
),
"existsTip": m3,
"existsTip": m4,
"exit": MessageLookupByLibrary.simpleMessage("Exit"),
"expand": MessageLookupByLibrary.simpleMessage("Standard"),
"expirationTime": MessageLookupByLibrary.simpleMessage("Expiration time"),
@@ -312,6 +324,7 @@ class MessageLookup extends MessageLookupByLibrary {
"hasCacheChange": MessageLookupByLibrary.simpleMessage(
"Do you want to cache the changes?",
),
"host": MessageLookupByLibrary.simpleMessage("Host"),
"hostsDesc": MessageLookupByLibrary.simpleMessage("Add Hosts"),
"hotkeyConflict": MessageLookupByLibrary.simpleMessage("Hotkey conflict"),
"hotkeyManagement": MessageLookupByLibrary.simpleMessage(
@@ -366,6 +379,7 @@ class MessageLookup extends MessageLookupByLibrary {
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"Recovery data from file",
),
"log": MessageLookupByLibrary.simpleMessage("Log"),
"logLevel": MessageLookupByLibrary.simpleMessage("LogLevel"),
"logcat": MessageLookupByLibrary.simpleMessage("Logcat"),
"logcatDesc": MessageLookupByLibrary.simpleMessage(
@@ -415,6 +429,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Network detection",
),
"networkSpeed": MessageLookupByLibrary.simpleMessage("Network speed"),
"networkType": MessageLookupByLibrary.simpleMessage("Network type"),
"neutralScheme": MessageLookupByLibrary.simpleMessage("Neutral"),
"noData": MessageLookupByLibrary.simpleMessage("No data"),
"noHotKey": MessageLookupByLibrary.simpleMessage("No HotKey"),
@@ -435,8 +450,8 @@ class MessageLookup extends MessageLookupByLibrary {
"nullProfileDesc": MessageLookupByLibrary.simpleMessage(
"No profile, Please add a profile",
),
"nullTip": m4,
"numberTip": m5,
"nullTip": m5,
"numberTip": m6,
"oneColumn": MessageLookupByLibrary.simpleMessage("One column"),
"onlyIcon": MessageLookupByLibrary.simpleMessage("Icon"),
"onlyOtherApps": MessageLookupByLibrary.simpleMessage(
@@ -490,7 +505,7 @@ class MessageLookup extends MessageLookupByLibrary {
"portConflictTip": MessageLookupByLibrary.simpleMessage(
"Please enter a different port",
),
"portTip": m6,
"portTip": m7,
"preferH3Desc": MessageLookupByLibrary.simpleMessage(
"Prioritize the use of DOH\'s http/3",
),
@@ -524,10 +539,12 @@ class MessageLookup extends MessageLookupByLibrary {
),
"profiles": MessageLookupByLibrary.simpleMessage("Profiles"),
"profilesSort": MessageLookupByLibrary.simpleMessage("Profiles sort"),
"progress": MessageLookupByLibrary.simpleMessage("Progress"),
"project": MessageLookupByLibrary.simpleMessage("Project"),
"providers": MessageLookupByLibrary.simpleMessage("Providers"),
"proxies": MessageLookupByLibrary.simpleMessage("Proxies"),
"proxiesSetting": MessageLookupByLibrary.simpleMessage("Proxies setting"),
"proxyChains": MessageLookupByLibrary.simpleMessage("Proxy chains"),
"proxyGroup": MessageLookupByLibrary.simpleMessage("Proxy group"),
"proxyNameserver": MessageLookupByLibrary.simpleMessage("Proxy nameserver"),
"proxyNameserverDesc": MessageLookupByLibrary.simpleMessage(
@@ -566,11 +583,15 @@ class MessageLookup extends MessageLookupByLibrary {
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage(
"Backup local data to WebDAV",
),
"remoteDestination": MessageLookupByLibrary.simpleMessage(
"Remote destination",
),
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"Recovery data from WebDAV",
),
"remove": MessageLookupByLibrary.simpleMessage("Remove"),
"rename": MessageLookupByLibrary.simpleMessage("Rename"),
"request": MessageLookupByLibrary.simpleMessage("Request"),
"requests": MessageLookupByLibrary.simpleMessage("Requests"),
"requestsDesc": MessageLookupByLibrary.simpleMessage(
"View recently request records",
@@ -611,7 +632,7 @@ class MessageLookup extends MessageLookupByLibrary {
"seconds": MessageLookupByLibrary.simpleMessage("Seconds"),
"selectAll": MessageLookupByLibrary.simpleMessage("Select all"),
"selected": MessageLookupByLibrary.simpleMessage("Selected"),
"selectedCountTitle": m7,
"selectedCountTitle": m8,
"settings": MessageLookupByLibrary.simpleMessage("Settings"),
"show": MessageLookupByLibrary.simpleMessage("Show"),
"shrink": MessageLookupByLibrary.simpleMessage("Shrink"),
@@ -624,6 +645,8 @@ class MessageLookup extends MessageLookupByLibrary {
"sort": MessageLookupByLibrary.simpleMessage("Sort"),
"source": MessageLookupByLibrary.simpleMessage("Source"),
"sourceIp": MessageLookupByLibrary.simpleMessage("Source IP"),
"specialProxy": MessageLookupByLibrary.simpleMessage("Special proxy"),
"specialRules": MessageLookupByLibrary.simpleMessage("special rules"),
"stackMode": MessageLookupByLibrary.simpleMessage("Stack mode"),
"standard": MessageLookupByLibrary.simpleMessage("Standard"),
"start": MessageLookupByLibrary.simpleMessage("Start"),
@@ -692,7 +715,7 @@ class MessageLookup extends MessageLookupByLibrary {
"urlDesc": MessageLookupByLibrary.simpleMessage(
"Obtain profile through URL",
),
"urlTip": m8,
"urlTip": m9,
"useHosts": MessageLookupByLibrary.simpleMessage("Use hosts"),
"useSystemHosts": MessageLookupByLibrary.simpleMessage("Use system hosts"),
"value": MessageLookupByLibrary.simpleMessage("Value"),

View File

@@ -24,19 +24,21 @@ class MessageLookup extends MessageLookupByLibrary {
static String m1(label) => "現在の${label}を削除してもよろしいですか?";
static String m2(label) => "${label}は空欄にできません";
static String m2(label) => "${label}詳細";
static String m3(label) => "現在の${label}既に存在しています";
static String m3(label) => "${label}空欄にできません";
static String m4(label) => "現在${label}ありません";
static String m4(label) => "現在${label}既に存在しています";
static String m5(label) => "${label}数字でなければなりません";
static String m5(label) => "現在${label}りません";
static String m6(label) => "${label} は 1024 から 49151 の間でなければなりません";
static String m6(label) => "${label}は数字でなければなりません";
static String m7(count) => "${count} 項目が選択されています";
static String m7(label) => "${label} は 1024 から 49151 の間でなければなりません";
static String m8(label) => "${label}はURLである必要があります";
static String m8(count) => "${count} 項目が選択されています";
static String m9(label) => "${label}はURLである必要があります";
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -131,6 +133,7 @@ class MessageLookup extends MessageLookupByLibrary {
"有効化すると一部機能を失いますが、Clashの完全サポートを獲得",
),
"confirm": MessageLookupByLibrary.simpleMessage("確認"),
"connection": MessageLookupByLibrary.simpleMessage("接続"),
"connections": MessageLookupByLibrary.simpleMessage("接続"),
"connectionsDesc": MessageLookupByLibrary.simpleMessage("現在の接続データを表示"),
"connectivity": MessageLookupByLibrary.simpleMessage("接続性:"),
@@ -146,6 +149,7 @@ class MessageLookup extends MessageLookupByLibrary {
"country": MessageLookupByLibrary.simpleMessage(""),
"crashTest": MessageLookupByLibrary.simpleMessage("クラッシュテスト"),
"create": MessageLookupByLibrary.simpleMessage("作成"),
"creationTime": MessageLookupByLibrary.simpleMessage("作成時間"),
"cut": MessageLookupByLibrary.simpleMessage("切り取り"),
"dark": MessageLookupByLibrary.simpleMessage("ダーク"),
"dashboard": MessageLookupByLibrary.simpleMessage("ダッシュボード"),
@@ -164,6 +168,10 @@ class MessageLookup extends MessageLookupByLibrary {
"desc": MessageLookupByLibrary.simpleMessage(
"ClashMetaベースのマルチプラットフォームプロキシクライアント。シンプルで使いやすく、オープンソースで広告なし。",
),
"destination": MessageLookupByLibrary.simpleMessage("宛先"),
"destinationGeoIP": MessageLookupByLibrary.simpleMessage("宛先地理情報"),
"destinationIPASN": MessageLookupByLibrary.simpleMessage("宛先IP ASN"),
"details": m2,
"detectionTip": MessageLookupByLibrary.simpleMessage("サードパーティAPIに依存参考値"),
"developerMode": MessageLookupByLibrary.simpleMessage("デベロッパーモード"),
"developerModeEnableTip": MessageLookupByLibrary.simpleMessage(
@@ -182,7 +190,7 @@ class MessageLookup extends MessageLookupByLibrary {
"domain": MessageLookupByLibrary.simpleMessage("ドメイン"),
"download": MessageLookupByLibrary.simpleMessage("ダウンロード"),
"edit": MessageLookupByLibrary.simpleMessage("編集"),
"emptyTip": m2,
"emptyTip": m3,
"en": MessageLookupByLibrary.simpleMessage("英語"),
"enableOverride": MessageLookupByLibrary.simpleMessage("上書きを有効化"),
"entries": MessageLookupByLibrary.simpleMessage(" エントリ"),
@@ -190,7 +198,7 @@ class MessageLookup extends MessageLookupByLibrary {
"excludeDesc": MessageLookupByLibrary.simpleMessage(
"アプリがバックグラウンド時に最近のタスクから非表示",
),
"existsTip": m3,
"existsTip": m4,
"exit": MessageLookupByLibrary.simpleMessage("終了"),
"expand": MessageLookupByLibrary.simpleMessage("標準"),
"expirationTime": MessageLookupByLibrary.simpleMessage("有効期限"),
@@ -236,6 +244,7 @@ class MessageLookup extends MessageLookupByLibrary {
"go": MessageLookupByLibrary.simpleMessage("移動"),
"goDownload": MessageLookupByLibrary.simpleMessage("ダウンロードへ"),
"hasCacheChange": MessageLookupByLibrary.simpleMessage("変更をキャッシュしますか?"),
"host": MessageLookupByLibrary.simpleMessage("ホスト"),
"hostsDesc": MessageLookupByLibrary.simpleMessage("ホストを追加"),
"hotkeyConflict": MessageLookupByLibrary.simpleMessage("ホットキー競合"),
"hotkeyManagement": MessageLookupByLibrary.simpleMessage("ホットキー管理"),
@@ -274,6 +283,7 @@ class MessageLookup extends MessageLookupByLibrary {
"local": MessageLookupByLibrary.simpleMessage("ローカル"),
"localBackupDesc": MessageLookupByLibrary.simpleMessage("ローカルにデータをバックアップ"),
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage("ファイルからデータを復元"),
"log": MessageLookupByLibrary.simpleMessage("ログ"),
"logLevel": MessageLookupByLibrary.simpleMessage("ログレベル"),
"logcat": MessageLookupByLibrary.simpleMessage("ログキャット"),
"logcatDesc": MessageLookupByLibrary.simpleMessage("無効化するとログエントリを非表示"),
@@ -309,6 +319,7 @@ class MessageLookup extends MessageLookupByLibrary {
"networkDesc": MessageLookupByLibrary.simpleMessage("ネットワーク関連設定の変更"),
"networkDetection": MessageLookupByLibrary.simpleMessage("ネットワーク検出"),
"networkSpeed": MessageLookupByLibrary.simpleMessage("ネットワーク速度"),
"networkType": MessageLookupByLibrary.simpleMessage("ネットワーク種別"),
"neutralScheme": MessageLookupByLibrary.simpleMessage("ニュートラル"),
"noData": MessageLookupByLibrary.simpleMessage("データなし"),
"noHotKey": MessageLookupByLibrary.simpleMessage("ホットキーなし"),
@@ -329,8 +340,8 @@ class MessageLookup extends MessageLookupByLibrary {
"nullProfileDesc": MessageLookupByLibrary.simpleMessage(
"プロファイルがありません。追加してください",
),
"nullTip": m4,
"numberTip": m5,
"nullTip": m5,
"numberTip": m6,
"oneColumn": MessageLookupByLibrary.simpleMessage("1列"),
"onlyIcon": MessageLookupByLibrary.simpleMessage("アイコンのみ"),
"onlyOtherApps": MessageLookupByLibrary.simpleMessage("サードパーティアプリのみ"),
@@ -372,7 +383,7 @@ class MessageLookup extends MessageLookupByLibrary {
),
"port": MessageLookupByLibrary.simpleMessage("ポート"),
"portConflictTip": MessageLookupByLibrary.simpleMessage("別のポートを入力してください"),
"portTip": m6,
"portTip": m7,
"preferH3Desc": MessageLookupByLibrary.simpleMessage("DOHのHTTP/3を優先使用"),
"pressKeyboard": MessageLookupByLibrary.simpleMessage("キーボードを押してください"),
"preview": MessageLookupByLibrary.simpleMessage("プレビュー"),
@@ -398,10 +409,12 @@ class MessageLookup extends MessageLookupByLibrary {
),
"profiles": MessageLookupByLibrary.simpleMessage("プロファイル一覧"),
"profilesSort": MessageLookupByLibrary.simpleMessage("プロファイルの並び替え"),
"progress": MessageLookupByLibrary.simpleMessage("進捗"),
"project": MessageLookupByLibrary.simpleMessage("プロジェクト"),
"providers": MessageLookupByLibrary.simpleMessage("プロバイダー"),
"proxies": MessageLookupByLibrary.simpleMessage("プロキシ"),
"proxiesSetting": MessageLookupByLibrary.simpleMessage("プロキシ設定"),
"proxyChains": MessageLookupByLibrary.simpleMessage("プロキシチェーン"),
"proxyGroup": MessageLookupByLibrary.simpleMessage("プロキシグループ"),
"proxyNameserver": MessageLookupByLibrary.simpleMessage("プロキシネームサーバー"),
"proxyNameserverDesc": MessageLookupByLibrary.simpleMessage(
@@ -430,11 +443,13 @@ class MessageLookup extends MessageLookupByLibrary {
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage(
"WebDAVにデータをバックアップ",
),
"remoteDestination": MessageLookupByLibrary.simpleMessage("リモート宛先"),
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"WebDAVからデータを復元",
),
"remove": MessageLookupByLibrary.simpleMessage("削除"),
"rename": MessageLookupByLibrary.simpleMessage("リネーム"),
"request": MessageLookupByLibrary.simpleMessage("リクエスト"),
"requests": MessageLookupByLibrary.simpleMessage("リクエスト"),
"requestsDesc": MessageLookupByLibrary.simpleMessage("最近のリクエスト記録を表示"),
"reset": MessageLookupByLibrary.simpleMessage("リセット"),
@@ -465,7 +480,7 @@ class MessageLookup extends MessageLookupByLibrary {
"seconds": MessageLookupByLibrary.simpleMessage(""),
"selectAll": MessageLookupByLibrary.simpleMessage("すべて選択"),
"selected": MessageLookupByLibrary.simpleMessage("選択済み"),
"selectedCountTitle": m7,
"selectedCountTitle": m8,
"settings": MessageLookupByLibrary.simpleMessage("設定"),
"show": MessageLookupByLibrary.simpleMessage("表示"),
"shrink": MessageLookupByLibrary.simpleMessage("縮小"),
@@ -476,6 +491,8 @@ class MessageLookup extends MessageLookupByLibrary {
"sort": MessageLookupByLibrary.simpleMessage("並び替え"),
"source": MessageLookupByLibrary.simpleMessage("ソース"),
"sourceIp": MessageLookupByLibrary.simpleMessage("送信元IP"),
"specialProxy": MessageLookupByLibrary.simpleMessage("特殊プロキシ"),
"specialRules": MessageLookupByLibrary.simpleMessage("特殊ルール"),
"stackMode": MessageLookupByLibrary.simpleMessage("スタックモード"),
"standard": MessageLookupByLibrary.simpleMessage("標準"),
"start": MessageLookupByLibrary.simpleMessage("開始"),
@@ -532,7 +549,7 @@ class MessageLookup extends MessageLookupByLibrary {
"upload": MessageLookupByLibrary.simpleMessage("アップロード"),
"url": MessageLookupByLibrary.simpleMessage("URL"),
"urlDesc": MessageLookupByLibrary.simpleMessage("URL経由でプロファイルを取得"),
"urlTip": m8,
"urlTip": m9,
"useHosts": MessageLookupByLibrary.simpleMessage("ホストを使用"),
"useSystemHosts": MessageLookupByLibrary.simpleMessage("システムホストを使用"),
"value": MessageLookupByLibrary.simpleMessage(""),

View File

@@ -25,19 +25,21 @@ class MessageLookup extends MessageLookupByLibrary {
static String m1(label) => "Вы уверены, что хотите удалить текущий ${label}?";
static String m2(label) => "${label} не может быть пустым";
static String m2(label) => "Детали {}";
static String m3(label) => "Текущий ${label} уже существует";
static String m3(label) => "${label} не может быть пустым";
static String m4(label) => "Сейчас ${label} нет";
static String m4(label) => "Текущий ${label} уже существует";
static String m5(label) => "${label} должно быть числом";
static String m5(label) => "Сейчас ${label} нет";
static String m6(label) => "${label} должен быть числом от 1024 до 49151";
static String m6(label) => "${label} должно быть числом";
static String m7(count) => "Выбрано ${count} элементов";
static String m7(label) => "${label} должен быть числом от 1024 до 49151";
static String m8(label) => "${label} должен быть URL";
static String m8(count) => "Выбрано ${count} элементов";
static String m9(label) => "${label} должен быть URL";
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -180,6 +182,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Включение приведет к потере части функциональности приложения, но обеспечит полную поддержку Clash.",
),
"confirm": MessageLookupByLibrary.simpleMessage("Подтвердить"),
"connection": MessageLookupByLibrary.simpleMessage("Соединение"),
"connections": MessageLookupByLibrary.simpleMessage("Соединения"),
"connectionsDesc": MessageLookupByLibrary.simpleMessage(
"Просмотр текущих данных о соединениях",
@@ -199,6 +202,7 @@ class MessageLookup extends MessageLookupByLibrary {
"country": MessageLookupByLibrary.simpleMessage("Страна"),
"crashTest": MessageLookupByLibrary.simpleMessage("Тест на сбои"),
"create": MessageLookupByLibrary.simpleMessage("Создать"),
"creationTime": MessageLookupByLibrary.simpleMessage("Время создания"),
"cut": MessageLookupByLibrary.simpleMessage("Вырезать"),
"dark": MessageLookupByLibrary.simpleMessage("Темный"),
"dashboard": MessageLookupByLibrary.simpleMessage("Панель управления"),
@@ -221,6 +225,12 @@ class MessageLookup extends MessageLookupByLibrary {
"desc": MessageLookupByLibrary.simpleMessage(
"Многоплатформенный прокси-клиент на основе ClashMeta, простой и удобный в использовании, с открытым исходным кодом и без рекламы.",
),
"destination": MessageLookupByLibrary.simpleMessage("Назначение"),
"destinationGeoIP": MessageLookupByLibrary.simpleMessage(
"Геолокация назначения",
),
"destinationIPASN": MessageLookupByLibrary.simpleMessage("ASN назначения"),
"details": m2,
"detectionTip": MessageLookupByLibrary.simpleMessage(
"Опирается на сторонний API, только для справки",
),
@@ -251,7 +261,7 @@ class MessageLookup extends MessageLookupByLibrary {
"domain": MessageLookupByLibrary.simpleMessage("Домен"),
"download": MessageLookupByLibrary.simpleMessage("Скачивание"),
"edit": MessageLookupByLibrary.simpleMessage("Редактировать"),
"emptyTip": m2,
"emptyTip": m3,
"en": MessageLookupByLibrary.simpleMessage("Английский"),
"enableOverride": MessageLookupByLibrary.simpleMessage(
"Включить переопределение",
@@ -263,7 +273,7 @@ class MessageLookup extends MessageLookupByLibrary {
"excludeDesc": MessageLookupByLibrary.simpleMessage(
"Когда приложение находится в фоновом режиме, оно скрыто из последних задач",
),
"existsTip": m3,
"existsTip": m4,
"exit": MessageLookupByLibrary.simpleMessage("Выход"),
"expand": MessageLookupByLibrary.simpleMessage("Стандартный"),
"expirationTime": MessageLookupByLibrary.simpleMessage("Время истечения"),
@@ -329,6 +339,7 @@ class MessageLookup extends MessageLookupByLibrary {
"hasCacheChange": MessageLookupByLibrary.simpleMessage(
"Хотите сохранить изменения в кэше?",
),
"host": MessageLookupByLibrary.simpleMessage("Хост"),
"hostsDesc": MessageLookupByLibrary.simpleMessage("Добавить Hosts"),
"hotkeyConflict": MessageLookupByLibrary.simpleMessage(
"Конфликт горячих клавиш",
@@ -387,6 +398,7 @@ class MessageLookup extends MessageLookupByLibrary {
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"Восстановление данных из файла",
),
"log": MessageLookupByLibrary.simpleMessage("Журнал"),
"logLevel": MessageLookupByLibrary.simpleMessage("Уровень логов"),
"logcat": MessageLookupByLibrary.simpleMessage("Logcat"),
"logcatDesc": MessageLookupByLibrary.simpleMessage(
@@ -440,6 +452,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Обнаружение сети",
),
"networkSpeed": MessageLookupByLibrary.simpleMessage("Скорость сети"),
"networkType": MessageLookupByLibrary.simpleMessage("Тип сети"),
"neutralScheme": MessageLookupByLibrary.simpleMessage("Нейтральные"),
"noData": MessageLookupByLibrary.simpleMessage("Нет данных"),
"noHotKey": MessageLookupByLibrary.simpleMessage("Нет горячей клавиши"),
@@ -462,8 +475,8 @@ class MessageLookup extends MessageLookupByLibrary {
"nullProfileDesc": MessageLookupByLibrary.simpleMessage(
"Нет профиля, пожалуйста, добавьте профиль",
),
"nullTip": m4,
"numberTip": m5,
"nullTip": m5,
"numberTip": m6,
"oneColumn": MessageLookupByLibrary.simpleMessage("Один столбец"),
"onlyIcon": MessageLookupByLibrary.simpleMessage("Только иконка"),
"onlyOtherApps": MessageLookupByLibrary.simpleMessage(
@@ -519,7 +532,7 @@ class MessageLookup extends MessageLookupByLibrary {
"portConflictTip": MessageLookupByLibrary.simpleMessage(
"Введите другой порт",
),
"portTip": m6,
"portTip": m7,
"preferH3Desc": MessageLookupByLibrary.simpleMessage(
"Приоритетное использование HTTP/3 для DOH",
),
@@ -553,10 +566,12 @@ class MessageLookup extends MessageLookupByLibrary {
),
"profiles": MessageLookupByLibrary.simpleMessage("Профили"),
"profilesSort": MessageLookupByLibrary.simpleMessage("Сортировка профилей"),
"progress": MessageLookupByLibrary.simpleMessage("Прогресс"),
"project": MessageLookupByLibrary.simpleMessage("Проект"),
"providers": MessageLookupByLibrary.simpleMessage("Провайдеры"),
"proxies": MessageLookupByLibrary.simpleMessage("Прокси"),
"proxiesSetting": MessageLookupByLibrary.simpleMessage("Настройка прокси"),
"proxyChains": MessageLookupByLibrary.simpleMessage("Цепочки прокси"),
"proxyGroup": MessageLookupByLibrary.simpleMessage("Группа прокси"),
"proxyNameserver": MessageLookupByLibrary.simpleMessage(
"Прокси-сервер имен",
@@ -601,11 +616,15 @@ class MessageLookup extends MessageLookupByLibrary {
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage(
"Резервное копирование локальных данных на WebDAV",
),
"remoteDestination": MessageLookupByLibrary.simpleMessage(
"Удалённое назначение",
),
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage(
"Восстановление данных с WebDAV",
),
"remove": MessageLookupByLibrary.simpleMessage("Удалить"),
"rename": MessageLookupByLibrary.simpleMessage("Переименовать"),
"request": MessageLookupByLibrary.simpleMessage("Запрос"),
"requests": MessageLookupByLibrary.simpleMessage("Запросы"),
"requestsDesc": MessageLookupByLibrary.simpleMessage(
"Просмотр последних записей запросов",
@@ -648,7 +667,7 @@ class MessageLookup extends MessageLookupByLibrary {
"seconds": MessageLookupByLibrary.simpleMessage("Секунд"),
"selectAll": MessageLookupByLibrary.simpleMessage("Выбрать все"),
"selected": MessageLookupByLibrary.simpleMessage("Выбрано"),
"selectedCountTitle": m7,
"selectedCountTitle": m8,
"settings": MessageLookupByLibrary.simpleMessage("Настройки"),
"show": MessageLookupByLibrary.simpleMessage("Показать"),
"shrink": MessageLookupByLibrary.simpleMessage("Сжать"),
@@ -661,6 +680,8 @@ class MessageLookup extends MessageLookupByLibrary {
"sort": MessageLookupByLibrary.simpleMessage("Сортировка"),
"source": MessageLookupByLibrary.simpleMessage("Источник"),
"sourceIp": MessageLookupByLibrary.simpleMessage("Исходный IP"),
"specialProxy": MessageLookupByLibrary.simpleMessage("Специальный прокси"),
"specialRules": MessageLookupByLibrary.simpleMessage("Специальные правила"),
"stackMode": MessageLookupByLibrary.simpleMessage("Режим стека"),
"standard": MessageLookupByLibrary.simpleMessage("Стандартный"),
"start": MessageLookupByLibrary.simpleMessage("Старт"),
@@ -733,7 +754,7 @@ class MessageLookup extends MessageLookupByLibrary {
"urlDesc": MessageLookupByLibrary.simpleMessage(
"Получить профиль через URL",
),
"urlTip": m8,
"urlTip": m9,
"useHosts": MessageLookupByLibrary.simpleMessage("Использовать hosts"),
"useSystemHosts": MessageLookupByLibrary.simpleMessage(
"Использовать системные hosts",

View File

@@ -24,19 +24,21 @@ class MessageLookup extends MessageLookupByLibrary {
static String m1(label) => "确定删除当前${label}吗?";
static String m2(label) => "${label}不能为空";
static String m2(label) => "${label}详情";
static String m3(label) => "${label}当前已存在";
static String m3(label) => "${label}不能为空";
static String m4(label) => "暂无${label}";
static String m4(label) => "${label}当前已存在";
static String m5(label) => "${label}必须为数字";
static String m5(label) => "暂无${label}";
static String m6(label) => "${label} 必须在 1024 到 49151 之间";
static String m6(label) => "${label}必须为数字";
static String m7(count) => "已选择 ${count}";
static String m7(label) => "${label} 必须在 1024 到 49151 之间";
static String m8(label) => "${label}必须为URL";
static String m8(count) => "已选择 ${count}";
static String m9(label) => "${label}必须为URL";
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -121,6 +123,7 @@ class MessageLookup extends MessageLookupByLibrary {
"开启将失去部分应用能力获得全量的Clash的支持",
),
"confirm": MessageLookupByLibrary.simpleMessage("确定"),
"connection": MessageLookupByLibrary.simpleMessage("连接"),
"connections": MessageLookupByLibrary.simpleMessage("连接"),
"connectionsDesc": MessageLookupByLibrary.simpleMessage("查看当前连接数据"),
"connectivity": MessageLookupByLibrary.simpleMessage("连通性:"),
@@ -136,6 +139,7 @@ class MessageLookup extends MessageLookupByLibrary {
"country": MessageLookupByLibrary.simpleMessage("区域"),
"crashTest": MessageLookupByLibrary.simpleMessage("崩溃测试"),
"create": MessageLookupByLibrary.simpleMessage("创建"),
"creationTime": MessageLookupByLibrary.simpleMessage("创建时间"),
"cut": MessageLookupByLibrary.simpleMessage("剪切"),
"dark": MessageLookupByLibrary.simpleMessage("深色"),
"dashboard": MessageLookupByLibrary.simpleMessage("仪表盘"),
@@ -152,6 +156,10 @@ class MessageLookup extends MessageLookupByLibrary {
"desc": MessageLookupByLibrary.simpleMessage(
"基于ClashMeta的多平台代理客户端简单易用开源无广告。",
),
"destination": MessageLookupByLibrary.simpleMessage("目标地址"),
"destinationGeoIP": MessageLookupByLibrary.simpleMessage("目标地理定位"),
"destinationIPASN": MessageLookupByLibrary.simpleMessage("目标IP ASN"),
"details": m2,
"detectionTip": MessageLookupByLibrary.simpleMessage("依赖第三方api仅供参考"),
"developerMode": MessageLookupByLibrary.simpleMessage("开发者模式"),
"developerModeEnableTip": MessageLookupByLibrary.simpleMessage("开发者模式已启用。"),
@@ -168,13 +176,13 @@ class MessageLookup extends MessageLookupByLibrary {
"domain": MessageLookupByLibrary.simpleMessage("域名"),
"download": MessageLookupByLibrary.simpleMessage("下载"),
"edit": MessageLookupByLibrary.simpleMessage("编辑"),
"emptyTip": m2,
"emptyTip": m3,
"en": MessageLookupByLibrary.simpleMessage("英语"),
"enableOverride": MessageLookupByLibrary.simpleMessage("启用覆写"),
"entries": MessageLookupByLibrary.simpleMessage("个条目"),
"exclude": MessageLookupByLibrary.simpleMessage("从最近任务中隐藏"),
"excludeDesc": MessageLookupByLibrary.simpleMessage("应用在后台时,从最近任务中隐藏应用"),
"existsTip": m3,
"existsTip": m4,
"exit": MessageLookupByLibrary.simpleMessage("退出"),
"expand": MessageLookupByLibrary.simpleMessage("标准"),
"expirationTime": MessageLookupByLibrary.simpleMessage("到期时间"),
@@ -214,6 +222,7 @@ class MessageLookup extends MessageLookupByLibrary {
"go": MessageLookupByLibrary.simpleMessage("前往"),
"goDownload": MessageLookupByLibrary.simpleMessage("前往下载"),
"hasCacheChange": MessageLookupByLibrary.simpleMessage("是否缓存修改"),
"host": MessageLookupByLibrary.simpleMessage("主机"),
"hostsDesc": MessageLookupByLibrary.simpleMessage("追加Hosts"),
"hotkeyConflict": MessageLookupByLibrary.simpleMessage("快捷键冲突"),
"hotkeyManagement": MessageLookupByLibrary.simpleMessage("快捷键管理"),
@@ -248,6 +257,7 @@ class MessageLookup extends MessageLookupByLibrary {
"local": MessageLookupByLibrary.simpleMessage("本地"),
"localBackupDesc": MessageLookupByLibrary.simpleMessage("备份数据到本地"),
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage("通过文件恢复数据"),
"log": MessageLookupByLibrary.simpleMessage("日志"),
"logLevel": MessageLookupByLibrary.simpleMessage("日志等级"),
"logcat": MessageLookupByLibrary.simpleMessage("日志捕获"),
"logcatDesc": MessageLookupByLibrary.simpleMessage("禁用将会隐藏日志入口"),
@@ -279,6 +289,7 @@ class MessageLookup extends MessageLookupByLibrary {
"networkDesc": MessageLookupByLibrary.simpleMessage("修改网络相关设置"),
"networkDetection": MessageLookupByLibrary.simpleMessage("网络检测"),
"networkSpeed": MessageLookupByLibrary.simpleMessage("网络速度"),
"networkType": MessageLookupByLibrary.simpleMessage("网络类型"),
"neutralScheme": MessageLookupByLibrary.simpleMessage("中性"),
"noData": MessageLookupByLibrary.simpleMessage("暂无数据"),
"noHotKey": MessageLookupByLibrary.simpleMessage("暂无快捷键"),
@@ -293,8 +304,8 @@ class MessageLookup extends MessageLookupByLibrary {
"none": MessageLookupByLibrary.simpleMessage(""),
"notSelectedTip": MessageLookupByLibrary.simpleMessage("当前代理组无法选中"),
"nullProfileDesc": MessageLookupByLibrary.simpleMessage("没有配置文件,请先添加配置文件"),
"nullTip": m4,
"numberTip": m5,
"nullTip": m5,
"numberTip": m6,
"oneColumn": MessageLookupByLibrary.simpleMessage("一列"),
"onlyIcon": MessageLookupByLibrary.simpleMessage("仅图标"),
"onlyOtherApps": MessageLookupByLibrary.simpleMessage("仅第三方应用"),
@@ -326,7 +337,7 @@ class MessageLookup extends MessageLookupByLibrary {
),
"port": MessageLookupByLibrary.simpleMessage("端口"),
"portConflictTip": MessageLookupByLibrary.simpleMessage("请输入不同的端口"),
"portTip": m6,
"portTip": m7,
"preferH3Desc": MessageLookupByLibrary.simpleMessage("优先使用DOH的http/3"),
"pressKeyboard": MessageLookupByLibrary.simpleMessage("请按下按键"),
"preview": MessageLookupByLibrary.simpleMessage("预览"),
@@ -350,10 +361,12 @@ class MessageLookup extends MessageLookupByLibrary {
),
"profiles": MessageLookupByLibrary.simpleMessage("配置"),
"profilesSort": MessageLookupByLibrary.simpleMessage("配置排序"),
"progress": MessageLookupByLibrary.simpleMessage("进度"),
"project": MessageLookupByLibrary.simpleMessage("项目"),
"providers": MessageLookupByLibrary.simpleMessage("提供者"),
"proxies": MessageLookupByLibrary.simpleMessage("代理"),
"proxiesSetting": MessageLookupByLibrary.simpleMessage("代理设置"),
"proxyChains": MessageLookupByLibrary.simpleMessage("代理链"),
"proxyGroup": MessageLookupByLibrary.simpleMessage("代理组"),
"proxyNameserver": MessageLookupByLibrary.simpleMessage("代理域名服务器"),
"proxyNameserverDesc": MessageLookupByLibrary.simpleMessage("用于解析代理节点的域名"),
@@ -376,9 +389,11 @@ class MessageLookup extends MessageLookupByLibrary {
"regExp": MessageLookupByLibrary.simpleMessage("正则"),
"remote": MessageLookupByLibrary.simpleMessage("远程"),
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage("备份数据到WebDAV"),
"remoteDestination": MessageLookupByLibrary.simpleMessage("远程目标"),
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage("通过WebDAV恢复数据"),
"remove": MessageLookupByLibrary.simpleMessage("移除"),
"rename": MessageLookupByLibrary.simpleMessage("重命名"),
"request": MessageLookupByLibrary.simpleMessage("请求"),
"requests": MessageLookupByLibrary.simpleMessage("请求"),
"requestsDesc": MessageLookupByLibrary.simpleMessage("查看最近请求记录"),
"reset": MessageLookupByLibrary.simpleMessage("重置"),
@@ -407,7 +422,7 @@ class MessageLookup extends MessageLookupByLibrary {
"seconds": MessageLookupByLibrary.simpleMessage(""),
"selectAll": MessageLookupByLibrary.simpleMessage("全选"),
"selected": MessageLookupByLibrary.simpleMessage("已选择"),
"selectedCountTitle": m7,
"selectedCountTitle": m8,
"settings": MessageLookupByLibrary.simpleMessage("设置"),
"show": MessageLookupByLibrary.simpleMessage("显示"),
"shrink": MessageLookupByLibrary.simpleMessage("紧凑"),
@@ -418,6 +433,8 @@ class MessageLookup extends MessageLookupByLibrary {
"sort": MessageLookupByLibrary.simpleMessage("排序"),
"source": MessageLookupByLibrary.simpleMessage("来源"),
"sourceIp": MessageLookupByLibrary.simpleMessage("源IP"),
"specialProxy": MessageLookupByLibrary.simpleMessage("特殊代理"),
"specialRules": MessageLookupByLibrary.simpleMessage("特殊规则"),
"stackMode": MessageLookupByLibrary.simpleMessage("栈模式"),
"standard": MessageLookupByLibrary.simpleMessage("标准"),
"start": MessageLookupByLibrary.simpleMessage("启动"),
@@ -470,7 +487,7 @@ class MessageLookup extends MessageLookupByLibrary {
"upload": MessageLookupByLibrary.simpleMessage("上传"),
"url": MessageLookupByLibrary.simpleMessage("URL"),
"urlDesc": MessageLookupByLibrary.simpleMessage("通过URL获取配置文件"),
"urlTip": m8,
"urlTip": m9,
"useHosts": MessageLookupByLibrary.simpleMessage("使用Hosts"),
"useSystemHosts": MessageLookupByLibrary.simpleMessage("使用系统Hosts"),
"value": MessageLookupByLibrary.simpleMessage(""),

View File

@@ -3139,6 +3139,126 @@ class AppLocalizations {
args: [],
);
}
/// `{label} details`
String details(Object label) {
return Intl.message(
'$label details',
name: 'details',
desc: '',
args: [label],
);
}
/// `Creation time`
String get creationTime {
return Intl.message(
'Creation time',
name: 'creationTime',
desc: '',
args: [],
);
}
/// `Progress`
String get progress {
return Intl.message('Progress', name: 'progress', desc: '', args: []);
}
/// `Host`
String get host {
return Intl.message('Host', name: 'host', desc: '', args: []);
}
/// `Destination`
String get destination {
return Intl.message('Destination', name: 'destination', desc: '', args: []);
}
/// `Destination GeoIP`
String get destinationGeoIP {
return Intl.message(
'Destination GeoIP',
name: 'destinationGeoIP',
desc: '',
args: [],
);
}
/// `Destination IPASN`
String get destinationIPASN {
return Intl.message(
'Destination IPASN',
name: 'destinationIPASN',
desc: '',
args: [],
);
}
/// `Special proxy`
String get specialProxy {
return Intl.message(
'Special proxy',
name: 'specialProxy',
desc: '',
args: [],
);
}
/// `special rules`
String get specialRules {
return Intl.message(
'special rules',
name: 'specialRules',
desc: '',
args: [],
);
}
/// `Remote destination`
String get remoteDestination {
return Intl.message(
'Remote destination',
name: 'remoteDestination',
desc: '',
args: [],
);
}
/// `Network type`
String get networkType {
return Intl.message(
'Network type',
name: 'networkType',
desc: '',
args: [],
);
}
/// `Proxy chains`
String get proxyChains {
return Intl.message(
'Proxy chains',
name: 'proxyChains',
desc: '',
args: [],
);
}
/// `Log`
String get log {
return Intl.message('Log', name: 'log', desc: '', args: []);
}
/// `Connection`
String get connection {
return Intl.message('Connection', name: 'connection', desc: '', args: []);
}
/// `Request`
String get request {
return Intl.message('Request', name: 'request', desc: '', args: []);
}
}
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations> {

View File

@@ -36,7 +36,7 @@ Future<void> main() async {
Future<void> _service(List<String> flags) async {
globalState.isService = true;
WidgetsFlutterBinding.ensureInitialized();
final quickStart = flags.contains("quick");
final quickStart = flags.contains('quick');
final clashLibHandler = ClashLibHandler();
await globalState.init();
@@ -54,15 +54,14 @@ Future<void> _service(List<String> flags) async {
vpn?.handleGetStartForegroundParams = () {
final traffic = clashLibHandler.getTraffic();
return json.encode({
"title": clashLibHandler.getCurrentProfileName(),
"content": "$traffic"
'title': clashLibHandler.getCurrentProfileName(),
'content': '$traffic'
});
};
vpn?.addListener(
_VpnListenerWithService(
onDnsChanged: (String dns) {
print("handle dns $dns");
clashLibHandler.updateDns(dns);
},
),
@@ -70,7 +69,7 @@ Future<void> _service(List<String> flags) async {
if (!quickStart) {
_handleMainIpc(clashLibHandler);
} else {
commonPrint.log("quick start");
commonPrint.log('quick start');
await ClashCore.initGeo();
app?.tip(appLocalizations.startVpn);
final homeDirPath = await appPath.homeDirPath;
@@ -107,7 +106,7 @@ Future<void> _service(List<String> flags) async {
}
}
_handleMainIpc(ClashLibHandler clashLibHandler) {
void _handleMainIpc(ClashLibHandler clashLibHandler) {
final sendPort = IsolateNameServer.lookupPortByName(mainIsolate);
if (sendPort == null) {
return;

View File

@@ -1,7 +1,6 @@
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class AndroidManager extends ConsumerStatefulWidget {
@@ -20,14 +19,10 @@ class _AndroidContainerState extends ConsumerState<AndroidManager> {
@override
void initState() {
super.initState();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
ref.listenManual(
appSettingProvider.select((state) => state.hidden),
(prev, next) {
app?.updateExcludeFromRecents(next);
},
fireImmediately: true
);
ref.listenManual(appSettingProvider.select((state) => state.hidden),
(prev, next) {
app?.updateExcludeFromRecents(next);
}, fireImmediately: true);
}
@override

View File

@@ -0,0 +1,291 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/manager/window_manager.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_acrylic/widgets/transparent_macos_sidebar.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
class AppStateManager extends ConsumerStatefulWidget {
final Widget child;
const AppStateManager({
super.key,
required this.child,
});
@override
ConsumerState<AppStateManager> createState() => _AppStateManagerState();
}
class _AppStateManagerState extends ConsumerState<AppStateManager>
with WidgetsBindingObserver {
@override
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();
}
},
fireImmediately: true,
);
ref.listenManual(configStateProvider, (prev, next) {
if (prev != next) {
globalState.appController.savePreferencesDebounce();
}
});
if (window == null) {
return;
}
ref.listenManual(
autoSetSystemDnsStateProvider,
(prev, next) async {
if (prev == next) {
return;
}
if (next.a == true && next.b == true) {
macOS?.updateDns(false);
} else {
macOS?.updateDns(true);
}
},
);
ref.listenManual(
currentBrightnessProvider,
(prev, next) {
if (prev == next) {
return;
}
window?.updateMacOSBrightness(next);
},
fireImmediately: true,
);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
commonPrint.log('$state');
if (state == AppLifecycleState.paused ||
state == AppLifecycleState.inactive) {
globalState.appController.savePreferences();
} else {
render?.resume();
}
if (state == AppLifecycleState.inactive) {
WidgetsBinding.instance.addPostFrameCallback((_) {
detectionState.tryStartCheck();
});
}
}
@override
void didChangePlatformBrightness() {
globalState.appController.updateBrightness();
}
@override
Widget build(BuildContext context) {
return Listener(
onPointerHover: (_) {
render?.resume();
},
child: widget.child,
);
}
}
class AppEnvManager extends StatelessWidget {
final Widget child;
const AppEnvManager({
super.key,
required this.child,
});
@override
Widget build(BuildContext context) {
if (kDebugMode) {
if (globalState.isPre) {
return Banner(
message: 'DEBUG',
location: BannerLocation.topEnd,
child: child,
);
}
}
if (globalState.isPre) {
return Banner(
message: 'PRE',
location: BannerLocation.topEnd,
child: child,
);
}
return child;
}
}
class AppSidebarContainer extends ConsumerWidget {
final Widget child;
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 _buildBackground({
required BuildContext context,
required Widget child,
}) {
if (!system.isMacOS) {
return Material(
color: context.colorScheme.surfaceContainer,
child: child,
);
}
return TransparentMacOSSidebar(
child: Material(
color: Colors.transparent,
child: child,
),
);
}
@override
Widget build(BuildContext context, WidgetRef ref) {
final navigationState = ref.watch(navigationStateProvider);
final navigationItems = navigationState.navigationItems;
final isMobileView = navigationState.viewMode == ViewMode.mobile;
if (isMobileView) {
return child;
}
final currentIndex = navigationState.currentIndex;
final showLabel = ref.watch(appSettingProvider).showLabel;
return Row(
children: [
Stack(
alignment: Alignment.topRight,
children: [
_buildBackground(
context: context,
child: Column(
children: [
SizedBox(
height: 32,
),
if (!system.isMacOS) ...[
AppIcon(),
SizedBox(
height: 12,
),
],
Expanded(
child: ScrollConfiguration(
behavior: HiddenBarScrollBehavior(),
child: SingleChildScrollView(
child: IntrinsicHeight(
child: NavigationRail(
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,
),
),
),
),
),
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(),
],
),
Expanded(
flex: 1,
child: ClipRect(
child: child,
),
)
],
);
}
}

View File

@@ -1,133 +0,0 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class AppStateManager extends ConsumerStatefulWidget {
final Widget child;
const AppStateManager({
super.key,
required this.child,
});
@override
ConsumerState<AppStateManager> createState() => _AppStateManagerState();
}
class _AppStateManagerState extends ConsumerState<AppStateManager>
with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
ref.listenManual(layoutChangeProvider, (prev, next) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (prev != next) {
globalState.cacheHeightMap = {};
}
});
});
ref.listenManual(
checkIpProvider,
(prev, next) {
if (prev != next && next.b) {
detectionState.startCheck();
}
},
fireImmediately: true,
);
ref.listenManual(configStateProvider, (prev, next) {
if (prev != next) {
globalState.appController.savePreferencesDebounce();
}
});
ref.listenManual(
autoSetSystemDnsStateProvider,
(prev, next) async {
if (prev == next) {
return;
}
if (next.a == true && next.b == true) {
system.setMacOSDns(false);
} else {
system.setMacOSDns(true);
}
},
);
}
@override
reassemble() {
super.reassemble();
}
@override
void dispose() async {
await system.setMacOSDns(true);
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
commonPrint.log("$state");
if (state == AppLifecycleState.paused ||
state == AppLifecycleState.inactive) {
globalState.appController.savePreferences();
} else {
render?.resume();
}
}
@override
void didChangePlatformBrightness() {
globalState.appController.updateBrightness(
WidgetsBinding.instance.platformDispatcher.platformBrightness,
);
}
@override
Widget build(BuildContext context) {
return Listener(
onPointerHover: (_) {
render?.resume();
},
child: widget.child,
);
}
}
class AppEnvManager extends StatelessWidget {
final Widget child;
const AppEnvManager({
super.key,
required this.child,
});
@override
Widget build(BuildContext context) {
if (kDebugMode) {
if (globalState.isPre) {
return Banner(
message: 'DEBUG',
location: BannerLocation.topEnd,
child: child,
);
}
}
if (globalState.isPre) {
return Banner(
message: 'PRE',
location: BannerLocation.topEnd,
child: child,
);
}
return child;
}
}

View File

@@ -74,7 +74,7 @@ class _ClashContainerState extends ConsumerState<ClashManager>
debouncer.call(
FunctionTag.updateDelay,
() async {
await appController.updateGroupsDebounce();
appController.updateGroupsDebounce();
},
duration: const Duration(milliseconds: 5000),
);
@@ -90,9 +90,9 @@ class _ClashContainerState extends ConsumerState<ClashManager>
}
@override
void onRequest(Connection connection) async {
ref.read(requestsProvider.notifier).addRequest(connection);
super.onRequest(connection);
void onRequest(TrackerInfo trackerInfo) async {
ref.read(requestsProvider.notifier).addRequest(trackerInfo);
super.onRequest(trackerInfo);
}
@override
@@ -102,7 +102,7 @@ class _ClashContainerState extends ConsumerState<ClashManager>
providerName,
),
);
await globalState.appController.updateGroupsDebounce();
globalState.appController.updateGroupsDebounce();
super.onLoaded(providerName);
}
}

View File

@@ -35,7 +35,7 @@ class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
);
}
_handleHotKeyAction(HotAction action) async {
Future<void> _handleHotKeyAction(HotAction action) async {
switch (action) {
case HotAction.mode:
globalState.appController.updateMode();
@@ -50,7 +50,7 @@ class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
}
}
_updateHotKeys({
Future<void> _updateHotKeys({
required List<HotKeyAction> hotKeyActions,
}) async {
await hotKeyManager.unregisterAll();
@@ -78,7 +78,7 @@ class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
await Future.wait(hotkeyActionHandles);
}
_buildShortcuts(Widget child) {
Shortcuts _buildShortcuts(Widget child) {
return Shortcuts(
shortcuts: {
utils.controlSingleActivator(LogicalKeyboardKey.keyW):

View File

@@ -1,11 +1,11 @@
export 'tray_manager.dart';
export 'window_manager.dart';
export 'android_manager.dart';
export 'app_manager.dart';
export 'clash_manager.dart';
export 'tile_manager.dart';
export 'app_state_manager.dart';
export 'vpn_manager.dart';
export 'proxy_manager.dart';
export 'connectivity_manager.dart';
export 'message_manager.dart';
export 'theme_manager.dart';
export 'proxy_manager.dart';
export 'theme_manager.dart';
export 'tile_manager.dart';
export 'tray_manager.dart';
export 'vpn_manager.dart';
export 'window_manager.dart';

View File

@@ -44,7 +44,7 @@ class MessageManagerState extends State<MessageManager> {
await _showMessage();
}
_showMessage() async {
Future<void> _showMessage() async {
if (_pushing == true) {
return;
}
@@ -65,7 +65,7 @@ class MessageManagerState extends State<MessageManager> {
}
}
_handleRemove(CommonMessage commonMessage) async {
Future<void> _handleRemove(CommonMessage commonMessage) async {
_messagesNotifier.value = List<CommonMessage>.from(_messagesNotifier.value)
..remove(commonMessage);
}
@@ -91,7 +91,7 @@ class MessageManagerState extends State<MessageManager> {
key: Key(messages.last.id),
builder: (_, constraints) {
return Card(
shape: const RoundedSuperellipseBorder(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(12.0),
),

View File

@@ -14,7 +14,7 @@ class ProxyManager extends ConsumerStatefulWidget {
}
class _ProxyManagerState extends ConsumerState<ProxyManager> {
_updateProxy(ProxyState proxyState) async {
Future<void> _updateProxy(ProxyState proxyState) async {
final isStart = proxyState.isStart;
final systemProxy = proxyState.systemProxy;
final port = proxyState.port;

View File

@@ -1,12 +1,15 @@
import 'dart:math';
import 'package:fl_clash/common/constant.dart';
import 'package:fl_clash/common/measure.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/common/theme.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';
import '../providers/state.dart';
class ThemeManager extends ConsumerWidget {
final Widget child;
@@ -15,6 +18,54 @@ class ThemeManager extends ConsumerWidget {
required this.child,
});
Widget _buildSystemUi(Widget child) {
if (!system.isAndroid) {
return child;
}
return AnnotatedRegion<SystemUiMode>(
sized: false,
value: SystemUiMode.edgeToEdge,
child: Consumer(
builder: (context, ref, _) {
final brightness = ref.watch(currentBrightnessProvider);
final iconBrightness = brightness == Brightness.light
? Brightness.dark
: Brightness.light;
globalState.appState = globalState.appState.copyWith(
systemUiOverlayStyle: 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,
);
},
),
);
}
// _buildScrollbar(Widget child) {
// return Consumer(
// builder: (_, ref, child) {
// final isMobileView = ref.read(isMobileViewProvider);
// if (isMobileView) {
// return ScrollConfiguration(
// behavior: HiddenBarScrollBehavior(),
// child: child!,
// );
// }
// return child!;
// },
// child: child,
// );
// }
@override
Widget build(BuildContext context, ref) {
final textScale = ref.read(
@@ -49,7 +100,7 @@ class ThemeManager extends ConsumerWidget {
container.maxHeight,
),
);
return child;
return _buildSystemUi(child);
},
),
);

View File

@@ -39,7 +39,7 @@ class _TrayContainerState extends ConsumerState<TrayManager> with TrayListener {
@override
void onTrayIconRightMouseDown() {
trayManager.popUpContextMenu();
trayManager.popUpContextMenu(bringAppToFront: true);
}
@override

View File

@@ -27,7 +27,7 @@ class _VpnContainerState extends ConsumerState<VpnManager> {
});
}
showTip() {
void showTip() {
debouncer.call(
FunctionTag.vpnTip,
() {

View File

@@ -1,10 +1,8 @@
import 'dart:async';
import 'dart:io';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/providers/config.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';
@@ -59,7 +57,7 @@ class _WindowContainerState extends ConsumerState<WindowManager>
@override
void onWindowFocus() {
super.onWindowFocus();
commonPrint.log("focus");
commonPrint.log('focus');
render?.resume();
}
@@ -96,14 +94,14 @@ class _WindowContainerState extends ConsumerState<WindowManager>
@override
void onWindowMinimize() async {
globalState.appController.savePreferencesDebounce();
commonPrint.log("minimize");
commonPrint.log('minimize');
render?.pause();
super.onWindowMinimize();
}
@override
void onWindowRestore() {
commonPrint.log("restore");
commonPrint.log('restore');
render?.resume();
super.onWindowRestore();
}
@@ -128,8 +126,9 @@ class WindowHeaderContainer extends StatelessWidget {
Widget build(BuildContext context) {
return Consumer(
builder: (_, ref, child) {
final isMobileView = ref.watch(isMobileViewProvider);
final version = ref.watch(versionProvider);
if (version <= 10 && Platform.isMacOS) {
if ((version <= 10 || !isMobileView) && system.isMacOS) {
return child!;
}
return Stack(
@@ -171,7 +170,7 @@ class _WindowHeaderState extends State<WindowHeader> {
_initNotifier();
}
_initNotifier() async {
Future<void> _initNotifier() async {
isMaximizedNotifier.value = await windowManager.isMaximized();
isPinNotifier.value = await windowManager.isAlwaysOnTop();
}
@@ -183,7 +182,7 @@ class _WindowHeaderState extends State<WindowHeader> {
super.dispose();
}
_updateMaximized() async {
Future<void> _updateMaximized() async {
final isMaximized = await windowManager.isMaximized();
switch (isMaximized) {
case true:
@@ -196,13 +195,13 @@ class _WindowHeaderState extends State<WindowHeader> {
isMaximizedNotifier.value = await windowManager.isMaximized();
}
_updatePin() async {
Future<void> _updatePin() async {
final isAlwaysOnTop = await windowManager.isAlwaysOnTop();
await windowManager.setAlwaysOnTop(!isAlwaysOnTop);
isPinNotifier.value = await windowManager.isAlwaysOnTop();
}
_buildActions() {
Widget _buildActions() {
return Row(
children: [
IconButton(
@@ -280,15 +279,11 @@ class _WindowHeaderState extends State<WindowHeader> {
),
),
),
if (Platform.isMacOS)
if (system.isMacOS)
const Text(
appName,
)
else ...[
const Positioned(
left: 0,
child: AppIcon(),
),
Positioned(
right: 0,
child: _buildActions(),
@@ -306,24 +301,18 @@ class AppIcon extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(left: 8),
child: const Row(
children: [
SizedBox(
width: 24,
height: 24,
child: CircleAvatar(
foregroundImage: AssetImage("assets/images/icon.png"),
backgroundColor: Colors.transparent,
),
),
SizedBox(
width: 8,
),
Text(
appName,
),
],
decoration: BoxDecoration(
color: context.colorScheme.primaryContainer,
borderRadius: BorderRadius.circular(12),
),
padding: EdgeInsets.all(6),
child: SizedBox(
width: 28,
height: 28,
child: CircleAvatar(
foregroundImage: AssetImage('assets/images/icon.png'),
backgroundColor: Colors.transparent,
),
),
);
}

View File

@@ -1,6 +1,6 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'common.dart';
@@ -22,17 +22,18 @@ class AppState with _$AppState {
@Default({}) DelayMap delayMap,
@Default([]) List<Group> groups,
@Default(0) int checkIpNum,
Brightness? brightness,
required Brightness brightness,
int? runTime,
@Default([]) List<ExternalProvider> providers,
String? localIp,
required FixedList<Connection> requests,
required FixedList<TrackerInfo> requests,
required int version,
required FixedList<Log> logs,
required FixedList<Traffic> traffics,
required Traffic totalTraffic,
@Default("") String proxiesQuery,
@Default(false) bool realTunEnable,
@Default(false) bool loading,
required SystemUiOverlayStyle systemUiOverlayStyle,
}) = _AppState;
}

View File

@@ -19,88 +19,88 @@ const defaultMixedPort = 7890;
const defaultKeepAliveInterval = 30;
const defaultBypassPrivateRouteAddress = [
"1.0.0.0/8",
"2.0.0.0/7",
"4.0.0.0/6",
"8.0.0.0/7",
"11.0.0.0/8",
"12.0.0.0/6",
"16.0.0.0/4",
"32.0.0.0/3",
"64.0.0.0/3",
"96.0.0.0/4",
"112.0.0.0/5",
"120.0.0.0/6",
"124.0.0.0/7",
"126.0.0.0/8",
"128.0.0.0/3",
"160.0.0.0/5",
"168.0.0.0/8",
"169.0.0.0/9",
"169.128.0.0/10",
"169.192.0.0/11",
"169.224.0.0/12",
"169.240.0.0/13",
"169.248.0.0/14",
"169.252.0.0/15",
"169.255.0.0/16",
"170.0.0.0/7",
"172.0.0.0/12",
"172.32.0.0/11",
"172.64.0.0/10",
"172.128.0.0/9",
"173.0.0.0/8",
"174.0.0.0/7",
"176.0.0.0/4",
"192.0.0.0/9",
"192.128.0.0/11",
"192.160.0.0/13",
"192.169.0.0/16",
"192.170.0.0/15",
"192.172.0.0/14",
"192.176.0.0/12",
"192.192.0.0/10",
"193.0.0.0/8",
"194.0.0.0/7",
"196.0.0.0/6",
"200.0.0.0/5",
"208.0.0.0/4",
"240.0.0.0/5",
"248.0.0.0/6",
"252.0.0.0/7",
"254.0.0.0/8",
"255.0.0.0/9",
"255.128.0.0/10",
"255.192.0.0/11",
"255.224.0.0/12",
"255.240.0.0/13",
"255.248.0.0/14",
"255.252.0.0/15",
"255.254.0.0/16",
"255.255.0.0/17",
"255.255.128.0/18",
"255.255.192.0/19",
"255.255.224.0/20",
"255.255.240.0/21",
"255.255.248.0/22",
"255.255.252.0/23",
"255.255.254.0/24",
"255.255.255.0/25",
"255.255.255.128/26",
"255.255.255.192/27",
"255.255.255.224/28",
"255.255.255.240/29",
"255.255.255.248/30",
"255.255.255.252/31",
"255.255.255.254/32",
"::/1",
"8000::/2",
"c000::/3",
"e000::/4",
"f000::/5",
"f800::/6",
"fe00::/9",
"fec0::/10"
'1.0.0.0/8',
'2.0.0.0/7',
'4.0.0.0/6',
'8.0.0.0/7',
'11.0.0.0/8',
'12.0.0.0/6',
'16.0.0.0/4',
'32.0.0.0/3',
'64.0.0.0/3',
'96.0.0.0/4',
'112.0.0.0/5',
'120.0.0.0/6',
'124.0.0.0/7',
'126.0.0.0/8',
'128.0.0.0/3',
'160.0.0.0/5',
'168.0.0.0/8',
'169.0.0.0/9',
'169.128.0.0/10',
'169.192.0.0/11',
'169.224.0.0/12',
'169.240.0.0/13',
'169.248.0.0/14',
'169.252.0.0/15',
'169.255.0.0/16',
'170.0.0.0/7',
'172.0.0.0/12',
'172.32.0.0/11',
'172.64.0.0/10',
'172.128.0.0/9',
'173.0.0.0/8',
'174.0.0.0/7',
'176.0.0.0/4',
'192.0.0.0/9',
'192.128.0.0/11',
'192.160.0.0/13',
'192.169.0.0/16',
'192.170.0.0/15',
'192.172.0.0/14',
'192.176.0.0/12',
'192.192.0.0/10',
'193.0.0.0/8',
'194.0.0.0/7',
'196.0.0.0/6',
'200.0.0.0/5',
'208.0.0.0/4',
'240.0.0.0/5',
'248.0.0.0/6',
'252.0.0.0/7',
'254.0.0.0/8',
'255.0.0.0/9',
'255.128.0.0/10',
'255.192.0.0/11',
'255.224.0.0/12',
'255.240.0.0/13',
'255.248.0.0/14',
'255.252.0.0/15',
'255.254.0.0/16',
'255.255.0.0/17',
'255.255.128.0/18',
'255.255.192.0/19',
'255.255.224.0/20',
'255.255.240.0/21',
'255.255.248.0/22',
'255.255.252.0/23',
'255.255.254.0/24',
'255.255.255.0/25',
'255.255.255.128/26',
'255.255.255.192/27',
'255.255.255.224/28',
'255.255.255.240/29',
'255.255.255.248/30',
'255.255.255.252/31',
'255.255.255.254/32',
'::/1',
'8000::/2',
'c000::/3',
'e000::/4',
'f000::/5',
'f800::/6',
'fe00::/9',
'fec0::/10'
];
@freezed
@@ -117,11 +117,11 @@ class ProxyGroup with _$ProxyGroup {
bool? lazy,
String? url,
int? timeout,
@JsonKey(name: "max-failed-times") int? maxFailedTimes,
@JsonKey(name: 'max-failed-times') int? maxFailedTimes,
String? filter,
@JsonKey(name: "expected-filter") String? excludeFilter,
@JsonKey(name: "exclude-type") String? excludeType,
@JsonKey(name: "expected-status") dynamic expectedStatus,
@JsonKey(name: 'expected-filter') String? excludeFilter,
@JsonKey(name: 'exclude-type') String? excludeType,
@JsonKey(name: 'expected-status') dynamic expectedStatus,
bool? hidden,
String? icon,
}) = _ProxyGroup;
@@ -144,15 +144,15 @@ class RuleProvider with _$RuleProvider {
class Sniffer with _$Sniffer {
const factory Sniffer({
@Default(false) bool enable,
@Default(true) @JsonKey(name: "override-destination") bool overrideDest,
@Default(true) @JsonKey(name: 'override-destination') bool overrideDest,
@Default([]) List<String> sniffing,
@Default([]) @JsonKey(name: "force-domain") List<String> forceDomain,
@Default([]) @JsonKey(name: "skip-src-address") List<String> skipSrcAddress,
@Default([]) @JsonKey(name: "skip-dst-address") List<String> skipDstAddress,
@Default([]) @JsonKey(name: "skip-domain") List<String> skipDomain,
@Default([]) @JsonKey(name: "port-whitelist") List<String> port,
@Default(true) @JsonKey(name: "force-dns-mapping") bool forceDnsMapping,
@Default(true) @JsonKey(name: "parse-pure-ip") bool parsePureIp,
@Default([]) @JsonKey(name: 'force-domain') List<String> forceDomain,
@Default([]) @JsonKey(name: 'skip-src-address') List<String> skipSrcAddress,
@Default([]) @JsonKey(name: 'skip-dst-address') List<String> skipDstAddress,
@Default([]) @JsonKey(name: 'skip-domain') List<String> skipDomain,
@Default([]) @JsonKey(name: 'port-whitelist') List<String> port,
@Default(true) @JsonKey(name: 'force-dns-mapping') bool forceDnsMapping,
@Default(true) @JsonKey(name: 'parse-pure-ip') bool parsePureIp,
@Default({}) Map<String, SnifferConfig> sniff,
}) = _Sniffer;
@@ -168,7 +168,7 @@ List<String> _formJsonPorts(List? ports) {
class SnifferConfig with _$SnifferConfig {
const factory SnifferConfig({
@Default([]) @JsonKey(fromJson: _formJsonPorts) List<String> ports,
@JsonKey(name: "override-destination") bool? overrideDest,
@JsonKey(name: 'override-destination') bool? overrideDest,
}) = _SnifferConfig;
factory SnifferConfig.fromJson(Map<String, Object?> json) =>
@@ -180,10 +180,10 @@ class Tun with _$Tun {
const factory Tun({
@Default(false) bool enable,
@Default(appName) String device,
@JsonKey(name: "auto-route") @Default(false) bool autoRoute,
@JsonKey(name: 'auto-route') @Default(false) bool autoRoute,
@Default(TunStack.mixed) TunStack stack,
@JsonKey(name: "dns-hijack") @Default(["any:53"]) List<String> dnsHijack,
@JsonKey(name: "route-address") @Default([]) List<String> routeAddress,
@JsonKey(name: 'dns-hijack') @Default(['any:53']) List<String> dnsHijack,
@JsonKey(name: 'route-address') @Default([]) List<String> routeAddress,
}) = _Tun;
factory Tun.fromJson(Map<String, Object?> json) => _$TunFromJson(json);
@@ -222,13 +222,13 @@ extension TunExt on Tun {
class FallbackFilter with _$FallbackFilter {
const factory FallbackFilter({
@Default(true) bool geoip,
@Default("CN") @JsonKey(name: "geoip-code") String geoipCode,
@Default(["gfw"]) List<String> geosite,
@Default(["240.0.0.0/4"]) List<String> ipcidr,
@Default('CN') @JsonKey(name: 'geoip-code') String geoipCode,
@Default(['gfw']) List<String> geosite,
@Default(['240.0.0.0/4']) List<String> ipcidr,
@Default([
"+.google.com",
"+.facebook.com",
"+.youtube.com",
'+.google.com',
'+.facebook.com',
'+.youtube.com',
])
List<String> domain,
}) = _FallbackFilter;
@@ -241,51 +241,51 @@ class FallbackFilter with _$FallbackFilter {
class Dns with _$Dns {
const factory Dns({
@Default(true) bool enable,
@Default("0.0.0.0:1053") String listen,
@Default(false) @JsonKey(name: "prefer-h3") bool preferH3,
@Default(true) @JsonKey(name: "use-hosts") bool useHosts,
@Default(true) @JsonKey(name: "use-system-hosts") bool useSystemHosts,
@Default(false) @JsonKey(name: "respect-rules") bool respectRules,
@Default('0.0.0.0:1053') String listen,
@Default(false) @JsonKey(name: 'prefer-h3') bool preferH3,
@Default(true) @JsonKey(name: 'use-hosts') bool useHosts,
@Default(true) @JsonKey(name: 'use-system-hosts') bool useSystemHosts,
@Default(false) @JsonKey(name: 'respect-rules') bool respectRules,
@Default(false) bool ipv6,
@Default(["223.5.5.5"])
@JsonKey(name: "default-nameserver")
@Default(['223.5.5.5'])
@JsonKey(name: 'default-nameserver')
List<String> defaultNameserver,
@Default(DnsMode.fakeIp)
@JsonKey(name: "enhanced-mode")
@JsonKey(name: 'enhanced-mode')
DnsMode enhancedMode,
@Default("198.18.0.1/16")
@JsonKey(name: "fake-ip-range")
@Default('198.18.0.1/16')
@JsonKey(name: 'fake-ip-range')
String fakeIpRange,
@Default([
"*.lan",
"localhost.ptlogin2.qq.com",
'*.lan',
'localhost.ptlogin2.qq.com',
])
@JsonKey(name: "fake-ip-filter")
@JsonKey(name: 'fake-ip-filter')
List<String> fakeIpFilter,
@Default({
"www.baidu.com": "114.114.114.114",
"+.internal.crop.com": "10.0.0.1",
"geosite:cn": "https://doh.pub/dns-query"
'www.baidu.com': '114.114.114.114',
'+.internal.crop.com': '10.0.0.1',
'geosite:cn': 'https://doh.pub/dns-query'
})
@JsonKey(name: "nameserver-policy")
@JsonKey(name: 'nameserver-policy')
Map<String, String> nameserverPolicy,
@Default([
"https://doh.pub/dns-query",
"https://dns.alidns.com/dns-query",
'https://doh.pub/dns-query',
'https://dns.alidns.com/dns-query',
])
List<String> nameserver,
@Default([
"tls://8.8.4.4",
"tls://1.1.1.1",
'tls://8.8.4.4',
'tls://1.1.1.1',
])
List<String> fallback,
@Default([
"https://doh.pub/dns-query",
'https://doh.pub/dns-query',
])
@JsonKey(name: "proxy-server-nameserver")
@JsonKey(name: 'proxy-server-nameserver')
List<String> proxyServerNameserver,
@Default(FallbackFilter())
@JsonKey(name: "fallback-filter")
@JsonKey(name: 'fallback-filter')
FallbackFilter fallbackFilter,
}) = _Dns;
@@ -304,19 +304,19 @@ class Dns with _$Dns {
class GeoXUrl with _$GeoXUrl {
const factory GeoXUrl({
@Default(
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb",
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb',
)
String mmdb,
@Default(
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb",
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb',
)
String asn,
@Default(
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat",
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat',
)
String geoip,
@Default(
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat",
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat',
)
String geosite,
}) = _GeoXUrl;
@@ -349,10 +349,10 @@ class ParsedRule with _$ParsedRule {
}) = _ParsedRule;
factory ParsedRule.parseString(String value) {
final splits = value.split(",");
final splits = value.split(',');
final shortSplits = splits
.where(
(item) => !item.contains("src") && !item.contains("no-resolve"),
(item) => !item.contains('src') && !item.contains('no-resolve'),
)
.toList();
final ruleAction = RuleAction.values.firstWhere(
@@ -372,17 +372,17 @@ class ParsedRule with _$ParsedRule {
String? ruleProvider;
if (ruleAction == RuleAction.RULE_SET) {
ruleProvider = shortSplits.sublist(1, shortSplits.length - 1).join(",");
ruleProvider = shortSplits.sublist(1, shortSplits.length - 1).join(',');
} else {
content = shortSplits.sublist(1, shortSplits.length - 1).join(",");
content = shortSplits.sublist(1, shortSplits.length - 1).join(',');
}
return ParsedRule(
ruleAction: ruleAction,
content: content,
src: splits.contains("src"),
src: splits.contains('src'),
ruleProvider: ruleProvider,
noResolve: splits.contains("no-resolve"),
noResolve: splits.contains('no-resolve'),
subRule: subRule,
ruleTarget: ruleTarget,
);
@@ -396,10 +396,10 @@ extension ParsedRuleExt on ParsedRule {
ruleAction == RuleAction.RULE_SET ? ruleProvider : content,
ruleAction == RuleAction.SUB_RULE ? subRule : ruleTarget,
if (ruleAction.hasParams) ...[
if (src) "src",
if (noResolve) "no-resolve",
if (src) 'src',
if (noResolve) 'no-resolve',
]
].join(",");
].join(',');
}
}
@@ -430,7 +430,7 @@ class SubRule with _$SubRule {
_$SubRuleFromJson(json);
}
_genRule(List<dynamic>? rules) {
List<Rule> _genRule(List<dynamic>? rules) {
if (rules == null) {
return [];
}
@@ -458,12 +458,12 @@ List<SubRule> _genSubRules(Map<String, dynamic> json) {
@freezed
class ClashConfigSnippet with _$ClashConfigSnippet {
const factory ClashConfigSnippet({
@Default([]) @JsonKey(name: "proxy-groups") List<ProxyGroup> proxyGroups,
@JsonKey(fromJson: _genRule, name: "rules") @Default([]) List<Rule> rule,
@JsonKey(name: "rule-providers", fromJson: _genRuleProviders)
@Default([]) @JsonKey(name: 'proxy-groups') List<ProxyGroup> proxyGroups,
@JsonKey(fromJson: _genRule, name: 'rules') @Default([]) List<Rule> rule,
@JsonKey(name: 'rule-providers', fromJson: _genRuleProviders)
@Default([])
List<RuleProvider> ruleProvider,
@JsonKey(name: "sub-rules", fromJson: _genSubRules)
@JsonKey(name: 'sub-rules', fromJson: _genSubRules)
@Default([])
List<SubRule> subRules,
}) = _ClashConfigSnippet;
@@ -475,39 +475,39 @@ class ClashConfigSnippet with _$ClashConfigSnippet {
@freezed
class ClashConfig with _$ClashConfig {
const factory ClashConfig({
@Default(defaultMixedPort) @JsonKey(name: "mixed-port") int mixedPort,
@Default(0) @JsonKey(name: "socks-port") int socksPort,
@Default(0) @JsonKey(name: "port") int port,
@Default(0) @JsonKey(name: "redir-port") int redirPort,
@Default(0) @JsonKey(name: "tproxy-port") int tproxyPort,
@Default(defaultMixedPort) @JsonKey(name: 'mixed-port') int mixedPort,
@Default(0) @JsonKey(name: 'socks-port') int socksPort,
@Default(0) @JsonKey(name: 'port') int port,
@Default(0) @JsonKey(name: 'redir-port') int redirPort,
@Default(0) @JsonKey(name: 'tproxy-port') int tproxyPort,
@Default(Mode.rule) Mode mode,
@Default(false) @JsonKey(name: "allow-lan") bool allowLan,
@Default(LogLevel.error) @JsonKey(name: "log-level") LogLevel logLevel,
@Default(false) @JsonKey(name: 'allow-lan') bool allowLan,
@Default(LogLevel.error) @JsonKey(name: 'log-level') LogLevel logLevel,
@Default(false) bool ipv6,
@Default(FindProcessMode.off)
@JsonKey(
name: "find-process-mode",
name: 'find-process-mode',
unknownEnumValue: FindProcessMode.always,
)
FindProcessMode findProcessMode,
@Default(defaultKeepAliveInterval)
@JsonKey(name: "keep-alive-interval")
@JsonKey(name: 'keep-alive-interval')
int keepAliveInterval,
@Default(true) @JsonKey(name: "unified-delay") bool unifiedDelay,
@Default(true) @JsonKey(name: "tcp-concurrent") bool tcpConcurrent,
@Default(true) @JsonKey(name: 'unified-delay') bool unifiedDelay,
@Default(true) @JsonKey(name: 'tcp-concurrent') bool tcpConcurrent,
@Default(defaultTun) @JsonKey(fromJson: Tun.safeFormJson) Tun tun,
@Default(defaultDns) @JsonKey(fromJson: Dns.safeDnsFromJson) Dns dns,
@Default(defaultGeoXUrl)
@JsonKey(name: "geox-url", fromJson: GeoXUrl.safeFormJson)
@JsonKey(name: 'geox-url', fromJson: GeoXUrl.safeFormJson)
GeoXUrl geoXUrl,
@Default(GeodataLoader.memconservative)
@JsonKey(name: "geodata-loader")
@JsonKey(name: 'geodata-loader')
GeodataLoader geodataLoader,
@Default([]) @JsonKey(name: "proxy-groups") List<ProxyGroup> proxyGroups,
@Default([]) @JsonKey(name: 'proxy-groups') List<ProxyGroup> proxyGroups,
@Default([]) List<String> rule,
@JsonKey(name: "global-ua") String? globalUa,
@JsonKey(name: 'global-ua') String? globalUa,
@Default(ExternalControllerStatus.close)
@JsonKey(name: "external-controller")
@JsonKey(name: 'external-controller')
ExternalControllerStatus externalController,
@Default({}) HostsMap hosts,
}) = _ClashConfig;

View File

@@ -16,7 +16,7 @@ class NavigationItem with _$NavigationItem {
required Icon icon,
required PageLabel label,
final String? description,
required Widget view,
required WidgetBuilder builder,
@Default(true) bool keep,
String? path,
@Default([NavigationItemMode.mobile, NavigationItemMode.desktop])
@@ -41,15 +41,23 @@ class Package with _$Package {
@freezed
class Metadata with _$Metadata {
const factory Metadata({
required int uid,
required String network,
required String sourceIP,
required String sourcePort,
required String destinationIP,
required String destinationPort,
required String host,
required String process,
required String remoteDestination,
@Default(0) int uid,
@Default('') String network,
@Default('') String sourceIP,
@Default('') String sourcePort,
@Default('') String destinationIP,
@Default('') String destinationPort,
@Default('') String host,
DnsMode? dnsMode,
@Default('') String process,
@Default('') String processPath,
@Default('') String remoteDestination,
@Default([]) List<String> sourceGeoIP,
@Default([]) List<String> destinationGeoIP,
@Default('') String destinationIPASN,
@Default('') String sourceIPASN,
@Default('') String specialRules,
@Default('') String specialProxy,
}) = _Metadata;
factory Metadata.fromJson(Map<String, Object?> json) =>
@@ -57,35 +65,48 @@ class Metadata with _$Metadata {
}
@freezed
class Connection with _$Connection {
const factory Connection({
class TrackerInfo with _$TrackerInfo {
const factory TrackerInfo({
required String id,
num? upload,
num? download,
@Default(0) int upload,
@Default(0) int download,
required DateTime start,
required Metadata metadata,
required List<String> chains,
}) = _Connection;
required String rule,
required String rulePayload,
int? downloadSpeed,
int? uploadSpeed,
}) = _TrackerInfo;
factory Connection.fromJson(Map<String, Object?> json) =>
_$ConnectionFromJson(json);
factory TrackerInfo.fromJson(Map<String, Object?> json) =>
_$TrackerInfoFromJson(json);
}
extension ConnectionExt on Connection {
extension TrackerInfoExt on TrackerInfo {
String get desc {
var text = "${metadata.network}://";
var text = '${metadata.network}://';
final ips = [
metadata.host,
metadata.destinationIP,
].where((ip) => ip.isNotEmpty);
text += ips.join("/");
text += ":${metadata.destinationPort}";
text += ips.join('/');
text += ':${metadata.destinationPort}';
return text;
}
String get progressText {
final process = metadata.process;
final uid = metadata.uid;
if (uid != 0) {
return '$process($uid)';
}
return process;
}
}
String _logDateTime(_) {
return DateTime.now().toString();
String _logDateTime(dynamic _) {
return DateTime.now().showFull;
}
// String _logId(_) {
@@ -95,8 +116,9 @@ String _logDateTime(_) {
@freezed
class Log with _$Log {
const factory Log({
@JsonKey(name: "LogLevel") @Default(LogLevel.app) LogLevel logLevel,
@JsonKey(name: "Payload") @Default("") String payload,
// @JsonKey(fromJson: _logId) required String id,
@JsonKey(name: 'LogLevel') @Default(LogLevel.info) LogLevel logLevel,
@JsonKey(name: 'Payload') @Default('') String payload,
@JsonKey(fromJson: _logDateTime) required String dateTime,
}) = _Log;
@@ -118,8 +140,8 @@ class LogsState with _$LogsState {
const factory LogsState({
@Default([]) List<Log> logs,
@Default([]) List<String> keywords,
@Default("") String query,
@Default(false) bool loading,
@Default('') String query,
@Default(true) bool autoScrollToEnd,
}) = _LogsState;
}
@@ -138,27 +160,28 @@ extension LogsStateExt on LogsState {
}
@freezed
class ConnectionsState with _$ConnectionsState {
const factory ConnectionsState({
@Default([]) List<Connection> connections,
class TrackerInfosState with _$TrackerInfosState {
const factory TrackerInfosState({
@Default([]) List<TrackerInfo> trackerInfos,
@Default([]) List<String> keywords,
@Default("") String query,
@Default(false) bool loading,
}) = _ConnectionsState;
@Default('') String query,
@Default(true) bool autoScrollToEnd,
}) = _TrackerInfosState;
}
extension ConnectionsStateExt on ConnectionsState {
List<Connection> get list {
extension TrackerInfosStateExt on TrackerInfosState {
List<TrackerInfo> get list {
final lowerQuery = query.toLowerCase().trim();
final lowQuery = query.toLowerCase();
return connections.where((connection) {
final chains = connection.chains;
final process = connection.metadata.process;
final networkText = connection.metadata.network.toLowerCase();
final hostText = connection.metadata.host.toLowerCase();
final destinationIPText = connection.metadata.destinationIP.toLowerCase();
final processText = connection.metadata.process.toLowerCase();
final chainsText = chains.join("").toLowerCase();
return trackerInfos.where((trackerInfo) {
final chains = trackerInfo.chains;
final process = trackerInfo.metadata.process;
final networkText = trackerInfo.metadata.network.toLowerCase();
final hostText = trackerInfo.metadata.host.toLowerCase();
final destinationIPText =
trackerInfo.metadata.destinationIP.toLowerCase();
final processText = trackerInfo.metadata.process.toLowerCase();
final chainsText = chains.join('').toLowerCase();
return {...chains, process}.containsAll(keywords) &&
(networkText.contains(lowerQuery) ||
hostText.contains(lowerQuery) ||
@@ -169,7 +192,7 @@ extension ConnectionsStateExt on ConnectionsState {
}
}
const defaultDavFileName = "backup.zip";
const defaultDavFileName = 'backup.zip';
@freezed
class DAV with _$DAV {
@@ -193,14 +216,14 @@ class FileInfo with _$FileInfo {
extension FileInfoExt on FileInfo {
String get desc =>
"${TrafficValue(value: size).show} · ${lastModified.lastUpdateTimeDesc}";
'${TrafficValue(value: size).show} · ${lastModified.lastUpdateTimeDesc}';
}
@freezed
class VersionInfo with _$VersionInfo {
const factory VersionInfo({
@Default("") String clashName,
@Default("") String version,
@Default('') String clashName,
@Default('') String version,
}) = _VersionInfo;
factory VersionInfo.fromJson(Map<String, Object?> json) =>
@@ -226,6 +249,10 @@ class Traffic {
);
}
String toSpeedText() {
return '$up/s ↓ $down/s';
}
@override
String toString() {
return '$up$down';
@@ -274,7 +301,7 @@ class Group with _$Group {
String? now,
bool? hidden,
String? testUrl,
@Default("") String icon,
@Default('') String icon,
required String name,
}) = _Group;
@@ -289,7 +316,7 @@ extension GroupsExt on List<Group> {
}
extension GroupExt on Group {
String get realNow => now ?? "";
String get realNow => now ?? '';
String getCurrentSelectedName(String proxyName) {
if (type.isComputedSelected) {
@@ -307,10 +334,10 @@ class TrafficValue {
int get value => _value;
String get show => "$showValue $showUnit";
String get show => '$showValue $showUnit';
String get shortShow =>
"${trafficValueShow.value.fixed(decimals: 1)} $showUnit";
'${trafficValueShow.value.fixed(decimals: 1)} $showUnit';
String get showValue => trafficValueShow.value.fixed();
@@ -347,7 +374,7 @@ class TrafficValue {
@override
String toString() {
return "$showValue$showUnit";
return '$showValue$showUnit';
}
@override
@@ -411,56 +438,56 @@ class IpInfo {
static IpInfo fromIpInfoIoJson(Map<String, dynamic> json) {
return switch (json) {
{
"ip": final String ip,
"country": final String country,
'ip': final String ip,
'country': final String country,
} =>
IpInfo(
ip: ip,
countryCode: country,
),
_ => throw const FormatException("invalid json"),
_ => throw const FormatException('invalid json'),
};
}
static IpInfo fromIpApiCoJson(Map<String, dynamic> json) {
return switch (json) {
{
"ip": final String ip,
"country_code": final String countryCode,
'ip': final String ip,
'country_code': final String countryCode,
} =>
IpInfo(
ip: ip,
countryCode: countryCode,
),
_ => throw const FormatException("invalid json"),
_ => throw const FormatException('invalid json'),
};
}
static IpInfo fromIpSbJson(Map<String, dynamic> json) {
return switch (json) {
{
"ip": final String ip,
"country_code": final String countryCode,
'ip': final String ip,
'country_code': final String countryCode,
} =>
IpInfo(
ip: ip,
countryCode: countryCode,
),
_ => throw const FormatException("invalid json"),
_ => throw const FormatException('invalid json'),
};
}
static IpInfo fromIpwhoIsJson(Map<String, dynamic> json) {
return switch (json) {
{
"ip": final String ip,
"country_code": final String countryCode,
'ip': final String ip,
'country_code': final String countryCode,
} =>
IpInfo(
ip: ip,
countryCode: countryCode,
),
_ => throw const FormatException("invalid json"),
_ => throw const FormatException('invalid json'),
};
}
@@ -539,7 +566,7 @@ class Result<T> with _$Result<T> {
factory Result.success(T data) => Result(
data: data,
type: ResultType.success,
message: "",
message: '',
);
factory Result.error(String message) => Result(

View File

@@ -11,23 +11,23 @@ part 'generated/config.freezed.dart';
part 'generated/config.g.dart';
const defaultBypassDomain = [
"*zhihu.com",
"*zhimg.com",
"*jd.com",
"100ime-iat-api.xfyun.cn",
"*360buyimg.com",
"localhost",
"*.local",
"127.*",
"10.*",
"172.16.*",
"172.17.*",
"172.18.*",
"172.19.*",
"172.2*",
"172.30.*",
"172.31.*",
"192.168.*"
'*zhihu.com',
'*zhimg.com',
'*jd.com',
'100ime-iat-api.xfyun.cn',
'*360buyimg.com',
'localhost',
'*.local',
'127.*',
'10.*',
'172.16.*',
'172.17.*',
'172.18.*',
'172.19.*',
'172.2*',
'172.30.*',
'172.31.*',
'192.168.*'
];
const defaultAppSettingProps = AppSettingProps();
@@ -178,8 +178,8 @@ class ProxiesStyle with _$ProxiesStyle {
@freezed
class TextScale with _$TextScale {
const factory TextScale({
@Default(false) enable,
@Default(1.0) scale,
@Default(false) bool enable,
@Default(1.0) double scale,
}) = _TextScale;
factory TextScale.fromJson(Map<String, Object?> json) =>
@@ -265,12 +265,12 @@ class Config with _$Config {
factory Config.compatibleFromJson(Map<String, Object?> json) {
try {
final accessControlMap = json["accessControl"];
final isAccessControl = json["isAccessControl"];
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;
(accessControlMap as Map)['enable'] = isAccessControl;
if (json['vpnProps'] != null) {
(json['vpnProps'] as Map)['accessControl'] = accessControlMap;
}
}
} catch (_) {}

View File

@@ -12,7 +12,7 @@ abstract mixin class AppMessageListener {
void onDelay(Delay delay) {}
void onRequest(Connection connection) {}
void onRequest(TrackerInfo connection) {}
void onLoaded(String providerName) {}
}
@@ -26,9 +26,9 @@ abstract mixin class AppMessageListener {
@freezed
class SetupParams with _$SetupParams {
const factory SetupParams({
@JsonKey(name: "config") required Map<String, dynamic> config,
@JsonKey(name: "selected-map") required Map<String, String> selectedMap,
@JsonKey(name: "test-url") required String testUrl,
@JsonKey(name: 'config') required Map<String, dynamic> config,
@JsonKey(name: 'selected-map') required Map<String, String> selectedMap,
@JsonKey(name: 'test-url') required String testUrl,
}) = _SetupParams;
factory SetupParams.fromJson(Map<String, dynamic> json) =>
@@ -68,10 +68,10 @@ class UpdateParams with _$UpdateParams {
@freezed
class CoreState with _$CoreState {
const factory CoreState({
@JsonKey(name: "vpn-props") required VpnProps vpnProps,
@JsonKey(name: "only-statistics-proxy") required bool onlyStatisticsProxy,
@JsonKey(name: "current-profile-name") required String currentProfileName,
@JsonKey(name: "bypass-domain") @Default([]) List<String> bypassDomain,
@JsonKey(name: 'vpn-props') required VpnProps vpnProps,
@JsonKey(name: 'only-statistics-proxy') required bool onlyStatisticsProxy,
@JsonKey(name: 'current-profile-name') required String currentProfileName,
@JsonKey(name: 'bypass-domain') @Default([]) List<String> bypassDomain,
}) = _CoreState;
factory CoreState.fromJson(Map<String, Object?> json) =>
@@ -100,7 +100,7 @@ class AndroidVpnOptions with _$AndroidVpnOptions {
@freezed
class InitParams with _$InitParams {
const factory InitParams({
@JsonKey(name: "home-dir") required String homeDir,
@JsonKey(name: 'home-dir') required String homeDir,
required int version,
}) = _InitParams;
@@ -111,8 +111,8 @@ class InitParams with _$InitParams {
@freezed
class ChangeProxyParams with _$ChangeProxyParams {
const factory ChangeProxyParams({
@JsonKey(name: "group-name") required String groupName,
@JsonKey(name: "proxy-name") required String proxyName,
@JsonKey(name: 'group-name') required String groupName,
@JsonKey(name: 'proxy-name') required String proxyName,
}) = _ChangeProxyParams;
factory ChangeProxyParams.fromJson(Map<String, Object?> json) =>
@@ -122,8 +122,8 @@ class ChangeProxyParams with _$ChangeProxyParams {
@freezed
class UpdateGeoDataParams with _$UpdateGeoDataParams {
const factory UpdateGeoDataParams({
@JsonKey(name: "geo-type") required String geoType,
@JsonKey(name: "geo-name") required String geoName,
@JsonKey(name: 'geo-type') required String geoType,
@JsonKey(name: 'geo-name') required String geoName,
}) = _UpdateGeoDataParams;
factory UpdateGeoDataParams.fromJson(Map<String, Object?> json) =>
@@ -197,10 +197,10 @@ class Now with _$Now {
@freezed
class ProviderSubscriptionInfo with _$ProviderSubscriptionInfo {
const factory ProviderSubscriptionInfo({
@JsonKey(name: "UPLOAD") @Default(0) int upload,
@JsonKey(name: "DOWNLOAD") @Default(0) int download,
@JsonKey(name: "TOTAL") @Default(0) int total,
@JsonKey(name: "EXPIRE") @Default(0) int expire,
@JsonKey(name: 'UPLOAD') @Default(0) int upload,
@JsonKey(name: 'DOWNLOAD') @Default(0) int download,
@JsonKey(name: 'TOTAL') @Default(0) int total,
@JsonKey(name: 'EXPIRE') @Default(0) int expire,
}) = _ProviderSubscriptionInfo;
factory ProviderSubscriptionInfo.fromJson(Map<String, Object?> json) =>
@@ -224,11 +224,11 @@ class ExternalProvider with _$ExternalProvider {
required String type,
String? path,
required int count,
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
@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,
@JsonKey(name: 'vehicle-type') required String vehicleType,
@JsonKey(name: 'update-at') required DateTime updateAt,
}) = _ExternalProvider;
factory ExternalProvider.fromJson(Map<String, Object?> json) =>

View File

@@ -26,17 +26,19 @@ mixin _$AppState {
throw _privateConstructorUsedError;
List<Group> get groups => throw _privateConstructorUsedError;
int get checkIpNum => throw _privateConstructorUsedError;
Brightness? get brightness => throw _privateConstructorUsedError;
Brightness get brightness => throw _privateConstructorUsedError;
int? get runTime => throw _privateConstructorUsedError;
List<ExternalProvider> get providers => throw _privateConstructorUsedError;
String? get localIp => throw _privateConstructorUsedError;
FixedList<Connection> get requests => throw _privateConstructorUsedError;
FixedList<TrackerInfo> get requests => throw _privateConstructorUsedError;
int get version => throw _privateConstructorUsedError;
FixedList<Log> get logs => throw _privateConstructorUsedError;
FixedList<Traffic> get traffics => throw _privateConstructorUsedError;
Traffic get totalTraffic => throw _privateConstructorUsedError;
String get proxiesQuery => throw _privateConstructorUsedError;
bool get realTunEnable => throw _privateConstructorUsedError;
bool get loading => throw _privateConstructorUsedError;
SystemUiOverlayStyle get systemUiOverlayStyle =>
throw _privateConstructorUsedError;
/// Create a copy of AppState
/// with the given fields replaced by the non-null parameter values.
@@ -60,17 +62,18 @@ abstract class $AppStateCopyWith<$Res> {
Map<String, Map<String, int?>> delayMap,
List<Group> groups,
int checkIpNum,
Brightness? brightness,
Brightness brightness,
int? runTime,
List<ExternalProvider> providers,
String? localIp,
FixedList<Connection> requests,
FixedList<TrackerInfo> requests,
int version,
FixedList<Log> logs,
FixedList<Traffic> traffics,
Traffic totalTraffic,
String proxiesQuery,
bool realTunEnable});
bool realTunEnable,
bool loading,
SystemUiOverlayStyle systemUiOverlayStyle});
}
/// @nodoc
@@ -97,7 +100,7 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
Object? delayMap = null,
Object? groups = null,
Object? checkIpNum = null,
Object? brightness = freezed,
Object? brightness = null,
Object? runTime = freezed,
Object? providers = null,
Object? localIp = freezed,
@@ -106,8 +109,9 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
Object? logs = null,
Object? traffics = null,
Object? totalTraffic = null,
Object? proxiesQuery = null,
Object? realTunEnable = null,
Object? loading = null,
Object? systemUiOverlayStyle = null,
}) {
return _then(_value.copyWith(
isInit: null == isInit
@@ -146,10 +150,10 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
? _value.checkIpNum
: checkIpNum // ignore: cast_nullable_to_non_nullable
as int,
brightness: freezed == brightness
brightness: null == brightness
? _value.brightness
: brightness // ignore: cast_nullable_to_non_nullable
as Brightness?,
as Brightness,
runTime: freezed == runTime
? _value.runTime
: runTime // ignore: cast_nullable_to_non_nullable
@@ -165,7 +169,7 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
requests: null == requests
? _value.requests
: requests // ignore: cast_nullable_to_non_nullable
as FixedList<Connection>,
as FixedList<TrackerInfo>,
version: null == version
? _value.version
: version // ignore: cast_nullable_to_non_nullable
@@ -182,14 +186,18 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
? _value.totalTraffic
: totalTraffic // ignore: cast_nullable_to_non_nullable
as Traffic,
proxiesQuery: null == proxiesQuery
? _value.proxiesQuery
: proxiesQuery // ignore: cast_nullable_to_non_nullable
as String,
realTunEnable: null == realTunEnable
? _value.realTunEnable
: realTunEnable // ignore: cast_nullable_to_non_nullable
as bool,
loading: null == loading
? _value.loading
: loading // ignore: cast_nullable_to_non_nullable
as bool,
systemUiOverlayStyle: null == systemUiOverlayStyle
? _value.systemUiOverlayStyle
: systemUiOverlayStyle // ignore: cast_nullable_to_non_nullable
as SystemUiOverlayStyle,
) as $Val);
}
}
@@ -212,17 +220,18 @@ abstract class _$$AppStateImplCopyWith<$Res>
Map<String, Map<String, int?>> delayMap,
List<Group> groups,
int checkIpNum,
Brightness? brightness,
Brightness brightness,
int? runTime,
List<ExternalProvider> providers,
String? localIp,
FixedList<Connection> requests,
FixedList<TrackerInfo> requests,
int version,
FixedList<Log> logs,
FixedList<Traffic> traffics,
Traffic totalTraffic,
String proxiesQuery,
bool realTunEnable});
bool realTunEnable,
bool loading,
SystemUiOverlayStyle systemUiOverlayStyle});
}
/// @nodoc
@@ -247,7 +256,7 @@ class __$$AppStateImplCopyWithImpl<$Res>
Object? delayMap = null,
Object? groups = null,
Object? checkIpNum = null,
Object? brightness = freezed,
Object? brightness = null,
Object? runTime = freezed,
Object? providers = null,
Object? localIp = freezed,
@@ -256,8 +265,9 @@ class __$$AppStateImplCopyWithImpl<$Res>
Object? logs = null,
Object? traffics = null,
Object? totalTraffic = null,
Object? proxiesQuery = null,
Object? realTunEnable = null,
Object? loading = null,
Object? systemUiOverlayStyle = null,
}) {
return _then(_$AppStateImpl(
isInit: null == isInit
@@ -296,10 +306,10 @@ class __$$AppStateImplCopyWithImpl<$Res>
? _value.checkIpNum
: checkIpNum // ignore: cast_nullable_to_non_nullable
as int,
brightness: freezed == brightness
brightness: null == brightness
? _value.brightness
: brightness // ignore: cast_nullable_to_non_nullable
as Brightness?,
as Brightness,
runTime: freezed == runTime
? _value.runTime
: runTime // ignore: cast_nullable_to_non_nullable
@@ -315,7 +325,7 @@ class __$$AppStateImplCopyWithImpl<$Res>
requests: null == requests
? _value.requests
: requests // ignore: cast_nullable_to_non_nullable
as FixedList<Connection>,
as FixedList<TrackerInfo>,
version: null == version
? _value.version
: version // ignore: cast_nullable_to_non_nullable
@@ -332,14 +342,18 @@ class __$$AppStateImplCopyWithImpl<$Res>
? _value.totalTraffic
: totalTraffic // ignore: cast_nullable_to_non_nullable
as Traffic,
proxiesQuery: null == proxiesQuery
? _value.proxiesQuery
: proxiesQuery // ignore: cast_nullable_to_non_nullable
as String,
realTunEnable: null == realTunEnable
? _value.realTunEnable
: realTunEnable // ignore: cast_nullable_to_non_nullable
as bool,
loading: null == loading
? _value.loading
: loading // ignore: cast_nullable_to_non_nullable
as bool,
systemUiOverlayStyle: null == systemUiOverlayStyle
? _value.systemUiOverlayStyle
: systemUiOverlayStyle // ignore: cast_nullable_to_non_nullable
as SystemUiOverlayStyle,
));
}
}
@@ -357,7 +371,7 @@ class _$AppStateImpl implements _AppState {
final Map<String, Map<String, int?>> delayMap = const {},
final List<Group> groups = const [],
this.checkIpNum = 0,
this.brightness,
required this.brightness,
this.runTime,
final List<ExternalProvider> providers = const [],
this.localIp,
@@ -366,8 +380,9 @@ class _$AppStateImpl implements _AppState {
required this.logs,
required this.traffics,
required this.totalTraffic,
this.proxiesQuery = "",
this.realTunEnable = false})
this.realTunEnable = false,
this.loading = false,
required this.systemUiOverlayStyle})
: _packages = packages,
_delayMap = delayMap,
_groups = groups,
@@ -418,7 +433,7 @@ class _$AppStateImpl implements _AppState {
@JsonKey()
final int checkIpNum;
@override
final Brightness? brightness;
final Brightness brightness;
@override
final int? runTime;
final List<ExternalProvider> _providers;
@@ -433,7 +448,7 @@ class _$AppStateImpl implements _AppState {
@override
final String? localIp;
@override
final FixedList<Connection> requests;
final FixedList<TrackerInfo> requests;
@override
final int version;
@override
@@ -444,14 +459,16 @@ class _$AppStateImpl implements _AppState {
final Traffic totalTraffic;
@override
@JsonKey()
final String proxiesQuery;
final bool realTunEnable;
@override
@JsonKey()
final bool realTunEnable;
final bool loading;
@override
final SystemUiOverlayStyle systemUiOverlayStyle;
@override
String toString() {
return 'AppState(isInit: $isInit, backBlock: $backBlock, pageLabel: $pageLabel, packages: $packages, sortNum: $sortNum, viewSize: $viewSize, delayMap: $delayMap, groups: $groups, checkIpNum: $checkIpNum, brightness: $brightness, runTime: $runTime, providers: $providers, localIp: $localIp, requests: $requests, version: $version, logs: $logs, traffics: $traffics, totalTraffic: $totalTraffic, proxiesQuery: $proxiesQuery, realTunEnable: $realTunEnable)';
return 'AppState(isInit: $isInit, backBlock: $backBlock, pageLabel: $pageLabel, packages: $packages, sortNum: $sortNum, viewSize: $viewSize, 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)';
}
@override
@@ -486,10 +503,11 @@ class _$AppStateImpl implements _AppState {
other.traffics == traffics) &&
(identical(other.totalTraffic, totalTraffic) ||
other.totalTraffic == totalTraffic) &&
(identical(other.proxiesQuery, proxiesQuery) ||
other.proxiesQuery == proxiesQuery) &&
(identical(other.realTunEnable, realTunEnable) ||
other.realTunEnable == realTunEnable));
other.realTunEnable == realTunEnable) &&
(identical(other.loading, loading) || other.loading == loading) &&
(identical(other.systemUiOverlayStyle, systemUiOverlayStyle) ||
other.systemUiOverlayStyle == systemUiOverlayStyle));
}
@override
@@ -513,8 +531,9 @@ class _$AppStateImpl implements _AppState {
logs,
traffics,
totalTraffic,
proxiesQuery,
realTunEnable
realTunEnable,
loading,
systemUiOverlayStyle
]);
/// Create a copy of AppState
@@ -528,26 +547,28 @@ class _$AppStateImpl implements _AppState {
abstract class _AppState implements AppState {
const factory _AppState(
{final bool isInit,
final bool backBlock,
final PageLabel pageLabel,
final List<Package> packages,
final int sortNum,
required final Size viewSize,
final Map<String, Map<String, int?>> delayMap,
final List<Group> groups,
final int checkIpNum,
final Brightness? brightness,
final int? runTime,
final List<ExternalProvider> providers,
final String? localIp,
required final FixedList<Connection> requests,
required final int version,
required final FixedList<Log> logs,
required final FixedList<Traffic> traffics,
required final Traffic totalTraffic,
final String proxiesQuery,
final bool realTunEnable}) = _$AppStateImpl;
{final bool isInit,
final bool backBlock,
final PageLabel pageLabel,
final List<Package> packages,
final int sortNum,
required final Size viewSize,
final Map<String, Map<String, int?>> delayMap,
final List<Group> groups,
final int checkIpNum,
required final Brightness brightness,
final int? runTime,
final List<ExternalProvider> providers,
final String? localIp,
required final FixedList<TrackerInfo> requests,
required final int version,
required final FixedList<Log> logs,
required final FixedList<Traffic> traffics,
required final Traffic totalTraffic,
final bool realTunEnable,
final bool loading,
required final SystemUiOverlayStyle systemUiOverlayStyle}) =
_$AppStateImpl;
@override
bool get isInit;
@@ -568,7 +589,7 @@ abstract class _AppState implements AppState {
@override
int get checkIpNum;
@override
Brightness? get brightness;
Brightness get brightness;
@override
int? get runTime;
@override
@@ -576,7 +597,7 @@ abstract class _AppState implements AppState {
@override
String? get localIp;
@override
FixedList<Connection> get requests;
FixedList<TrackerInfo> get requests;
@override
int get version;
@override
@@ -586,9 +607,11 @@ abstract class _AppState implements AppState {
@override
Traffic get totalTraffic;
@override
String get proxiesQuery;
@override
bool get realTunEnable;
@override
bool get loading;
@override
SystemUiOverlayStyle get systemUiOverlayStyle;
/// Create a copy of AppState
/// with the given fields replaced by the non-null parameter values.

File diff suppressed because it is too large Load Diff

View File

@@ -138,7 +138,7 @@ _$TunImpl _$$TunImplFromJson(Map<String, dynamic> json) => _$TunImpl(
dnsHijack: (json['dns-hijack'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const ["any:53"],
const ['any:53'],
routeAddress: (json['route-address'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
@@ -163,19 +163,19 @@ const _$TunStackEnumMap = {
_$FallbackFilterImpl _$$FallbackFilterImplFromJson(Map<String, dynamic> json) =>
_$FallbackFilterImpl(
geoip: json['geoip'] as bool? ?? true,
geoipCode: json['geoip-code'] as String? ?? "CN",
geoipCode: json['geoip-code'] as String? ?? 'CN',
geosite: (json['geosite'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const ["gfw"],
const ['gfw'],
ipcidr: (json['ipcidr'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const ["240.0.0.0/4"],
const ['240.0.0.0/4'],
domain: (json['domain'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const ["+.google.com", "+.facebook.com", "+.youtube.com"],
const ['+.google.com', '+.facebook.com', '+.youtube.com'],
);
Map<String, dynamic> _$$FallbackFilterImplToJson(
@@ -190,7 +190,7 @@ Map<String, dynamic> _$$FallbackFilterImplToJson(
_$DnsImpl _$$DnsImplFromJson(Map<String, dynamic> json) => _$DnsImpl(
enable: json['enable'] as bool? ?? true,
listen: json['listen'] as String? ?? "0.0.0.0:1053",
listen: json['listen'] as String? ?? '0.0.0.0:1053',
preferH3: json['prefer-h3'] as bool? ?? false,
useHosts: json['use-hosts'] as bool? ?? true,
useSystemHosts: json['use-system-hosts'] as bool? ?? true,
@@ -199,39 +199,39 @@ _$DnsImpl _$$DnsImplFromJson(Map<String, dynamic> json) => _$DnsImpl(
defaultNameserver: (json['default-nameserver'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const ["223.5.5.5"],
const ['223.5.5.5'],
enhancedMode:
$enumDecodeNullable(_$DnsModeEnumMap, json['enhanced-mode']) ??
DnsMode.fakeIp,
fakeIpRange: json['fake-ip-range'] as String? ?? "198.18.0.1/16",
fakeIpRange: json['fake-ip-range'] as String? ?? '198.18.0.1/16',
fakeIpFilter: (json['fake-ip-filter'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const ["*.lan", "localhost.ptlogin2.qq.com"],
const ['*.lan', 'localhost.ptlogin2.qq.com'],
nameserverPolicy:
(json['nameserver-policy'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, e as String),
) ??
const {
"www.baidu.com": "114.114.114.114",
"+.internal.crop.com": "10.0.0.1",
"geosite:cn": "https://doh.pub/dns-query"
'www.baidu.com': '114.114.114.114',
'+.internal.crop.com': '10.0.0.1',
'geosite:cn': 'https://doh.pub/dns-query'
},
nameserver: (json['nameserver'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const [
"https://doh.pub/dns-query",
"https://dns.alidns.com/dns-query"
'https://doh.pub/dns-query',
'https://dns.alidns.com/dns-query'
],
fallback: (json['fallback'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const ["tls://8.8.4.4", "tls://1.1.1.1"],
const ['tls://8.8.4.4', 'tls://1.1.1.1'],
proxyServerNameserver: (json['proxy-server-nameserver'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const ["https://doh.pub/dns-query"],
const ['https://doh.pub/dns-query'],
fallbackFilter: json['fallback-filter'] == null
? const FallbackFilter()
: FallbackFilter.fromJson(
@@ -267,13 +267,13 @@ const _$DnsModeEnumMap = {
_$GeoXUrlImpl _$$GeoXUrlImplFromJson(Map<String, dynamic> json) =>
_$GeoXUrlImpl(
mmdb: json['mmdb'] as String? ??
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb",
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb',
asn: json['asn'] as String? ??
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb",
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb',
geoip: json['geoip'] as String? ??
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat",
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat',
geosite: json['geosite'] as String? ??
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat",
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat',
);
Map<String, dynamic> _$$GeoXUrlImplToJson(_$GeoXUrlImpl instance) =>
@@ -418,7 +418,6 @@ const _$LogLevelEnumMap = {
LogLevel.warning: 'warning',
LogLevel.error: 'error',
LogLevel.silent: 'silent',
LogLevel.app: 'app',
};
const _$FindProcessModeEnumMap = {

File diff suppressed because it is too large Load Diff

View File

@@ -26,15 +26,29 @@ Map<String, dynamic> _$$PackageImplToJson(_$PackageImpl instance) =>
_$MetadataImpl _$$MetadataImplFromJson(Map<String, dynamic> json) =>
_$MetadataImpl(
uid: (json['uid'] as num).toInt(),
network: json['network'] as String,
sourceIP: json['sourceIP'] as String,
sourcePort: json['sourcePort'] as String,
destinationIP: json['destinationIP'] as String,
destinationPort: json['destinationPort'] as String,
host: json['host'] as String,
process: json['process'] as String,
remoteDestination: json['remoteDestination'] as String,
uid: (json['uid'] as num?)?.toInt() ?? 0,
network: json['network'] as String? ?? '',
sourceIP: json['sourceIP'] as String? ?? '',
sourcePort: json['sourcePort'] as String? ?? '',
destinationIP: json['destinationIP'] as String? ?? '',
destinationPort: json['destinationPort'] as String? ?? '',
host: json['host'] as String? ?? '',
dnsMode: $enumDecodeNullable(_$DnsModeEnumMap, json['dnsMode']),
process: json['process'] as String? ?? '',
processPath: json['processPath'] as String? ?? '',
remoteDestination: json['remoteDestination'] as String? ?? '',
sourceGeoIP: (json['sourceGeoIP'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const [],
destinationGeoIP: (json['destinationGeoIP'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const [],
destinationIPASN: json['destinationIPASN'] as String? ?? '',
sourceIPASN: json['sourceIPASN'] as String? ?? '',
specialRules: json['specialRules'] as String? ?? '',
specialProxy: json['specialProxy'] as String? ?? '',
);
Map<String, dynamic> _$$MetadataImplToJson(_$MetadataImpl instance) =>
@@ -46,22 +60,41 @@ Map<String, dynamic> _$$MetadataImplToJson(_$MetadataImpl instance) =>
'destinationIP': instance.destinationIP,
'destinationPort': instance.destinationPort,
'host': instance.host,
'dnsMode': _$DnsModeEnumMap[instance.dnsMode],
'process': instance.process,
'processPath': instance.processPath,
'remoteDestination': instance.remoteDestination,
'sourceGeoIP': instance.sourceGeoIP,
'destinationGeoIP': instance.destinationGeoIP,
'destinationIPASN': instance.destinationIPASN,
'sourceIPASN': instance.sourceIPASN,
'specialRules': instance.specialRules,
'specialProxy': instance.specialProxy,
};
_$ConnectionImpl _$$ConnectionImplFromJson(Map<String, dynamic> json) =>
_$ConnectionImpl(
const _$DnsModeEnumMap = {
DnsMode.normal: 'normal',
DnsMode.fakeIp: 'fake-ip',
DnsMode.redirHost: 'redir-host',
DnsMode.hosts: 'hosts',
};
_$TrackerInfoImpl _$$TrackerInfoImplFromJson(Map<String, dynamic> json) =>
_$TrackerInfoImpl(
id: json['id'] as String,
upload: json['upload'] as num?,
download: json['download'] as num?,
upload: (json['upload'] as num?)?.toInt() ?? 0,
download: (json['download'] as num?)?.toInt() ?? 0,
start: DateTime.parse(json['start'] as String),
metadata: Metadata.fromJson(json['metadata'] as Map<String, dynamic>),
chains:
(json['chains'] as List<dynamic>).map((e) => e as String).toList(),
rule: json['rule'] as String,
rulePayload: json['rulePayload'] as String,
downloadSpeed: (json['downloadSpeed'] as num?)?.toInt(),
uploadSpeed: (json['uploadSpeed'] as num?)?.toInt(),
);
Map<String, dynamic> _$$ConnectionImplToJson(_$ConnectionImpl instance) =>
Map<String, dynamic> _$$TrackerInfoImplToJson(_$TrackerInfoImpl instance) =>
<String, dynamic>{
'id': instance.id,
'upload': instance.upload,
@@ -69,12 +102,16 @@ Map<String, dynamic> _$$ConnectionImplToJson(_$ConnectionImpl instance) =>
'start': instance.start.toIso8601String(),
'metadata': instance.metadata,
'chains': instance.chains,
'rule': instance.rule,
'rulePayload': instance.rulePayload,
'downloadSpeed': instance.downloadSpeed,
'uploadSpeed': instance.uploadSpeed,
};
_$LogImpl _$$LogImplFromJson(Map<String, dynamic> json) => _$LogImpl(
logLevel: $enumDecodeNullable(_$LogLevelEnumMap, json['LogLevel']) ??
LogLevel.app,
payload: json['Payload'] as String? ?? "",
LogLevel.info,
payload: json['Payload'] as String? ?? '',
dateTime: _logDateTime(json['dateTime']),
);
@@ -90,7 +127,6 @@ const _$LogLevelEnumMap = {
LogLevel.warning: 'warning',
LogLevel.error: 'error',
LogLevel.silent: 'silent',
LogLevel.app: 'app',
};
_$DAVImpl _$$DAVImplFromJson(Map<String, dynamic> json) => _$DAVImpl(
@@ -109,8 +145,8 @@ Map<String, dynamic> _$$DAVImplToJson(_$DAVImpl instance) => <String, dynamic>{
_$VersionInfoImpl _$$VersionInfoImplFromJson(Map<String, dynamic> json) =>
_$VersionInfoImpl(
clashName: json['clashName'] as String? ?? "",
version: json['version'] as String? ?? "",
clashName: json['clashName'] as String? ?? '',
version: json['version'] as String? ?? '',
);
Map<String, dynamic> _$$VersionInfoImplToJson(_$VersionInfoImpl instance) =>
@@ -141,7 +177,7 @@ _$GroupImpl _$$GroupImplFromJson(Map<String, dynamic> json) => _$GroupImpl(
now: json['now'] as String?,
hidden: json['hidden'] as bool?,
testUrl: json['testUrl'] as String?,
icon: json['icon'] as String? ?? "",
icon: json['icon'] as String? ?? '',
name: json['name'] as String,
);

View File

@@ -1824,8 +1824,8 @@ TextScale _$TextScaleFromJson(Map<String, dynamic> json) {
/// @nodoc
mixin _$TextScale {
dynamic get enable => throw _privateConstructorUsedError;
dynamic get scale => throw _privateConstructorUsedError;
bool get enable => throw _privateConstructorUsedError;
double get scale => throw _privateConstructorUsedError;
/// Serializes this TextScale to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@@ -1842,7 +1842,7 @@ abstract class $TextScaleCopyWith<$Res> {
factory $TextScaleCopyWith(TextScale value, $Res Function(TextScale) then) =
_$TextScaleCopyWithImpl<$Res, TextScale>;
@useResult
$Res call({dynamic enable, dynamic scale});
$Res call({bool enable, double scale});
}
/// @nodoc
@@ -1860,18 +1860,18 @@ class _$TextScaleCopyWithImpl<$Res, $Val extends TextScale>
@pragma('vm:prefer-inline')
@override
$Res call({
Object? enable = freezed,
Object? scale = freezed,
Object? enable = null,
Object? scale = null,
}) {
return _then(_value.copyWith(
enable: freezed == enable
enable: null == enable
? _value.enable
: enable // ignore: cast_nullable_to_non_nullable
as dynamic,
scale: freezed == scale
as bool,
scale: null == scale
? _value.scale
: scale // ignore: cast_nullable_to_non_nullable
as dynamic,
as double,
) as $Val);
}
}
@@ -1884,7 +1884,7 @@ abstract class _$$TextScaleImplCopyWith<$Res>
__$$TextScaleImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({dynamic enable, dynamic scale});
$Res call({bool enable, double scale});
}
/// @nodoc
@@ -1900,12 +1900,18 @@ class __$$TextScaleImplCopyWithImpl<$Res>
@pragma('vm:prefer-inline')
@override
$Res call({
Object? enable = freezed,
Object? scale = freezed,
Object? enable = null,
Object? scale = null,
}) {
return _then(_$TextScaleImpl(
enable: freezed == enable ? _value.enable! : enable,
scale: freezed == scale ? _value.scale! : scale,
enable: null == enable
? _value.enable
: enable // ignore: cast_nullable_to_non_nullable
as bool,
scale: null == scale
? _value.scale
: scale // ignore: cast_nullable_to_non_nullable
as double,
));
}
}
@@ -1920,10 +1926,10 @@ class _$TextScaleImpl implements _TextScale {
@override
@JsonKey()
final dynamic enable;
final bool enable;
@override
@JsonKey()
final dynamic scale;
final double scale;
@override
String toString() {
@@ -1935,16 +1941,13 @@ class _$TextScaleImpl implements _TextScale {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$TextScaleImpl &&
const DeepCollectionEquality().equals(other.enable, enable) &&
const DeepCollectionEquality().equals(other.scale, scale));
(identical(other.enable, enable) || other.enable == enable) &&
(identical(other.scale, scale) || other.scale == scale));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType,
const DeepCollectionEquality().hash(enable),
const DeepCollectionEquality().hash(scale));
int get hashCode => Object.hash(runtimeType, enable, scale);
/// Create a copy of TextScale
/// with the given fields replaced by the non-null parameter values.
@@ -1963,16 +1966,16 @@ class _$TextScaleImpl implements _TextScale {
}
abstract class _TextScale implements TextScale {
const factory _TextScale({final dynamic enable, final dynamic scale}) =
const factory _TextScale({final bool enable, final double scale}) =
_$TextScaleImpl;
factory _TextScale.fromJson(Map<String, dynamic> json) =
_$TextScaleImpl.fromJson;
@override
dynamic get enable;
bool get enable;
@override
dynamic get scale;
double get scale;
/// Create a copy of TextScale
/// with the given fields replaced by the non-null parameter values.

View File

@@ -238,8 +238,8 @@ const _$ProxyCardTypeEnumMap = {
_$TextScaleImpl _$$TextScaleImplFromJson(Map<String, dynamic> json) =>
_$TextScaleImpl(
enable: json['enable'] ?? false,
scale: json['scale'] ?? 1.0,
enable: json['enable'] as bool? ?? false,
scale: (json['scale'] as num?)?.toDouble() ?? 1.0,
);
Map<String, dynamic> _$$TextScaleImplToJson(_$TextScaleImpl instance) =>

View File

@@ -20,11 +20,11 @@ SetupParams _$SetupParamsFromJson(Map<String, dynamic> json) {
/// @nodoc
mixin _$SetupParams {
@JsonKey(name: "config")
@JsonKey(name: 'config')
Map<String, dynamic> get config => throw _privateConstructorUsedError;
@JsonKey(name: "selected-map")
@JsonKey(name: 'selected-map')
Map<String, String> get selectedMap => throw _privateConstructorUsedError;
@JsonKey(name: "test-url")
@JsonKey(name: 'test-url')
String get testUrl => throw _privateConstructorUsedError;
/// Serializes this SetupParams to a JSON map.
@@ -44,9 +44,9 @@ abstract class $SetupParamsCopyWith<$Res> {
_$SetupParamsCopyWithImpl<$Res, SetupParams>;
@useResult
$Res call(
{@JsonKey(name: "config") Map<String, dynamic> config,
@JsonKey(name: "selected-map") Map<String, String> selectedMap,
@JsonKey(name: "test-url") String testUrl});
{@JsonKey(name: 'config') Map<String, dynamic> config,
@JsonKey(name: 'selected-map') Map<String, String> selectedMap,
@JsonKey(name: 'test-url') String testUrl});
}
/// @nodoc
@@ -94,9 +94,9 @@ abstract class _$$SetupParamsImplCopyWith<$Res>
@override
@useResult
$Res call(
{@JsonKey(name: "config") Map<String, dynamic> config,
@JsonKey(name: "selected-map") Map<String, String> selectedMap,
@JsonKey(name: "test-url") String testUrl});
{@JsonKey(name: 'config') Map<String, dynamic> config,
@JsonKey(name: 'selected-map') Map<String, String> selectedMap,
@JsonKey(name: 'test-url') String testUrl});
}
/// @nodoc
@@ -137,10 +137,10 @@ class __$$SetupParamsImplCopyWithImpl<$Res>
@JsonSerializable()
class _$SetupParamsImpl implements _SetupParams {
const _$SetupParamsImpl(
{@JsonKey(name: "config") required final Map<String, dynamic> config,
@JsonKey(name: "selected-map")
{@JsonKey(name: 'config') required final Map<String, dynamic> config,
@JsonKey(name: 'selected-map')
required final Map<String, String> selectedMap,
@JsonKey(name: "test-url") required this.testUrl})
@JsonKey(name: 'test-url') required this.testUrl})
: _config = config,
_selectedMap = selectedMap;
@@ -149,7 +149,7 @@ class _$SetupParamsImpl implements _SetupParams {
final Map<String, dynamic> _config;
@override
@JsonKey(name: "config")
@JsonKey(name: 'config')
Map<String, dynamic> get config {
if (_config is EqualUnmodifiableMapView) return _config;
// ignore: implicit_dynamic_type
@@ -158,7 +158,7 @@ class _$SetupParamsImpl implements _SetupParams {
final Map<String, String> _selectedMap;
@override
@JsonKey(name: "selected-map")
@JsonKey(name: 'selected-map')
Map<String, String> get selectedMap {
if (_selectedMap is EqualUnmodifiableMapView) return _selectedMap;
// ignore: implicit_dynamic_type
@@ -166,7 +166,7 @@ class _$SetupParamsImpl implements _SetupParams {
}
@override
@JsonKey(name: "test-url")
@JsonKey(name: 'test-url')
final String testUrl;
@override
@@ -211,23 +211,23 @@ class _$SetupParamsImpl implements _SetupParams {
abstract class _SetupParams implements SetupParams {
const factory _SetupParams(
{@JsonKey(name: "config") required final Map<String, dynamic> config,
@JsonKey(name: "selected-map")
{@JsonKey(name: 'config') required final Map<String, dynamic> config,
@JsonKey(name: 'selected-map')
required final Map<String, String> selectedMap,
@JsonKey(name: "test-url") required final String testUrl}) =
@JsonKey(name: 'test-url') required final String testUrl}) =
_$SetupParamsImpl;
factory _SetupParams.fromJson(Map<String, dynamic> json) =
_$SetupParamsImpl.fromJson;
@override
@JsonKey(name: "config")
@JsonKey(name: 'config')
Map<String, dynamic> get config;
@override
@JsonKey(name: "selected-map")
@JsonKey(name: 'selected-map')
Map<String, String> get selectedMap;
@override
@JsonKey(name: "test-url")
@JsonKey(name: 'test-url')
String get testUrl;
/// Create a copy of SetupParams
@@ -637,13 +637,13 @@ CoreState _$CoreStateFromJson(Map<String, dynamic> json) {
/// @nodoc
mixin _$CoreState {
@JsonKey(name: "vpn-props")
@JsonKey(name: 'vpn-props')
VpnProps get vpnProps => throw _privateConstructorUsedError;
@JsonKey(name: "only-statistics-proxy")
@JsonKey(name: 'only-statistics-proxy')
bool get onlyStatisticsProxy => throw _privateConstructorUsedError;
@JsonKey(name: "current-profile-name")
@JsonKey(name: 'current-profile-name')
String get currentProfileName => throw _privateConstructorUsedError;
@JsonKey(name: "bypass-domain")
@JsonKey(name: 'bypass-domain')
List<String> get bypassDomain => throw _privateConstructorUsedError;
/// Serializes this CoreState to a JSON map.
@@ -662,10 +662,10 @@ abstract class $CoreStateCopyWith<$Res> {
_$CoreStateCopyWithImpl<$Res, CoreState>;
@useResult
$Res call(
{@JsonKey(name: "vpn-props") VpnProps vpnProps,
@JsonKey(name: "only-statistics-proxy") bool onlyStatisticsProxy,
@JsonKey(name: "current-profile-name") String currentProfileName,
@JsonKey(name: "bypass-domain") List<String> bypassDomain});
{@JsonKey(name: 'vpn-props') VpnProps vpnProps,
@JsonKey(name: 'only-statistics-proxy') bool onlyStatisticsProxy,
@JsonKey(name: 'current-profile-name') String currentProfileName,
@JsonKey(name: 'bypass-domain') List<String> bypassDomain});
$VpnPropsCopyWith<$Res> get vpnProps;
}
@@ -730,10 +730,10 @@ abstract class _$$CoreStateImplCopyWith<$Res>
@override
@useResult
$Res call(
{@JsonKey(name: "vpn-props") VpnProps vpnProps,
@JsonKey(name: "only-statistics-proxy") bool onlyStatisticsProxy,
@JsonKey(name: "current-profile-name") String currentProfileName,
@JsonKey(name: "bypass-domain") List<String> bypassDomain});
{@JsonKey(name: 'vpn-props') VpnProps vpnProps,
@JsonKey(name: 'only-statistics-proxy') bool onlyStatisticsProxy,
@JsonKey(name: 'current-profile-name') String currentProfileName,
@JsonKey(name: 'bypass-domain') List<String> bypassDomain});
@override
$VpnPropsCopyWith<$Res> get vpnProps;
@@ -782,10 +782,10 @@ class __$$CoreStateImplCopyWithImpl<$Res>
@JsonSerializable()
class _$CoreStateImpl implements _CoreState {
const _$CoreStateImpl(
{@JsonKey(name: "vpn-props") required this.vpnProps,
@JsonKey(name: "only-statistics-proxy") required this.onlyStatisticsProxy,
@JsonKey(name: "current-profile-name") required this.currentProfileName,
@JsonKey(name: "bypass-domain")
{@JsonKey(name: 'vpn-props') required this.vpnProps,
@JsonKey(name: 'only-statistics-proxy') required this.onlyStatisticsProxy,
@JsonKey(name: 'current-profile-name') required this.currentProfileName,
@JsonKey(name: 'bypass-domain')
final List<String> bypassDomain = const []})
: _bypassDomain = bypassDomain;
@@ -793,17 +793,17 @@ class _$CoreStateImpl implements _CoreState {
_$$CoreStateImplFromJson(json);
@override
@JsonKey(name: "vpn-props")
@JsonKey(name: 'vpn-props')
final VpnProps vpnProps;
@override
@JsonKey(name: "only-statistics-proxy")
@JsonKey(name: 'only-statistics-proxy')
final bool onlyStatisticsProxy;
@override
@JsonKey(name: "current-profile-name")
@JsonKey(name: 'current-profile-name')
final String currentProfileName;
final List<String> _bypassDomain;
@override
@JsonKey(name: "bypass-domain")
@JsonKey(name: 'bypass-domain')
List<String> get bypassDomain {
if (_bypassDomain is EqualUnmodifiableListView) return _bypassDomain;
// ignore: implicit_dynamic_type
@@ -853,28 +853,28 @@ class _$CoreStateImpl implements _CoreState {
abstract class _CoreState implements CoreState {
const factory _CoreState(
{@JsonKey(name: "vpn-props") required final VpnProps vpnProps,
@JsonKey(name: "only-statistics-proxy")
{@JsonKey(name: 'vpn-props') required final VpnProps vpnProps,
@JsonKey(name: 'only-statistics-proxy')
required final bool onlyStatisticsProxy,
@JsonKey(name: "current-profile-name")
@JsonKey(name: 'current-profile-name')
required final String currentProfileName,
@JsonKey(name: "bypass-domain") final List<String> bypassDomain}) =
@JsonKey(name: 'bypass-domain') final List<String> bypassDomain}) =
_$CoreStateImpl;
factory _CoreState.fromJson(Map<String, dynamic> json) =
_$CoreStateImpl.fromJson;
@override
@JsonKey(name: "vpn-props")
@JsonKey(name: 'vpn-props')
VpnProps get vpnProps;
@override
@JsonKey(name: "only-statistics-proxy")
@JsonKey(name: 'only-statistics-proxy')
bool get onlyStatisticsProxy;
@override
@JsonKey(name: "current-profile-name")
@JsonKey(name: 'current-profile-name')
String get currentProfileName;
@override
@JsonKey(name: "bypass-domain")
@JsonKey(name: 'bypass-domain')
List<String> get bypassDomain;
/// Create a copy of CoreState
@@ -1278,7 +1278,7 @@ InitParams _$InitParamsFromJson(Map<String, dynamic> json) {
/// @nodoc
mixin _$InitParams {
@JsonKey(name: "home-dir")
@JsonKey(name: 'home-dir')
String get homeDir => throw _privateConstructorUsedError;
int get version => throw _privateConstructorUsedError;
@@ -1298,7 +1298,7 @@ abstract class $InitParamsCopyWith<$Res> {
InitParams value, $Res Function(InitParams) then) =
_$InitParamsCopyWithImpl<$Res, InitParams>;
@useResult
$Res call({@JsonKey(name: "home-dir") String homeDir, int version});
$Res call({@JsonKey(name: 'home-dir') String homeDir, int version});
}
/// @nodoc
@@ -1340,7 +1340,7 @@ abstract class _$$InitParamsImplCopyWith<$Res>
__$$InitParamsImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({@JsonKey(name: "home-dir") String homeDir, int version});
$Res call({@JsonKey(name: 'home-dir') String homeDir, int version});
}
/// @nodoc
@@ -1376,14 +1376,14 @@ class __$$InitParamsImplCopyWithImpl<$Res>
@JsonSerializable()
class _$InitParamsImpl implements _InitParams {
const _$InitParamsImpl(
{@JsonKey(name: "home-dir") required this.homeDir,
{@JsonKey(name: 'home-dir') required this.homeDir,
required this.version});
factory _$InitParamsImpl.fromJson(Map<String, dynamic> json) =>
_$$InitParamsImplFromJson(json);
@override
@JsonKey(name: "home-dir")
@JsonKey(name: 'home-dir')
final String homeDir;
@override
final int version;
@@ -1424,14 +1424,14 @@ class _$InitParamsImpl implements _InitParams {
abstract class _InitParams implements InitParams {
const factory _InitParams(
{@JsonKey(name: "home-dir") required final String homeDir,
{@JsonKey(name: 'home-dir') required final String homeDir,
required final int version}) = _$InitParamsImpl;
factory _InitParams.fromJson(Map<String, dynamic> json) =
_$InitParamsImpl.fromJson;
@override
@JsonKey(name: "home-dir")
@JsonKey(name: 'home-dir')
String get homeDir;
@override
int get version;
@@ -1450,9 +1450,9 @@ ChangeProxyParams _$ChangeProxyParamsFromJson(Map<String, dynamic> json) {
/// @nodoc
mixin _$ChangeProxyParams {
@JsonKey(name: "group-name")
@JsonKey(name: 'group-name')
String get groupName => throw _privateConstructorUsedError;
@JsonKey(name: "proxy-name")
@JsonKey(name: 'proxy-name')
String get proxyName => throw _privateConstructorUsedError;
/// Serializes this ChangeProxyParams to a JSON map.
@@ -1472,8 +1472,8 @@ abstract class $ChangeProxyParamsCopyWith<$Res> {
_$ChangeProxyParamsCopyWithImpl<$Res, ChangeProxyParams>;
@useResult
$Res call(
{@JsonKey(name: "group-name") String groupName,
@JsonKey(name: "proxy-name") String proxyName});
{@JsonKey(name: 'group-name') String groupName,
@JsonKey(name: 'proxy-name') String proxyName});
}
/// @nodoc
@@ -1516,8 +1516,8 @@ abstract class _$$ChangeProxyParamsImplCopyWith<$Res>
@override
@useResult
$Res call(
{@JsonKey(name: "group-name") String groupName,
@JsonKey(name: "proxy-name") String proxyName});
{@JsonKey(name: 'group-name') String groupName,
@JsonKey(name: 'proxy-name') String proxyName});
}
/// @nodoc
@@ -1553,17 +1553,17 @@ class __$$ChangeProxyParamsImplCopyWithImpl<$Res>
@JsonSerializable()
class _$ChangeProxyParamsImpl implements _ChangeProxyParams {
const _$ChangeProxyParamsImpl(
{@JsonKey(name: "group-name") required this.groupName,
@JsonKey(name: "proxy-name") required this.proxyName});
{@JsonKey(name: 'group-name') required this.groupName,
@JsonKey(name: 'proxy-name') required this.proxyName});
factory _$ChangeProxyParamsImpl.fromJson(Map<String, dynamic> json) =>
_$$ChangeProxyParamsImplFromJson(json);
@override
@JsonKey(name: "group-name")
@JsonKey(name: 'group-name')
final String groupName;
@override
@JsonKey(name: "proxy-name")
@JsonKey(name: 'proxy-name')
final String proxyName;
@override
@@ -1605,18 +1605,18 @@ class _$ChangeProxyParamsImpl implements _ChangeProxyParams {
abstract class _ChangeProxyParams implements ChangeProxyParams {
const factory _ChangeProxyParams(
{@JsonKey(name: "group-name") required final String groupName,
@JsonKey(name: "proxy-name") required final String proxyName}) =
{@JsonKey(name: 'group-name') required final String groupName,
@JsonKey(name: 'proxy-name') required final String proxyName}) =
_$ChangeProxyParamsImpl;
factory _ChangeProxyParams.fromJson(Map<String, dynamic> json) =
_$ChangeProxyParamsImpl.fromJson;
@override
@JsonKey(name: "group-name")
@JsonKey(name: 'group-name')
String get groupName;
@override
@JsonKey(name: "proxy-name")
@JsonKey(name: 'proxy-name')
String get proxyName;
/// Create a copy of ChangeProxyParams
@@ -1633,9 +1633,9 @@ UpdateGeoDataParams _$UpdateGeoDataParamsFromJson(Map<String, dynamic> json) {
/// @nodoc
mixin _$UpdateGeoDataParams {
@JsonKey(name: "geo-type")
@JsonKey(name: 'geo-type')
String get geoType => throw _privateConstructorUsedError;
@JsonKey(name: "geo-name")
@JsonKey(name: 'geo-name')
String get geoName => throw _privateConstructorUsedError;
/// Serializes this UpdateGeoDataParams to a JSON map.
@@ -1655,8 +1655,8 @@ abstract class $UpdateGeoDataParamsCopyWith<$Res> {
_$UpdateGeoDataParamsCopyWithImpl<$Res, UpdateGeoDataParams>;
@useResult
$Res call(
{@JsonKey(name: "geo-type") String geoType,
@JsonKey(name: "geo-name") String geoName});
{@JsonKey(name: 'geo-type') String geoType,
@JsonKey(name: 'geo-name') String geoName});
}
/// @nodoc
@@ -1699,8 +1699,8 @@ abstract class _$$UpdateGeoDataParamsImplCopyWith<$Res>
@override
@useResult
$Res call(
{@JsonKey(name: "geo-type") String geoType,
@JsonKey(name: "geo-name") String geoName});
{@JsonKey(name: 'geo-type') String geoType,
@JsonKey(name: 'geo-name') String geoName});
}
/// @nodoc
@@ -1736,17 +1736,17 @@ class __$$UpdateGeoDataParamsImplCopyWithImpl<$Res>
@JsonSerializable()
class _$UpdateGeoDataParamsImpl implements _UpdateGeoDataParams {
const _$UpdateGeoDataParamsImpl(
{@JsonKey(name: "geo-type") required this.geoType,
@JsonKey(name: "geo-name") required this.geoName});
{@JsonKey(name: 'geo-type') required this.geoType,
@JsonKey(name: 'geo-name') required this.geoName});
factory _$UpdateGeoDataParamsImpl.fromJson(Map<String, dynamic> json) =>
_$$UpdateGeoDataParamsImplFromJson(json);
@override
@JsonKey(name: "geo-type")
@JsonKey(name: 'geo-type')
final String geoType;
@override
@JsonKey(name: "geo-name")
@JsonKey(name: 'geo-name')
final String geoName;
@override
@@ -1786,18 +1786,18 @@ class _$UpdateGeoDataParamsImpl implements _UpdateGeoDataParams {
abstract class _UpdateGeoDataParams implements UpdateGeoDataParams {
const factory _UpdateGeoDataParams(
{@JsonKey(name: "geo-type") required final String geoType,
@JsonKey(name: "geo-name") required final String geoName}) =
{@JsonKey(name: 'geo-type') required final String geoType,
@JsonKey(name: 'geo-name') required final String geoName}) =
_$UpdateGeoDataParamsImpl;
factory _UpdateGeoDataParams.fromJson(Map<String, dynamic> json) =
_$UpdateGeoDataParamsImpl.fromJson;
@override
@JsonKey(name: "geo-type")
@JsonKey(name: 'geo-type')
String get geoType;
@override
@JsonKey(name: "geo-name")
@JsonKey(name: 'geo-name')
String get geoName;
/// Create a copy of UpdateGeoDataParams
@@ -2489,13 +2489,13 @@ ProviderSubscriptionInfo _$ProviderSubscriptionInfoFromJson(
/// @nodoc
mixin _$ProviderSubscriptionInfo {
@JsonKey(name: "UPLOAD")
@JsonKey(name: 'UPLOAD')
int get upload => throw _privateConstructorUsedError;
@JsonKey(name: "DOWNLOAD")
@JsonKey(name: 'DOWNLOAD')
int get download => throw _privateConstructorUsedError;
@JsonKey(name: "TOTAL")
@JsonKey(name: 'TOTAL')
int get total => throw _privateConstructorUsedError;
@JsonKey(name: "EXPIRE")
@JsonKey(name: 'EXPIRE')
int get expire => throw _privateConstructorUsedError;
/// Serializes this ProviderSubscriptionInfo to a JSON map.
@@ -2515,10 +2515,10 @@ abstract class $ProviderSubscriptionInfoCopyWith<$Res> {
_$ProviderSubscriptionInfoCopyWithImpl<$Res, ProviderSubscriptionInfo>;
@useResult
$Res call(
{@JsonKey(name: "UPLOAD") int upload,
@JsonKey(name: "DOWNLOAD") int download,
@JsonKey(name: "TOTAL") int total,
@JsonKey(name: "EXPIRE") int expire});
{@JsonKey(name: 'UPLOAD') int upload,
@JsonKey(name: 'DOWNLOAD') int download,
@JsonKey(name: 'TOTAL') int total,
@JsonKey(name: 'EXPIRE') int expire});
}
/// @nodoc
@@ -2573,10 +2573,10 @@ abstract class _$$ProviderSubscriptionInfoImplCopyWith<$Res>
@override
@useResult
$Res call(
{@JsonKey(name: "UPLOAD") int upload,
@JsonKey(name: "DOWNLOAD") int download,
@JsonKey(name: "TOTAL") int total,
@JsonKey(name: "EXPIRE") int expire});
{@JsonKey(name: 'UPLOAD') int upload,
@JsonKey(name: 'DOWNLOAD') int download,
@JsonKey(name: 'TOTAL') int total,
@JsonKey(name: 'EXPIRE') int expire});
}
/// @nodoc
@@ -2624,25 +2624,25 @@ class __$$ProviderSubscriptionInfoImplCopyWithImpl<$Res>
@JsonSerializable()
class _$ProviderSubscriptionInfoImpl implements _ProviderSubscriptionInfo {
const _$ProviderSubscriptionInfoImpl(
{@JsonKey(name: "UPLOAD") this.upload = 0,
@JsonKey(name: "DOWNLOAD") this.download = 0,
@JsonKey(name: "TOTAL") this.total = 0,
@JsonKey(name: "EXPIRE") this.expire = 0});
{@JsonKey(name: 'UPLOAD') this.upload = 0,
@JsonKey(name: 'DOWNLOAD') this.download = 0,
@JsonKey(name: 'TOTAL') this.total = 0,
@JsonKey(name: 'EXPIRE') this.expire = 0});
factory _$ProviderSubscriptionInfoImpl.fromJson(Map<String, dynamic> json) =>
_$$ProviderSubscriptionInfoImplFromJson(json);
@override
@JsonKey(name: "UPLOAD")
@JsonKey(name: 'UPLOAD')
final int upload;
@override
@JsonKey(name: "DOWNLOAD")
@JsonKey(name: 'DOWNLOAD')
final int download;
@override
@JsonKey(name: "TOTAL")
@JsonKey(name: 'TOTAL')
final int total;
@override
@JsonKey(name: "EXPIRE")
@JsonKey(name: 'EXPIRE')
final int expire;
@override
@@ -2685,26 +2685,26 @@ class _$ProviderSubscriptionInfoImpl implements _ProviderSubscriptionInfo {
abstract class _ProviderSubscriptionInfo implements ProviderSubscriptionInfo {
const factory _ProviderSubscriptionInfo(
{@JsonKey(name: "UPLOAD") final int upload,
@JsonKey(name: "DOWNLOAD") final int download,
@JsonKey(name: "TOTAL") final int total,
@JsonKey(name: "EXPIRE") final int expire}) =
{@JsonKey(name: 'UPLOAD') final int upload,
@JsonKey(name: 'DOWNLOAD') final int download,
@JsonKey(name: 'TOTAL') final int total,
@JsonKey(name: 'EXPIRE') final int expire}) =
_$ProviderSubscriptionInfoImpl;
factory _ProviderSubscriptionInfo.fromJson(Map<String, dynamic> json) =
_$ProviderSubscriptionInfoImpl.fromJson;
@override
@JsonKey(name: "UPLOAD")
@JsonKey(name: 'UPLOAD')
int get upload;
@override
@JsonKey(name: "DOWNLOAD")
@JsonKey(name: 'DOWNLOAD')
int get download;
@override
@JsonKey(name: "TOTAL")
@JsonKey(name: 'TOTAL')
int get total;
@override
@JsonKey(name: "EXPIRE")
@JsonKey(name: 'EXPIRE')
int get expire;
/// Create a copy of ProviderSubscriptionInfo
@@ -2725,12 +2725,12 @@ mixin _$ExternalProvider {
String get type => throw _privateConstructorUsedError;
String? get path => throw _privateConstructorUsedError;
int get count => throw _privateConstructorUsedError;
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
SubscriptionInfo? get subscriptionInfo => throw _privateConstructorUsedError;
bool get isUpdating => throw _privateConstructorUsedError;
@JsonKey(name: "vehicle-type")
@JsonKey(name: 'vehicle-type')
String get vehicleType => throw _privateConstructorUsedError;
@JsonKey(name: "update-at")
@JsonKey(name: 'update-at')
DateTime get updateAt => throw _privateConstructorUsedError;
/// Serializes this ExternalProvider to a JSON map.
@@ -2754,11 +2754,11 @@ abstract class $ExternalProviderCopyWith<$Res> {
String type,
String? path,
int count,
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
SubscriptionInfo? subscriptionInfo,
bool isUpdating,
@JsonKey(name: "vehicle-type") String vehicleType,
@JsonKey(name: "update-at") DateTime updateAt});
@JsonKey(name: 'vehicle-type') String vehicleType,
@JsonKey(name: 'update-at') DateTime updateAt});
$SubscriptionInfoCopyWith<$Res>? get subscriptionInfo;
}
@@ -2851,11 +2851,11 @@ abstract class _$$ExternalProviderImplCopyWith<$Res>
String type,
String? path,
int count,
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
SubscriptionInfo? subscriptionInfo,
bool isUpdating,
@JsonKey(name: "vehicle-type") String vehicleType,
@JsonKey(name: "update-at") DateTime updateAt});
@JsonKey(name: 'vehicle-type') String vehicleType,
@JsonKey(name: 'update-at') DateTime updateAt});
@override
$SubscriptionInfoCopyWith<$Res>? get subscriptionInfo;
@@ -2928,11 +2928,11 @@ class _$ExternalProviderImpl implements _ExternalProvider {
required this.type,
this.path,
required this.count,
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
@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});
@JsonKey(name: 'vehicle-type') required this.vehicleType,
@JsonKey(name: 'update-at') required this.updateAt});
factory _$ExternalProviderImpl.fromJson(Map<String, dynamic> json) =>
_$$ExternalProviderImplFromJson(json);
@@ -2946,16 +2946,16 @@ class _$ExternalProviderImpl implements _ExternalProvider {
@override
final int count;
@override
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
final SubscriptionInfo? subscriptionInfo;
@override
@JsonKey()
final bool isUpdating;
@override
@JsonKey(name: "vehicle-type")
@JsonKey(name: 'vehicle-type')
final String vehicleType;
@override
@JsonKey(name: "update-at")
@JsonKey(name: 'update-at')
final DateTime updateAt;
@override
@@ -3010,11 +3010,11 @@ abstract class _ExternalProvider implements ExternalProvider {
required final String type,
final String? path,
required final int count,
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
final SubscriptionInfo? subscriptionInfo,
final bool isUpdating,
@JsonKey(name: "vehicle-type") required final String vehicleType,
@JsonKey(name: "update-at")
@JsonKey(name: 'vehicle-type') required final String vehicleType,
@JsonKey(name: 'update-at')
required final DateTime updateAt}) = _$ExternalProviderImpl;
factory _ExternalProvider.fromJson(Map<String, dynamic> json) =
@@ -3029,15 +3029,15 @@ abstract class _ExternalProvider implements ExternalProvider {
@override
int get count;
@override
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
SubscriptionInfo? get subscriptionInfo;
@override
bool get isUpdating;
@override
@JsonKey(name: "vehicle-type")
@JsonKey(name: 'vehicle-type')
String get vehicleType;
@override
@JsonKey(name: "update-at")
@JsonKey(name: 'update-at')
DateTime get updateAt;
/// Create a copy of ExternalProvider

View File

@@ -68,7 +68,6 @@ const _$LogLevelEnumMap = {
LogLevel.warning: 'warning',
LogLevel.error: 'error',
LogLevel.silent: 'silent',
LogLevel.app: 'app',
};
const _$ExternalControllerStatusEnumMap = {

View File

@@ -492,7 +492,7 @@ class _$ProfileImpl implements _Profile {
{required this.id,
this.label,
this.currentGroupName,
this.url = "",
this.url = '',
this.lastUpdateDate,
required this.autoUpdateDuration,
this.subscriptionInfo,

View File

@@ -29,7 +29,7 @@ _$ProfileImpl _$$ProfileImplFromJson(Map<String, dynamic> json) =>
id: json['id'] as String,
label: json['label'] as String?,
currentGroupName: json['currentGroupName'] as String?,
url: json['url'] as String? ?? "",
url: json['url'] as String? ?? '',
lastUpdateDate: json['lastUpdateDate'] == null
? null
: DateTime.parse(json['lastUpdateDate'] as String),

File diff suppressed because it is too large Load Diff

View File

@@ -531,7 +531,7 @@ abstract class _AppBarState implements AppBarState {
/// @nodoc
mixin _$AppBarSearchState {
dynamic Function(String) get onSearch => throw _privateConstructorUsedError;
bool get isSearch => throw _privateConstructorUsedError;
String? get query => throw _privateConstructorUsedError;
/// Create a copy of AppBarSearchState
/// with the given fields replaced by the non-null parameter values.
@@ -546,7 +546,7 @@ abstract class $AppBarSearchStateCopyWith<$Res> {
AppBarSearchState value, $Res Function(AppBarSearchState) then) =
_$AppBarSearchStateCopyWithImpl<$Res, AppBarSearchState>;
@useResult
$Res call({dynamic Function(String) onSearch, bool isSearch});
$Res call({dynamic Function(String) onSearch, String? query});
}
/// @nodoc
@@ -565,17 +565,17 @@ class _$AppBarSearchStateCopyWithImpl<$Res, $Val extends AppBarSearchState>
@override
$Res call({
Object? onSearch = null,
Object? isSearch = null,
Object? query = freezed,
}) {
return _then(_value.copyWith(
onSearch: null == onSearch
? _value.onSearch
: onSearch // ignore: cast_nullable_to_non_nullable
as dynamic Function(String),
isSearch: null == isSearch
? _value.isSearch
: isSearch // ignore: cast_nullable_to_non_nullable
as bool,
query: freezed == query
? _value.query
: query // ignore: cast_nullable_to_non_nullable
as String?,
) as $Val);
}
}
@@ -588,7 +588,7 @@ abstract class _$$AppBarSearchStateImplCopyWith<$Res>
__$$AppBarSearchStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({dynamic Function(String) onSearch, bool isSearch});
$Res call({dynamic Function(String) onSearch, String? query});
}
/// @nodoc
@@ -605,17 +605,17 @@ class __$$AppBarSearchStateImplCopyWithImpl<$Res>
@override
$Res call({
Object? onSearch = null,
Object? isSearch = null,
Object? query = freezed,
}) {
return _then(_$AppBarSearchStateImpl(
onSearch: null == onSearch
? _value.onSearch
: onSearch // ignore: cast_nullable_to_non_nullable
as dynamic Function(String),
isSearch: null == isSearch
? _value.isSearch
: isSearch // ignore: cast_nullable_to_non_nullable
as bool,
query: freezed == query
? _value.query
: query // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
@@ -623,18 +623,17 @@ class __$$AppBarSearchStateImplCopyWithImpl<$Res>
/// @nodoc
class _$AppBarSearchStateImpl implements _AppBarSearchState {
const _$AppBarSearchStateImpl(
{required this.onSearch, this.isSearch = false});
const _$AppBarSearchStateImpl({required this.onSearch, this.query = null});
@override
final dynamic Function(String) onSearch;
@override
@JsonKey()
final bool isSearch;
final String? query;
@override
String toString() {
return 'AppBarSearchState(onSearch: $onSearch, isSearch: $isSearch)';
return 'AppBarSearchState(onSearch: $onSearch, query: $query)';
}
@override
@@ -644,12 +643,11 @@ class _$AppBarSearchStateImpl implements _AppBarSearchState {
other is _$AppBarSearchStateImpl &&
(identical(other.onSearch, onSearch) ||
other.onSearch == onSearch) &&
(identical(other.isSearch, isSearch) ||
other.isSearch == isSearch));
(identical(other.query, query) || other.query == query));
}
@override
int get hashCode => Object.hash(runtimeType, onSearch, isSearch);
int get hashCode => Object.hash(runtimeType, onSearch, query);
/// Create a copy of AppBarSearchState
/// with the given fields replaced by the non-null parameter values.
@@ -664,12 +662,12 @@ class _$AppBarSearchStateImpl implements _AppBarSearchState {
abstract class _AppBarSearchState implements AppBarSearchState {
const factory _AppBarSearchState(
{required final dynamic Function(String) onSearch,
final bool isSearch}) = _$AppBarSearchStateImpl;
final String? query}) = _$AppBarSearchStateImpl;
@override
dynamic Function(String) get onSearch;
@override
bool get isSearch;
String? get query;
/// Create a copy of AppBarSearchState
/// with the given fields replaced by the non-null parameter values.
@@ -681,8 +679,7 @@ abstract class _AppBarSearchState implements AppBarSearchState {
/// @nodoc
mixin _$AppBarEditState {
dynamic get editCount => throw _privateConstructorUsedError;
bool get isEdit => throw _privateConstructorUsedError;
int get editCount => throw _privateConstructorUsedError;
dynamic Function() get onExit => throw _privateConstructorUsedError;
/// Create a copy of AppBarEditState
@@ -698,7 +695,7 @@ abstract class $AppBarEditStateCopyWith<$Res> {
AppBarEditState value, $Res Function(AppBarEditState) then) =
_$AppBarEditStateCopyWithImpl<$Res, AppBarEditState>;
@useResult
$Res call({dynamic editCount, bool isEdit, dynamic Function() onExit});
$Res call({int editCount, dynamic Function() onExit});
}
/// @nodoc
@@ -716,19 +713,14 @@ class _$AppBarEditStateCopyWithImpl<$Res, $Val extends AppBarEditState>
@pragma('vm:prefer-inline')
@override
$Res call({
Object? editCount = freezed,
Object? isEdit = null,
Object? editCount = null,
Object? onExit = null,
}) {
return _then(_value.copyWith(
editCount: freezed == editCount
editCount: null == editCount
? _value.editCount
: editCount // ignore: cast_nullable_to_non_nullable
as dynamic,
isEdit: null == isEdit
? _value.isEdit
: isEdit // ignore: cast_nullable_to_non_nullable
as bool,
as int,
onExit: null == onExit
? _value.onExit
: onExit // ignore: cast_nullable_to_non_nullable
@@ -745,7 +737,7 @@ abstract class _$$AppBarEditStateImplCopyWith<$Res>
__$$AppBarEditStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({dynamic editCount, bool isEdit, dynamic Function() onExit});
$Res call({int editCount, dynamic Function() onExit});
}
/// @nodoc
@@ -761,16 +753,14 @@ class __$$AppBarEditStateImplCopyWithImpl<$Res>
@pragma('vm:prefer-inline')
@override
$Res call({
Object? editCount = freezed,
Object? isEdit = null,
Object? editCount = null,
Object? onExit = null,
}) {
return _then(_$AppBarEditStateImpl(
editCount: freezed == editCount ? _value.editCount! : editCount,
isEdit: null == isEdit
? _value.isEdit
: isEdit // ignore: cast_nullable_to_non_nullable
as bool,
editCount: null == editCount
? _value.editCount
: editCount // ignore: cast_nullable_to_non_nullable
as int,
onExit: null == onExit
? _value.onExit
: onExit // ignore: cast_nullable_to_non_nullable
@@ -782,21 +772,17 @@ class __$$AppBarEditStateImplCopyWithImpl<$Res>
/// @nodoc
class _$AppBarEditStateImpl implements _AppBarEditState {
const _$AppBarEditStateImpl(
{this.editCount = 0, this.isEdit = false, required this.onExit});
const _$AppBarEditStateImpl({this.editCount = 0, required this.onExit});
@override
@JsonKey()
final dynamic editCount;
@override
@JsonKey()
final bool isEdit;
final int editCount;
@override
final dynamic Function() onExit;
@override
String toString() {
return 'AppBarEditState(editCount: $editCount, isEdit: $isEdit, onExit: $onExit)';
return 'AppBarEditState(editCount: $editCount, onExit: $onExit)';
}
@override
@@ -804,14 +790,13 @@ class _$AppBarEditStateImpl implements _AppBarEditState {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$AppBarEditStateImpl &&
const DeepCollectionEquality().equals(other.editCount, editCount) &&
(identical(other.isEdit, isEdit) || other.isEdit == isEdit) &&
(identical(other.editCount, editCount) ||
other.editCount == editCount) &&
(identical(other.onExit, onExit) || other.onExit == onExit));
}
@override
int get hashCode => Object.hash(runtimeType,
const DeepCollectionEquality().hash(editCount), isEdit, onExit);
int get hashCode => Object.hash(runtimeType, editCount, onExit);
/// Create a copy of AppBarEditState
/// with the given fields replaced by the non-null parameter values.
@@ -825,14 +810,11 @@ class _$AppBarEditStateImpl implements _AppBarEditState {
abstract class _AppBarEditState implements AppBarEditState {
const factory _AppBarEditState(
{final dynamic editCount,
final bool isEdit,
{final int editCount,
required final dynamic Function() onExit}) = _$AppBarEditStateImpl;
@override
dynamic get editCount;
@override
bool get isEdit;
int get editCount;
@override
dynamic Function() get onExit;

View File

@@ -29,17 +29,17 @@ class SubscriptionInfo with _$SubscriptionInfo {
factory SubscriptionInfo.formHString(String? info) {
if (info == null) return const SubscriptionInfo();
final list = info.split(";");
final list = info.split(';');
Map<String, int?> map = {};
for (final i in list) {
final keyValue = i.trim().split("=");
final keyValue = i.trim().split('=');
map[keyValue[0]] = int.tryParse(keyValue[1]);
}
return SubscriptionInfo(
upload: map["upload"] ?? 0,
download: map["download"] ?? 0,
total: map["total"] ?? 0,
expire: map["expire"] ?? 0,
upload: map['upload'] ?? 0,
download: map['download'] ?? 0,
total: map['total'] ?? 0,
expire: map['expire'] ?? 0,
);
}
}
@@ -50,7 +50,7 @@ class Profile with _$Profile {
required String id,
String? label,
String? currentGroupName,
@Default("") String url,
@Default('') String url,
DateTime? lastUpdateDate,
required Duration autoUpdateDuration,
SubscriptionInfo? subscriptionInfo,
@@ -169,7 +169,7 @@ extension ProfileExtension on Profile {
Future<Profile> update() async {
final response = await request.getFileResponseForUrl(url);
final disposition = response.headers.value("content-disposition");
final disposition = response.headers.value('content-disposition');
final userinfo = response.headers.value('subscription-userinfo');
return await copyWith(
label: label ?? utils.getFileNameForDisposition(disposition) ?? id,

View File

@@ -66,7 +66,6 @@ class ProfilesSelectorState with _$ProfilesSelectorState {
class NetworkDetectionState with _$NetworkDetectionState {
const factory NetworkDetectionState({
required bool isLoading,
required bool isTesting,
required IpInfo? ipInfo,
}) = _NetworkDetectionState;
}
@@ -88,28 +87,14 @@ class TrayState with _$TrayState {
}
@freezed
class HomeState with _$HomeState {
const factory HomeState({
class NavigationState with _$NavigationState {
const factory NavigationState({
required PageLabel pageLabel,
required List<NavigationItem> navigationItems,
required ViewMode viewMode,
required String? locale,
}) = _HomeState;
}
@freezed
class ProxiesSelectorState with _$ProxiesSelectorState {
const factory ProxiesSelectorState({
required List<String> groupNames,
required String? currentGroupName,
}) = _ProxiesSelectorState;
}
@freezed
class GroupNamesState with _$GroupNamesState {
const factory GroupNamesState({
required List<String> groupNames,
}) = _GroupNamesState;
required int currentIndex,
}) = _NavigationState;
}
@freezed
@@ -127,16 +112,27 @@ class NavigationItemsState with _$NavigationItemsState {
}
@freezed
class ProxiesListSelectorState with _$ProxiesListSelectorState {
const factory ProxiesListSelectorState({
required List<String> groupNames,
class ProxiesListState with _$ProxiesListState {
const factory ProxiesListState({
required List<Group> groups,
required Set<String> currentUnfoldSet,
required ProxiesSortType proxiesSortType,
required ProxyCardType proxyCardType,
required num sortNum,
required int columns,
required String query,
}) = _ProxiesListSelectorState;
}) = _ProxiesListState;
}
@freezed
class ProxiesTabState with _$ProxiesTabState {
const factory ProxiesTabState({
required List<Group> groups,
required String? currentGroupName,
required ProxiesSortType proxiesSortType,
required ProxyCardType proxyCardType,
required num sortNum,
required int columns,
}) = _ProxiesTabState;
}
@freezed

View File

@@ -32,15 +32,14 @@ class AppBarState with _$AppBarState {
class AppBarSearchState with _$AppBarSearchState {
const factory AppBarSearchState({
required Function(String) onSearch,
@Default(false) bool isSearch,
@Default(null) String? query,
}) = _AppBarSearchState;
}
@freezed
class AppBarEditState with _$AppBarEditState {
const factory AppBarEditState({
@Default(0) editCount,
@Default(false) bool isEdit,
@Default(0) int editCount,
required Function() onExit,
}) = _AppBarEditState;
}

View File

@@ -107,11 +107,11 @@ class _EditorPageState extends ConsumerState<EditorPage> {
);
}
_handleSearch() {
void _handleSearch() {
_findController.findMode();
}
_handleImport() async {
Future<void> _handleImport() async {
final option = await globalState.showCommonDialog<ImportOption>(
child: _ImportOptionsDialog(),
);
@@ -129,8 +129,8 @@ class _EditorPageState extends ConsumerState<EditorPage> {
}
final url = await globalState.showCommonDialog(
child: InputDialog(
title: "导入",
value: "",
title: '导入',
value: '',
labelText: appLocalizations.url,
validator: (value) {
if (value == null || value.isEmpty) {
@@ -292,7 +292,7 @@ class _EditorPageState extends ConsumerState<EditorPage> {
mode: langYaml,
),
if (widget.languages.contains(Language.javaScript))
"javascript": CodeHighlightThemeMode(
'javascript': CodeHighlightThemeMode(
mode: langJavascript,
),
},
@@ -433,7 +433,7 @@ class FindPanel extends StatelessWidget implements PreferredSizeWidget {
return bar;
}
_buildFindInput(BuildContext context, CodeFindValue value) {
Stack _buildFindInput(BuildContext context, CodeFindValue value) {
return Stack(
alignment: Alignment.center,
children: [
@@ -550,7 +550,7 @@ class ContextMenuControllerImpl implements SelectionToolbarController {
OverlayEntry? _overlayEntry;
bool _isFirstRender = true;
_removeOverLayEntry() {
void _removeOverLayEntry() {
_overlayEntry?.remove();
_overlayEntry = null;
_isFirstRender = true;
@@ -689,7 +689,7 @@ class _ImportOptionsDialog extends StatefulWidget {
}
class _ImportOptionsDialogState extends State<_ImportOptionsDialog> {
_handleOnTab(ImportOption value) {
void _handleOnTab(ImportOption value) {
Navigator.of(context).pop(value);
}

View File

@@ -1,12 +1,10 @@
import 'dart:io';
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/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';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
@@ -18,43 +16,99 @@ class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return HomeBackScope(
child: Consumer(
builder: (_, ref, child) {
final state = ref.watch(homeStateProvider);
final viewMode = state.viewMode;
final navigationItems = state.navigationItems;
final pageLabel = state.pageLabel;
final index = navigationItems.lastIndexWhere(
(element) => element.label == pageLabel,
);
final currentIndex = index == -1 ? 0 : index;
final navigationBar = CommonNavigationBar(
viewMode: viewMode,
navigationItems: navigationItems,
currentIndex: currentIndex,
);
final bottomNavigationBar =
viewMode == ViewMode.mobile ? navigationBar : null;
final sideNavigationBar =
viewMode != ViewMode.mobile ? navigationBar : null;
return CommonScaffold(
key: globalState.homeScaffoldKey,
title: Intl.message(
pageLabel.name,
),
sideNavigationBar: sideNavigationBar,
body: child!,
bottomNavigationBar: bottomNavigationBar,
);
},
child: _HomePageView(),
child: Material(
color: context.colorScheme.surface,
child: Consumer(
builder: (context, ref, __) {
final state = ref.watch(navigationStateProvider);
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 = isMobile
? KeepScope(
keep: navigationItem.keep,
child: navigationView,
)
: KeepScope(
keep: navigationItem.keep,
child: Navigator(
onGenerateRoute: (_) {
return CommonRoute(
builder: (_) => navigationView,
);
},
),
);
return view;
});
final currentIndex = state.currentIndex;
final bottomNavigationBar = NavigationBarTheme(
data: _NavigationBarDefaultsM3(context),
child: NavigationBar(
destinations: navigationItems
.map(
(e) => NavigationDestination(
icon: e.icon,
label: Intl.message(e.label.name),
),
)
.toList(),
onDestinationSelected: (index) {
globalState.appController.toPage(
navigationItems[index].label,
);
},
selectedIndex: currentIndex,
),
);
if (isMobile) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: globalState.appState.systemUiOverlayStyle.copyWith(
systemNavigationBarColor:
context.colorScheme.surfaceContainer,
),
child: Column(
children: [
Flexible(
flex: 1,
child: MediaQuery.removePadding(
removeTop: false,
removeBottom: true,
removeLeft: true,
removeRight: true,
context: context,
child: pageView,
),
),
MediaQuery.removePadding(
removeTop: true,
removeBottom: false,
removeLeft: true,
removeRight: true,
context: context,
child: bottomNavigationBar,
),
],
),
);
} else {
return pageView;
}
},
),
),
);
}
}
class _HomePageView extends ConsumerStatefulWidget {
const _HomePageView();
final IndexedWidgetBuilder pageBuilder;
const _HomePageView({
required this.pageBuilder,
});
@override
ConsumerState createState() => _HomePageViewState();
@@ -64,18 +118,17 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
late PageController _pageController;
@override
void initState() {
initState() {
super.initState();
_pageController = PageController(
initialPage: _pageIndex,
keepPage: true,
);
ref.listenManual(currentPageLabelProvider, (prev, next) {
if (prev != next) {
_toPage(next);
}
});
ref.listenManual(currentNavigationsStateProvider, (prev, next) {
ref.listenManual(currentNavigationItemsStateProvider, (prev, next) {
if (prev?.value.length != next.value.length) {
_updatePageController();
}
@@ -83,17 +136,18 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
}
int get _pageIndex {
final navigationItems = ref.read(currentNavigationsStateProvider).value;
final navigationItems = ref.read(currentNavigationItemsStateProvider).value;
return navigationItems.indexWhere(
(item) => item.label == globalState.appState.pageLabel,
);
}
_toPage(PageLabel pageLabel, [bool ignoreAnimateTo = false]) async {
Future<void> _toPage(PageLabel pageLabel,
[bool ignoreAnimateTo = false]) async {
if (!mounted) {
return;
}
final navigationItems = ref.read(currentNavigationsStateProvider).value;
final navigationItems = ref.read(currentNavigationItemsStateProvider).value;
final index = navigationItems.indexWhere((item) => item.label == pageLabel);
if (index == -1) {
return;
@@ -111,7 +165,7 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
}
}
_updatePageController() {
void _updatePageController() {
final pageLabel = globalState.appState.pageLabel;
_toPage(pageLabel, true);
}
@@ -124,138 +178,19 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
@override
Widget build(BuildContext context) {
final navigationItems = ref.watch(currentNavigationsStateProvider).value;
final itemCount = ref.watch(currentNavigationItemsStateProvider
.select((state) => state.value.length));
return PageView.builder(
controller: _pageController,
physics: const NeverScrollableScrollPhysics(),
itemCount: navigationItems.length,
// onPageChanged: (index) {
// debouncer.call(DebounceTag.pageChange, () {
// WidgetsBinding.instance.addPostFrameCallback((_) {
// if (_pageIndex != index) {
// final pageLabel = navigationItems[index].label;
// _toPage(pageLabel, true);
// }
// });
// });
// },
itemBuilder: (_, index) {
final navigationItem = navigationItems[index];
return KeepScope(
keep: navigationItem.keep,
key: Key(navigationItem.label.name),
child: navigationItem.view,
);
itemCount: itemCount,
itemBuilder: (context, index) {
return widget.pageBuilder(context, index);
},
);
}
}
class CommonNavigationBar extends ConsumerWidget {
final ViewMode viewMode;
final List<NavigationItem> navigationItems;
final int currentIndex;
const CommonNavigationBar({
super.key,
required this.viewMode,
required this.navigationItems,
required this.currentIndex,
});
@override
Widget build(BuildContext context, ref) {
if (viewMode == ViewMode.mobile) {
return NavigationBarTheme(
data: _NavigationBarDefaultsM3(context),
child: NavigationBar(
destinations: navigationItems
.map(
(e) => NavigationDestination(
icon: e.icon,
label: Intl.message(e.label.name),
),
)
.toList(),
onDestinationSelected: (index) {
globalState.appController.toPage(navigationItems[index].label);
},
selectedIndex: currentIndex,
),
);
}
final showLabel = ref.watch(appSettingProvider).showLabel;
return Material(
color: context.colorScheme.surfaceContainer,
child: Column(
children: [
Expanded(
child: ScrollConfiguration(
behavior: HiddenBarScrollBehavior(),
child: SingleChildScrollView(
child: IntrinsicHeight(
child: NavigationRail(
backgroundColor: context.colorScheme.surfaceContainer,
selectedIconTheme: IconThemeData(
color: context.colorScheme.onSurfaceVariant,
),
unselectedIconTheme: IconThemeData(
color: context.colorScheme.onSurfaceVariant,
),
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,
),
),
),
),
),
const SizedBox(
height: 16,
),
IconButton(
onPressed: () {
ref.read(appSettingProvider.notifier).updateState(
(state) => state.copyWith(
showLabel: !state.showLabel,
),
);
},
icon: const Icon(Icons.menu),
),
const SizedBox(
height: 16,
),
],
),
);
}
}
class _NavigationBarDefaultsM3 extends NavigationBarThemeData {
_NavigationBarDefaultsM3(this.context)
: super(
@@ -319,7 +254,7 @@ class HomeBackScope extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (Platform.isAndroid) {
if (system.isAndroid) {
return CommonPopScope(
onPop: () async {
final canPop = Navigator.canPop(context);

View File

@@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:math';
import 'package:fl_clash/common/color.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/activate_box.dart';
@@ -29,7 +30,7 @@ class _ScanPageState extends State<ScanPage> with WidgetsBindingObserver {
unawaited(controller.start());
}
_handleBarcode(BarcodeCapture barcodeCapture) {
void _handleBarcode(BarcodeCapture barcodeCapture) {
final barcode = barcodeCapture.barcodes.first;
if (barcode.type == BarcodeType.url) {
Navigator.pop<String>(

View File

@@ -1,9 +1,9 @@
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/system.dart';
import 'package:fl_clash/models/models.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -15,18 +15,18 @@ class App {
Function()? onExit;
App._internal() {
methodChannel = const MethodChannel("app");
methodChannel = const MethodChannel('app');
methodChannel.setMethodCallHandler((call) async {
switch (call.method) {
case "exit":
case 'exit':
if (onExit != null) {
await onExit!();
}
case "getText":
case 'getText':
try {
return Intl.message(call.arguments as String);
} catch (_) {
return "";
return '';
}
default:
throw MissingPluginException();
@@ -40,12 +40,12 @@ class App {
}
Future<bool?> moveTaskToBack() async {
return await methodChannel.invokeMethod<bool>("moveTaskToBack");
return await methodChannel.invokeMethod<bool>('moveTaskToBack');
}
Future<List<Package>> getPackages() async {
final packagesString =
await methodChannel.invokeMethod<String>("getPackages");
await methodChannel.invokeMethod<String>('getPackages');
return Isolate.run<List<Package>>(() {
final List<dynamic> packagesRaw =
packagesString != null ? json.decode(packagesString) : [];
@@ -55,7 +55,7 @@ class App {
Future<List<String>> getChinaPackageNames() async {
final packageNamesString =
await methodChannel.invokeMethod<String>("getChinaPackageNames");
await methodChannel.invokeMethod<String>('getChinaPackageNames');
return Isolate.run<List<String>>(() {
final List<dynamic> packageNamesRaw =
packageNamesString != null ? json.decode(packageNamesString) : [];
@@ -64,15 +64,15 @@ class App {
}
Future<bool> openFile(String path) async {
return await methodChannel.invokeMethod<bool>("openFile", {
"path": path,
return await methodChannel.invokeMethod<bool>('openFile', {
'path': path,
}) ??
false;
}
Future<ImageProvider?> getPackageIcon(String packageName) async {
final base64 = await methodChannel.invokeMethod<String>("getPackageIcon", {
"packageName": packageName,
final base64 = await methodChannel.invokeMethod<String>('getPackageIcon', {
'packageName': packageName,
});
if (base64 == null) {
return null;
@@ -81,23 +81,23 @@ class App {
}
Future<bool?> tip(String? message) async {
return await methodChannel.invokeMethod<bool>("tip", {
"message": "$message",
return await methodChannel.invokeMethod<bool>('tip', {
'message': '$message',
});
}
Future<bool?> initShortcuts() async {
return await methodChannel.invokeMethod<bool>(
"initShortcuts",
'initShortcuts',
appLocalizations.toggle,
);
}
Future<bool?> updateExcludeFromRecents(bool value) async {
return await methodChannel.invokeMethod<bool>("updateExcludeFromRecents", {
"value": value,
return await methodChannel.invokeMethod<bool>('updateExcludeFromRecents', {
'value': value,
});
}
}
final app = Platform.isAndroid ? App() : null;
final app = system.isAndroid ? App() : null;

View File

@@ -1,7 +1,8 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'package:fl_clash/common/system.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/services.dart';
@@ -13,7 +14,7 @@ class Service {
ReceivePort? receiver;
Service._internal() {
methodChannel = const MethodChannel("service");
methodChannel = const MethodChannel('service');
}
factory Service() {
@@ -22,23 +23,24 @@ class Service {
}
Future<bool?> init() async {
return await methodChannel.invokeMethod<bool>("init");
return await methodChannel.invokeMethod<bool>('init');
}
Future<bool?> destroy() async {
return await methodChannel.invokeMethod<bool>("destroy");
return await methodChannel.invokeMethod<bool>('destroy');
}
Future<bool?> startVpn() async {
final options = await clashLib?.getAndroidVpnOptions();
return await methodChannel.invokeMethod<bool>("startVpn", {
return await methodChannel.invokeMethod<bool>('startVpn', {
'data': json.encode(options),
});
}
Future<bool?> stopVpn() async {
return await methodChannel.invokeMethod<bool>("stopVpn");
return await methodChannel.invokeMethod<bool>('stopVpn');
}
}
Service? get service => Platform.isAndroid && !globalState.isService ? Service() : null;
Service? get service =>
system.isAndroid && !globalState.isService ? Service() : null;

View File

@@ -1,6 +1,6 @@
import 'dart:async';
import 'dart:io';
import 'package:fl_clash/common/system.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
@@ -9,13 +9,10 @@ abstract mixin class TileListener {
void onStop() {}
void onDetached(){
}
void onDetached() {}
}
class Tile {
final MethodChannel _channel = const MethodChannel('tile');
Tile._() {
@@ -29,13 +26,13 @@ class Tile {
Future<void> _methodCallHandler(MethodCall call) async {
for (final TileListener listener in _listeners) {
switch (call.method) {
case "start":
case 'start':
listener.onStart();
break;
case "stop":
case 'stop':
listener.onStop();
break;
case "detached":
case 'detached':
listener.onDetached();
break;
}
@@ -55,4 +52,4 @@ class Tile {
}
}
final tile = Platform.isAndroid ? Tile.instance : null;
final tile = system.isAndroid ? Tile.instance : null;

View File

@@ -17,22 +17,22 @@ class Vpn {
FutureOr<String> Function()? handleGetStartForegroundParams;
Vpn._internal() {
methodChannel = const MethodChannel("vpn");
methodChannel = const MethodChannel('vpn');
methodChannel.setMethodCallHandler((call) async {
switch (call.method) {
case "gc":
case 'gc':
clashCore.requestGc();
case "getStartForegroundParams":
case 'getStartForegroundParams':
if (handleGetStartForegroundParams != null) {
return await handleGetStartForegroundParams!();
}
return "";
case "status":
return '';
case 'status':
return clashLibHandler?.getRunTime() != null;
default:
for (final VpnListener listener in _listeners) {
switch (call.method) {
case "dnsChanged":
case 'dnsChanged':
final dns = call.arguments as String;
listener.onDnsChanged(dns);
}
@@ -49,13 +49,13 @@ class Vpn {
final ObserverList<VpnListener> _listeners = ObserverList<VpnListener>();
Future<bool?> start(AndroidVpnOptions options) async {
return await methodChannel.invokeMethod<bool>("start", {
return await methodChannel.invokeMethod<bool>('start', {
'data': json.encode(options),
});
}
Future<bool?> stop() async {
return await methodChannel.invokeMethod<bool>("stop");
return await methodChannel.invokeMethod<bool>('stop');
}
void addListener(VpnListener listener) {

View File

@@ -2,7 +2,7 @@ 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:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -30,7 +30,7 @@ class Logs extends _$Logs with AutoDisposeNotifierMixin {
return globalState.appState.logs;
}
addLog(Log value) {
void addLog(Log value) {
state = state.copyWith()..add(value);
}
@@ -45,7 +45,7 @@ class Logs extends _$Logs with AutoDisposeNotifierMixin {
@riverpod
class Requests extends _$Requests with AutoDisposeNotifierMixin {
@override
FixedList<Connection> build() {
FixedList<TrackerInfo> build() {
return globalState.appState.requests;
}
@@ -56,7 +56,7 @@ class Requests extends _$Requests with AutoDisposeNotifierMixin {
);
}
addRequest(Connection value) {
void addRequest(TrackerInfo value) {
state = state.copyWith()..add(value);
}
}
@@ -75,7 +75,7 @@ class Providers extends _$Providers with AutoDisposeNotifierMixin {
);
}
setProvider(ExternalProvider? provider) {
void setProvider(ExternalProvider? provider) {
if (provider == null) return;
final index = state.indexWhere((item) => item.name == provider.name);
if (index == -1) return;
@@ -99,9 +99,10 @@ class Packages extends _$Packages with AutoDisposeNotifierMixin {
}
@riverpod
class AppBrightness extends _$AppBrightness with AutoDisposeNotifierMixin {
class SystemBrightness extends _$SystemBrightness
with AutoDisposeNotifierMixin {
@override
Brightness? build() {
Brightness build() {
return globalState.appState.brightness;
}
@@ -112,7 +113,7 @@ class AppBrightness extends _$AppBrightness with AutoDisposeNotifierMixin {
);
}
setState(Brightness? value) {
void setState(Brightness value) {
state = value;
}
}
@@ -131,11 +132,11 @@ class Traffics extends _$Traffics with AutoDisposeNotifierMixin {
);
}
addTraffic(Traffic value) {
void addTraffic(Traffic value) {
state = state.copyWith()..add(value);
}
clear() {
void clear() {
state = state.copyWith()..clear();
}
}
@@ -281,7 +282,7 @@ class SortNum extends _$SortNum with AutoDisposeNotifierMixin {
);
}
add() => state++;
int add() => state++;
}
@riverpod
@@ -298,7 +299,7 @@ class CheckIpNum extends _$CheckIpNum with AutoDisposeNotifierMixin {
);
}
add() => state++;
int add() => state++;
}
@riverpod
@@ -316,6 +317,21 @@ class BackBlock extends _$BackBlock with AutoDisposeNotifierMixin {
}
}
@riverpod
class Loading extends _$Loading with AutoDisposeNotifierMixin {
@override
bool build() {
return globalState.appState.loading;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(
loading: value,
);
}
}
@riverpod
class Version extends _$Version with AutoDisposeNotifierMixin {
@override
@@ -360,7 +376,7 @@ class DelayDataSource extends _$DelayDataSource with AutoDisposeNotifierMixin {
);
}
setDelay(Delay delay) {
void setDelay(Delay delay) {
if (state[delay.url]?[delay.name] != delay.value) {
final DelayMap newDelayMap = Map.from(state);
if (newDelayMap[delay.url] == null) {
@@ -373,16 +389,17 @@ class DelayDataSource extends _$DelayDataSource with AutoDisposeNotifierMixin {
}
@riverpod
class ProxiesQuery extends _$ProxiesQuery with AutoDisposeNotifierMixin {
class SystemUiOverlayStyleState extends _$SystemUiOverlayStyleState
with AutoDisposeNotifierMixin {
@override
String build() {
return globalState.appState.proxiesQuery;
SystemUiOverlayStyle build() {
return globalState.appState.systemUiOverlayStyle;
}
@override
onUpdate(value) {
globalState.appState = globalState.appState.copyWith(
proxiesQuery: value,
systemUiOverlayStyle: value,
);
}
}

View File

@@ -19,7 +19,7 @@ class AppSetting extends _$AppSetting with AutoDisposeNotifierMixin {
);
}
updateState(AppSettingProps Function(AppSettingProps state) builder) {
void updateState(AppSettingProps Function(AppSettingProps state) builder) {
state = builder(state);
}
}
@@ -38,7 +38,7 @@ class WindowSetting extends _$WindowSetting with AutoDisposeNotifierMixin {
);
}
updateState(WindowProps Function(WindowProps state) builder) {
void updateState(WindowProps Function(WindowProps state) builder) {
state = builder(state);
}
}
@@ -57,7 +57,7 @@ class VpnSetting extends _$VpnSetting with AutoDisposeNotifierMixin {
);
}
updateState(VpnProps Function(VpnProps state) builder) {
void updateState(VpnProps Function(VpnProps state) builder) {
state = builder(state);
}
}
@@ -76,7 +76,7 @@ class NetworkSetting extends _$NetworkSetting with AutoDisposeNotifierMixin {
);
}
updateState(NetworkProps Function(NetworkProps state) builder) {
void updateState(NetworkProps Function(NetworkProps state) builder) {
state = builder(state);
}
}
@@ -95,7 +95,7 @@ class ThemeSetting extends _$ThemeSetting with AutoDisposeNotifierMixin {
);
}
updateState(ThemeProps Function(ThemeProps state) builder) {
void updateState(ThemeProps Function(ThemeProps state) builder) {
state = builder(state);
}
}
@@ -126,7 +126,7 @@ class Profiles extends _$Profiles with AutoDisposeNotifierMixin {
}
}
setProfile(Profile profile) {
void setProfile(Profile profile) {
final List<Profile> profilesTemp = List.from(state);
final index =
profilesTemp.indexWhere((element) => element.id == profile.id);
@@ -141,7 +141,8 @@ class Profiles extends _$Profiles with AutoDisposeNotifierMixin {
state = profilesTemp;
}
updateProfile(String profileId, Profile Function(Profile profile) builder) {
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) {
@@ -150,7 +151,7 @@ class Profiles extends _$Profiles with AutoDisposeNotifierMixin {
state = profilesTemp;
}
deleteProfileById(String id) {
void deleteProfileById(String id) {
state = state.where((element) => element.id != id).toList();
}
}
@@ -185,7 +186,7 @@ class AppDAVSetting extends _$AppDAVSetting with AutoDisposeNotifierMixin {
);
}
updateState(DAV? Function(DAV? state) builder) {
void updateState(DAV? Function(DAV? state) builder) {
state = builder(state);
}
}
@@ -235,7 +236,7 @@ class ProxiesStyleSetting extends _$ProxiesStyleSetting
);
}
updateState(ProxiesStyle Function(ProxiesStyle state) builder) {
void updateState(ProxiesStyle Function(ProxiesStyle state) builder) {
state = builder(state);
}
}
@@ -254,7 +255,7 @@ class ScriptState extends _$ScriptState with AutoDisposeNotifierMixin {
);
}
setScript(Script script) {
void setScript(Script script) {
final list = List<Script>.from(state.scripts);
final index = list.indexWhere((item) => item.id == script.id);
if (index != -1) {
@@ -267,13 +268,13 @@ class ScriptState extends _$ScriptState with AutoDisposeNotifierMixin {
);
}
setId(String id) {
void setId(String id) {
state = state.copyWith(
currentId: state.currentId != id ? id : null,
);
}
del(String id) {
void del(String id) {
final list = List<Script>.from(state.scripts);
final index = list.indexWhere((item) => item.label == id);
if (index != -1) {
@@ -286,7 +287,7 @@ class ScriptState extends _$ScriptState with AutoDisposeNotifierMixin {
);
}
isExits(String label) {
bool isExits(String label) {
return state.scripts.indexWhere((item) => item.label == label) != -1;
}
}
@@ -299,7 +300,7 @@ class PatchClashConfig extends _$PatchClashConfig
return globalState.config.patchClashConfig;
}
updateState(ClashConfig? Function(ClashConfig state) builder) {
void updateState(ClashConfig? Function(ClashConfig state) builder) {
final newState = builder(state);
if (newState == null) {
return;

View File

@@ -86,7 +86,7 @@ final realTunEnableProvider =
);
typedef _$RealTunEnable = AutoDisposeNotifier<bool>;
String _$logsHash() => r'56fb8aa9d62a97b026b749d204576a7384084737';
String _$logsHash() => r'0a32e067292d449d61af59a689cb26691f4afe44';
/// See also [Logs].
@ProviderFor(Logs)
@@ -100,12 +100,12 @@ final logsProvider = AutoDisposeNotifierProvider<Logs, FixedList<Log>>.internal(
);
typedef _$Logs = AutoDisposeNotifier<FixedList<Log>>;
String _$requestsHash() => r'51c9dbba18649206b22dd0ba86c58ab986fc0939';
String _$requestsHash() => r'526f2c1da1347fd2e6e3e23aac0335fcfe0cb28a';
/// See also [Requests].
@ProviderFor(Requests)
final requestsProvider =
AutoDisposeNotifierProvider<Requests, FixedList<Connection>>.internal(
AutoDisposeNotifierProvider<Requests, FixedList<TrackerInfo>>.internal(
Requests.new,
name: r'requestsProvider',
debugGetCreateSourceHash:
@@ -114,8 +114,8 @@ final requestsProvider =
allTransitiveDependencies: null,
);
typedef _$Requests = AutoDisposeNotifier<FixedList<Connection>>;
String _$providersHash() => r'69e480ef409837596937d233e45b9995a83b3949';
typedef _$Requests = AutoDisposeNotifier<FixedList<TrackerInfo>>;
String _$providersHash() => r'4292240629a99470b2e72426dde3b9049b9b57e0';
/// See also [Providers].
@ProviderFor(Providers)
@@ -145,23 +145,23 @@ final packagesProvider =
);
typedef _$Packages = AutoDisposeNotifier<List<Package>>;
String _$appBrightnessHash() => r'bc893bacdc2645c985037d3754bad4e651587771';
String _$systemBrightnessHash() => r'46eb2d23b05405723efc29480e8f258bf2d8138b';
/// See also [AppBrightness].
@ProviderFor(AppBrightness)
final appBrightnessProvider =
AutoDisposeNotifierProvider<AppBrightness, Brightness?>.internal(
AppBrightness.new,
name: r'appBrightnessProvider',
/// See also [SystemBrightness].
@ProviderFor(SystemBrightness)
final systemBrightnessProvider =
AutoDisposeNotifierProvider<SystemBrightness, Brightness>.internal(
SystemBrightness.new,
name: r'systemBrightnessProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$appBrightnessHash,
: _$systemBrightnessHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$AppBrightness = AutoDisposeNotifier<Brightness?>;
String _$trafficsHash() => r'c3f33e9be5ae399562a380156280406fdeeb72aa';
typedef _$SystemBrightness = AutoDisposeNotifier<Brightness>;
String _$trafficsHash() => r'8b86eb718fed5776de174c51fd5b231957011fe6';
/// See also [Traffics].
@ProviderFor(Traffics)
@@ -263,7 +263,7 @@ final currentPageLabelProvider =
);
typedef _$CurrentPageLabel = AutoDisposeNotifier<PageLabel>;
String _$sortNumHash() => r'0f85ebbc77124020eaccf988c6ac9d86a7f34d7e';
String _$sortNumHash() => r'b67bee9fdfbb74b484190fbc6e5c3da7d773bed0';
/// See also [SortNum].
@ProviderFor(SortNum)
@@ -277,7 +277,7 @@ final sortNumProvider = AutoDisposeNotifierProvider<SortNum, int>.internal(
);
typedef _$SortNum = AutoDisposeNotifier<int>;
String _$checkIpNumHash() => r'794de8e31e98ee4fde10509dc8f433699bff18b4';
String _$checkIpNumHash() => r'4d8b32ed9c0013c056f90c9d5483f11fa5fddec5';
/// See also [CheckIpNum].
@ProviderFor(CheckIpNum)
@@ -306,6 +306,20 @@ final backBlockProvider = AutoDisposeNotifierProvider<BackBlock, bool>.internal(
);
typedef _$BackBlock = AutoDisposeNotifier<bool>;
String _$loadingHash() => r'a0a09132a78495616785461cdc2a8b412c19b51b';
/// See also [Loading].
@ProviderFor(Loading)
final loadingProvider = AutoDisposeNotifierProvider<Loading, bool>.internal(
Loading.new,
name: r'loadingProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$loadingHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$Loading = AutoDisposeNotifier<bool>;
String _$versionHash() => r'8c0ee019d20df3f112c38ae4dc4abd61148d3809';
/// See also [Version].
@@ -335,7 +349,7 @@ final groupsProvider =
);
typedef _$Groups = AutoDisposeNotifier<List<Group>>;
String _$delayDataSourceHash() => r'9731553fb48dd89840767bf5508547d90562eb55';
String _$delayDataSourceHash() => r'1b94dcfdb9e1eb4c0b7ca69d933f2299d1f94ed5';
/// See also [DelayDataSource].
@ProviderFor(DelayDataSource)
@@ -351,20 +365,22 @@ final delayDataSourceProvider =
);
typedef _$DelayDataSource = AutoDisposeNotifier<DelayMap>;
String _$proxiesQueryHash() => r'9f3907e06534b6882684bec47ca3ba2988297e19';
String _$systemUiOverlayStyleStateHash() =>
r'4420d92227ae617ce685c8943dda64f29f57d5d1';
/// See also [ProxiesQuery].
@ProviderFor(ProxiesQuery)
final proxiesQueryProvider =
AutoDisposeNotifierProvider<ProxiesQuery, String>.internal(
ProxiesQuery.new,
name: r'proxiesQueryProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$proxiesQueryHash,
/// See also [SystemUiOverlayStyleState].
@ProviderFor(SystemUiOverlayStyleState)
final systemUiOverlayStyleStateProvider = AutoDisposeNotifierProvider<
SystemUiOverlayStyleState, SystemUiOverlayStyle>.internal(
SystemUiOverlayStyleState.new,
name: r'systemUiOverlayStyleStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$systemUiOverlayStyleStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$ProxiesQuery = AutoDisposeNotifier<String>;
typedef _$SystemUiOverlayStyleState = AutoDisposeNotifier<SystemUiOverlayStyle>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

View File

@@ -6,7 +6,7 @@ part of '../config.dart';
// RiverpodGenerator
// **************************************************************************
String _$appSettingHash() => r'99236f2cd5498f9af70b43e41faeb361d344f866';
String _$appSettingHash() => r'13a93334e18b97f5d52eb3e05bbc7b0b8a5c453e';
/// See also [AppSetting].
@ProviderFor(AppSetting)
@@ -21,7 +21,7 @@ final appSettingProvider =
);
typedef _$AppSetting = AutoDisposeNotifier<AppSettingProps>;
String _$windowSettingHash() => r'3dbbf3e169023b49e79b2fb983002687ce077e23';
String _$windowSettingHash() => r'9bf31c7e08fab84213f31e249270f9d730bdf711';
/// See also [WindowSetting].
@ProviderFor(WindowSetting)
@@ -37,7 +37,7 @@ final windowSettingProvider =
);
typedef _$WindowSetting = AutoDisposeNotifier<WindowProps>;
String _$vpnSettingHash() => r'e660cc71ed6677f136eb98885680aae66be74881';
String _$vpnSettingHash() => r'3dae8b56504bfb906aca546c5a5389d79d259a5e';
/// See also [VpnSetting].
@ProviderFor(VpnSetting)
@@ -52,7 +52,7 @@ final vpnSettingProvider =
);
typedef _$VpnSetting = AutoDisposeNotifier<VpnProps>;
String _$networkSettingHash() => r'689ce908662dfe64660557153a4244ae1fdf696e';
String _$networkSettingHash() => r'5a30d4cbfaba94cc29ad08dc1771ebb368b4ba14';
/// See also [NetworkSetting].
@ProviderFor(NetworkSetting)
@@ -68,7 +68,7 @@ final networkSettingProvider =
);
typedef _$NetworkSetting = AutoDisposeNotifier<NetworkProps>;
String _$themeSettingHash() => r'ae5eeaad9729627eaa1b3ccf0266c13bf2ce68d4';
String _$themeSettingHash() => r'0b5620b696d73260d94f63cbfb65857acd2000f0';
/// See also [ThemeSetting].
@ProviderFor(ThemeSetting)
@@ -83,7 +83,7 @@ final themeSettingProvider =
);
typedef _$ThemeSetting = AutoDisposeNotifier<ThemeProps>;
String _$profilesHash() => r'a6514c89064e4f42fc31fe7d525088fd26c51016';
String _$profilesHash() => r'3203cc7de88b91fff86b79c75c2cacd8116fffb7';
/// See also [Profiles].
@ProviderFor(Profiles)
@@ -114,7 +114,7 @@ final currentProfileIdProvider =
);
typedef _$CurrentProfileId = AutoDisposeNotifier<String?>;
String _$appDAVSettingHash() => r'20439d1f8cc0843a092766dc1cad68e8e8273dbb';
String _$appDAVSettingHash() => r'4bf293ac0d1fba157f60df920b7ffd5afefaab26';
/// See also [AppDAVSetting].
@ProviderFor(AppDAVSetting)
@@ -162,7 +162,7 @@ final hotKeyActionsProvider =
typedef _$HotKeyActions = AutoDisposeNotifier<List<HotKeyAction>>;
String _$proxiesStyleSettingHash() =>
r'162e7320dff8063e7a2deca5071ef5024f4d3d04';
r'54ebf20a8d4455b2d7a65824f375c4c02a5fba28';
/// See also [ProxiesStyleSetting].
@ProviderFor(ProxiesStyleSetting)
@@ -178,7 +178,7 @@ final proxiesStyleSettingProvider =
);
typedef _$ProxiesStyleSetting = AutoDisposeNotifier<ProxiesStyle>;
String _$scriptStateHash() => r'884581c71fd5afa3c9d34f31625d967cf561cdbe';
String _$scriptStateHash() => r'afbb70d1dd7e577b2377ecd8ab35d0905c1d0e87';
/// See also [ScriptState].
@ProviderFor(ScriptState)
@@ -193,7 +193,7 @@ final scriptStateProvider =
);
typedef _$ScriptState = AutoDisposeNotifier<ScriptProps>;
String _$patchClashConfigHash() => r'52906195d85525d6688aec231da8b38c24364494';
String _$patchClashConfigHash() => r'd9acdd0ace673fc1c1460b63d7a27c5787713c14';
/// See also [PatchClashConfig].
@ProviderFor(PatchClashConfig)

View File

@@ -40,45 +40,46 @@ final currentGroupsStateProvider = AutoDisposeProvider<GroupsState>.internal(
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef CurrentGroupsStateRef = AutoDisposeProviderRef<GroupsState>;
String _$navigationsStateHash() => r'802ae70cc8b7d7f5620b340911da89d74960bfbd';
String _$navigationItemsStateHash() =>
r'1fc37c14d129f9725b0e62fd53f6b25382f51102';
/// See also [navigationsState].
@ProviderFor(navigationsState)
final navigationsStateProvider =
/// See also [navigationItemsState].
@ProviderFor(navigationItemsState)
final navigationItemsStateProvider =
AutoDisposeProvider<NavigationItemsState>.internal(
navigationsState,
name: r'navigationsStateProvider',
navigationItemsState,
name: r'navigationItemsStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$navigationsStateHash,
: _$navigationItemsStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef NavigationsStateRef = AutoDisposeProviderRef<NavigationItemsState>;
String _$currentNavigationsStateHash() =>
r'0eecc0ffef6e000ae45e069d1ad79f4da4a8f082';
typedef NavigationItemsStateRef = AutoDisposeProviderRef<NavigationItemsState>;
String _$currentNavigationItemsStateHash() =>
r'06fbdc194f4527b945695fe3b72b16e0585fa440';
/// See also [currentNavigationsState].
@ProviderFor(currentNavigationsState)
final currentNavigationsStateProvider =
/// See also [currentNavigationItemsState].
@ProviderFor(currentNavigationItemsState)
final currentNavigationItemsStateProvider =
AutoDisposeProvider<NavigationItemsState>.internal(
currentNavigationsState,
name: r'currentNavigationsStateProvider',
currentNavigationItemsState,
name: r'currentNavigationItemsStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$currentNavigationsStateHash,
: _$currentNavigationItemsStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef CurrentNavigationsStateRef
typedef CurrentNavigationItemsStateRef
= AutoDisposeProviderRef<NavigationItemsState>;
String _$coreStateHash() => r'33f01ee9173525862c89522bf73b3174beb63daa';
String _$coreStateHash() => r'3a651f6254443f4f760720cb570195199d014d4b';
/// See also [coreState].
@ProviderFor(coreState)
@@ -126,7 +127,7 @@ final proxyStateProvider = AutoDisposeProvider<ProxyState>.internal(
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef ProxyStateRef = AutoDisposeProviderRef<ProxyState>;
String _$trayStateHash() => r'61c99bbae2cb7ed69dc9ee0f2149510eb6a87df4';
String _$trayStateHash() => r'2237a7dbf8fd66a0618e3d9caf99667857e6fd4d';
/// See also [trayState].
@ProviderFor(trayState)
@@ -158,22 +159,23 @@ final vpnStateProvider = AutoDisposeProvider<VpnState>.internal(
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef VpnStateRef = AutoDisposeProviderRef<VpnState>;
String _$homeStateHash() => r'2829f5d6a8548f8a97253a5437bf5c498b17c9ba';
String _$navigationStateHash() => r'657dc47ecc35ba0807b58cb37e7f1baa14f6c2f9';
/// See also [homeState].
@ProviderFor(homeState)
final homeStateProvider = AutoDisposeProvider<HomeState>.internal(
homeState,
name: r'homeStateProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$homeStateHash,
/// See also [navigationState].
@ProviderFor(navigationState)
final navigationStateProvider = AutoDisposeProvider<NavigationState>.internal(
navigationState,
name: r'navigationStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$navigationStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef HomeStateRef = AutoDisposeProviderRef<HomeState>;
typedef NavigationStateRef = AutoDisposeProviderRef<NavigationState>;
String _$dashboardStateHash() => r'4434206df2753d7df9eb5223c07ddead4ed170fa';
/// See also [dashboardState].
@@ -250,64 +252,7 @@ final profilesSelectorStateProvider =
// ignore: unused_element
typedef ProfilesSelectorStateRef
= AutoDisposeProviderRef<ProfilesSelectorState>;
String _$proxiesListSelectorStateHash() =>
r'5e6bbe1a0cecbdea6c9c62e6ccf314968deac264';
/// See also [proxiesListSelectorState].
@ProviderFor(proxiesListSelectorState)
final proxiesListSelectorStateProvider =
AutoDisposeProvider<ProxiesListSelectorState>.internal(
proxiesListSelectorState,
name: r'proxiesListSelectorStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$proxiesListSelectorStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef ProxiesListSelectorStateRef
= AutoDisposeProviderRef<ProxiesListSelectorState>;
String _$proxiesSelectorStateHash() =>
r'4b96e83c09efd17de6caede484e71c904273c9f8';
/// See also [proxiesSelectorState].
@ProviderFor(proxiesSelectorState)
final proxiesSelectorStateProvider =
AutoDisposeProvider<ProxiesSelectorState>.internal(
proxiesSelectorState,
name: r'proxiesSelectorStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$proxiesSelectorStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef ProxiesSelectorStateRef = AutoDisposeProviderRef<ProxiesSelectorState>;
String _$groupNamesStateHash() => r'd4ba8f2fd72a0db7186ab5d96aa1548bd5a7cdcb';
/// See also [groupNamesState].
@ProviderFor(groupNamesState)
final groupNamesStateProvider = AutoDisposeProvider<GroupNamesState>.internal(
groupNamesState,
name: r'groupNamesStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$groupNamesStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef GroupNamesStateRef = AutoDisposeProviderRef<GroupNamesState>;
String _$proxyGroupSelectorStateHash() =>
r'27d42af16ed77f2d22017edbb34ab60f45566be3';
String _$filterGroupsStateHash() => r'c50aafbb50f98a66e21fc069d22031351d93a0ab';
/// Copied from Dart SDK
class _SystemHash {
@@ -330,6 +275,200 @@ class _SystemHash {
}
}
/// See also [filterGroupsState].
@ProviderFor(filterGroupsState)
const filterGroupsStateProvider = FilterGroupsStateFamily();
/// See also [filterGroupsState].
class FilterGroupsStateFamily extends Family<GroupsState> {
/// See also [filterGroupsState].
const FilterGroupsStateFamily();
/// See also [filterGroupsState].
FilterGroupsStateProvider call(
String query,
) {
return FilterGroupsStateProvider(
query,
);
}
@override
FilterGroupsStateProvider getProviderOverride(
covariant FilterGroupsStateProvider provider,
) {
return call(
provider.query,
);
}
static const Iterable<ProviderOrFamily>? _dependencies = null;
@override
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
@override
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
_allTransitiveDependencies;
@override
String? get name => r'filterGroupsStateProvider';
}
/// See also [filterGroupsState].
class FilterGroupsStateProvider extends AutoDisposeProvider<GroupsState> {
/// See also [filterGroupsState].
FilterGroupsStateProvider(
String query,
) : this._internal(
(ref) => filterGroupsState(
ref as FilterGroupsStateRef,
query,
),
from: filterGroupsStateProvider,
name: r'filterGroupsStateProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$filterGroupsStateHash,
dependencies: FilterGroupsStateFamily._dependencies,
allTransitiveDependencies:
FilterGroupsStateFamily._allTransitiveDependencies,
query: query,
);
FilterGroupsStateProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.query,
}) : super.internal();
final String query;
@override
Override overrideWith(
GroupsState Function(FilterGroupsStateRef provider) create,
) {
return ProviderOverride(
origin: this,
override: FilterGroupsStateProvider._internal(
(ref) => create(ref as FilterGroupsStateRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
query: query,
),
);
}
@override
AutoDisposeProviderElement<GroupsState> createElement() {
return _FilterGroupsStateProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is FilterGroupsStateProvider && other.query == query;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, query.hashCode);
return _SystemHash.finish(hash);
}
}
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
mixin FilterGroupsStateRef on AutoDisposeProviderRef<GroupsState> {
/// The parameter `query` of this provider.
String get query;
}
class _FilterGroupsStateProviderElement
extends AutoDisposeProviderElement<GroupsState> with FilterGroupsStateRef {
_FilterGroupsStateProviderElement(super.provider);
@override
String get query => (origin as FilterGroupsStateProvider).query;
}
String _$proxiesListStateHash() => r'68f712bdbed5be9f9ba7709ec7c861e1d321f8fc';
/// See also [proxiesListState].
@ProviderFor(proxiesListState)
final proxiesListStateProvider = AutoDisposeProvider<ProxiesListState>.internal(
proxiesListState,
name: r'proxiesListStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$proxiesListStateHash,
dependencies: <ProviderOrFamily>[queryProvider],
allTransitiveDependencies: <ProviderOrFamily>{
queryProvider,
...?queryProvider.allTransitiveDependencies
},
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef ProxiesListStateRef = AutoDisposeProviderRef<ProxiesListState>;
String _$proxiesTabStateHash() => r'4b6d355c2892208f67bc843ead7687a5816c18e3';
/// See also [proxiesTabState].
@ProviderFor(proxiesTabState)
final proxiesTabStateProvider = AutoDisposeProvider<ProxiesTabState>.internal(
proxiesTabState,
name: r'proxiesTabStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$proxiesTabStateHash,
dependencies: <ProviderOrFamily>[queryProvider],
allTransitiveDependencies: <ProviderOrFamily>{
queryProvider,
...?queryProvider.allTransitiveDependencies
},
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef ProxiesTabStateRef = AutoDisposeProviderRef<ProxiesTabState>;
String _$proxiesTabControllerStateHash() =>
r'696c680f6aebe856752c31ce3d961753aaad75ca';
/// See also [proxiesTabControllerState].
@ProviderFor(proxiesTabControllerState)
final proxiesTabControllerStateProvider =
AutoDisposeProvider<VM2<List<String>, String?>>.internal(
proxiesTabControllerState,
name: r'proxiesTabControllerStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$proxiesTabControllerStateHash,
dependencies: <ProviderOrFamily>[proxiesTabStateProvider],
allTransitiveDependencies: <ProviderOrFamily>{
proxiesTabStateProvider,
...?proxiesTabStateProvider.allTransitiveDependencies
},
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef ProxiesTabControllerStateRef
= AutoDisposeProviderRef<VM2<List<String>, String?>>;
String _$proxyGroupSelectorStateHash() =>
r'c2a059873a38907071a2664409bacfe21b7d6c3c';
/// See also [proxyGroupSelectorState].
@ProviderFor(proxyGroupSelectorState)
const proxyGroupSelectorStateProvider = ProxyGroupSelectorStateFamily();
@@ -342,9 +481,11 @@ class ProxyGroupSelectorStateFamily extends Family<ProxyGroupSelectorState> {
/// See also [proxyGroupSelectorState].
ProxyGroupSelectorStateProvider call(
String groupName,
String query,
) {
return ProxyGroupSelectorStateProvider(
groupName,
query,
);
}
@@ -354,6 +495,7 @@ class ProxyGroupSelectorStateFamily extends Family<ProxyGroupSelectorState> {
) {
return call(
provider.groupName,
provider.query,
);
}
@@ -378,10 +520,12 @@ class ProxyGroupSelectorStateProvider
/// See also [proxyGroupSelectorState].
ProxyGroupSelectorStateProvider(
String groupName,
String query,
) : this._internal(
(ref) => proxyGroupSelectorState(
ref as ProxyGroupSelectorStateRef,
groupName,
query,
),
from: proxyGroupSelectorStateProvider,
name: r'proxyGroupSelectorStateProvider',
@@ -393,6 +537,7 @@ class ProxyGroupSelectorStateProvider
allTransitiveDependencies:
ProxyGroupSelectorStateFamily._allTransitiveDependencies,
groupName: groupName,
query: query,
);
ProxyGroupSelectorStateProvider._internal(
@@ -403,9 +548,11 @@ class ProxyGroupSelectorStateProvider
required super.debugGetCreateSourceHash,
required super.from,
required this.groupName,
required this.query,
}) : super.internal();
final String groupName;
final String query;
@override
Override overrideWith(
@@ -422,6 +569,7 @@ class ProxyGroupSelectorStateProvider
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
groupName: groupName,
query: query,
),
);
}
@@ -434,13 +582,15 @@ class ProxyGroupSelectorStateProvider
@override
bool operator ==(Object other) {
return other is ProxyGroupSelectorStateProvider &&
other.groupName == groupName;
other.groupName == groupName &&
other.query == query;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, groupName.hashCode);
hash = _SystemHash.combine(hash, query.hashCode);
return _SystemHash.finish(hash);
}
@@ -452,6 +602,9 @@ mixin ProxyGroupSelectorStateRef
on AutoDisposeProviderRef<ProxyGroupSelectorState> {
/// The parameter `groupName` of this provider.
String get groupName;
/// The parameter `query` of this provider.
String get query;
}
class _ProxyGroupSelectorStateProviderElement
@@ -461,6 +614,8 @@ class _ProxyGroupSelectorStateProviderElement
@override
String get groupName => (origin as ProxyGroupSelectorStateProvider).groupName;
@override
String get query => (origin as ProxyGroupSelectorStateProvider).query;
}
String _$packageListSelectorStateHash() =>
@@ -484,7 +639,7 @@ final packageListSelectorStateProvider =
typedef PackageListSelectorStateRef
= AutoDisposeProviderRef<PackageListSelectorState>;
String _$moreToolsSelectorStateHash() =>
r'd27e3eceec2422ad6b6231cf52b892e63c67e365';
r'6329d92652135e2af009dddeac590b4369d2fa04';
/// See also [moreToolsSelectorState].
@ProviderFor(moreToolsSelectorState)
@@ -1992,6 +2147,23 @@ final needSetupProvider =
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef NeedSetupRef = AutoDisposeProviderRef<VM3<String?, String?, Dns?>>;
String _$currentBrightnessHash() => r'ab56c47af4fcae773c8f9f81c91800c1e1890b70';
/// See also [currentBrightness].
@ProviderFor(currentBrightness)
final currentBrightnessProvider = AutoDisposeProvider<Brightness>.internal(
currentBrightness,
name: r'currentBrightnessProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$currentBrightnessHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef CurrentBrightnessRef = AutoDisposeProviderRef<Brightness>;
String _$autoSetSystemDnsStateHash() =>
r'2e0976e079100325b1ca797285df48a94c2c066c';
@@ -2012,7 +2184,7 @@ final autoSetSystemDnsStateProvider =
// ignore: unused_element
typedef AutoSetSystemDnsStateRef = AutoDisposeProviderRef<VM2<bool, bool>>;
String _$profileOverrideStateHash() =>
r'fa26570a355ab39e27b1f93d1d2f358717065592';
r'0a1657ff3b4657fcc481a4cdd1deda5b353bf845';
/// See also [ProfileOverrideState].
@ProviderFor(ProfileOverrideState)
@@ -2028,5 +2200,19 @@ final profileOverrideStateProvider = AutoDisposeNotifierProvider<
);
typedef _$ProfileOverrideState = AutoDisposeNotifier<ProfileOverrideStateModel>;
String _$queryHash() => r'e99b2a2439872f88f09fee8d63f0cc7fb4852186';
/// See also [Query].
@ProviderFor(Query)
final queryProvider = AutoDisposeNotifierProvider<Query, String>.internal(
Query.new,
name: r'queryProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$queryHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$Query = AutoDisposeNotifier<String>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

View File

@@ -62,22 +62,26 @@ GroupsState currentGroupsState(Ref ref) {
}
@riverpod
NavigationItemsState navigationsState(Ref ref) {
NavigationItemsState navigationItemsState(Ref ref) {
final openLogs = ref.watch(appSettingProvider).openLogs;
final hasProxies = ref.watch(
currentGroupsStateProvider.select((state) => state.value.isNotEmpty));
final hasProfiles =
ref.watch(profilesProvider.select((state) => state.isNotEmpty));
final hasProxies = ref.watch(currentGroupsStateProvider.select(
(state) => state.value.isNotEmpty,
));
final isInit = ref.watch(initProvider);
return NavigationItemsState(
value: navigation.getItems(
openLogs: openLogs,
hasProxies: hasProxies,
hasProxies: !isInit ? hasProfiles : hasProxies,
),
);
}
@riverpod
NavigationItemsState currentNavigationsState(Ref ref) {
NavigationItemsState currentNavigationItemsState(Ref ref) {
final viewWidth = ref.watch(viewWidthProvider);
final navigationItemsState = ref.watch(navigationsStateProvider);
final navigationItemsState = ref.watch(navigationItemsStateProvider);
final navigationItemMode = switch (viewWidth <= maxMobileWidth) {
true => NavigationItemMode.mobile,
false => NavigationItemMode.desktop,
@@ -99,7 +103,7 @@ CoreState coreState(Ref ref) {
return CoreState(
vpnProps: vpnProps,
onlyStatisticsProxy: onlyStatisticsProxy,
currentProfileName: currentProfile?.label ?? currentProfile?.id ?? "",
currentProfileName: currentProfile?.label ?? currentProfile?.id ?? '',
);
}
@@ -164,7 +168,7 @@ TrayState trayState(Ref ref) {
)
.value;
final brightness = ref.watch(
appBrightnessProvider,
systemBrightnessProvider,
);
final selectedMap = ref.watch(selectedMapProvider);
@@ -197,16 +201,21 @@ VpnState vpnState(Ref ref) {
}
@riverpod
HomeState homeState(Ref ref) {
NavigationState navigationState(Ref ref) {
final pageLabel = ref.watch(currentPageLabelProvider);
final navigationItems = ref.watch(currentNavigationsStateProvider).value;
final navigationItems = ref.watch(currentNavigationItemsStateProvider).value;
final viewMode = ref.watch(viewModeProvider);
final locale = ref.watch(appSettingProvider).locale;
return HomeState(
final index = navigationItems.lastIndexWhere(
(element) => element.label == pageLabel,
);
final currentIndex = index == -1 ? 0 : index;
return NavigationState(
pageLabel: pageLabel,
navigationItems: navigationItems,
viewMode: viewMode,
locale: locale,
currentIndex: currentIndex,
);
}
@@ -265,63 +274,99 @@ ProfilesSelectorState profilesSelectorState(Ref ref) {
}
@riverpod
ProxiesListSelectorState proxiesListSelectorState(Ref ref) {
final groupNames = ref.watch(currentGroupsStateProvider.select((state) {
return state.value.map((e) => e.name).toList();
}));
GroupsState filterGroupsState(Ref ref, String query) {
final currentGroups = ref.watch(currentGroupsStateProvider);
if (query.isEmpty) {
return currentGroups;
}
final lowQuery = query.toLowerCase();
final groups = currentGroups.value
.map(
(group) {
return group.copyWith(
all: group.all
.where((proxy) => proxy.name.toLowerCase().contains(lowQuery))
.toList());
},
)
.where(
(group) => group.all.isNotEmpty,
)
.toList();
return GroupsState(value: groups);
}
@Riverpod(dependencies: [Query])
ProxiesListState proxiesListState(Ref ref) {
final query = ref.watch(queryProvider);
final currentGroups = ref.watch(filterGroupsStateProvider(query));
final currentUnfoldSet = ref.watch(unfoldSetProvider);
final proxiesStyle = ref.watch(proxiesStyleSettingProvider);
final sortNum = ref.watch(sortNumProvider);
final columns = ref.watch(getProxiesColumnsProvider);
final query = ref.watch(
proxiesQueryProvider.select(
(state) => state.toLowerCase(),
final vm2 = ref.watch(
proxiesStyleSettingProvider.select(
(state) => VM2(
a: state.sortType,
b: state.cardType,
),
),
);
return ProxiesListSelectorState(
groupNames: groupNames,
final sortNum = ref.watch(sortNumProvider);
final columns = ref.watch(getProxiesColumnsProvider);
return ProxiesListState(
groups: currentGroups.value,
currentUnfoldSet: currentUnfoldSet,
proxiesSortType: proxiesStyle.sortType,
proxyCardType: proxiesStyle.cardType,
proxiesSortType: vm2.a,
proxyCardType: vm2.b,
sortNum: sortNum,
columns: columns,
query: query,
);
}
@riverpod
ProxiesSelectorState proxiesSelectorState(Ref ref) {
final groupNames = ref.watch(
currentGroupsStateProvider.select(
(state) {
return state.value.map((e) => e.name).toList();
},
),
);
@Riverpod(dependencies: [Query])
ProxiesTabState proxiesTabState(Ref ref) {
final query = ref.watch(queryProvider);
final currentGroups = ref.watch(filterGroupsStateProvider(query));
final currentGroupName = ref.watch(currentProfileProvider.select(
(state) => state?.currentGroupName,
));
return ProxiesSelectorState(
groupNames: groupNames,
final vm2 = ref.watch(
proxiesStyleSettingProvider.select(
(state) => VM2(
a: state.sortType,
b: state.cardType,
),
),
);
final sortNum = ref.watch(sortNumProvider);
final columns = ref.watch(getProxiesColumnsProvider);
return ProxiesTabState(
groups: currentGroups.value,
currentGroupName: currentGroupName,
proxiesSortType: vm2.a,
proxyCardType: vm2.b,
sortNum: sortNum,
columns: columns,
);
}
@riverpod
GroupNamesState groupNamesState(Ref ref) {
return GroupNamesState(
groupNames: ref.watch(
currentGroupsStateProvider.select(
(state) {
return state.value.map((e) => e.name).toList();
},
@Riverpod(dependencies: [proxiesTabState])
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,
),
),
);
}
@riverpod
ProxyGroupSelectorState proxyGroupSelectorState(Ref ref, String groupName) {
ProxyGroupSelectorState proxyGroupSelectorState(
Ref ref,
String groupName,
String query,
) {
final proxiesStyle = ref.watch(
proxiesStyleSettingProvider,
);
@@ -332,10 +377,9 @@ ProxyGroupSelectorState proxyGroupSelectorState(Ref ref, String groupName) {
);
final sortNum = ref.watch(sortNumProvider);
final columns = ref.watch(getProxiesColumnsProvider);
final query =
ref.watch(proxiesQueryProvider.select((state) => state.toLowerCase()));
final lowQuery = query.toLowerCase();
final proxies = group?.all.where((item) {
return item.name.toLowerCase().contains(query);
return item.name.toLowerCase().contains(lowQuery);
}).toList() ??
[];
return ProxyGroupSelectorState(
@@ -363,7 +407,8 @@ PackageListSelectorState packageListSelectorState(Ref ref) {
@riverpod
MoreToolsSelectorState moreToolsSelectorState(Ref ref) {
final viewMode = ref.watch(viewModeProvider);
final navigationItems = ref.watch(navigationsStateProvider.select((state) {
final navigationItems =
ref.watch(navigationItemsStateProvider.select((state) {
return state.value.where((element) {
final isMore = element.modes.contains(NavigationItemMode.more);
final isDesktop = element.modes.contains(NavigationItemMode.desktop);
@@ -546,7 +591,7 @@ class ProfileOverrideState extends _$ProfileOverrideState {
);
}
updateState(
void updateState(
ProfileOverrideStateModel? Function(ProfileOverrideStateModel state)
builder,
) {
@@ -646,6 +691,18 @@ VM3<String?, String?, Dns?> needSetup(Ref ref) {
);
}
@riverpod
Brightness currentBrightness(Ref ref) {
final themeMode =
ref.watch(themeSettingProvider.select((state) => state.themeMode));
final systemBrightness = ref.watch(systemBrightnessProvider);
return switch (themeMode) {
ThemeMode.system => systemBrightness,
ThemeMode.light => Brightness.light,
ThemeMode.dark => Brightness.dark,
};
}
@riverpod
VM2<bool, bool> autoSetSystemDnsState(Ref ref) {
final isStart = ref.watch(runTimeProvider.select((state) => state != null));
@@ -660,3 +717,9 @@ VM2<bool, bool> autoSetSystemDnsState(Ref ref) {
b: autoSetSystemDns,
);
}
@riverpod
class Query extends _$Query with AutoDisposeNotifierMixin {
@override
String build() => '';
}

View File

@@ -11,8 +11,8 @@ 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/widgets/dialog.dart';
import 'package:fl_clash/widgets/scaffold.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';
@@ -26,8 +26,10 @@ typedef UpdateTasks = List<FutureOr Function()>;
class GlobalState {
static GlobalState? _instance;
Map<CacheTag, double> cacheScrollPosition = {};
Map<CacheTag, FixedMap<String, double>> cacheHeightMap = {};
Map<CacheTag, FixedMap<String, double>> computeHeightMapCache = {};
// Map<CacheTag, double> computeScrollPositionCache = {};
// final Map<String, double> scrollPositionCache = {};
bool isService = false;
Timer? timer;
Timer? groupsUpdateTimer;
@@ -45,7 +47,8 @@ class GlobalState {
UpdateTasks tasks = [];
final navigatorKey = GlobalKey<NavigatorState>();
AppController? _appController;
GlobalKey<CommonScaffoldState> homeScaffoldKey = GlobalKey();
// GlobalKey<CommonScaffoldState> homeScaffoldKey = GlobalKey();
bool isInit = false;
bool get isStart => startTime != null && startTime!.isBeforeNow;
@@ -64,22 +67,24 @@ class GlobalState {
return _instance!;
}
initApp(int version) async {
coreSHA256 = const String.fromEnvironment("CORE_SHA256");
isPre = const String.fromEnvironment("APP_ENV") != 'stable';
Future<void> initApp(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();
}
_initDynamicColor() async {
Future<void> _initDynamicColor() async {
try {
corePalette = await DynamicColorPlugin.getCorePalette();
accentColor = await DynamicColorPlugin.getAccentColor() ??
@@ -87,7 +92,7 @@ class GlobalState {
} catch (_) {}
}
init() async {
Future<void> init() async {
packageInfo = await PackageInfo.fromPlatform();
config = await preferences.getConfig() ??
Config(
@@ -102,7 +107,7 @@ class GlobalState {
String get ua => config.patchClashConfig.globalUa ?? packageInfo.ua;
startUpdateTasks([UpdateTasks? tasks]) async {
Future<void> startUpdateTasks([UpdateTasks? tasks]) async {
if (timer != null && timer!.isActive == true) return;
if (tasks != null) {
this.tasks = tasks;
@@ -113,20 +118,20 @@ class GlobalState {
});
}
executorUpdateTask() async {
Future<void> executorUpdateTask() async {
for (final task in tasks) {
await task();
}
timer = null;
}
stopUpdateTasks() {
void stopUpdateTasks() {
if (timer == null || timer?.isActive == false) return;
timer?.cancel();
timer = null;
}
handleStart([UpdateTasks? tasks]) async {
Future<void> handleStart([UpdateTasks? tasks]) async {
startTime ??= DateTime.now();
await clashCore.startListener();
await service?.startVpn();
@@ -227,38 +232,14 @@ class GlobalState {
);
}
Future<T?> safeRun<T>(
FutureOr<T> Function() futureFunction, {
String? title,
bool silence = true,
}) async {
try {
final res = await futureFunction();
return res;
} catch (e) {
commonPrint.log("$e");
if (silence) {
showNotifier(e.toString());
} else {
showMessage(
title: title ?? appLocalizations.tip,
message: TextSpan(
text: e.toString(),
),
);
}
return null;
}
}
showNotifier(String text) {
void showNotifier(String text) {
if (text.isEmpty) {
return;
}
navigatorKey.currentContext?.showNotifier(text);
}
openUrl(String url) async {
Future<void> openUrl(String url) async {
final res = await showMessage(
message: TextSpan(text: url),
title: appLocalizations.externalLink,
@@ -286,7 +267,7 @@ class GlobalState {
return CoreState(
vpnProps: config.vpnProps,
onlyStatisticsProxy: config.appSetting.onlyStatisticsProxy,
currentProfileName: currentProfile?.label ?? currentProfile?.id ?? "",
currentProfileName: currentProfile?.label ?? currentProfile?.id ?? '',
bypassDomain: config.networkProps.bypassDomain,
);
}
@@ -318,112 +299,112 @@ class GlobalState {
final realPatchConfig = patchConfig.copyWith(
tun: patchConfig.tun.getRealTun(config.networkProps.routeMode),
);
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['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() ?? [];
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['profile'] == null) {
rawConfig['profile'] = {};
}
if (rawConfig["proxy-providers"] != null) {
final proxyProviders = rawConfig["proxy-providers"] as Map;
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") {
if (proxyProvider['type'] != 'http') {
continue;
}
if (proxyProvider["url"] != null) {
proxyProvider["path"] = await appPath.getProvidersFilePath(
if (proxyProvider['url'] != null) {
proxyProvider['path'] = await appPath.getProvidersFilePath(
profile.id,
"proxies",
proxyProvider["url"],
'proxies',
proxyProvider['url'],
);
}
}
}
if (rawConfig["rule-providers"] != null) {
final ruleProviders = rawConfig["rule-providers"] as Map;
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") {
if (ruleProvider['type'] != 'http') {
continue;
}
if (ruleProvider["url"] != null) {
ruleProvider["path"] = await appPath.getProvidersFilePath(
if (ruleProvider['url'] != null) {
ruleProvider['path'] = await appPath.getProvidersFilePath(
profile.id,
"rules",
ruleProvider["url"],
'rules',
ruleProvider['url'],
);
}
}
}
rawConfig["profile"]["store-selected"] = false;
rawConfig["geox-url"] = realPatchConfig.geoXUrl.toJson();
rawConfig["global-ua"] = realPatchConfig.globalUa;
if (rawConfig["hosts"] == null) {
rawConfig["hosts"] = {};
rawConfig['profile']['store-selected'] = false;
rawConfig['geox-url'] = realPatchConfig.geoXUrl.toJson();
rawConfig['global-ua'] = realPatchConfig.globalUa;
if (rawConfig['hosts'] == null) {
rawConfig['hosts'] = {};
}
for (final host in realPatchConfig.hosts.entries) {
rawConfig["hosts"][host.key] = host.value.splitByMultipleSeparators;
rawConfig['hosts'][host.key] = host.value.splitByMultipleSeparators;
}
if (rawConfig["dns"] == null) {
rawConfig["dns"] = {};
if (rawConfig['dns'] == null) {
rawConfig['dns'] = {};
}
final isEnableDns = rawConfig["dns"]["enable"] == true;
final isEnableDns = rawConfig['dns']['enable'] == true;
final overrideDns = globalState.config.overrideDns;
if (overrideDns || !isEnableDns) {
final dns = switch (!isEnableDns) {
true => realPatchConfig.dns.copyWith(
nameserver: [...realPatchConfig.dns.nameserver, "system://"]),
nameserver: [...realPatchConfig.dns.nameserver, 'system://']),
false => realPatchConfig.dns,
};
rawConfig["dns"] = dns.toJson();
rawConfig["dns"]["nameserver-policy"] = {};
rawConfig['dns'] = dns.toJson();
rawConfig['dns']['nameserver-policy'] = {};
for (final entry in dns.nameserverPolicy.entries) {
rawConfig["dns"]["nameserver-policy"][entry.key] =
rawConfig['dns']['nameserver-policy'][entry.key] =
entry.value.splitByMultipleSeparators;
}
}
var rules = [];
if (rawConfig["rules"] != null) {
rules = rawConfig["rules"];
if (rawConfig['rules'] != null) {
rules = rawConfig['rules'];
}
rawConfig.remove("rules");
rawConfig.remove('rules');
final overrideData = profile.overrideData;
if (overrideData.enable && config.scriptProps.currentScript == null) {
@@ -433,7 +414,7 @@ class GlobalState {
rules = [...overrideData.runningRule, ...rules];
}
}
rawConfig["rule"] = rules;
rawConfig['rule'] = rules;
return rawConfig;
}
@@ -442,8 +423,8 @@ class GlobalState {
true => clashLibHandler!.getConfig(profileId),
false => clashCore.getConfig(profileId),
};
configMap["rules"] = configMap["rule"];
configMap.remove("rule");
configMap['rules'] = configMap['rule'];
configMap.remove('rule');
return configMap;
}
@@ -454,15 +435,15 @@ class GlobalState {
if (currentScript == null) {
return config;
}
if (config["proxy-providers"] == null) {
config["proxy-providers"] = {};
if (config['proxy-providers'] == null) {
config['proxy-providers'] = {};
}
final configJs = json.encode(config);
final runtime = getJavascriptRuntime();
final res = await runtime.evaluateAsync("""
final res = await runtime.evaluateAsync('''
${currentScript.content}
main($configJs)
""");
''');
if (res.isError) {
throw res.stringResult;
}
@@ -484,7 +465,6 @@ class DetectionState {
final state = ValueNotifier<NetworkDetectionState>(
const NetworkDetectionState(
isTesting: false,
isLoading: true,
ipInfo: null,
),
@@ -497,7 +477,7 @@ class DetectionState {
return _instance!;
}
startCheck() {
void startCheck() {
debouncer.call(
FunctionTag.checkIp,
_checkIp,
@@ -507,7 +487,13 @@ class DetectionState {
);
}
_checkIp() async {
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;
@@ -528,9 +514,6 @@ class DetectionState {
cancelToken = null;
}
cancelToken = CancelToken();
state.value = state.value.copyWith(
isTesting: true,
);
final res = await request.checkIp(cancelToken: cancelToken);
if (res.isError) {
state.value = state.value.copyWith(
@@ -540,9 +523,6 @@ class DetectionState {
return;
}
final ipInfo = res.data;
state.value = state.value.copyWith(
isTesting: false,
);
if (ipInfo != null) {
state.value = state.value.copyWith(
isLoading: false,
@@ -559,7 +539,7 @@ class DetectionState {
});
}
_clearSetTimeoutTimer() {
void _clearSetTimeoutTimer() {
if (_setTimeoutTimer != null) {
_setTimeoutTimer?.cancel();
_setTimeoutTimer = null;

View File

@@ -23,12 +23,13 @@ class Contributor {
class AboutView extends StatelessWidget {
const AboutView({super.key});
_checkUpdate(BuildContext context) async {
Future<void> _checkUpdate(BuildContext context) async {
final commonScaffoldState = context.commonScaffoldState;
if (commonScaffoldState?.mounted != true) return;
final data = await commonScaffoldState?.loadingRun<Map<String, dynamic>?>(
final data = await globalState.appController.safeRun<Map<String, dynamic>?>(
request.checkForUpdate,
title: appLocalizations.checkUpdate,
needLoading: true,
);
globalState.appController.checkUpdateResultHandle(
data: data,
@@ -48,10 +49,10 @@ class AboutView extends StatelessWidget {
},
),
ListItem(
title: const Text("Telegram"),
title: const Text('Telegram'),
onTap: () {
globalState.openUrl(
"https://t.me/FlClash",
'https://t.me/FlClash',
);
},
trailing: const Icon(Icons.launch),
@@ -60,7 +61,7 @@ class AboutView extends StatelessWidget {
title: Text(appLocalizations.project),
onTap: () {
globalState.openUrl(
"https://github.com/$repository",
'https://github.com/$repository',
);
},
trailing: const Icon(Icons.launch),
@@ -69,7 +70,7 @@ class AboutView extends StatelessWidget {
title: Text(appLocalizations.core),
onTap: () {
globalState.openUrl(
"https://github.com/chen08209/Clash.Meta/tree/FlClash",
'https://github.com/chen08209/Clash.Meta/tree/FlClash',
);
},
trailing: const Icon(Icons.launch),
@@ -81,14 +82,14 @@ class AboutView extends StatelessWidget {
List<Widget> _buildContributorsSection() {
const contributors = [
Contributor(
avatar: "assets/images/avatars/june2.jpg",
name: "June2",
link: "https://t.me/Jibadong",
avatar: 'assets/images/avatars/june2.jpg',
name: 'June2',
link: 'https://t.me/Jibadong',
),
Contributor(
avatar: "assets/images/avatars/arue.jpg",
name: "Arue",
link: "https://t.me/xrcm6868",
avatar: 'assets/images/avatars/arue.jpg',
name: 'Arue',
link: 'https://t.me/xrcm6868',
),
];
return generateSection(

View File

@@ -39,7 +39,7 @@ class _AccessViewState extends ConsumerState<AccessView> {
super.dispose();
}
_updateInitList() {
void _updateInitList() {
acceptList = globalState.config.vpnProps.accessControl.acceptList;
rejectList = globalState.config.vpnProps.accessControl.rejectList;
}
@@ -106,7 +106,7 @@ class _AccessViewState extends ConsumerState<AccessView> {
);
}
_intelligentSelected() async {
Future<void> _intelligentSelected() async {
final packageNames = ref.read(
packageListSelectorStateProvider.select(
(state) => state.list.map((item) => item.packageName),
@@ -115,7 +115,8 @@ class _AccessViewState extends ConsumerState<AccessView> {
final commonScaffoldState = context.commonScaffoldState;
if (commonScaffoldState?.mounted != true) return;
final selectedPackageNames =
(await commonScaffoldState?.loadingRun<List<String>>(
(await globalState.appController.safeRun<List<String>>(
needLoading: true,
() async {
return await app?.getChinaPackageNames() ?? [];
},
@@ -160,7 +161,7 @@ class _AccessViewState extends ConsumerState<AccessView> {
);
}
_handleSelected(List<String> valueList, Package package, bool? value) {
void _handleSelected(List<String> valueList, Package package, bool? value) {
if (value == true) {
valueList.add(package.packageName);
} else {
@@ -267,7 +268,7 @@ class _AccessViewState extends ConsumerState<AccessView> {
),
Flexible(
child: Text(
"${valueList.length}",
'${valueList.length}',
style: Theme.of(context)
.textTheme
.labelLarge
@@ -459,7 +460,7 @@ class AccessControlSearchDelegate extends SearchDelegate {
);
}
_handleSelected(
void _handleSelected(
WidgetRef ref, List<String> valueList, Package package, bool? value) {
if (value == true) {
valueList.add(package.packageName);
@@ -715,8 +716,8 @@ class _AccessControlPanelState extends ConsumerState<AccessControlPanel> {
);
}
_copyToClipboard() async {
await globalState.safeRun(() {
Future<void> _copyToClipboard() async {
await globalState.appController.safeRun(() {
final data = globalState.config.vpnProps.accessControl.toJson();
Clipboard.setData(
ClipboardData(
@@ -728,8 +729,8 @@ class _AccessControlPanelState extends ConsumerState<AccessControlPanel> {
Navigator.of(context).pop();
}
_pasteToClipboard() async {
await globalState.safeRun(
Future<void> _pasteToClipboard() async {
await globalState.appController.safeRun(
() async {
final data = await Clipboard.getData('text/plain');
final text = data?.text;

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