diff --git a/core/common.go b/core/common.go index 98b9948..e555263 100644 --- a/core/common.go +++ b/core/common.go @@ -17,6 +17,7 @@ import ( "os" "os/exec" "runtime" + "strings" "sync" "syscall" ) @@ -114,6 +115,152 @@ func decorationConfig(profilePath *string, cfg config.RawConfig) *config.RawConf return prof } +func Reduce[T any, U any](s []T, initVal U, f func(U, T) U) U { + for _, v := range s { + initVal = f(initVal, v) + } + return initVal +} + +func Map[T, U any](slice []T, fn func(T) U) []U { + result := make([]U, len(slice)) + for i, v := range slice { + result[i] = fn(v) + } + return result +} + +func replaceFromMap(s string, m map[string]string) string { + for k, v := range m { + s = strings.ReplaceAll(s, k, v) + } + return s +} + +func removeDuplicateFromSlice[T any](slice []T) []T { + result := make([]T, 0) + seen := make(map[any]struct{}) + for _, value := range slice { + if _, ok := seen[value]; !ok { + result = append(result, value) + seen[value] = struct{}{} + } + } + return result +} + +func generateProxyGroupAndRule(proxyGroup *[]map[string]any, rule *[]string) { + var replacements = map[string]string{} + var selectArr []map[string]any + var urlTestArr []map[string]any + var fallbackArr []map[string]any + for _, group := range *proxyGroup { + switch group["type"] { + case "select": + selectArr = append(selectArr, group) + replacements[group["name"].(string)] = "Proxy" + break + case "url-test": + urlTestArr = append(urlTestArr, group) + replacements[group["name"].(string)] = "Auto" + break + case "fallback": + fallbackArr = append(fallbackArr, group) + replacements[group["name"].(string)] = "Fallback" + break + default: + break + } + } + + ProxyProxies := Reduce(selectArr, []string{}, func(res []string, cur map[string]any) []string { + if cur["proxies"] == nil { + return res + } + for _, proxyName := range cur["proxies"].([]interface{}) { + if str, ok := proxyName.(string); ok { + str = replaceFromMap(str, replacements) + if str != "Proxy" { + res = append(res, str) + } + } + } + return res + }) + + ProxyProxies = removeDuplicateFromSlice(ProxyProxies) + + AutoProxies := Reduce(urlTestArr, []string{}, func(res []string, cur map[string]any) []string { + if cur["proxies"] == nil { + return res + } + for _, proxyName := range cur["proxies"].([]interface{}) { + if str, ok := proxyName.(string); ok { + str = replaceFromMap(str, replacements) + if str != "Auto" { + res = append(res, str) + } + } + } + return res + }) + + AutoProxies = removeDuplicateFromSlice(AutoProxies) + + FallbackProxies := Reduce(fallbackArr, []string{}, func(res []string, cur map[string]any) []string { + if cur["proxies"] == nil { + return res + } + for _, proxyName := range cur["proxies"].([]interface{}) { + if str, ok := proxyName.(string); ok { + str = replaceFromMap(str, replacements) + if str != "Fallback" { + res = append(res, str) + } + } + } + return res + }) + + FallbackProxies = removeDuplicateFromSlice(FallbackProxies) + + var computedProxyGroup []map[string]any + + if len(ProxyProxies) > 0 { + computedProxyGroup = append(computedProxyGroup, + map[string]any{ + "name": "Proxy", + "type": "select", + "proxies": ProxyProxies, + }) + } + + if len(AutoProxies) > 0 { + computedProxyGroup = append(computedProxyGroup, + map[string]any{ + "name": "Auto", + "type": "url-test", + "proxies": AutoProxies, + }) + } + + if len(FallbackProxies) > 0 { + computedProxyGroup = append(computedProxyGroup, + map[string]any{ + "name": "Fallback", + "type": "fallback", + "proxies": FallbackProxies, + }) + } + + computedRule := Map(*rule, func(value string) string { + return replaceFromMap(value, replacements) + }) + + *proxyGroup = computedProxyGroup + *rule = computedRule +} + func overwriteConfig(targetConfig *config.RawConfig, patchConfig config.RawConfig) { targetConfig.ExternalController = "" targetConfig.ExternalUI = "" @@ -129,23 +276,19 @@ func overwriteConfig(targetConfig *config.RawConfig, patchConfig config.RawConfi targetConfig.Tun.Device = patchConfig.Tun.Device targetConfig.Tun.DNSHijack = patchConfig.Tun.DNSHijack targetConfig.Tun.Stack = patchConfig.Tun.Stack + targetConfig.GeodataLoader = "standard" targetConfig.Profile.StoreSelected = false if targetConfig.DNS.Enable == false { targetConfig.DNS = patchConfig.DNS - } else { - targetConfig.DNS.UseHosts = patchConfig.DNS.UseHosts - targetConfig.DNS.EnhancedMode = patchConfig.DNS.EnhancedMode - targetConfig.DNS.IPv6 = patchConfig.DNS.IPv6 - targetConfig.DNS.DefaultNameserver = append(patchConfig.DNS.DefaultNameserver, targetConfig.DNS.DefaultNameserver...) - targetConfig.DNS.NameServer = append(patchConfig.DNS.NameServer, targetConfig.DNS.NameServer...) - targetConfig.DNS.FakeIPFilter = append(patchConfig.DNS.FakeIPFilter, targetConfig.DNS.FakeIPFilter...) - targetConfig.DNS.Fallback = append(patchConfig.DNS.Fallback, targetConfig.DNS.Fallback...) - if runtime.GOOS == "android" { - targetConfig.DNS.NameServer = append(targetConfig.DNS.NameServer, "dhcp://"+dns.SystemDNSPlaceholder) - } else if runtime.GOOS == "windows" { - targetConfig.DNS.NameServer = append(targetConfig.DNS.NameServer, dns.SystemDNSPlaceholder) - } } + if runtime.GOOS == "android" { + targetConfig.DNS.NameServer = append(targetConfig.DNS.NameServer, "dhcp://"+dns.SystemDNSPlaceholder) + } else if runtime.GOOS == "windows" { + targetConfig.DNS.NameServer = append(targetConfig.DNS.NameServer, dns.SystemDNSPlaceholder) + } + targetConfig.ProxyProvider = make(map[string]map[string]any) + targetConfig.RuleProvider = make(map[string]map[string]any) + generateProxyGroupAndRule(&targetConfig.ProxyGroup, &targetConfig.Rule) } func patchConfig(general *config.General) { diff --git a/core/dart-bridge/message.go b/core/dart-bridge/message.go index 4b3b8b6..2caa90d 100644 --- a/core/dart-bridge/message.go +++ b/core/dart-bridge/message.go @@ -19,11 +19,11 @@ type Message struct { Data interface{} `json:"data"` } -func (message *Message) toJson() string { +func (message *Message) Json() string { data, _ := json.Marshal(message) return string(data) } func SendMessage(message Message) { - SendToPort(*Port, message.toJson()) + SendToPort(*Port, message.Json()) } diff --git a/core/hub.go b/core/hub.go index 7380b06..97aee20 100644 --- a/core/hub.go +++ b/core/hub.go @@ -96,34 +96,31 @@ func getProxies() *C.char { //export changeProxy func changeProxy(s *C.char) bool { - paramsString := C.GoString(s) - var params = &ChangeProxyParams{} - err := json.Unmarshal([]byte(paramsString), params) - if err != nil { - log.Infoln("Unmarshal ChangeProxyParams %v", err) - return false - } - proxies := tunnel.ProxiesWithProviders() - proxy := proxies[*params.GroupName] - if proxy == nil { - return false - } - log.Infoln("change proxy %s", proxy.Name()) - adapterProxy := proxy.(*adapter.Proxy) - selector, ok := adapterProxy.ProxyAdapter.(*outboundgroup.Selector) - if !ok { - return false - } - if err := selector.Set(*params.ProxyName); err != nil { - return false - } + go func() { + paramsString := C.GoString(s) + var params = &ChangeProxyParams{} + err := json.Unmarshal([]byte(paramsString), params) + if err != nil { + log.Infoln("Unmarshal ChangeProxyParams %v", err) + } + proxies := tunnel.ProxiesWithProviders() + proxy := proxies[*params.GroupName] + if proxy == nil { + return + } + log.Infoln("change proxy %s", proxy.Name()) + adapterProxy := proxy.(*adapter.Proxy) + selector, ok := adapterProxy.ProxyAdapter.(*outboundgroup.Selector) + if !ok { + return + } + if err := selector.Set(*params.ProxyName); err != nil { + return + } + }() return true } -// clearEffect -func clearConfigEffect() { -} - //export getTraffic func getTraffic() *C.char { up, down := statistic.DefaultManager.Now() @@ -140,7 +137,8 @@ func getTraffic() *C.char { } //export asyncTestDelay -func asyncTestDelay(s *C.char) { +func asyncTestDelay(s *C.char, port C.longlong) { + i := int64(port) go func() { paramsString := C.GoString(s) var params = &TestDelayParams{} @@ -148,42 +146,34 @@ func asyncTestDelay(s *C.char) { if err != nil { return } - expectedStatus, err := utils.NewUnsignedRanges[uint16]("") if err != nil { return } - ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*time.Duration(params.Timeout)) defer cancel() - proxies := tunnel.ProxiesWithProviders() proxy := proxies[params.ProxyName] - delayData := &Delay{ Name: params.ProxyName, } - message := bridge.Message{ Type: bridge.Delay, Data: delayData, } - if proxy == nil { delayData.Value = -1 - bridge.SendMessage(message) + bridge.SendToPort(i, message.Json()) return } - delay, err := proxy.URLTest(ctx, constant.DefaultTestURL, expectedStatus) if err != nil || delay == 0 { delayData.Value = -1 - bridge.SendMessage(message) + bridge.SendToPort(i, message.Json()) return } - delayData.Value = int32(delay) - bridge.SendMessage(message) + bridge.SendToPort(i, message.Json()) }() } diff --git a/lib/application.dart b/lib/application.dart index 09d08a6..3ecddc6 100644 --- a/lib/application.dart +++ b/lib/application.dart @@ -27,8 +27,13 @@ runAppWithPreferences( ChangeNotifierProvider( create: (_) => config, ), - ChangeNotifierProvider( + ChangeNotifierProxyProvider2( create: (_) => appState, + update: (_, config, clashConfig, appState) { + appState?.mode = clashConfig.mode; + appState?.currentProxyName = config.currentProxyName; + return appState!; + }, ) ], child: child, diff --git a/lib/clash/core.dart b/lib/clash/core.dart index 581a118..f7038fc 100644 --- a/lib/clash/core.dart +++ b/lib/clash/core.dart @@ -100,9 +100,6 @@ class ClashCore { .map( (name) => proxies[name], ) - .where( - (proxy) => proxy["type"] != GroupType.Selector.value, - ) .toList(); return group; }).toList(); @@ -115,13 +112,38 @@ class ClashCore { return clashFFI.changeProxy(params.toNativeUtf8().cast()) == 1; } - bool delay(String proxyName) { + Future delay(String proxyName) { + final completer = Completer(); + final receiver = ReceivePort(); + receiver.listen((message) { + if (!completer.isCompleted) { + final m = Message.fromJson(json.decode(message)); + final delay = Delay.fromJson(m.data); + completer.complete(delay); + receiver.close(); + } + }); final delayParams = { "proxy-name": proxyName, "timeout": appConstant.httpTimeoutDuration.inMilliseconds, }; - clashFFI.asyncTestDelay(json.encode(delayParams).toNativeUtf8().cast()); - return true; + clashFFI.asyncTestDelay( + json.encode(delayParams).toNativeUtf8().cast(), + receiver.sendPort.nativePort, + ); + Future.delayed(appConstant.httpTimeoutDuration + appConstant.moreDuration, + () { + if (!completer.isCompleted) { + receiver.close(); + completer.complete( + Delay( + name: proxyName, + value: -1, + ), + ); + } + }); + return completer.future; } healthcheck() { diff --git a/lib/clash/generated/clash_ffi.dart b/lib/clash/generated/clash_ffi.dart index 9b64fbb..b723e4d 100644 --- a/lib/clash/generated/clash_ffi.dart +++ b/lib/clash/generated/clash_ffi.dart @@ -960,17 +960,20 @@ class ClashFFI { void asyncTestDelay( ffi.Pointer s, + int port, ) { return _asyncTestDelay( s, + port, ); } - late final _asyncTestDelayPtr = - _lookup)>>( - 'asyncTestDelay'); - late final _asyncTestDelay = - _asyncTestDelayPtr.asFunction)>(); + late final _asyncTestDelayPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer, ffi.LongLong)>>('asyncTestDelay'); + late final _asyncTestDelay = _asyncTestDelayPtr + .asFunction, int)>(); ffi.Pointer getVersionInfo() { return _getVersionInfo(); diff --git a/lib/controller.dart b/lib/controller.dart index 0253c34..4d22dd8 100644 --- a/lib/controller.dart +++ b/lib/controller.dart @@ -172,13 +172,6 @@ class AppController { appState.systemColorSchemes = systemColorSchemes; } - clearCurrentDelay() { - final currentProxyName = - appState.getCurrentProxyName(config.currentProxyName, clashConfig.mode); - if (currentProxyName == null) return; - appState.setDelay(Delay(name: currentProxyName, value: null)); - } - savePreferences() async { await saveConfigPreferences(); await saveClashConfigPreferences(); diff --git a/lib/enum/enum.dart b/lib/enum/enum.dart index 5ee2ce0..dde8d6b 100644 --- a/lib/enum/enum.dart +++ b/lib/enum/enum.dart @@ -2,6 +2,8 @@ enum GroupType { Selector, URLTest, Fallback } +enum GroupName { GLOBAL, Proxy, Auto, Fallback } + extension GroupTypeExtension on GroupType { static List get valueList => GroupType.values .map( diff --git a/lib/fragments/dashboard/network_detection.dart b/lib/fragments/dashboard/network_detection.dart index c8b5f53..8bd6c9d 100644 --- a/lib/fragments/dashboard/network_detection.dart +++ b/lib/fragments/dashboard/network_detection.dart @@ -88,12 +88,8 @@ class _NetworkDetectionState extends State { child: Selector3( selector: (_, appState, config, clashConfig) { - final proxyName = appState.getCurrentProxyName( - config.currentProxyName, - clashConfig.mode, - ); + final proxyName = appState.currentProxyName; return NetworkDetectionSelectorState( - isInit: appState.isInit, currentProxyName: proxyName, delay: appState.getDelay( proxyName, diff --git a/lib/fragments/dashboard/start_button.dart b/lib/fragments/dashboard/start_button.dart index 410ee2e..793b7a9 100644 --- a/lib/fragments/dashboard/start_button.dart +++ b/lib/fragments/dashboard/start_button.dart @@ -1,5 +1,7 @@ +import 'package:fl_clash/clash/clash.dart'; import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/models/models.dart'; +import 'package:fl_clash/state.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -50,9 +52,6 @@ class _StartButtonState extends State updateSystemProxy() async { final appController = context.appController; await appController.updateSystemProxy(isStart); - if (isStart && mounted) { - appController.healthcheck(); - } } @override @@ -66,14 +65,17 @@ class _StartButtonState extends State if (!state.isInit || !state.hasProfile) { return Container(); } - final textWidth = context.appController.measure.computeTextSize( - Text( - Other.getTimeDifference( - DateTime.now(), - ), - style: Theme.of(context).textTheme.titleMedium?.toSoftBold(), - ), - ).width + + final textWidth = context.appController.measure + .computeTextSize( + Text( + Other.getTimeDifference( + DateTime.now(), + ), + style: + Theme.of(context).textTheme.titleMedium?.toSoftBold(), + ), + ) + .width + 16; return AnimatedBuilder( animation: _controller.view, diff --git a/lib/fragments/proxies.dart b/lib/fragments/proxies.dart index e32832d..e791929 100644 --- a/lib/fragments/proxies.dart +++ b/lib/fragments/proxies.dart @@ -1,4 +1,3 @@ -import 'package:fl_clash/clash/clash.dart'; import 'package:flutter/material.dart'; import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; import 'package:provider/provider.dart'; @@ -17,8 +16,6 @@ class ProxiesFragment extends StatefulWidget { class _ProxiesFragmentState extends State with TickerProviderStateMixin { - TabController? _tabController; - _initActions() { WidgetsBinding.instance.addPostFrameCallback((timeStamp) { final commonScaffoldState = @@ -56,95 +53,6 @@ class _ProxiesFragmentState extends State }); } - @override - Widget build(BuildContext context) { - return DelayTestButtonContainer( - child: Selector( - selector: (_, appState) => appState.currentLabel == 'proxies', - builder: (_, isCurrent, child) { - if (isCurrent) { - _initActions(); - } - return child!; - }, - child: Selector3( - selector: (_, appState, config, clashConfig) { - final currentGroups = appState.getCurrentGroups(clashConfig.mode); - final groupNames = currentGroups.map((e) => e.name).toList(); - final currentProxyName = appState.getCurrentGroupNameWithGroups( - currentGroups, - config.currentGroupName, - clashConfig.mode, - ); - final currentIndex = currentGroups - .indexWhere((element) => element.name == currentProxyName); - return ProxiesSelectorState( - currentIndex: currentIndex, - groupNames: groupNames, - ); - }, - shouldRebuild: (prev,next){ - if(prev.groupNames.length != next.groupNames.length){ - _tabController?.dispose(); - _tabController =null; - } - return prev != next; - }, - builder: (_, state, __) { - _tabController ??= TabController( - length: state.groupNames.length, - vsync: this, - initialIndex: state.currentIndex, - ); - return Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TabBar( - controller: _tabController, - padding: const EdgeInsets.symmetric(horizontal: 16), - dividerColor: Colors.transparent, - isScrollable: true, - tabAlignment: TabAlignment.start, - overlayColor: - const MaterialStatePropertyAll(Colors.transparent), - tabs: [ - for (final groupName in state.groupNames) - Tab( - text: groupName, - ), - ], - ), - Expanded( - child: TabBarView( - controller: _tabController, - children: [ - for (final groupName in state.groupNames) - KeepContainer( - child: ProxiesTabView( - groupName: groupName, - ), - ), - ], - ), - ) - ], - ); - }, - ), - ), - ); - } -} - -class ProxiesTabView extends StatelessWidget { - final String groupName; - - const ProxiesTabView({ - super.key, - required this.groupName, - }); - List _sortOfName(List proxies) { return List.of(proxies) ..sort( @@ -175,7 +83,6 @@ class ProxiesTabView extends StatelessWidget { } _getProxies( - BuildContext context, List proxies, ProxiesSortType proxiesSortType, ) { @@ -195,8 +102,7 @@ class ProxiesTabView extends StatelessWidget { 8 * 2; } - _card( - BuildContext context, { + _card({ required void Function() onPressed, required bool isSelected, required Proxy proxy, @@ -238,12 +144,22 @@ class ProxiesTabView extends StatelessWidget { ), SizedBox( height: measure.bodySmallHeight, - child: Text( - proxy.type, - style: context.textTheme.bodySmall?.copyWith( - overflow: TextOverflow.ellipsis, - color: context.textTheme.bodySmall?.color?.toLight(), + child: Selector( + selector: (context, appState) => appState.getDesc( + proxy.type, + proxy.name, ), + builder: (_, desc, __) { + return TooltipText( + text: Text( + desc, + style: context.textTheme.bodySmall?.copyWith( + overflow: TextOverflow.ellipsis, + color: context.textTheme.bodySmall?.color?.toLight(), + ), + ), + ); + }, ), ), const SizedBox( @@ -306,42 +222,14 @@ class ProxiesTabView extends StatelessWidget { itemCount: proxies.length, itemBuilder: (_, index) { final proxy = proxies[index]; - return Selector3( - selector: (_, appState, config, clashConfig) { - final currentGroupName = appState.getCurrentGroupName( - config.currentGroupName, - clashConfig.mode, - ); - final currentProxyName = appState.getCurrentProxyName( - config.currentProxyName, - clashConfig.mode, - ); - final group = appState.getGroupWithName(groupName); - final isSelected = group.type == GroupType.Selector - ? group.name == currentGroupName && - proxy.name == currentProxyName - : group.now == proxy.name; - return ProxiesCardSelectorState( - isSelected: isSelected, - currentGroupName: currentGroupName, - currentProxyName: currentProxyName, - ); - }, - builder: (_, state, __) { + return Selector( + selector: (_, appState) => proxy.name == appState.currentProxyName, + builder: (_, isSelected, __) { return _card( - context, - isSelected: state.isSelected, + isSelected: isSelected, onPressed: () { - final group = - context.appController.appState.getGroupWithName(groupName); - if (group.type == GroupType.Selector) { - final config = context.read(); - config.currentProfile?.groupName = group.name; - config.currentProfile?.proxyName = proxy.name; - config.update(); - context.appController.changeProxy(); - } + context.appController.config.currentProxyName = proxy.name; + context.appController.changeProxy(); }, proxy: proxy, ); @@ -353,52 +241,63 @@ class ProxiesTabView extends StatelessWidget { @override Widget build(BuildContext context) { - return Selector2( - selector: (_, appState, config) { - return ProxiesTabViewSelectorState( - proxiesSortType: config.proxiesSortType, - sortNum: appState.sortNum, - group: appState.getGroupWithName(groupName), - ); - }, - builder: (_, state, __) { - final proxies = _getProxies( - context, - state.group.all, - state.proxiesSortType, - ); - return Align( - alignment: Alignment.topCenter, - child: SlotLayout( - config: { - Breakpoints.small: SlotLayout.from( - key: const Key('proxies_grid_small'), - builder: (_) => _buildGrid( - context, - proxies: proxies, - columns: 2, - ), + return DelayTestButtonContainer( + child: Selector( + selector: (_, appState) => appState.currentLabel == 'proxies', + builder: (_, isCurrent, child) { + if (isCurrent) { + _initActions(); + } + return child!; + }, + child: Selector2( + selector: (_, appState, config) { + return ProxiesSelectorState( + proxiesSortType: config.proxiesSortType, + sortNum: appState.sortNum, + group: appState.currentGroup, + ); + }, + builder: (_, state, __) { + if (state.group == null) return Container(); + final proxies = _getProxies( + state.group!.all, + state.proxiesSortType, + ); + return Align( + alignment: Alignment.topCenter, + child: SlotLayout( + config: { + Breakpoints.small: SlotLayout.from( + key: const Key('proxies_grid_small'), + builder: (_) => _buildGrid( + context, + proxies: proxies, + columns: 2, + ), + ), + Breakpoints.medium: SlotLayout.from( + key: const Key('proxies_grid_medium'), + builder: (_) => _buildGrid( + context, + proxies: proxies, + columns: 3, + ), + ), + Breakpoints.large: SlotLayout.from( + key: const Key('proxies_grid_large'), + builder: (_) => _buildGrid( + context, + proxies: proxies, + columns: 4, + ), + ), + }, ), - Breakpoints.medium: SlotLayout.from( - key: const Key('proxies_grid_medium'), - builder: (_) => _buildGrid( - context, - proxies: proxies, - columns: 3, - ), - ), - Breakpoints.large: SlotLayout.from( - key: const Key('proxies_grid_large'), - builder: (_) => _buildGrid( - context, - proxies: proxies, - columns: 4, - ), - ), - }, - ), - ); - }, + ); + }, + ), + ), ); } } diff --git a/lib/main.dart b/lib/main.dart index f63d89a..1e9e26a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -17,7 +17,10 @@ Future main() async { await window?.init(); final config = await preferences.getConfig() ?? Config(); final clashConfig = await preferences.getClashConfig() ?? ClashConfig(); - final appState = AppState(); + final appState = AppState( + mode: clashConfig.mode, + currentProxyName: config.currentProxyName, + ); await globalState.init( appState: appState, config: config, @@ -41,7 +44,10 @@ Future vpnService() async { WidgetsFlutterBinding.ensureInitialized(); final config = await preferences.getConfig() ?? Config(); final clashConfig = await preferences.getClashConfig() ?? ClashConfig(); - final appState = AppState(); + final appState = AppState( + mode: clashConfig.mode, + currentProxyName: config.currentProxyName, + ); clashMessage.addListener(ClashMessageListenerWithVpn(onTun: (String fd) { proxyManager.setProtect( int.parse(fd), diff --git a/lib/models/app.dart b/lib/models/app.dart index 7f29b06..381b9ce 100644 --- a/lib/models/app.dart +++ b/lib/models/app.dart @@ -23,8 +23,10 @@ class AppState with ChangeNotifier { SystemColorSchemes _systemColorSchemes; List _groups; num _sortNum; + Mode _mode; + String? _currentProxyName; - AppState() + AppState({required Mode mode, required currentProxyName}) : _navigationItems = [], _delayMap = {}, _isInit = false, @@ -34,6 +36,8 @@ class AppState with ChangeNotifier { _groups = [], _packages = [], _sortNum = 0, + _mode = mode, + _currentProxyName = currentProxyName, _systemColorSchemes = SystemColorSchemes(); String get currentLabel => _currentLabel; @@ -81,6 +85,17 @@ class AppState with ChangeNotifier { } } + String getDesc(String type, String? proxyName) { + final groupTypeNamesList = GroupType.values.map((e) => e.name).toList(); + if (!groupTypeNamesList.contains(type)) { + return type; + }else{ + final index = groups.indexWhere((element) => element.name == proxyName); + if(index == -1) return type; + return "$type(${groups[index].now})"; + } + } + int? getDelay(String? proxyName) { if (proxyName == null) return null; final index = groups.indexWhere((element) => element.name == proxyName); @@ -90,6 +105,15 @@ class AppState with ChangeNotifier { return _delayMap[group.now]; } + String? get realCurrentProxyName { + if (currentProxyName == null) return null; + final index = groups.indexWhere((element) => element.name == currentProxyName); + if (index == -1) return currentProxyName; + final group = groups[index]; + if (group.now == null) return null; + return group.now; + } + setDelay(Delay delay) { if (_delayMap[delay.name] != delay.value) { _delayMap = Map.from(_delayMap)..[delay.name] = delay.value; @@ -170,53 +194,48 @@ class AppState with ChangeNotifier { } } - List getCurrentGroups(Mode mode) { - switch (mode) { - case Mode.direct: - return []; - case Mode.global: - return groups - .where((element) => element.name == UsedProxy.GLOBAL.name) - .toList(); - case Mode.rule: - return groups - .where((element) => element.name != UsedProxy.GLOBAL.name) - .toList(); + Mode get mode => _mode; + + set mode(Mode value) { + if (_mode != value) { + _mode = value; + notifyListeners(); } } - String? getCurrentGroupNameWithGroups( - List groups, - String? groupName, - Mode mode, - ) { + String? get currentProxyName { + if (mode == Mode.direct) return UsedProxy.DIRECT.name; + if (_currentProxyName != null) return _currentProxyName!; + return currentGroup?.now; + } + + set currentProxyName(String? value) { + if (_currentProxyName != value) { + _currentProxyName = value; + notifyListeners(); + } + } + + Group? get currentGroup { switch (mode) { case Mode.direct: return null; case Mode.global: - return UsedProxy.GLOBAL.name; + return globalGroup; case Mode.rule: - return groupName ?? (groups.isNotEmpty ? groups.first.name : null); + return ruleGroup; } } - String? getCurrentGroupName(String? groupName, Mode mode) { - final currentGroups = getCurrentGroups(mode); - return getCurrentGroupNameWithGroups(currentGroups, groupName, mode); + Group? get globalGroup { + final index = + groups.indexWhere((element) => element.name == GroupName.GLOBAL.name); + return index != -1 ? groups[index] : null; } - Group getGroupWithName(String groupName) { - return groups.firstWhere((e) => e.name == groupName); - } - - String? getCurrentProxyName(String? proxyName, Mode mode) { - final currentGroups = getCurrentGroups(mode); - switch (mode) { - case Mode.direct: - return UsedProxy.DIRECT.name; - case Mode.global || Mode.rule: - return proxyName ?? - (currentGroups.isNotEmpty ? currentGroups.first.now : null); - } + Group? get ruleGroup { + final index = + groups.indexWhere((element) => element.name == GroupName.Proxy.name); + return index != -1 ? groups[index] : null; } } diff --git a/lib/models/config.dart b/lib/models/config.dart index 2a33998..ecb7d69 100644 --- a/lib/models/config.dart +++ b/lib/models/config.dart @@ -161,7 +161,12 @@ class Config extends ChangeNotifier { String? get currentProxyName => currentProfile?.proxyName; - String? get currentGroupName => currentProfile?.groupName; + set currentProxyName(String? value){ + if (currentProfile?.proxyName != value) { + currentProfile?.proxyName = value; + notifyListeners(); + } + } @JsonKey(defaultValue: false) bool get autoLaunch { diff --git a/lib/models/generated/profile.g.dart b/lib/models/generated/profile.g.dart index 1be65b2..9242066 100644 --- a/lib/models/generated/profile.g.dart +++ b/lib/models/generated/profile.g.dart @@ -27,7 +27,6 @@ Profile _$ProfileFromJson(Map json) => Profile( userInfo: json['userInfo'] == null ? null : UserInfo.fromJson(json['userInfo'] as Map), - groupName: json['groupName'] as String?, proxyName: json['proxyName'] as String?, lastUpdateDate: json['lastUpdateDate'] == null ? null @@ -41,7 +40,6 @@ Profile _$ProfileFromJson(Map json) => Profile( Map _$ProfileToJson(Profile instance) => { 'id': instance.id, 'label': instance.label, - 'groupName': instance.groupName, 'proxyName': instance.proxyName, 'url': instance.url, 'lastUpdateDate': instance.lastUpdateDate?.toIso8601String(), diff --git a/lib/models/generated/selector.freezed.dart b/lib/models/generated/selector.freezed.dart index 307a98a..76a2fa9 100644 --- a/lib/models/generated/selector.freezed.dart +++ b/lib/models/generated/selector.freezed.dart @@ -349,7 +349,6 @@ abstract class _UpdateCurrentDelaySelectorState mixin _$NetworkDetectionSelectorState { String? get currentProxyName => throw _privateConstructorUsedError; int? get delay => throw _privateConstructorUsedError; - bool get isInit => throw _privateConstructorUsedError; @JsonKey(ignore: true) $NetworkDetectionSelectorStateCopyWith @@ -364,7 +363,7 @@ abstract class $NetworkDetectionSelectorStateCopyWith<$Res> { _$NetworkDetectionSelectorStateCopyWithImpl<$Res, NetworkDetectionSelectorState>; @useResult - $Res call({String? currentProxyName, int? delay, bool isInit}); + $Res call({String? currentProxyName, int? delay}); } /// @nodoc @@ -383,7 +382,6 @@ class _$NetworkDetectionSelectorStateCopyWithImpl<$Res, $Res call({ Object? currentProxyName = freezed, Object? delay = freezed, - Object? isInit = null, }) { return _then(_value.copyWith( currentProxyName: freezed == currentProxyName @@ -394,10 +392,6 @@ class _$NetworkDetectionSelectorStateCopyWithImpl<$Res, ? _value.delay : delay // ignore: cast_nullable_to_non_nullable as int?, - isInit: null == isInit - ? _value.isInit - : isInit // ignore: cast_nullable_to_non_nullable - as bool, ) as $Val); } } @@ -411,7 +405,7 @@ abstract class _$$NetworkDetectionSelectorStateImplCopyWith<$Res> __$$NetworkDetectionSelectorStateImplCopyWithImpl<$Res>; @override @useResult - $Res call({String? currentProxyName, int? delay, bool isInit}); + $Res call({String? currentProxyName, int? delay}); } /// @nodoc @@ -429,7 +423,6 @@ class __$$NetworkDetectionSelectorStateImplCopyWithImpl<$Res> $Res call({ Object? currentProxyName = freezed, Object? delay = freezed, - Object? isInit = null, }) { return _then(_$NetworkDetectionSelectorStateImpl( currentProxyName: freezed == currentProxyName @@ -440,10 +433,6 @@ class __$$NetworkDetectionSelectorStateImplCopyWithImpl<$Res> ? _value.delay : delay // ignore: cast_nullable_to_non_nullable as int?, - isInit: null == isInit - ? _value.isInit - : isInit // ignore: cast_nullable_to_non_nullable - as bool, )); } } @@ -453,20 +442,16 @@ class __$$NetworkDetectionSelectorStateImplCopyWithImpl<$Res> class _$NetworkDetectionSelectorStateImpl implements _NetworkDetectionSelectorState { const _$NetworkDetectionSelectorStateImpl( - {required this.currentProxyName, - required this.delay, - required this.isInit}); + {required this.currentProxyName, required this.delay}); @override final String? currentProxyName; @override final int? delay; - @override - final bool isInit; @override String toString() { - return 'NetworkDetectionSelectorState(currentProxyName: $currentProxyName, delay: $delay, isInit: $isInit)'; + return 'NetworkDetectionSelectorState(currentProxyName: $currentProxyName, delay: $delay)'; } @override @@ -476,12 +461,11 @@ class _$NetworkDetectionSelectorStateImpl other is _$NetworkDetectionSelectorStateImpl && (identical(other.currentProxyName, currentProxyName) || other.currentProxyName == currentProxyName) && - (identical(other.delay, delay) || other.delay == delay) && - (identical(other.isInit, isInit) || other.isInit == isInit)); + (identical(other.delay, delay) || other.delay == delay)); } @override - int get hashCode => Object.hash(runtimeType, currentProxyName, delay, isInit); + int get hashCode => Object.hash(runtimeType, currentProxyName, delay); @JsonKey(ignore: true) @override @@ -496,16 +480,13 @@ abstract class _NetworkDetectionSelectorState implements NetworkDetectionSelectorState { const factory _NetworkDetectionSelectorState( {required final String? currentProxyName, - required final int? delay, - required final bool isInit}) = _$NetworkDetectionSelectorStateImpl; + required final int? delay}) = _$NetworkDetectionSelectorStateImpl; @override String? get currentProxyName; @override int? get delay; @override - bool get isInit; - @override @JsonKey(ignore: true) _$$NetworkDetectionSelectorStateImplCopyWith< _$NetworkDetectionSelectorStateImpl> @@ -1741,157 +1722,8 @@ abstract class _HomeNavigationSelectorState get copyWith => throw _privateConstructorUsedError; } -/// @nodoc -mixin _$ProxiesSelectorState { - int get currentIndex => throw _privateConstructorUsedError; - List get groupNames => throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $ProxiesSelectorStateCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $ProxiesSelectorStateCopyWith<$Res> { - factory $ProxiesSelectorStateCopyWith(ProxiesSelectorState value, - $Res Function(ProxiesSelectorState) then) = - _$ProxiesSelectorStateCopyWithImpl<$Res, ProxiesSelectorState>; - @useResult - $Res call({int currentIndex, List groupNames}); -} - -/// @nodoc -class _$ProxiesSelectorStateCopyWithImpl<$Res, - $Val extends ProxiesSelectorState> - implements $ProxiesSelectorStateCopyWith<$Res> { - _$ProxiesSelectorStateCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? currentIndex = null, - Object? groupNames = null, - }) { - return _then(_value.copyWith( - currentIndex: null == currentIndex - ? _value.currentIndex - : currentIndex // ignore: cast_nullable_to_non_nullable - as int, - groupNames: null == groupNames - ? _value.groupNames - : groupNames // ignore: cast_nullable_to_non_nullable - as List, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$ProxiesSelectorStateImplCopyWith<$Res> - implements $ProxiesSelectorStateCopyWith<$Res> { - factory _$$ProxiesSelectorStateImplCopyWith(_$ProxiesSelectorStateImpl value, - $Res Function(_$ProxiesSelectorStateImpl) then) = - __$$ProxiesSelectorStateImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({int currentIndex, List groupNames}); -} - -/// @nodoc -class __$$ProxiesSelectorStateImplCopyWithImpl<$Res> - extends _$ProxiesSelectorStateCopyWithImpl<$Res, _$ProxiesSelectorStateImpl> - implements _$$ProxiesSelectorStateImplCopyWith<$Res> { - __$$ProxiesSelectorStateImplCopyWithImpl(_$ProxiesSelectorStateImpl _value, - $Res Function(_$ProxiesSelectorStateImpl) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? currentIndex = null, - Object? groupNames = null, - }) { - return _then(_$ProxiesSelectorStateImpl( - currentIndex: null == currentIndex - ? _value.currentIndex - : currentIndex // ignore: cast_nullable_to_non_nullable - as int, - groupNames: null == groupNames - ? _value._groupNames - : groupNames // ignore: cast_nullable_to_non_nullable - as List, - )); - } -} - -/// @nodoc - -class _$ProxiesSelectorStateImpl implements _ProxiesSelectorState { - const _$ProxiesSelectorStateImpl( - {required this.currentIndex, required final List groupNames}) - : _groupNames = groupNames; - - @override - final int currentIndex; - final List _groupNames; - @override - List get groupNames { - if (_groupNames is EqualUnmodifiableListView) return _groupNames; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_groupNames); - } - - @override - String toString() { - return 'ProxiesSelectorState(currentIndex: $currentIndex, groupNames: $groupNames)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$ProxiesSelectorStateImpl && - (identical(other.currentIndex, currentIndex) || - other.currentIndex == currentIndex) && - const DeepCollectionEquality() - .equals(other._groupNames, _groupNames)); - } - - @override - int get hashCode => Object.hash(runtimeType, currentIndex, - const DeepCollectionEquality().hash(_groupNames)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$ProxiesSelectorStateImplCopyWith<_$ProxiesSelectorStateImpl> - get copyWith => - __$$ProxiesSelectorStateImplCopyWithImpl<_$ProxiesSelectorStateImpl>( - this, _$identity); -} - -abstract class _ProxiesSelectorState implements ProxiesSelectorState { - const factory _ProxiesSelectorState( - {required final int currentIndex, - required final List groupNames}) = _$ProxiesSelectorStateImpl; - - @override - int get currentIndex; - @override - List get groupNames; - @override - @JsonKey(ignore: true) - _$$ProxiesSelectorStateImplCopyWith<_$ProxiesSelectorStateImpl> - get copyWith => throw _privateConstructorUsedError; -} - /// @nodoc mixin _$ProxiesCardSelectorState { - String? get currentGroupName => throw _privateConstructorUsedError; String? get currentProxyName => throw _privateConstructorUsedError; bool get isSelected => throw _privateConstructorUsedError; @@ -1906,8 +1738,7 @@ abstract class $ProxiesCardSelectorStateCopyWith<$Res> { $Res Function(ProxiesCardSelectorState) then) = _$ProxiesCardSelectorStateCopyWithImpl<$Res, ProxiesCardSelectorState>; @useResult - $Res call( - {String? currentGroupName, String? currentProxyName, bool isSelected}); + $Res call({String? currentProxyName, bool isSelected}); } /// @nodoc @@ -1924,15 +1755,10 @@ class _$ProxiesCardSelectorStateCopyWithImpl<$Res, @pragma('vm:prefer-inline') @override $Res call({ - Object? currentGroupName = freezed, Object? currentProxyName = freezed, Object? isSelected = null, }) { return _then(_value.copyWith( - currentGroupName: freezed == currentGroupName - ? _value.currentGroupName - : currentGroupName // ignore: cast_nullable_to_non_nullable - as String?, currentProxyName: freezed == currentProxyName ? _value.currentProxyName : currentProxyName // ignore: cast_nullable_to_non_nullable @@ -1954,8 +1780,7 @@ abstract class _$$ProxiesCardSelectorStateImplCopyWith<$Res> __$$ProxiesCardSelectorStateImplCopyWithImpl<$Res>; @override @useResult - $Res call( - {String? currentGroupName, String? currentProxyName, bool isSelected}); + $Res call({String? currentProxyName, bool isSelected}); } /// @nodoc @@ -1971,15 +1796,10 @@ class __$$ProxiesCardSelectorStateImplCopyWithImpl<$Res> @pragma('vm:prefer-inline') @override $Res call({ - Object? currentGroupName = freezed, Object? currentProxyName = freezed, Object? isSelected = null, }) { return _then(_$ProxiesCardSelectorStateImpl( - currentGroupName: freezed == currentGroupName - ? _value.currentGroupName - : currentGroupName // ignore: cast_nullable_to_non_nullable - as String?, currentProxyName: freezed == currentProxyName ? _value.currentProxyName : currentProxyName // ignore: cast_nullable_to_non_nullable @@ -1996,12 +1816,8 @@ class __$$ProxiesCardSelectorStateImplCopyWithImpl<$Res> class _$ProxiesCardSelectorStateImpl implements _ProxiesCardSelectorState { const _$ProxiesCardSelectorStateImpl( - {required this.currentGroupName, - required this.currentProxyName, - required this.isSelected}); + {required this.currentProxyName, required this.isSelected}); - @override - final String? currentGroupName; @override final String? currentProxyName; @override @@ -2009,7 +1825,7 @@ class _$ProxiesCardSelectorStateImpl implements _ProxiesCardSelectorState { @override String toString() { - return 'ProxiesCardSelectorState(currentGroupName: $currentGroupName, currentProxyName: $currentProxyName, isSelected: $isSelected)'; + return 'ProxiesCardSelectorState(currentProxyName: $currentProxyName, isSelected: $isSelected)'; } @override @@ -2017,8 +1833,6 @@ class _$ProxiesCardSelectorStateImpl implements _ProxiesCardSelectorState { return identical(this, other) || (other.runtimeType == runtimeType && other is _$ProxiesCardSelectorStateImpl && - (identical(other.currentGroupName, currentGroupName) || - other.currentGroupName == currentGroupName) && (identical(other.currentProxyName, currentProxyName) || other.currentProxyName == currentProxyName) && (identical(other.isSelected, isSelected) || @@ -2026,8 +1840,7 @@ class _$ProxiesCardSelectorStateImpl implements _ProxiesCardSelectorState { } @override - int get hashCode => - Object.hash(runtimeType, currentGroupName, currentProxyName, isSelected); + int get hashCode => Object.hash(runtimeType, currentProxyName, isSelected); @JsonKey(ignore: true) @override @@ -2039,12 +1852,9 @@ class _$ProxiesCardSelectorStateImpl implements _ProxiesCardSelectorState { abstract class _ProxiesCardSelectorState implements ProxiesCardSelectorState { const factory _ProxiesCardSelectorState( - {required final String? currentGroupName, - required final String? currentProxyName, + {required final String? currentProxyName, required final bool isSelected}) = _$ProxiesCardSelectorStateImpl; - @override - String? get currentGroupName; @override String? get currentProxyName; @override @@ -2056,34 +1866,32 @@ abstract class _ProxiesCardSelectorState implements ProxiesCardSelectorState { } /// @nodoc -mixin _$ProxiesTabViewSelectorState { +mixin _$ProxiesSelectorState { ProxiesSortType get proxiesSortType => throw _privateConstructorUsedError; num get sortNum => throw _privateConstructorUsedError; - Group get group => throw _privateConstructorUsedError; + Group? get group => throw _privateConstructorUsedError; @JsonKey(ignore: true) - $ProxiesTabViewSelectorStateCopyWith - get copyWith => throw _privateConstructorUsedError; + $ProxiesSelectorStateCopyWith get copyWith => + throw _privateConstructorUsedError; } /// @nodoc -abstract class $ProxiesTabViewSelectorStateCopyWith<$Res> { - factory $ProxiesTabViewSelectorStateCopyWith( - ProxiesTabViewSelectorState value, - $Res Function(ProxiesTabViewSelectorState) then) = - _$ProxiesTabViewSelectorStateCopyWithImpl<$Res, - ProxiesTabViewSelectorState>; +abstract class $ProxiesSelectorStateCopyWith<$Res> { + factory $ProxiesSelectorStateCopyWith(ProxiesSelectorState value, + $Res Function(ProxiesSelectorState) then) = + _$ProxiesSelectorStateCopyWithImpl<$Res, ProxiesSelectorState>; @useResult - $Res call({ProxiesSortType proxiesSortType, num sortNum, Group group}); + $Res call({ProxiesSortType proxiesSortType, num sortNum, Group? group}); - $GroupCopyWith<$Res> get group; + $GroupCopyWith<$Res>? get group; } /// @nodoc -class _$ProxiesTabViewSelectorStateCopyWithImpl<$Res, - $Val extends ProxiesTabViewSelectorState> - implements $ProxiesTabViewSelectorStateCopyWith<$Res> { - _$ProxiesTabViewSelectorStateCopyWithImpl(this._value, this._then); +class _$ProxiesSelectorStateCopyWithImpl<$Res, + $Val extends ProxiesSelectorState> + implements $ProxiesSelectorStateCopyWith<$Res> { + _$ProxiesSelectorStateCopyWithImpl(this._value, this._then); // ignore: unused_field final $Val _value; @@ -2095,7 +1903,7 @@ class _$ProxiesTabViewSelectorStateCopyWithImpl<$Res, $Res call({ Object? proxiesSortType = null, Object? sortNum = null, - Object? group = null, + Object? group = freezed, }) { return _then(_value.copyWith( proxiesSortType: null == proxiesSortType @@ -2106,45 +1914,46 @@ class _$ProxiesTabViewSelectorStateCopyWithImpl<$Res, ? _value.sortNum : sortNum // ignore: cast_nullable_to_non_nullable as num, - group: null == group + group: freezed == group ? _value.group : group // ignore: cast_nullable_to_non_nullable - as Group, + as Group?, ) as $Val); } @override @pragma('vm:prefer-inline') - $GroupCopyWith<$Res> get group { - return $GroupCopyWith<$Res>(_value.group, (value) { + $GroupCopyWith<$Res>? get group { + if (_value.group == null) { + return null; + } + + return $GroupCopyWith<$Res>(_value.group!, (value) { return _then(_value.copyWith(group: value) as $Val); }); } } /// @nodoc -abstract class _$$ProxiesTabViewSelectorStateImplCopyWith<$Res> - implements $ProxiesTabViewSelectorStateCopyWith<$Res> { - factory _$$ProxiesTabViewSelectorStateImplCopyWith( - _$ProxiesTabViewSelectorStateImpl value, - $Res Function(_$ProxiesTabViewSelectorStateImpl) then) = - __$$ProxiesTabViewSelectorStateImplCopyWithImpl<$Res>; +abstract class _$$ProxiesSelectorStateImplCopyWith<$Res> + implements $ProxiesSelectorStateCopyWith<$Res> { + factory _$$ProxiesSelectorStateImplCopyWith(_$ProxiesSelectorStateImpl value, + $Res Function(_$ProxiesSelectorStateImpl) then) = + __$$ProxiesSelectorStateImplCopyWithImpl<$Res>; @override @useResult - $Res call({ProxiesSortType proxiesSortType, num sortNum, Group group}); + $Res call({ProxiesSortType proxiesSortType, num sortNum, Group? group}); @override - $GroupCopyWith<$Res> get group; + $GroupCopyWith<$Res>? get group; } /// @nodoc -class __$$ProxiesTabViewSelectorStateImplCopyWithImpl<$Res> - extends _$ProxiesTabViewSelectorStateCopyWithImpl<$Res, - _$ProxiesTabViewSelectorStateImpl> - implements _$$ProxiesTabViewSelectorStateImplCopyWith<$Res> { - __$$ProxiesTabViewSelectorStateImplCopyWithImpl( - _$ProxiesTabViewSelectorStateImpl _value, - $Res Function(_$ProxiesTabViewSelectorStateImpl) _then) +class __$$ProxiesSelectorStateImplCopyWithImpl<$Res> + extends _$ProxiesSelectorStateCopyWithImpl<$Res, _$ProxiesSelectorStateImpl> + implements _$$ProxiesSelectorStateImplCopyWith<$Res> { + __$$ProxiesSelectorStateImplCopyWithImpl(_$ProxiesSelectorStateImpl _value, + $Res Function(_$ProxiesSelectorStateImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2152,9 +1961,9 @@ class __$$ProxiesTabViewSelectorStateImplCopyWithImpl<$Res> $Res call({ Object? proxiesSortType = null, Object? sortNum = null, - Object? group = null, + Object? group = freezed, }) { - return _then(_$ProxiesTabViewSelectorStateImpl( + return _then(_$ProxiesSelectorStateImpl( proxiesSortType: null == proxiesSortType ? _value.proxiesSortType : proxiesSortType // ignore: cast_nullable_to_non_nullable @@ -2163,19 +1972,18 @@ class __$$ProxiesTabViewSelectorStateImplCopyWithImpl<$Res> ? _value.sortNum : sortNum // ignore: cast_nullable_to_non_nullable as num, - group: null == group + group: freezed == group ? _value.group : group // ignore: cast_nullable_to_non_nullable - as Group, + as Group?, )); } } /// @nodoc -class _$ProxiesTabViewSelectorStateImpl - implements _ProxiesTabViewSelectorState { - const _$ProxiesTabViewSelectorStateImpl( +class _$ProxiesSelectorStateImpl implements _ProxiesSelectorState { + const _$ProxiesSelectorStateImpl( {required this.proxiesSortType, required this.sortNum, required this.group}); @@ -2185,18 +1993,18 @@ class _$ProxiesTabViewSelectorStateImpl @override final num sortNum; @override - final Group group; + final Group? group; @override String toString() { - return 'ProxiesTabViewSelectorState(proxiesSortType: $proxiesSortType, sortNum: $sortNum, group: $group)'; + return 'ProxiesSelectorState(proxiesSortType: $proxiesSortType, sortNum: $sortNum, group: $group)'; } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$ProxiesTabViewSelectorStateImpl && + other is _$ProxiesSelectorStateImpl && (identical(other.proxiesSortType, proxiesSortType) || other.proxiesSortType == proxiesSortType) && (identical(other.sortNum, sortNum) || other.sortNum == sortNum) && @@ -2209,26 +2017,26 @@ class _$ProxiesTabViewSelectorStateImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$ProxiesTabViewSelectorStateImplCopyWith<_$ProxiesTabViewSelectorStateImpl> - get copyWith => __$$ProxiesTabViewSelectorStateImplCopyWithImpl< - _$ProxiesTabViewSelectorStateImpl>(this, _$identity); + _$$ProxiesSelectorStateImplCopyWith<_$ProxiesSelectorStateImpl> + get copyWith => + __$$ProxiesSelectorStateImplCopyWithImpl<_$ProxiesSelectorStateImpl>( + this, _$identity); } -abstract class _ProxiesTabViewSelectorState - implements ProxiesTabViewSelectorState { - const factory _ProxiesTabViewSelectorState( +abstract class _ProxiesSelectorState implements ProxiesSelectorState { + const factory _ProxiesSelectorState( {required final ProxiesSortType proxiesSortType, required final num sortNum, - required final Group group}) = _$ProxiesTabViewSelectorStateImpl; + required final Group? group}) = _$ProxiesSelectorStateImpl; @override ProxiesSortType get proxiesSortType; @override num get sortNum; @override - Group get group; + Group? get group; @override @JsonKey(ignore: true) - _$$ProxiesTabViewSelectorStateImplCopyWith<_$ProxiesTabViewSelectorStateImpl> + _$$ProxiesSelectorStateImplCopyWith<_$ProxiesSelectorStateImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/lib/models/profile.dart b/lib/models/profile.dart index 18a7819..4f44129 100644 --- a/lib/models/profile.dart +++ b/lib/models/profile.dart @@ -62,7 +62,6 @@ class UserInfo { class Profile { String id; String? label; - String? groupName; String? proxyName; String? url; DateTime? lastUpdateDate; @@ -75,7 +74,6 @@ class Profile { this.label, this.url, this.userInfo, - this.groupName, this.proxyName, this.lastUpdateDate, Duration? autoUpdateDuration, @@ -158,7 +156,6 @@ class Profile { runtimeType == other.runtimeType && id == other.id && label == other.label && - groupName == other.groupName && proxyName == other.proxyName && url == other.url && lastUpdateDate == other.lastUpdateDate && @@ -170,7 +167,6 @@ class Profile { int get hashCode => id.hashCode ^ label.hashCode ^ - groupName.hashCode ^ proxyName.hashCode ^ url.hashCode ^ lastUpdateDate.hashCode ^ @@ -180,7 +176,7 @@ class Profile { @override String toString() { - return 'Profile{id: $id, label: $label, groupName: $groupName, proxyName: $proxyName, url: $url, lastUpdateDate: $lastUpdateDate, autoUpdateDuration: $autoUpdateDuration, userInfo: $userInfo, autoUpdate: $autoUpdate}'; + return 'Profile{id: $id, label: $label, proxyName: $proxyName, url: $url, lastUpdateDate: $lastUpdateDate, autoUpdateDuration: $autoUpdateDuration, userInfo: $userInfo, autoUpdate: $autoUpdate}'; } Profile copyWith({ @@ -197,7 +193,6 @@ class Profile { id: id, label: label ?? this.label, url: url ?? this.url, - groupName: groupName ?? this.groupName, proxyName: proxyName ?? this.proxyName, userInfo: userInfo ?? this.userInfo, lastUpdateDate: lastUpdateDate ?? this.lastUpdateDate, diff --git a/lib/models/selector.dart b/lib/models/selector.dart index 13578a2..88913b7 100644 --- a/lib/models/selector.dart +++ b/lib/models/selector.dart @@ -32,7 +32,6 @@ class NetworkDetectionSelectorState with _$NetworkDetectionSelectorState { const factory NetworkDetectionSelectorState({ required String? currentProxyName, required int? delay, - required bool isInit, }) = _NetworkDetectionSelectorState; } @@ -103,28 +102,19 @@ class HomeNavigationSelectorState with _$HomeNavigationSelectorState{ }) = _HomeNavigationSelectorState; } -@freezed -class ProxiesSelectorState with _$ProxiesSelectorState{ - const factory ProxiesSelectorState({ - required int currentIndex, - required List groupNames, - }) = _ProxiesSelectorState; -} - @freezed class ProxiesCardSelectorState with _$ProxiesCardSelectorState{ const factory ProxiesCardSelectorState({ - required String? currentGroupName, required String? currentProxyName, required bool isSelected, }) = _ProxiesCardSelectorState; } @freezed -class ProxiesTabViewSelectorState with _$ProxiesTabViewSelectorState{ - const factory ProxiesTabViewSelectorState({ +class ProxiesSelectorState with _$ProxiesSelectorState{ + const factory ProxiesSelectorState({ required ProxiesSortType proxiesSortType, required num sortNum, - required Group group, - }) = _ProxiesTabViewSelectorState; + required Group? group, + }) = _ProxiesSelectorState; } diff --git a/lib/state.dart b/lib/state.dart index d2d39b0..cfd3edf 100644 --- a/lib/state.dart +++ b/lib/state.dart @@ -14,7 +14,6 @@ import 'common/common.dart'; class GlobalState { Timer? timer; - Function? updateCurrentDelayDebounce; Function? updateSortNumDebounce; PageController? pageController; final navigatorKey = GlobalKey(); @@ -75,18 +74,6 @@ class GlobalState { stopListenUpdate(); } - void updateCurrentDelay( - String? proxyName, - ) { - updateCurrentDelayDebounce ??= debounce((proxyName) { - if (proxyName != null) { - clashCore.delay( - proxyName, - ); - } - }); - updateCurrentDelayDebounce!([proxyName]); - } applyProfile({ required AppState appState, @@ -133,29 +120,36 @@ class GlobalState { required Config config, required ClashConfig clashConfig, }) { - final currentGroupName = - appState.getCurrentGroupName(config.currentGroupName, clashConfig.mode); - final currentProxyName = - appState.getCurrentProxyName(config.currentProxyName, clashConfig.mode); - if (config.profiles.isEmpty || currentProxyName == null) { - stopSystemProxy(); - return; - } - if (currentGroupName == null) return; - final groupIndex = appState.groups.indexWhere( - (element) => element.name == currentGroupName, - ); - if (groupIndex == -1) return; - final proxyIndex = appState.groups[groupIndex].all.indexWhere( - (element) => element.name == currentProxyName, - ); - if (proxyIndex == -1) return; - clashCore.changeProxy( - ChangeProxyParams( - groupName: currentGroupName, - proxyName: currentProxyName, - ), - ); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (config.profiles.isEmpty) { + stopSystemProxy(); + return; + } + final currentProxyName = appState.currentProxyName; + if (currentProxyName == null) return; + final index1 = appState.globalGroup?.all.indexWhere( + (element) => element.name == currentProxyName, + ); + if (index1 != null && index1 != -1) { + clashCore.changeProxy( + ChangeProxyParams( + groupName: GroupName.GLOBAL.name, + proxyName: currentProxyName, + ), + ); + } + final index2 = appState.ruleGroup?.all.indexWhere( + (element) => element.name == currentProxyName, + ); + if (index2 != null && index2 != -1) { + clashCore.changeProxy( + ChangeProxyParams( + groupName: GroupName.Proxy.name, + proxyName: currentProxyName, + ), + ); + } + }); } updatePackages(AppState appState) async { @@ -171,11 +165,11 @@ class GlobalState { required Config config, required ClashConfig clashConfig, }) { - final hasGroups = appState.getCurrentGroups(clashConfig.mode).isNotEmpty; + final group = appState.currentGroup; final hasProfile = config.profiles.isNotEmpty; appState.navigationItems = navigation.getItems( openLogs: config.openLogs, - hasProxies: hasGroups && hasProfile, + hasProxies: group != null && hasProfile, ); } diff --git a/lib/widgets/app_state_container.dart b/lib/widgets/app_state_container.dart index 6889826..91f5c61 100644 --- a/lib/widgets/app_state_container.dart +++ b/lib/widgets/app_state_container.dart @@ -23,14 +23,13 @@ class AppStateContainer extends StatelessWidget { } _updateNavigationsContainer(Widget child) { - return Selector3( - selector: (_, appState, config, clashConfig) { - final hasGroups = - appState.getCurrentGroups(clashConfig.mode).isNotEmpty; + return Selector2( + selector: (_, appState, config) { + final group = appState.currentGroup; final hasProfile = config.profiles.isNotEmpty; return UpdateNavigationsSelector( openLogs: config.openLogs, - hasProxies: hasGroups && hasProfile, + hasProxies: group != null && hasProfile, ); }, builder: (context, state, child) { diff --git a/lib/widgets/clash_message_container.dart b/lib/widgets/clash_message_container.dart index d1478c3..d9b8e55 100644 --- a/lib/widgets/clash_message_container.dart +++ b/lib/widgets/clash_message_container.dart @@ -57,6 +57,7 @@ class _ClashMessageContainerState extends State @override void onLog(Log log) { + print("$log"); context.appController.appState.addLog(log); super.onLog(log); }