Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78081a12e8 | ||
|
|
6896837f28 | ||
|
|
85eb903402 | ||
|
|
9aa9180f1f | ||
|
|
feb9688a29 | ||
|
|
5c71992174 |
Submodule core/Clash.Meta updated: 0096393b3a...d1dc1e4433
@@ -7,14 +7,17 @@ import (
|
|||||||
"github.com/metacubex/mihomo/component/process"
|
"github.com/metacubex/mihomo/component/process"
|
||||||
"github.com/metacubex/mihomo/component/resolver"
|
"github.com/metacubex/mihomo/component/resolver"
|
||||||
"github.com/metacubex/mihomo/config"
|
"github.com/metacubex/mihomo/config"
|
||||||
|
"github.com/metacubex/mihomo/constant/provider"
|
||||||
"github.com/metacubex/mihomo/dns"
|
"github.com/metacubex/mihomo/dns"
|
||||||
"github.com/metacubex/mihomo/hub/executor"
|
"github.com/metacubex/mihomo/hub/executor"
|
||||||
"github.com/metacubex/mihomo/listener"
|
"github.com/metacubex/mihomo/listener"
|
||||||
"github.com/metacubex/mihomo/log"
|
"github.com/metacubex/mihomo/log"
|
||||||
"github.com/metacubex/mihomo/tunnel"
|
"github.com/metacubex/mihomo/tunnel"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -46,6 +49,11 @@ type Process struct {
|
|||||||
Target string `json:"target"`
|
Target string `json:"target"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Now struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
func restartExecutable(execPath string) {
|
func restartExecutable(execPath string) {
|
||||||
var err error
|
var err error
|
||||||
executor.Shutdown()
|
executor.Shutdown()
|
||||||
@@ -121,6 +129,7 @@ func overwriteConfig(targetConfig *config.RawConfig, patchConfig config.RawConfi
|
|||||||
targetConfig.Tun.Device = patchConfig.Tun.Device
|
targetConfig.Tun.Device = patchConfig.Tun.Device
|
||||||
targetConfig.Tun.DNSHijack = patchConfig.Tun.DNSHijack
|
targetConfig.Tun.DNSHijack = patchConfig.Tun.DNSHijack
|
||||||
targetConfig.Tun.Stack = patchConfig.Tun.Stack
|
targetConfig.Tun.Stack = patchConfig.Tun.Stack
|
||||||
|
targetConfig.Profile.StoreSelected = false
|
||||||
if targetConfig.DNS.Enable == false {
|
if targetConfig.DNS.Enable == false {
|
||||||
targetConfig.DNS = patchConfig.DNS
|
targetConfig.DNS = patchConfig.DNS
|
||||||
} else {
|
} else {
|
||||||
@@ -164,6 +173,29 @@ func patchConfig(general *config.General) {
|
|||||||
resolver.DisableIPv6 = !general.IPv6
|
resolver.DisableIPv6 = !general.IPv6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const concurrentCount = math.MaxInt
|
||||||
|
|
||||||
|
func hcCompatibleProvider(proxyProviders map[string]provider.ProxyProvider) {
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
ch := make(chan struct{}, concurrentCount)
|
||||||
|
for _, proxyProvider := range proxyProviders {
|
||||||
|
proxyProvider := proxyProvider
|
||||||
|
if proxyProvider.VehicleType() == provider.Compatible {
|
||||||
|
log.Infoln("Start initial Compatible provider %s", proxyProvider.Name())
|
||||||
|
wg.Add(1)
|
||||||
|
ch <- struct{}{}
|
||||||
|
go func() {
|
||||||
|
defer func() { <-ch; wg.Done() }()
|
||||||
|
if err := proxyProvider.Initial(); err != nil {
|
||||||
|
log.Errorln("initial Compatible provider %s error: %v", proxyProvider.Name(), err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func applyConfig(isPatch bool) {
|
func applyConfig(isPatch bool) {
|
||||||
cfg, err := config.ParseRawConfig(currentConfig)
|
cfg, err := config.ParseRawConfig(currentConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const (
|
|||||||
Log MessageType = "log"
|
Log MessageType = "log"
|
||||||
Tun MessageType = "tun"
|
Tun MessageType = "tun"
|
||||||
Delay MessageType = "delay"
|
Delay MessageType = "delay"
|
||||||
|
Now MessageType = "now"
|
||||||
Process MessageType = "process"
|
Process MessageType = "process"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
26
core/hub.go
26
core/hub.go
@@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/metacubex/mihomo/adapter"
|
"github.com/metacubex/mihomo/adapter"
|
||||||
"github.com/metacubex/mihomo/adapter/outboundgroup"
|
"github.com/metacubex/mihomo/adapter/outboundgroup"
|
||||||
|
"github.com/metacubex/mihomo/adapter/provider"
|
||||||
"github.com/metacubex/mihomo/common/utils"
|
"github.com/metacubex/mihomo/common/utils"
|
||||||
"github.com/metacubex/mihomo/config"
|
"github.com/metacubex/mihomo/config"
|
||||||
"github.com/metacubex/mihomo/constant"
|
"github.com/metacubex/mihomo/constant"
|
||||||
@@ -243,17 +244,38 @@ func getProviders() *C.char {
|
|||||||
func getProvider(name *C.char) *C.char {
|
func getProvider(name *C.char) *C.char {
|
||||||
providerName := C.GoString(name)
|
providerName := C.GoString(name)
|
||||||
providers := tunnel.Providers()
|
providers := tunnel.Providers()
|
||||||
var provider = providers[providerName]
|
data, err := json.Marshal(providers[providerName])
|
||||||
data, err := json.Marshal(provider)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString("")
|
return C.CString("")
|
||||||
}
|
}
|
||||||
return C.CString(string(data))
|
return C.CString(string(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export healthcheck
|
||||||
|
func healthcheck() {
|
||||||
|
hcCompatibleProvider(tunnel.Providers())
|
||||||
|
}
|
||||||
|
|
||||||
//export initNativeApiBridge
|
//export initNativeApiBridge
|
||||||
func initNativeApiBridge(api unsafe.Pointer, port C.longlong) {
|
func initNativeApiBridge(api unsafe.Pointer, port C.longlong) {
|
||||||
bridge.InitDartApi(api)
|
bridge.InitDartApi(api)
|
||||||
i := int64(port)
|
i := int64(port)
|
||||||
bridge.Port = &i
|
bridge.Port = &i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
provider.HealthcheckHook = func(name string, delay uint16) {
|
||||||
|
delayData := &Delay{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
if delay == 0 {
|
||||||
|
delayData.Value = -1
|
||||||
|
} else {
|
||||||
|
delayData.Value = int32(delay)
|
||||||
|
}
|
||||||
|
bridge.SendMessage(bridge.Message{
|
||||||
|
Type: bridge.Delay,
|
||||||
|
Data: delayData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:dynamic_color/dynamic_color.dart';
|
import 'package:dynamic_color/dynamic_color.dart';
|
||||||
import 'package:fl_clash/l10n/l10n.dart';
|
import 'package:fl_clash/l10n/l10n.dart';
|
||||||
import 'package:fl_clash/common/common.dart';
|
import 'package:fl_clash/common/common.dart';
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import 'dart:io';
|
|||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import '../enum/enum.dart';
|
import '../enum/enum.dart';
|
||||||
import '../models/models.dart';
|
import '../models/models.dart';
|
||||||
import '../common/common.dart';
|
import '../common/common.dart';
|
||||||
@@ -70,7 +69,7 @@ class ClashCore {
|
|||||||
final completer = Completer<String>();
|
final completer = Completer<String>();
|
||||||
final receiver = ReceivePort();
|
final receiver = ReceivePort();
|
||||||
receiver.listen((message) {
|
receiver.listen((message) {
|
||||||
if(!completer.isCompleted){
|
if (!completer.isCompleted) {
|
||||||
completer.complete(message);
|
completer.complete(message);
|
||||||
receiver.close();
|
receiver.close();
|
||||||
}
|
}
|
||||||
@@ -98,12 +97,12 @@ class ClashCore {
|
|||||||
final groupsRaw = groupNames.map((groupName) {
|
final groupsRaw = groupNames.map((groupName) {
|
||||||
final group = proxies[groupName];
|
final group = proxies[groupName];
|
||||||
group["all"] = ((group["all"] ?? []) as List)
|
group["all"] = ((group["all"] ?? []) as List)
|
||||||
.where(
|
|
||||||
(name) => !groupNames.contains(groupNames),
|
|
||||||
)
|
|
||||||
.map(
|
.map(
|
||||||
(name) => proxies[name],
|
(name) => proxies[name],
|
||||||
)
|
)
|
||||||
|
.where(
|
||||||
|
(proxy) => proxy["type"] != GroupType.Selector.value,
|
||||||
|
)
|
||||||
.toList();
|
.toList();
|
||||||
return group;
|
return group;
|
||||||
}).toList();
|
}).toList();
|
||||||
@@ -125,6 +124,10 @@ class ClashCore {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
healthcheck() {
|
||||||
|
clashFFI.healthcheck();
|
||||||
|
}
|
||||||
|
|
||||||
VersionInfo getVersionInfo() {
|
VersionInfo getVersionInfo() {
|
||||||
final versionInfoRaw = clashFFI.getVersionInfo();
|
final versionInfoRaw = clashFFI.getVersionInfo();
|
||||||
final versionInfo = json.decode(versionInfoRaw.cast<Utf8>().toDartString());
|
final versionInfo = json.decode(versionInfoRaw.cast<Utf8>().toDartString());
|
||||||
|
|||||||
@@ -1040,6 +1040,14 @@ class ClashFFI {
|
|||||||
late final _getProvider = _getProviderPtr
|
late final _getProvider = _getProviderPtr
|
||||||
.asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>)>();
|
.asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>)>();
|
||||||
|
|
||||||
|
void healthcheck() {
|
||||||
|
return _healthcheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _healthcheckPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Void Function()>>('healthcheck');
|
||||||
|
late final _healthcheck = _healthcheckPtr.asFunction<void Function()>();
|
||||||
|
|
||||||
void initNativeApiBridge(
|
void initNativeApiBridge(
|
||||||
ffi.Pointer<ffi.Void> api,
|
ffi.Pointer<ffi.Void> api,
|
||||||
int port,
|
int port,
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ abstract mixin class ClashMessageListener {
|
|||||||
void onDelay(Delay delay) {}
|
void onDelay(Delay delay) {}
|
||||||
|
|
||||||
void onProcess(Metadata metadata) {}
|
void onProcess(Metadata metadata) {}
|
||||||
|
|
||||||
|
void onNow(Now now) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClashMessage {
|
class ClashMessage {
|
||||||
@@ -41,6 +43,9 @@ class ClashMessage {
|
|||||||
case MessageType.process:
|
case MessageType.process:
|
||||||
listener.onProcess(Metadata.fromJson(m.data));
|
listener.onProcess(Metadata.fromJson(m.data));
|
||||||
break;
|
break;
|
||||||
|
case MessageType.now:
|
||||||
|
listener.onNow(Now.fromJson(m.data));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ class AppController {
|
|||||||
config: config,
|
config: config,
|
||||||
clashConfig: clashConfig,
|
clashConfig: clashConfig,
|
||||||
);
|
);
|
||||||
|
|
||||||
updateRunTime();
|
updateRunTime();
|
||||||
updateTraffic();
|
updateTraffic();
|
||||||
globalState.updateFunctionLists = [
|
globalState.updateFunctionLists = [
|
||||||
@@ -56,9 +55,7 @@ class AppController {
|
|||||||
updateRunTime() {
|
updateRunTime() {
|
||||||
if (proxyManager.startTime != null) {
|
if (proxyManager.startTime != null) {
|
||||||
final startTimeStamp = proxyManager.startTime!.millisecondsSinceEpoch;
|
final startTimeStamp = proxyManager.startTime!.millisecondsSinceEpoch;
|
||||||
final nowTimeStamp = DateTime
|
final nowTimeStamp = DateTime.now().millisecondsSinceEpoch;
|
||||||
.now()
|
|
||||||
.millisecondsSinceEpoch;
|
|
||||||
appState.runTime = nowTimeStamp - startTimeStamp;
|
appState.runTime = nowTimeStamp - startTimeStamp;
|
||||||
} else {
|
} else {
|
||||||
appState.runTime = null;
|
appState.runTime = null;
|
||||||
@@ -133,7 +130,7 @@ class AppController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Function? _changeProfileDebounce;
|
Function? _changeProfileDebounce;
|
||||||
|
|
||||||
changeProfileDebounce(String? profileId) {
|
changeProfileDebounce(String? profileId) {
|
||||||
if (profileId == config.currentProfileId) return;
|
if (profileId == config.currentProfileId) return;
|
||||||
@@ -159,8 +156,8 @@ class AppController {
|
|||||||
if (!profile.autoUpdate) return;
|
if (!profile.autoUpdate) return;
|
||||||
final isNotNeedUpdate = profile.lastUpdateDate
|
final isNotNeedUpdate = profile.lastUpdateDate
|
||||||
?.add(
|
?.add(
|
||||||
profile.autoUpdateDuration,
|
profile.autoUpdateDuration,
|
||||||
)
|
)
|
||||||
.isBeforeNow();
|
.isBeforeNow();
|
||||||
if (isNotNeedUpdate == false) continue;
|
if (isNotNeedUpdate == false) continue;
|
||||||
await profile.update();
|
await profile.update();
|
||||||
@@ -177,7 +174,7 @@ class AppController {
|
|||||||
|
|
||||||
clearCurrentDelay() {
|
clearCurrentDelay() {
|
||||||
final currentProxyName =
|
final currentProxyName =
|
||||||
appState.getCurrentProxyName(config.currentProxyName, clashConfig.mode);
|
appState.getCurrentProxyName(config.currentProxyName, clashConfig.mode);
|
||||||
if (currentProxyName == null) return;
|
if (currentProxyName == null) return;
|
||||||
appState.setDelay(Delay(name: currentProxyName, value: null));
|
appState.setDelay(Delay(name: currentProxyName, value: null));
|
||||||
}
|
}
|
||||||
@@ -225,19 +222,30 @@ class AppController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
afterInit() async {
|
afterInit() async {
|
||||||
if (appState.isInit) {
|
if (config.autoRun) {
|
||||||
if (config.autoRun) {
|
await updateSystemProxy(true);
|
||||||
await updateSystemProxy(true);
|
} else {
|
||||||
} else {
|
await proxyManager.updateStartTime();
|
||||||
await proxyManager.updateStartTime();
|
await updateSystemProxy(proxyManager.isStart);
|
||||||
await updateSystemProxy(proxyManager.isStart);
|
|
||||||
}
|
|
||||||
autoUpdateProfiles();
|
|
||||||
updateLogStatus();
|
|
||||||
if (!config.silentLaunch) {
|
|
||||||
window?.show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
autoUpdateProfiles();
|
||||||
|
updateLogStatus();
|
||||||
|
if (!config.silentLaunch) {
|
||||||
|
window?.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
healthcheck() {
|
||||||
|
if (globalState.healthcheckLock) return;
|
||||||
|
for (final delay in appState.delayMap.entries) {
|
||||||
|
setDelay(
|
||||||
|
Delay(
|
||||||
|
name: delay.key,
|
||||||
|
value: 0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
clashCore.healthcheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
setDelay(Delay delay) {
|
setDelay(Delay delay) {
|
||||||
@@ -264,7 +272,7 @@ class AppController {
|
|||||||
|
|
||||||
toProfiles() {
|
toProfiles() {
|
||||||
final index = globalState.currentNavigationItems.indexWhere(
|
final index = globalState.currentNavigationItems.indexWhere(
|
||||||
(element) => element.label == "profiles",
|
(element) => element.label == "profiles",
|
||||||
);
|
);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
toPage(index);
|
toPage(index);
|
||||||
@@ -277,7 +285,7 @@ class AppController {
|
|||||||
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
||||||
if (commonScaffoldState?.mounted != true) return;
|
if (commonScaffoldState?.mounted != true) return;
|
||||||
commonScaffoldState?.loadingRun(
|
commonScaffoldState?.loadingRun(
|
||||||
() async {
|
() async {
|
||||||
await Future.delayed(const Duration(milliseconds: 300));
|
await Future.delayed(const Duration(milliseconds: 300));
|
||||||
final profile = Profile(
|
final profile = Profile(
|
||||||
url: url,
|
url: url,
|
||||||
@@ -298,7 +306,7 @@ class AppController {
|
|||||||
|
|
||||||
initLink() {
|
initLink() {
|
||||||
linkManager.initAppLinksListen(
|
linkManager.initAppLinksListen(
|
||||||
(url) {
|
(url) {
|
||||||
globalState.showMessage(
|
globalState.showMessage(
|
||||||
title: "${appLocalizations.add}${appLocalizations.profile}",
|
title: "${appLocalizations.add}${appLocalizations.profile}",
|
||||||
message: TextSpan(
|
message: TextSpan(
|
||||||
@@ -307,20 +315,14 @@ class AppController {
|
|||||||
TextSpan(
|
TextSpan(
|
||||||
text: " $url ",
|
text: " $url ",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme
|
color: Theme.of(context).colorScheme.primary,
|
||||||
.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.primary,
|
|
||||||
decoration: TextDecoration.underline,
|
decoration: TextDecoration.underline,
|
||||||
decorationColor: Theme
|
decorationColor: Theme.of(context).colorScheme.primary,
|
||||||
.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.primary,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text:
|
text:
|
||||||
"${appLocalizations.create}${appLocalizations.profile}"),
|
"${appLocalizations.create}${appLocalizations.profile}"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTab: () {
|
onTab: () {
|
||||||
@@ -340,7 +342,7 @@ class AppController {
|
|||||||
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
||||||
if (commonScaffoldState?.mounted != true) return;
|
if (commonScaffoldState?.mounted != true) return;
|
||||||
commonScaffoldState?.loadingRun(
|
commonScaffoldState?.loadingRun(
|
||||||
() async {
|
() async {
|
||||||
await Future.delayed(const Duration(milliseconds: 300));
|
await Future.delayed(const Duration(milliseconds: 300));
|
||||||
final bytes = result.data?.bytes;
|
final bytes = result.data?.bytes;
|
||||||
if (bytes == null) {
|
if (bytes == null) {
|
||||||
|
|||||||
@@ -52,4 +52,4 @@ enum ProfileType { file, url }
|
|||||||
|
|
||||||
enum ResultType { success, error }
|
enum ResultType { success, error }
|
||||||
|
|
||||||
enum MessageType { log, tun, delay, process }
|
enum MessageType { log, tun, delay, process, now }
|
||||||
|
|||||||
@@ -80,6 +80,15 @@ class AboutFragment extends StatelessWidget {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
title: const Text("Telegram"),
|
||||||
|
onTap: () {
|
||||||
|
launchUrl(
|
||||||
|
Uri.parse("https://t.me/+G-veVtwBOl4wODc1"),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
trailing: const Icon(Icons.launch),
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(appLocalizations.project),
|
title: Text(appLocalizations.project),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:fl_clash/common/common.dart';
|
import 'package:fl_clash/common/common.dart';
|
||||||
|
import 'package:fl_clash/enum/enum.dart';
|
||||||
import 'package:fl_clash/models/models.dart';
|
import 'package:fl_clash/models/models.dart';
|
||||||
import 'package:fl_clash/state.dart';
|
|
||||||
import 'package:fl_clash/widgets/widgets.dart';
|
import 'package:fl_clash/widgets/widgets.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@@ -25,6 +25,11 @@ class _NetworkDetectionState extends State<NetworkDetection> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (currentProxyName == UsedProxy.DIRECT.name) {
|
||||||
|
return const Icon(
|
||||||
|
Icons.offline_bolt_outlined,
|
||||||
|
);
|
||||||
|
}
|
||||||
if (delay == 0 || delay == null) {
|
if (delay == 0 || delay == null) {
|
||||||
return const AspectRatio(
|
return const AspectRatio(
|
||||||
aspectRatio: 1,
|
aspectRatio: 1,
|
||||||
@@ -73,56 +78,6 @@ class _NetworkDetectionState extends State<NetworkDetection> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateCurrentDelay(
|
|
||||||
String? currentProxyName,
|
|
||||||
int? delay,
|
|
||||||
bool isCurrent,
|
|
||||||
bool isInit,
|
|
||||||
) {
|
|
||||||
if (!isCurrent || currentProxyName == null || !isInit) return;
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
|
||||||
if (delay == null) {
|
|
||||||
context.appController.setDelay(
|
|
||||||
Delay(
|
|
||||||
name: currentProxyName,
|
|
||||||
value: 0,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
globalState.updateCurrentDelay(
|
|
||||||
currentProxyName,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateCurrentDelayContainer(Widget child) {
|
|
||||||
return Selector3<AppState, Config, ClashConfig,
|
|
||||||
UpdateCurrentDelaySelectorState>(
|
|
||||||
selector: (_, appState, config, clashConfig) {
|
|
||||||
final proxyName = appState.getCurrentProxyName(
|
|
||||||
config.currentProxyName,
|
|
||||||
clashConfig.mode,
|
|
||||||
);
|
|
||||||
return UpdateCurrentDelaySelectorState(
|
|
||||||
isInit: appState.isInit,
|
|
||||||
currentProxyName: proxyName,
|
|
||||||
delay: appState.delayMap[proxyName],
|
|
||||||
isCurrent: appState.currentLabel == 'dashboard',
|
|
||||||
);
|
|
||||||
},
|
|
||||||
builder: (_, state, __) {
|
|
||||||
_updateCurrentDelay(
|
|
||||||
state.currentProxyName,
|
|
||||||
state.delay,
|
|
||||||
state.isCurrent,
|
|
||||||
state.isInit,
|
|
||||||
);
|
|
||||||
return child;
|
|
||||||
},
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return CommonCard(
|
return CommonCard(
|
||||||
@@ -130,58 +85,59 @@ class _NetworkDetectionState extends State<NetworkDetection> {
|
|||||||
iconData: Icons.network_check,
|
iconData: Icons.network_check,
|
||||||
label: appLocalizations.networkDetection,
|
label: appLocalizations.networkDetection,
|
||||||
),
|
),
|
||||||
child: _updateCurrentDelayContainer(
|
child: Selector3<AppState, Config, ClashConfig,
|
||||||
Selector3<AppState, Config, ClashConfig, NetworkDetectionSelectorState>(
|
NetworkDetectionSelectorState>(
|
||||||
selector: (_, appState, config, clashConfig) {
|
selector: (_, appState, config, clashConfig) {
|
||||||
final proxyName = appState.getCurrentProxyName(
|
final proxyName = appState.getCurrentProxyName(
|
||||||
config.currentProxyName,
|
config.currentProxyName,
|
||||||
clashConfig.mode,
|
clashConfig.mode,
|
||||||
);
|
);
|
||||||
return NetworkDetectionSelectorState(
|
return NetworkDetectionSelectorState(
|
||||||
isInit: appState.isInit,
|
isInit: appState.isInit,
|
||||||
currentProxyName: proxyName,
|
currentProxyName: proxyName,
|
||||||
delay: appState.delayMap[proxyName],
|
delay: appState.getDelay(
|
||||||
);
|
proxyName,
|
||||||
},
|
),
|
||||||
builder: (_, state, __) {
|
);
|
||||||
return Container(
|
},
|
||||||
padding: const EdgeInsets.all(16).copyWith(top: 0),
|
builder: (_, state, __) {
|
||||||
child: Column(
|
return Container(
|
||||||
mainAxisSize: MainAxisSize.min,
|
padding: const EdgeInsets.all(16).copyWith(top: 0),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: Column(
|
||||||
children: [
|
mainAxisSize: MainAxisSize.min,
|
||||||
Flexible(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
flex: 0,
|
children: [
|
||||||
child: TooltipText(
|
Flexible(
|
||||||
text: Text(
|
flex: 0,
|
||||||
state.currentProxyName ?? appLocalizations.noProxy,
|
child: TooltipText(
|
||||||
overflow: TextOverflow.ellipsis,
|
text: Text(
|
||||||
maxLines: 1,
|
state.currentProxyName ?? appLocalizations.noProxy,
|
||||||
style:
|
overflow: TextOverflow.ellipsis,
|
||||||
Theme.of(context).textTheme.titleMedium?.toSoftBold(),
|
maxLines: 1,
|
||||||
|
style:
|
||||||
|
Theme.of(context).textTheme.titleMedium?.toSoftBold(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Container(
|
||||||
|
height: context.appController.measure.titleLargeHeight,
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: FadeBox(
|
||||||
|
child: _buildDescription(
|
||||||
|
state.currentProxyName,
|
||||||
|
state.delay,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
),
|
||||||
height: 8,
|
],
|
||||||
),
|
),
|
||||||
Flexible(
|
);
|
||||||
child: Container(
|
},
|
||||||
height: context.appController.measure.titleLargeHeight,
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
child: FadeBox(
|
|
||||||
child: _buildDescription(
|
|
||||||
state.currentProxyName,
|
|
||||||
state.delay,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class _StartButtonState extends State<StartButton>
|
|||||||
final appController = context.appController;
|
final appController = context.appController;
|
||||||
await appController.updateSystemProxy(isStart);
|
await appController.updateSystemProxy(isStart);
|
||||||
if (isStart && mounted) {
|
if (isStart && mounted) {
|
||||||
appController.clearCurrentDelay();
|
appController.healthcheck();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,145 +58,87 @@ class _ProxiesFragmentState extends State<ProxiesFragment>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Selector<AppState, bool>(
|
return DelayTestButtonContainer(
|
||||||
selector: (_, appState) => appState.currentLabel == 'proxies',
|
child: Selector<AppState, bool>(
|
||||||
builder: (_, isCurrent, child) {
|
selector: (_, appState) => appState.currentLabel == 'proxies',
|
||||||
if (isCurrent) {
|
builder: (_, isCurrent, child) {
|
||||||
_initActions();
|
if (isCurrent) {
|
||||||
}
|
_initActions();
|
||||||
return child!;
|
|
||||||
},
|
|
||||||
child: Selector3<AppState, Config, ClashConfig, ProxiesSelectorState>(
|
|
||||||
selector: (_, appState, config, clashConfig) {
|
|
||||||
final currentGroups = appState.getCurrentGroups(clashConfig.mode);
|
|
||||||
final currentProxyName = appState.getCurrentGroupNameWithGroups(
|
|
||||||
currentGroups,
|
|
||||||
config.currentGroupName,
|
|
||||||
clashConfig.mode,
|
|
||||||
);
|
|
||||||
final currentIndex = currentGroups
|
|
||||||
.indexWhere((element) => element.name == currentProxyName);
|
|
||||||
return ProxiesSelectorState(
|
|
||||||
currentIndex: currentIndex != -1 ? currentIndex : 0,
|
|
||||||
groups: currentGroups,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
builder: (_, state, __) {
|
|
||||||
if (_tabController != null) {
|
|
||||||
_tabController!.dispose();
|
|
||||||
_tabController = null;
|
|
||||||
}
|
}
|
||||||
_tabController = TabController(
|
return child!;
|
||||||
length: state.groups.length,
|
},
|
||||||
vsync: this,
|
child: Selector3<AppState, Config, ClashConfig, ProxiesSelectorState>(
|
||||||
initialIndex: state.currentIndex,
|
selector: (_, appState, config, clashConfig) {
|
||||||
);
|
final currentGroups = appState.getCurrentGroups(clashConfig.mode);
|
||||||
return Column(
|
final groupNames = currentGroups.map((e) => e.name).toList();
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
final currentProxyName = appState.getCurrentGroupNameWithGroups(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
currentGroups,
|
||||||
children: [
|
config.currentGroupName,
|
||||||
TabBar(
|
clashConfig.mode,
|
||||||
controller: _tabController,
|
);
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
final currentIndex = currentGroups
|
||||||
dividerColor: Colors.transparent,
|
.indexWhere((element) => element.name == currentProxyName);
|
||||||
isScrollable: true,
|
return ProxiesSelectorState(
|
||||||
tabAlignment: TabAlignment.start,
|
currentIndex: currentIndex,
|
||||||
overlayColor:
|
groupNames: groupNames,
|
||||||
const MaterialStatePropertyAll(Colors.transparent),
|
);
|
||||||
tabs: [
|
},
|
||||||
for (final group in state.groups)
|
builder: (_, state, __) {
|
||||||
Tab(
|
_tabController ??= TabController(
|
||||||
text: group.name,
|
length: state.groupNames.length,
|
||||||
),
|
vsync: this,
|
||||||
],
|
initialIndex: state.currentIndex,
|
||||||
),
|
);
|
||||||
Expanded(
|
return Column(
|
||||||
child: TabBarView(
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
TabBar(
|
||||||
controller: _tabController,
|
controller: _tabController,
|
||||||
children: [
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
for (final group in state.groups)
|
dividerColor: Colors.transparent,
|
||||||
KeepContainer(
|
isScrollable: true,
|
||||||
child: ProxiesTabView(
|
tabAlignment: TabAlignment.start,
|
||||||
group: group,
|
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(
|
||||||
|
key: ObjectKey(groupName),
|
||||||
|
child: ProxiesTabView(
|
||||||
|
groupName: groupName,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProxiesTabView extends StatefulWidget {
|
class ProxiesTabView extends StatelessWidget {
|
||||||
final Group group;
|
final String groupName;
|
||||||
|
|
||||||
const ProxiesTabView({
|
const ProxiesTabView({
|
||||||
super.key,
|
super.key,
|
||||||
required this.group,
|
required this.groupName,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
|
||||||
State<ProxiesTabView> createState() => _ProxiesTabViewState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ProxiesTabViewState extends State<ProxiesTabView>
|
|
||||||
with SingleTickerProviderStateMixin {
|
|
||||||
var lock = false;
|
|
||||||
late AnimationController _controller;
|
|
||||||
late Animation<double> _scale;
|
|
||||||
late Animation<double> _opacity;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_controller = AnimationController(
|
|
||||||
vsync: this,
|
|
||||||
duration: const Duration(
|
|
||||||
milliseconds: 200,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
_scale = Tween<double>(
|
|
||||||
begin: 1.0,
|
|
||||||
end: 0.8,
|
|
||||||
).animate(
|
|
||||||
CurvedAnimation(
|
|
||||||
parent: _controller,
|
|
||||||
curve: const Interval(
|
|
||||||
0.0,
|
|
||||||
0.3,
|
|
||||||
curve: Curves.easeIn,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
_opacity = Tween<double>(
|
|
||||||
begin: 1.0,
|
|
||||||
end: 0.0,
|
|
||||||
).animate(
|
|
||||||
CurvedAnimation(
|
|
||||||
parent: _controller,
|
|
||||||
curve: const Interval(
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
curve: Curves.easeIn,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
_controller.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
Group get group => widget.group;
|
|
||||||
|
|
||||||
get measure => context.appController.measure;
|
|
||||||
|
|
||||||
List<Proxy> _sortOfName(List<Proxy> proxies) {
|
List<Proxy> _sortOfName(List<Proxy> proxies) {
|
||||||
return List.of(proxies)
|
return List.of(proxies)
|
||||||
..sort(
|
..sort(
|
||||||
@@ -204,7 +146,7 @@ class _ProxiesTabViewState extends State<ProxiesTabView>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Proxy> _sortOfDelay(List<Proxy> proxies) {
|
List<Proxy> _sortOfDelay(BuildContext context, List<Proxy> proxies) {
|
||||||
final appState = context.read<AppState>();
|
final appState = context.read<AppState>();
|
||||||
final delayMap = appState.delayMap;
|
final delayMap = appState.delayMap;
|
||||||
return proxies = List.of(proxies)
|
return proxies = List.of(proxies)
|
||||||
@@ -227,38 +169,19 @@ class _ProxiesTabViewState extends State<ProxiesTabView>
|
|||||||
}
|
}
|
||||||
|
|
||||||
_getProxies(
|
_getProxies(
|
||||||
|
BuildContext context,
|
||||||
List<Proxy> proxies,
|
List<Proxy> proxies,
|
||||||
ProxiesSortType proxiesSortType,
|
ProxiesSortType proxiesSortType,
|
||||||
) {
|
) {
|
||||||
if (proxiesSortType == ProxiesSortType.delay) return _sortOfDelay(proxies);
|
if (proxiesSortType == ProxiesSortType.delay) {
|
||||||
|
return _sortOfDelay(context, proxies);
|
||||||
|
}
|
||||||
if (proxiesSortType == ProxiesSortType.name) return _sortOfName(proxies);
|
if (proxiesSortType == ProxiesSortType.name) return _sortOfName(proxies);
|
||||||
return proxies;
|
return proxies;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getDelayMap() async {
|
double _getItemHeight(BuildContext context) {
|
||||||
if (lock == true) return;
|
final measure = context.appController.measure;
|
||||||
lock = true;
|
|
||||||
_controller.forward();
|
|
||||||
for (final proxy in group.all) {
|
|
||||||
context.appController.setDelay(
|
|
||||||
Delay(
|
|
||||||
name: proxy.name,
|
|
||||||
value: 0,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
clashCore.delay(
|
|
||||||
proxy.name,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
await Future.delayed(
|
|
||||||
appConstant.httpTimeoutDuration + appConstant.moreDuration,
|
|
||||||
);
|
|
||||||
lock = false;
|
|
||||||
_controller.reverse();
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
double _getItemHeight() {
|
|
||||||
return 12 * 2 +
|
return 12 * 2 +
|
||||||
measure.bodyMediumHeight * 2 +
|
measure.bodyMediumHeight * 2 +
|
||||||
measure.bodySmallHeight +
|
measure.bodySmallHeight +
|
||||||
@@ -266,11 +189,13 @@ class _ProxiesTabViewState extends State<ProxiesTabView>
|
|||||||
8 * 2;
|
8 * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
_card({
|
_card(
|
||||||
|
BuildContext context, {
|
||||||
required void Function() onPressed,
|
required void Function() onPressed,
|
||||||
required bool isSelected,
|
required bool isSelected,
|
||||||
required Proxy proxy,
|
required Proxy proxy,
|
||||||
}) {
|
}) {
|
||||||
|
final measure = context.appController.measure;
|
||||||
return CommonCard(
|
return CommonCard(
|
||||||
isSelected: isSelected,
|
isSelected: isSelected,
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
@@ -321,7 +246,7 @@ class _ProxiesTabViewState extends State<ProxiesTabView>
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
height: measure.labelSmallHeight,
|
height: measure.labelSmallHeight,
|
||||||
child: Selector<AppState, int?>(
|
child: Selector<AppState, int?>(
|
||||||
selector: (context, appState) => appState.delayMap[proxy.name],
|
selector: (context, appState) => appState.getDelay(proxy.name),
|
||||||
builder: (_, delay, __) {
|
builder: (_, delay, __) {
|
||||||
return FadeBox(
|
return FadeBox(
|
||||||
child: Builder(
|
child: Builder(
|
||||||
@@ -359,115 +284,217 @@ class _ProxiesTabViewState extends State<ProxiesTabView>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildGrid({
|
Widget _buildGrid(
|
||||||
required ProxiesSortType proxiesSortType,
|
BuildContext context, {
|
||||||
|
required List<Proxy> proxies,
|
||||||
required int columns,
|
required int columns,
|
||||||
}) {
|
}) {
|
||||||
return SingleChildScrollView(
|
return GridView.builder(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
child: Selector3<AppState, Config, ClashConfig, ProxiesCardSelectorState>(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
selector: (_, appState, config, clashConfig) =>
|
crossAxisCount: columns,
|
||||||
ProxiesCardSelectorState(
|
mainAxisSpacing: 8,
|
||||||
currentGroupName: appState.getCurrentGroupName(
|
crossAxisSpacing: 8,
|
||||||
config.currentGroupName,
|
mainAxisExtent: _getItemHeight(context),
|
||||||
clashConfig.mode,
|
|
||||||
),
|
|
||||||
currentProxyName: appState.getCurrentProxyName(
|
|
||||||
config.currentProxyName,
|
|
||||||
clashConfig.mode,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
builder: (_, state, __) {
|
|
||||||
return AnimateGrid<Proxy>(
|
|
||||||
items: _getProxies(group.all, proxiesSortType),
|
|
||||||
columns: columns,
|
|
||||||
itemHeight: _getItemHeight(),
|
|
||||||
keyBuilder: (item) {
|
|
||||||
return ObjectKey(item);
|
|
||||||
},
|
|
||||||
builder: (_, proxy) {
|
|
||||||
final isSelected = group.type == GroupType.Selector
|
|
||||||
? group.name == state.currentGroupName &&
|
|
||||||
proxy.name == state.currentProxyName
|
|
||||||
: group.now == proxy.name;
|
|
||||||
return _card(
|
|
||||||
isSelected: isSelected,
|
|
||||||
onPressed: () {
|
|
||||||
if (group.type == GroupType.Selector) {
|
|
||||||
final config = context.read<Config>();
|
|
||||||
config.currentProfile?.groupName = group.name;
|
|
||||||
config.currentProfile?.proxyName = proxy.name;
|
|
||||||
config.update();
|
|
||||||
context.appController.changeProxy();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
proxy: proxy,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
|
itemCount: proxies.length,
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
final proxy = proxies[index];
|
||||||
|
return Selector3<AppState, Config, ClashConfig,
|
||||||
|
ProxiesCardSelectorState>(
|
||||||
|
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 _card(
|
||||||
|
context,
|
||||||
|
isSelected: state.isSelected,
|
||||||
|
onPressed: () {
|
||||||
|
final group =
|
||||||
|
context.appController.appState.getGroupWithName(groupName);
|
||||||
|
if (group.type == GroupType.Selector) {
|
||||||
|
final config = context.read<Config>();
|
||||||
|
config.currentProfile?.groupName = group.name;
|
||||||
|
config.currentProfile?.proxyName = proxy.name;
|
||||||
|
config.update();
|
||||||
|
context.appController.changeProxy();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
proxy: proxy,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Selector<Config, ProxiesSortType>(
|
return Selector2<AppState, Config, ProxiesTabViewSelectorState>(
|
||||||
selector: (_, config) => config.proxiesSortType,
|
selector: (_, appState, config) {
|
||||||
builder: (_, proxiesSortType, __) {
|
return ProxiesTabViewSelectorState(
|
||||||
return FloatLayout(
|
proxiesSortType: config.proxiesSortType,
|
||||||
floatingWidget: FloatWrapper(
|
sortNum: appState.sortNum,
|
||||||
child: AnimatedBuilder(
|
group: appState.getGroupWithName(groupName),
|
||||||
animation: _controller,
|
);
|
||||||
builder: (_, __) {
|
},
|
||||||
return Transform.scale(
|
builder: (_, state, __) {
|
||||||
scale: _scale.value,
|
final proxies = _getProxies(
|
||||||
child: SizedBox(
|
context,
|
||||||
width: 56,
|
state.group.all,
|
||||||
height: 56,
|
state.proxiesSortType,
|
||||||
child: Opacity(
|
);
|
||||||
opacity: _opacity.value,
|
return Align(
|
||||||
child: FloatingActionButton(
|
alignment: Alignment.topCenter,
|
||||||
heroTag: null,
|
child: SlotLayout(
|
||||||
onPressed: _getDelayMap,
|
config: {
|
||||||
child: const Icon(Icons.network_ping),
|
Breakpoints.small: SlotLayout.from(
|
||||||
),
|
key: const Key('proxies_grid_small'),
|
||||||
),
|
builder: (_) => _buildGrid(
|
||||||
),
|
context,
|
||||||
);
|
proxies: proxies,
|
||||||
},
|
columns: 2,
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Align(
|
|
||||||
alignment: Alignment.topCenter,
|
|
||||||
child: SlotLayout(
|
|
||||||
config: {
|
|
||||||
Breakpoints.small: SlotLayout.from(
|
|
||||||
key: const Key('proxies_grid_small'),
|
|
||||||
builder: (_) => _buildGrid(
|
|
||||||
proxiesSortType: proxiesSortType,
|
|
||||||
columns: 2,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Breakpoints.medium: SlotLayout.from(
|
),
|
||||||
key: const Key('proxies_grid_medium'),
|
Breakpoints.medium: SlotLayout.from(
|
||||||
builder: (_) => _buildGrid(
|
key: const Key('proxies_grid_medium'),
|
||||||
proxiesSortType: proxiesSortType,
|
builder: (_) => _buildGrid(
|
||||||
columns: 3,
|
context,
|
||||||
),
|
proxies: proxies,
|
||||||
|
columns: 3,
|
||||||
),
|
),
|
||||||
Breakpoints.large: SlotLayout.from(
|
),
|
||||||
key: const Key('proxies_grid_large'),
|
Breakpoints.large: SlotLayout.from(
|
||||||
builder: (_) => _buildGrid(
|
key: const Key('proxies_grid_large'),
|
||||||
proxiesSortType: proxiesSortType,
|
builder: (_) => _buildGrid(
|
||||||
columns: 4,
|
context,
|
||||||
),
|
proxies: proxies,
|
||||||
|
columns: 4,
|
||||||
),
|
),
|
||||||
},
|
),
|
||||||
),
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DelayTestButtonContainer extends StatefulWidget {
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const DelayTestButtonContainer({
|
||||||
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DelayTestButtonContainer> createState() =>
|
||||||
|
_DelayTestButtonContainerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DelayTestButtonContainerState extends State<DelayTestButtonContainer>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
late AnimationController _controller;
|
||||||
|
late Animation<double> _scale;
|
||||||
|
late Animation<double> _opacity;
|
||||||
|
|
||||||
|
_healthcheck() async {
|
||||||
|
_controller.forward();
|
||||||
|
context.appController.healthcheck();
|
||||||
|
await Future.delayed(
|
||||||
|
appConstant.httpTimeoutDuration + appConstant.moreDuration,
|
||||||
|
);
|
||||||
|
_controller.reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_controller = AnimationController(
|
||||||
|
vsync: this,
|
||||||
|
duration: const Duration(
|
||||||
|
milliseconds: 300,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_scale = Tween<double>(
|
||||||
|
begin: 1.0,
|
||||||
|
end: 0.0,
|
||||||
|
).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _controller,
|
||||||
|
curve: const Interval(
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
curve: Curves.easeIn,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_opacity = Tween<double>(
|
||||||
|
begin: 1.0,
|
||||||
|
end: 0.0,
|
||||||
|
).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _controller,
|
||||||
|
curve: const Interval(
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
curve: Curves.easeIn,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return FloatLayout(
|
||||||
|
floatingWidget: FloatWrapper(
|
||||||
|
child: AnimatedBuilder(
|
||||||
|
animation: _controller,
|
||||||
|
builder: (_, child) {
|
||||||
|
return SizedBox(
|
||||||
|
width: 56,
|
||||||
|
height: 56,
|
||||||
|
child: Transform.scale(
|
||||||
|
scale: _scale.value,
|
||||||
|
child: Opacity(
|
||||||
|
opacity: _opacity.value,
|
||||||
|
child: child!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: FloatingActionButton(
|
||||||
|
heroTag: null,
|
||||||
|
onPressed: _healthcheck,
|
||||||
|
child: const Icon(Icons.network_ping),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: widget.child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class AppState with ChangeNotifier {
|
|||||||
String _currentLabel;
|
String _currentLabel;
|
||||||
SystemColorSchemes _systemColorSchemes;
|
SystemColorSchemes _systemColorSchemes;
|
||||||
List<Group> _groups;
|
List<Group> _groups;
|
||||||
|
num _sortNum;
|
||||||
|
|
||||||
AppState()
|
AppState()
|
||||||
: _navigationItems = [],
|
: _navigationItems = [],
|
||||||
@@ -32,6 +33,7 @@ class AppState with ChangeNotifier {
|
|||||||
_logs = [],
|
_logs = [],
|
||||||
_groups = [],
|
_groups = [],
|
||||||
_packages = [],
|
_packages = [],
|
||||||
|
_sortNum = 0,
|
||||||
_systemColorSchemes = SystemColorSchemes();
|
_systemColorSchemes = SystemColorSchemes();
|
||||||
|
|
||||||
String get currentLabel => _currentLabel;
|
String get currentLabel => _currentLabel;
|
||||||
@@ -79,6 +81,15 @@ class AppState with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int? getDelay(String? proxyName) {
|
||||||
|
if (proxyName == null) return null;
|
||||||
|
final index = groups.indexWhere((element) => element.name == proxyName);
|
||||||
|
if (index == -1) return _delayMap[proxyName];
|
||||||
|
final group = groups[index];
|
||||||
|
if (group.now == null) return null;
|
||||||
|
return _delayMap[group.now];
|
||||||
|
}
|
||||||
|
|
||||||
setDelay(Delay delay) {
|
setDelay(Delay delay) {
|
||||||
if (_delayMap[delay.name] != delay.value) {
|
if (_delayMap[delay.name] != delay.value) {
|
||||||
_delayMap = Map.from(_delayMap)..[delay.name] = delay.value;
|
_delayMap = Map.from(_delayMap)..[delay.name] = delay.value;
|
||||||
@@ -144,12 +155,21 @@ class AppState with ChangeNotifier {
|
|||||||
List<Group> get groups => _groups;
|
List<Group> get groups => _groups;
|
||||||
|
|
||||||
set groups(List<Group> value) {
|
set groups(List<Group> value) {
|
||||||
if (_groups != value) {
|
if (!const ListEquality<Group>().equals(_groups, value)) {
|
||||||
_groups = value;
|
_groups = value;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
num get sortNum => _sortNum;
|
||||||
|
|
||||||
|
set sortNum(num value) {
|
||||||
|
if (_sortNum != value) {
|
||||||
|
_sortNum = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<Group> getCurrentGroups(Mode mode) {
|
List<Group> getCurrentGroups(Mode mode) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case Mode.direct:
|
case Mode.direct:
|
||||||
@@ -185,6 +205,10 @@ class AppState with ChangeNotifier {
|
|||||||
return getCurrentGroupNameWithGroups(currentGroups, groupName, mode);
|
return getCurrentGroupNameWithGroups(currentGroups, groupName, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Group getGroupWithName(String groupName) {
|
||||||
|
return groups.firstWhere((e) => e.name == groupName);
|
||||||
|
}
|
||||||
|
|
||||||
String? getCurrentProxyName(String? proxyName, Mode mode) {
|
String? getCurrentProxyName(String? proxyName, Mode mode) {
|
||||||
final currentGroups = getCurrentGroups(mode);
|
final currentGroups = getCurrentGroups(mode);
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
|||||||
@@ -52,6 +52,16 @@ class Delay with _$Delay {
|
|||||||
factory Delay.fromJson(Map<String, Object?> json) => _$DelayFromJson(json);
|
factory Delay.fromJson(Map<String, Object?> json) => _$DelayFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class Now with _$Now {
|
||||||
|
const factory Now({
|
||||||
|
required String name,
|
||||||
|
required String value,
|
||||||
|
}) = _Now;
|
||||||
|
|
||||||
|
factory Now.fromJson(Map<String, Object?> json) => _$NowFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class Process with _$Process {
|
class Process with _$Process {
|
||||||
const factory Process({
|
const factory Process({
|
||||||
|
|||||||
@@ -672,6 +672,151 @@ abstract class _Delay implements Delay {
|
|||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Now _$NowFromJson(Map<String, dynamic> json) {
|
||||||
|
return _Now.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$Now {
|
||||||
|
String get name => throw _privateConstructorUsedError;
|
||||||
|
String get value => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
$NowCopyWith<Now> get copyWith => throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $NowCopyWith<$Res> {
|
||||||
|
factory $NowCopyWith(Now value, $Res Function(Now) then) =
|
||||||
|
_$NowCopyWithImpl<$Res, Now>;
|
||||||
|
@useResult
|
||||||
|
$Res call({String name, String value});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$NowCopyWithImpl<$Res, $Val extends Now> implements $NowCopyWith<$Res> {
|
||||||
|
_$NowCopyWithImpl(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? name = null,
|
||||||
|
Object? value = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
name: null == name
|
||||||
|
? _value.name
|
||||||
|
: name // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
value: null == value
|
||||||
|
? _value.value
|
||||||
|
: value // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$NowImplCopyWith<$Res> implements $NowCopyWith<$Res> {
|
||||||
|
factory _$$NowImplCopyWith(_$NowImpl value, $Res Function(_$NowImpl) then) =
|
||||||
|
__$$NowImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({String name, String value});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$NowImplCopyWithImpl<$Res> extends _$NowCopyWithImpl<$Res, _$NowImpl>
|
||||||
|
implements _$$NowImplCopyWith<$Res> {
|
||||||
|
__$$NowImplCopyWithImpl(_$NowImpl _value, $Res Function(_$NowImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? name = null,
|
||||||
|
Object? value = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$NowImpl(
|
||||||
|
name: null == name
|
||||||
|
? _value.name
|
||||||
|
: name // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
value: null == value
|
||||||
|
? _value.value
|
||||||
|
: value // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$NowImpl implements _Now {
|
||||||
|
const _$NowImpl({required this.name, required this.value});
|
||||||
|
|
||||||
|
factory _$NowImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$NowImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String name;
|
||||||
|
@override
|
||||||
|
final String value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'Now(name: $name, value: $value)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$NowImpl &&
|
||||||
|
(identical(other.name, name) || other.name == name) &&
|
||||||
|
(identical(other.value, value) || other.value == value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, name, value);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$NowImplCopyWith<_$NowImpl> get copyWith =>
|
||||||
|
__$$NowImplCopyWithImpl<_$NowImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$NowImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _Now implements Now {
|
||||||
|
const factory _Now(
|
||||||
|
{required final String name, required final String value}) = _$NowImpl;
|
||||||
|
|
||||||
|
factory _Now.fromJson(Map<String, dynamic> json) = _$NowImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get name;
|
||||||
|
@override
|
||||||
|
String get value;
|
||||||
|
@override
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$NowImplCopyWith<_$NowImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
Process _$ProcessFromJson(Map<String, dynamic> json) {
|
Process _$ProcessFromJson(Map<String, dynamic> json) {
|
||||||
return _Process.fromJson(json);
|
return _Process.fromJson(json);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ const _$MessageTypeEnumMap = {
|
|||||||
MessageType.tun: 'tun',
|
MessageType.tun: 'tun',
|
||||||
MessageType.delay: 'delay',
|
MessageType.delay: 'delay',
|
||||||
MessageType.process: 'process',
|
MessageType.process: 'process',
|
||||||
|
MessageType.now: 'now',
|
||||||
};
|
};
|
||||||
|
|
||||||
_$DelayImpl _$$DelayImplFromJson(Map<String, dynamic> json) => _$DelayImpl(
|
_$DelayImpl _$$DelayImplFromJson(Map<String, dynamic> json) => _$DelayImpl(
|
||||||
@@ -66,6 +67,16 @@ Map<String, dynamic> _$$DelayImplToJson(_$DelayImpl instance) =>
|
|||||||
'value': instance.value,
|
'value': instance.value,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_$NowImpl _$$NowImplFromJson(Map<String, dynamic> json) => _$NowImpl(
|
||||||
|
name: json['name'] as String,
|
||||||
|
value: json['value'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$NowImplToJson(_$NowImpl instance) => <String, dynamic>{
|
||||||
|
'name': instance.name,
|
||||||
|
'value': instance.value,
|
||||||
|
};
|
||||||
|
|
||||||
_$ProcessImpl _$$ProcessImplFromJson(Map<String, dynamic> json) =>
|
_$ProcessImpl _$$ProcessImplFromJson(Map<String, dynamic> json) =>
|
||||||
_$ProcessImpl(
|
_$ProcessImpl(
|
||||||
uid: (json['uid'] as num).toInt(),
|
uid: (json['uid'] as num).toInt(),
|
||||||
|
|||||||
@@ -1744,7 +1744,7 @@ abstract class _HomeNavigationSelectorState
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$ProxiesSelectorState {
|
mixin _$ProxiesSelectorState {
|
||||||
int get currentIndex => throw _privateConstructorUsedError;
|
int get currentIndex => throw _privateConstructorUsedError;
|
||||||
List<Group> get groups => throw _privateConstructorUsedError;
|
List<String> get groupNames => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
$ProxiesSelectorStateCopyWith<ProxiesSelectorState> get copyWith =>
|
$ProxiesSelectorStateCopyWith<ProxiesSelectorState> get copyWith =>
|
||||||
@@ -1757,7 +1757,7 @@ abstract class $ProxiesSelectorStateCopyWith<$Res> {
|
|||||||
$Res Function(ProxiesSelectorState) then) =
|
$Res Function(ProxiesSelectorState) then) =
|
||||||
_$ProxiesSelectorStateCopyWithImpl<$Res, ProxiesSelectorState>;
|
_$ProxiesSelectorStateCopyWithImpl<$Res, ProxiesSelectorState>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({int currentIndex, List<Group> groups});
|
$Res call({int currentIndex, List<String> groupNames});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1775,17 +1775,17 @@ class _$ProxiesSelectorStateCopyWithImpl<$Res,
|
|||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? currentIndex = null,
|
Object? currentIndex = null,
|
||||||
Object? groups = null,
|
Object? groupNames = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
currentIndex: null == currentIndex
|
currentIndex: null == currentIndex
|
||||||
? _value.currentIndex
|
? _value.currentIndex
|
||||||
: currentIndex // ignore: cast_nullable_to_non_nullable
|
: currentIndex // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
groups: null == groups
|
groupNames: null == groupNames
|
||||||
? _value.groups
|
? _value.groupNames
|
||||||
: groups // ignore: cast_nullable_to_non_nullable
|
: groupNames // ignore: cast_nullable_to_non_nullable
|
||||||
as List<Group>,
|
as List<String>,
|
||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1798,7 +1798,7 @@ abstract class _$$ProxiesSelectorStateImplCopyWith<$Res>
|
|||||||
__$$ProxiesSelectorStateImplCopyWithImpl<$Res>;
|
__$$ProxiesSelectorStateImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({int currentIndex, List<Group> groups});
|
$Res call({int currentIndex, List<String> groupNames});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1813,17 +1813,17 @@ class __$$ProxiesSelectorStateImplCopyWithImpl<$Res>
|
|||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? currentIndex = null,
|
Object? currentIndex = null,
|
||||||
Object? groups = null,
|
Object? groupNames = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$ProxiesSelectorStateImpl(
|
return _then(_$ProxiesSelectorStateImpl(
|
||||||
currentIndex: null == currentIndex
|
currentIndex: null == currentIndex
|
||||||
? _value.currentIndex
|
? _value.currentIndex
|
||||||
: currentIndex // ignore: cast_nullable_to_non_nullable
|
: currentIndex // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
groups: null == groups
|
groupNames: null == groupNames
|
||||||
? _value._groups
|
? _value._groupNames
|
||||||
: groups // ignore: cast_nullable_to_non_nullable
|
: groupNames // ignore: cast_nullable_to_non_nullable
|
||||||
as List<Group>,
|
as List<String>,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1832,22 +1832,22 @@ class __$$ProxiesSelectorStateImplCopyWithImpl<$Res>
|
|||||||
|
|
||||||
class _$ProxiesSelectorStateImpl implements _ProxiesSelectorState {
|
class _$ProxiesSelectorStateImpl implements _ProxiesSelectorState {
|
||||||
const _$ProxiesSelectorStateImpl(
|
const _$ProxiesSelectorStateImpl(
|
||||||
{required this.currentIndex, required final List<Group> groups})
|
{required this.currentIndex, required final List<String> groupNames})
|
||||||
: _groups = groups;
|
: _groupNames = groupNames;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final int currentIndex;
|
final int currentIndex;
|
||||||
final List<Group> _groups;
|
final List<String> _groupNames;
|
||||||
@override
|
@override
|
||||||
List<Group> get groups {
|
List<String> get groupNames {
|
||||||
if (_groups is EqualUnmodifiableListView) return _groups;
|
if (_groupNames is EqualUnmodifiableListView) return _groupNames;
|
||||||
// ignore: implicit_dynamic_type
|
// ignore: implicit_dynamic_type
|
||||||
return EqualUnmodifiableListView(_groups);
|
return EqualUnmodifiableListView(_groupNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'ProxiesSelectorState(currentIndex: $currentIndex, groups: $groups)';
|
return 'ProxiesSelectorState(currentIndex: $currentIndex, groupNames: $groupNames)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -1857,12 +1857,13 @@ class _$ProxiesSelectorStateImpl implements _ProxiesSelectorState {
|
|||||||
other is _$ProxiesSelectorStateImpl &&
|
other is _$ProxiesSelectorStateImpl &&
|
||||||
(identical(other.currentIndex, currentIndex) ||
|
(identical(other.currentIndex, currentIndex) ||
|
||||||
other.currentIndex == currentIndex) &&
|
other.currentIndex == currentIndex) &&
|
||||||
const DeepCollectionEquality().equals(other._groups, _groups));
|
const DeepCollectionEquality()
|
||||||
|
.equals(other._groupNames, _groupNames));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(runtimeType, currentIndex,
|
||||||
runtimeType, currentIndex, const DeepCollectionEquality().hash(_groups));
|
const DeepCollectionEquality().hash(_groupNames));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@@ -1876,12 +1877,12 @@ class _$ProxiesSelectorStateImpl implements _ProxiesSelectorState {
|
|||||||
abstract class _ProxiesSelectorState implements ProxiesSelectorState {
|
abstract class _ProxiesSelectorState implements ProxiesSelectorState {
|
||||||
const factory _ProxiesSelectorState(
|
const factory _ProxiesSelectorState(
|
||||||
{required final int currentIndex,
|
{required final int currentIndex,
|
||||||
required final List<Group> groups}) = _$ProxiesSelectorStateImpl;
|
required final List<String> groupNames}) = _$ProxiesSelectorStateImpl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get currentIndex;
|
int get currentIndex;
|
||||||
@override
|
@override
|
||||||
List<Group> get groups;
|
List<String> get groupNames;
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
_$$ProxiesSelectorStateImplCopyWith<_$ProxiesSelectorStateImpl>
|
_$$ProxiesSelectorStateImplCopyWith<_$ProxiesSelectorStateImpl>
|
||||||
@@ -1892,6 +1893,7 @@ abstract class _ProxiesSelectorState implements ProxiesSelectorState {
|
|||||||
mixin _$ProxiesCardSelectorState {
|
mixin _$ProxiesCardSelectorState {
|
||||||
String? get currentGroupName => throw _privateConstructorUsedError;
|
String? get currentGroupName => throw _privateConstructorUsedError;
|
||||||
String? get currentProxyName => throw _privateConstructorUsedError;
|
String? get currentProxyName => throw _privateConstructorUsedError;
|
||||||
|
bool get isSelected => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
$ProxiesCardSelectorStateCopyWith<ProxiesCardSelectorState> get copyWith =>
|
$ProxiesCardSelectorStateCopyWith<ProxiesCardSelectorState> get copyWith =>
|
||||||
@@ -1904,7 +1906,8 @@ abstract class $ProxiesCardSelectorStateCopyWith<$Res> {
|
|||||||
$Res Function(ProxiesCardSelectorState) then) =
|
$Res Function(ProxiesCardSelectorState) then) =
|
||||||
_$ProxiesCardSelectorStateCopyWithImpl<$Res, ProxiesCardSelectorState>;
|
_$ProxiesCardSelectorStateCopyWithImpl<$Res, ProxiesCardSelectorState>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({String? currentGroupName, String? currentProxyName});
|
$Res call(
|
||||||
|
{String? currentGroupName, String? currentProxyName, bool isSelected});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1923,6 +1926,7 @@ class _$ProxiesCardSelectorStateCopyWithImpl<$Res,
|
|||||||
$Res call({
|
$Res call({
|
||||||
Object? currentGroupName = freezed,
|
Object? currentGroupName = freezed,
|
||||||
Object? currentProxyName = freezed,
|
Object? currentProxyName = freezed,
|
||||||
|
Object? isSelected = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
currentGroupName: freezed == currentGroupName
|
currentGroupName: freezed == currentGroupName
|
||||||
@@ -1933,6 +1937,10 @@ class _$ProxiesCardSelectorStateCopyWithImpl<$Res,
|
|||||||
? _value.currentProxyName
|
? _value.currentProxyName
|
||||||
: currentProxyName // ignore: cast_nullable_to_non_nullable
|
: currentProxyName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
|
isSelected: null == isSelected
|
||||||
|
? _value.isSelected
|
||||||
|
: isSelected // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1946,7 +1954,8 @@ abstract class _$$ProxiesCardSelectorStateImplCopyWith<$Res>
|
|||||||
__$$ProxiesCardSelectorStateImplCopyWithImpl<$Res>;
|
__$$ProxiesCardSelectorStateImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({String? currentGroupName, String? currentProxyName});
|
$Res call(
|
||||||
|
{String? currentGroupName, String? currentProxyName, bool isSelected});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1964,6 +1973,7 @@ class __$$ProxiesCardSelectorStateImplCopyWithImpl<$Res>
|
|||||||
$Res call({
|
$Res call({
|
||||||
Object? currentGroupName = freezed,
|
Object? currentGroupName = freezed,
|
||||||
Object? currentProxyName = freezed,
|
Object? currentProxyName = freezed,
|
||||||
|
Object? isSelected = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$ProxiesCardSelectorStateImpl(
|
return _then(_$ProxiesCardSelectorStateImpl(
|
||||||
currentGroupName: freezed == currentGroupName
|
currentGroupName: freezed == currentGroupName
|
||||||
@@ -1974,6 +1984,10 @@ class __$$ProxiesCardSelectorStateImplCopyWithImpl<$Res>
|
|||||||
? _value.currentProxyName
|
? _value.currentProxyName
|
||||||
: currentProxyName // ignore: cast_nullable_to_non_nullable
|
: currentProxyName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
|
isSelected: null == isSelected
|
||||||
|
? _value.isSelected
|
||||||
|
: isSelected // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1982,16 +1996,20 @@ class __$$ProxiesCardSelectorStateImplCopyWithImpl<$Res>
|
|||||||
|
|
||||||
class _$ProxiesCardSelectorStateImpl implements _ProxiesCardSelectorState {
|
class _$ProxiesCardSelectorStateImpl implements _ProxiesCardSelectorState {
|
||||||
const _$ProxiesCardSelectorStateImpl(
|
const _$ProxiesCardSelectorStateImpl(
|
||||||
{required this.currentGroupName, required this.currentProxyName});
|
{required this.currentGroupName,
|
||||||
|
required this.currentProxyName,
|
||||||
|
required this.isSelected});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final String? currentGroupName;
|
final String? currentGroupName;
|
||||||
@override
|
@override
|
||||||
final String? currentProxyName;
|
final String? currentProxyName;
|
||||||
|
@override
|
||||||
|
final bool isSelected;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'ProxiesCardSelectorState(currentGroupName: $currentGroupName, currentProxyName: $currentProxyName)';
|
return 'ProxiesCardSelectorState(currentGroupName: $currentGroupName, currentProxyName: $currentProxyName, isSelected: $isSelected)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -2002,12 +2020,14 @@ class _$ProxiesCardSelectorStateImpl implements _ProxiesCardSelectorState {
|
|||||||
(identical(other.currentGroupName, currentGroupName) ||
|
(identical(other.currentGroupName, currentGroupName) ||
|
||||||
other.currentGroupName == currentGroupName) &&
|
other.currentGroupName == currentGroupName) &&
|
||||||
(identical(other.currentProxyName, currentProxyName) ||
|
(identical(other.currentProxyName, currentProxyName) ||
|
||||||
other.currentProxyName == currentProxyName));
|
other.currentProxyName == currentProxyName) &&
|
||||||
|
(identical(other.isSelected, isSelected) ||
|
||||||
|
other.isSelected == isSelected));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
Object.hash(runtimeType, currentGroupName, currentProxyName);
|
Object.hash(runtimeType, currentGroupName, currentProxyName, isSelected);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@@ -2019,16 +2039,196 @@ class _$ProxiesCardSelectorStateImpl implements _ProxiesCardSelectorState {
|
|||||||
|
|
||||||
abstract class _ProxiesCardSelectorState implements ProxiesCardSelectorState {
|
abstract class _ProxiesCardSelectorState implements ProxiesCardSelectorState {
|
||||||
const factory _ProxiesCardSelectorState(
|
const factory _ProxiesCardSelectorState(
|
||||||
{required final String? currentGroupName,
|
{required final String? currentGroupName,
|
||||||
required final String? currentProxyName}) =
|
required final String? currentProxyName,
|
||||||
_$ProxiesCardSelectorStateImpl;
|
required final bool isSelected}) = _$ProxiesCardSelectorStateImpl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String? get currentGroupName;
|
String? get currentGroupName;
|
||||||
@override
|
@override
|
||||||
String? get currentProxyName;
|
String? get currentProxyName;
|
||||||
@override
|
@override
|
||||||
|
bool get isSelected;
|
||||||
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
_$$ProxiesCardSelectorStateImplCopyWith<_$ProxiesCardSelectorStateImpl>
|
_$$ProxiesCardSelectorStateImplCopyWith<_$ProxiesCardSelectorStateImpl>
|
||||||
get copyWith => throw _privateConstructorUsedError;
|
get copyWith => throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$ProxiesTabViewSelectorState {
|
||||||
|
ProxiesSortType get proxiesSortType => throw _privateConstructorUsedError;
|
||||||
|
num get sortNum => throw _privateConstructorUsedError;
|
||||||
|
Group get group => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
$ProxiesTabViewSelectorStateCopyWith<ProxiesTabViewSelectorState>
|
||||||
|
get copyWith => throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $ProxiesTabViewSelectorStateCopyWith<$Res> {
|
||||||
|
factory $ProxiesTabViewSelectorStateCopyWith(
|
||||||
|
ProxiesTabViewSelectorState value,
|
||||||
|
$Res Function(ProxiesTabViewSelectorState) then) =
|
||||||
|
_$ProxiesTabViewSelectorStateCopyWithImpl<$Res,
|
||||||
|
ProxiesTabViewSelectorState>;
|
||||||
|
@useResult
|
||||||
|
$Res call({ProxiesSortType proxiesSortType, num sortNum, Group group});
|
||||||
|
|
||||||
|
$GroupCopyWith<$Res> get group;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$ProxiesTabViewSelectorStateCopyWithImpl<$Res,
|
||||||
|
$Val extends ProxiesTabViewSelectorState>
|
||||||
|
implements $ProxiesTabViewSelectorStateCopyWith<$Res> {
|
||||||
|
_$ProxiesTabViewSelectorStateCopyWithImpl(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? proxiesSortType = null,
|
||||||
|
Object? sortNum = null,
|
||||||
|
Object? group = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
proxiesSortType: null == proxiesSortType
|
||||||
|
? _value.proxiesSortType
|
||||||
|
: proxiesSortType // ignore: cast_nullable_to_non_nullable
|
||||||
|
as ProxiesSortType,
|
||||||
|
sortNum: null == sortNum
|
||||||
|
? _value.sortNum
|
||||||
|
: sortNum // ignore: cast_nullable_to_non_nullable
|
||||||
|
as num,
|
||||||
|
group: null == group
|
||||||
|
? _value.group
|
||||||
|
: group // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Group,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$GroupCopyWith<$Res> get group {
|
||||||
|
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>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({ProxiesSortType proxiesSortType, num sortNum, Group group});
|
||||||
|
|
||||||
|
@override
|
||||||
|
$GroupCopyWith<$Res> get group;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$ProxiesTabViewSelectorStateImplCopyWithImpl<$Res>
|
||||||
|
extends _$ProxiesTabViewSelectorStateCopyWithImpl<$Res,
|
||||||
|
_$ProxiesTabViewSelectorStateImpl>
|
||||||
|
implements _$$ProxiesTabViewSelectorStateImplCopyWith<$Res> {
|
||||||
|
__$$ProxiesTabViewSelectorStateImplCopyWithImpl(
|
||||||
|
_$ProxiesTabViewSelectorStateImpl _value,
|
||||||
|
$Res Function(_$ProxiesTabViewSelectorStateImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? proxiesSortType = null,
|
||||||
|
Object? sortNum = null,
|
||||||
|
Object? group = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$ProxiesTabViewSelectorStateImpl(
|
||||||
|
proxiesSortType: null == proxiesSortType
|
||||||
|
? _value.proxiesSortType
|
||||||
|
: proxiesSortType // ignore: cast_nullable_to_non_nullable
|
||||||
|
as ProxiesSortType,
|
||||||
|
sortNum: null == sortNum
|
||||||
|
? _value.sortNum
|
||||||
|
: sortNum // ignore: cast_nullable_to_non_nullable
|
||||||
|
as num,
|
||||||
|
group: null == group
|
||||||
|
? _value.group
|
||||||
|
: group // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Group,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$ProxiesTabViewSelectorStateImpl
|
||||||
|
implements _ProxiesTabViewSelectorState {
|
||||||
|
const _$ProxiesTabViewSelectorStateImpl(
|
||||||
|
{required this.proxiesSortType,
|
||||||
|
required this.sortNum,
|
||||||
|
required this.group});
|
||||||
|
|
||||||
|
@override
|
||||||
|
final ProxiesSortType proxiesSortType;
|
||||||
|
@override
|
||||||
|
final num sortNum;
|
||||||
|
@override
|
||||||
|
final Group group;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ProxiesTabViewSelectorState(proxiesSortType: $proxiesSortType, sortNum: $sortNum, group: $group)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$ProxiesTabViewSelectorStateImpl &&
|
||||||
|
(identical(other.proxiesSortType, proxiesSortType) ||
|
||||||
|
other.proxiesSortType == proxiesSortType) &&
|
||||||
|
(identical(other.sortNum, sortNum) || other.sortNum == sortNum) &&
|
||||||
|
(identical(other.group, group) || other.group == group));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, proxiesSortType, sortNum, group);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$ProxiesTabViewSelectorStateImplCopyWith<_$ProxiesTabViewSelectorStateImpl>
|
||||||
|
get copyWith => __$$ProxiesTabViewSelectorStateImplCopyWithImpl<
|
||||||
|
_$ProxiesTabViewSelectorStateImpl>(this, _$identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _ProxiesTabViewSelectorState
|
||||||
|
implements ProxiesTabViewSelectorState {
|
||||||
|
const factory _ProxiesTabViewSelectorState(
|
||||||
|
{required final ProxiesSortType proxiesSortType,
|
||||||
|
required final num sortNum,
|
||||||
|
required final Group group}) = _$ProxiesTabViewSelectorStateImpl;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ProxiesSortType get proxiesSortType;
|
||||||
|
@override
|
||||||
|
num get sortNum;
|
||||||
|
@override
|
||||||
|
Group get group;
|
||||||
|
@override
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$ProxiesTabViewSelectorStateImplCopyWith<_$ProxiesTabViewSelectorStateImpl>
|
||||||
|
get copyWith => throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ class HomeNavigationSelectorState with _$HomeNavigationSelectorState{
|
|||||||
class ProxiesSelectorState with _$ProxiesSelectorState{
|
class ProxiesSelectorState with _$ProxiesSelectorState{
|
||||||
const factory ProxiesSelectorState({
|
const factory ProxiesSelectorState({
|
||||||
required int currentIndex,
|
required int currentIndex,
|
||||||
required List<Group> groups,
|
required List<String> groupNames,
|
||||||
}) = _ProxiesSelectorState;
|
}) = _ProxiesSelectorState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,5 +116,15 @@ class ProxiesCardSelectorState with _$ProxiesCardSelectorState{
|
|||||||
const factory ProxiesCardSelectorState({
|
const factory ProxiesCardSelectorState({
|
||||||
required String? currentGroupName,
|
required String? currentGroupName,
|
||||||
required String? currentProxyName,
|
required String? currentProxyName,
|
||||||
|
required bool isSelected,
|
||||||
}) = _ProxiesCardSelectorState;
|
}) = _ProxiesCardSelectorState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class ProxiesTabViewSelectorState with _$ProxiesTabViewSelectorState{
|
||||||
|
const factory ProxiesTabViewSelectorState({
|
||||||
|
required ProxiesSortType proxiesSortType,
|
||||||
|
required num sortNum,
|
||||||
|
required Group group,
|
||||||
|
}) = _ProxiesTabViewSelectorState;
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import 'common/common.dart';
|
|||||||
|
|
||||||
class GlobalState {
|
class GlobalState {
|
||||||
Timer? timer;
|
Timer? timer;
|
||||||
Timer? currentDelayTimer;
|
|
||||||
Function? updateCurrentDelayDebounce;
|
Function? updateCurrentDelayDebounce;
|
||||||
|
Function? updateSortNumDebounce;
|
||||||
PageController? pageController;
|
PageController? pageController;
|
||||||
final navigatorKey = GlobalKey<NavigatorState>();
|
final navigatorKey = GlobalKey<NavigatorState>();
|
||||||
final Map<int, String?> packageNameMap = {};
|
final Map<int, String?> packageNameMap = {};
|
||||||
@@ -23,6 +23,7 @@ class GlobalState {
|
|||||||
List<Function> updateFunctionLists = [];
|
List<Function> updateFunctionLists = [];
|
||||||
List<NavigationItem> currentNavigationItems = [];
|
List<NavigationItem> currentNavigationItems = [];
|
||||||
bool updatePackagesLock = false;
|
bool updatePackagesLock = false;
|
||||||
|
bool healthcheckLock = false;
|
||||||
|
|
||||||
startListenUpdate() {
|
startListenUpdate() {
|
||||||
if (timer != null && timer!.isActive == true) return;
|
if (timer != null && timer!.isActive == true) return;
|
||||||
|
|||||||
@@ -38,13 +38,24 @@ class _ClashMessageContainerState extends State<ClashMessageContainer>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onDelay(Delay delay) {
|
void onDelay(Delay delay) {
|
||||||
|
globalState.healthcheckLock = true;
|
||||||
context.appController.setDelay(delay);
|
context.appController.setDelay(delay);
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
globalState.updateSortNumDebounce ??= debounce<Function()>(
|
||||||
|
() {
|
||||||
|
context.appController.updateGroups();
|
||||||
|
context.appController.appState.sortNum++;
|
||||||
|
globalState.healthcheckLock = false;
|
||||||
|
},
|
||||||
|
milliseconds: 5000,
|
||||||
|
);
|
||||||
|
globalState.updateSortNumDebounce!();
|
||||||
|
});
|
||||||
super.onDelay(delay);
|
super.onDelay(delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onLog(Log log) {
|
void onLog(Log log) {
|
||||||
debugPrint("$log");
|
|
||||||
context.appController.appState.addLog(log);
|
context.appController.appState.addLog(log);
|
||||||
super.onLog(log);
|
super.onLog(log);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: fl_clash
|
name: fl_clash
|
||||||
description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free.
|
description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free.
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
version: 0.7.8
|
version: 0.7.11
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.1.0 <4.0.0'
|
sdk: '>=3.1.0 <4.0.0'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user