diff --git a/android/app/build.gradle b/android/app/build.gradle index ab0a450..f30139d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -73,6 +73,7 @@ android { applicationIdSuffix '.debug' } release { + debuggable false if (isRelease) { signingConfig signingConfigs.release } else { diff --git a/android/core/build.gradle.kts b/android/core/build.gradle.kts index 6c1404e..03d10ca 100644 --- a/android/core/build.gradle.kts +++ b/android/core/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.argumentsWithVarargAsSingleArray + plugins { id("com.android.library") id("org.jetbrains.kotlin.android") @@ -15,6 +17,7 @@ android { buildTypes { release { + isJniDebuggable = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" diff --git a/android/core/src/main/cpp/CMakeLists.txt b/android/core/src/main/cpp/CMakeLists.txt index 7c29f76..cdd7623 100644 --- a/android/core/src/main/cpp/CMakeLists.txt +++ b/android/core/src/main/cpp/CMakeLists.txt @@ -4,6 +4,8 @@ project("core") message("CMAKE_SOURCE_DIR ${CMAKE_SOURCE_DIR}") +message("CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}") + if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") add_compile_options(-O3) diff --git a/android/core/src/main/cpp/core.cpp b/android/core/src/main/cpp/core.cpp index 5392300..19804e8 100644 --- a/android/core/src/main/cpp/core.cpp +++ b/android/core/src/main/cpp/core.cpp @@ -1,21 +1,18 @@ -#include - #ifdef LIBCLASH #include -#include #include "jni_helper.h" #include "libclash.h" extern "C" JNIEXPORT void JNICALL -Java_com_follow_clash_core_Core_startTun(JNIEnv *env, jobject thiz, jint fd, jobject cb) { - auto interface = new_global(cb); +Java_com_follow_clash_core_Core_startTun(JNIEnv *env, jobject, const jint fd, jobject cb) { + const auto interface = new_global(cb); startTUN(fd, interface); } extern "C" JNIEXPORT void JNICALL -Java_com_follow_clash_core_Core_stopTun(JNIEnv *env, jobject thiz) { +Java_com_follow_clash_core_Core_stopTun(JNIEnv *) { stopTun(); } @@ -26,50 +23,50 @@ static jmethodID m_tun_interface_resolve_process; static void release_jni_object_impl(void *obj) { ATTACH_JNI(); - del_global((jobject) obj); + del_global(static_cast(obj)); } -static void call_tun_interface_protect_impl(void *tun_interface, int fd) { +static void call_tun_interface_protect_impl(void *tun_interface, const int fd) { ATTACH_JNI(); - env->CallVoidMethod((jobject) tun_interface, - (jmethodID) m_tun_interface_protect, - (jint) fd); + env->CallVoidMethod(static_cast(tun_interface), + m_tun_interface_protect, + fd); } -static const char* +static const char * call_tun_interface_resolve_process_impl(void *tun_interface, int protocol, - const char *source, - const char *target, - int uid) { + const char *source, + const char *target, + const int uid) { ATTACH_JNI(); - jstring packageName = (jstring)env->CallObjectMethod((jobject) tun_interface, - (jmethodID) m_tun_interface_resolve_process, - (jint) protocol, - (jstring) new_string(source), - (jstring) new_string(target), - (jint) uid); + const auto packageName = reinterpret_cast(env->CallObjectMethod(static_cast(tun_interface), + m_tun_interface_resolve_process, + protocol, + new_string(source), + new_string(target), + uid)); return get_string(packageName); } extern "C" JNIEXPORT jint JNICALL -JNI_OnLoad(JavaVM *vm, void *reserved) { +JNI_OnLoad(JavaVM *vm, void *) { JNIEnv *env = nullptr; - if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) { + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { return JNI_ERR; } initialize_jni(vm, env); - jclass c_tun_interface = find_class("com/follow/clash/core/TunInterface"); + const auto c_tun_interface = find_class("com/follow/clash/core/TunInterface"); m_tun_interface_protect = find_method(c_tun_interface, "protect", "(I)V"); m_tun_interface_resolve_process = find_method(c_tun_interface, "resolverProcess", - "(ILjava/lang/String;Ljava/lang/String;I)Ljava/lang/String;"); + "(ILjava/lang/String;Ljava/lang/String;I)Ljava/lang/String;"); registerCallbacks(&call_tun_interface_protect_impl, &call_tun_interface_resolve_process_impl, &release_jni_object_impl); return JNI_VERSION_1_6; } -#endif \ No newline at end of file +#endif diff --git a/android/core/src/main/cpp/jni_helper.cpp b/android/core/src/main/cpp/jni_helper.cpp index cb0f853..e840fe3 100644 --- a/android/core/src/main/cpp/jni_helper.cpp +++ b/android/core/src/main/cpp/jni_helper.cpp @@ -1,5 +1,6 @@ #include "jni_helper.h" +#include #include #include @@ -12,7 +13,7 @@ static jmethodID m_get_bytes; void initialize_jni(JavaVM *vm, JNIEnv *env) { global_vm = vm; - c_string = (jclass) new_global(find_class("java/lang/String")); + c_string = reinterpret_cast(new_global(find_class("java/lang/String"))); m_new_string = find_method(c_string, "", "([B)V"); m_get_bytes = find_method(c_string, "getBytes", "()[B"); } @@ -22,23 +23,23 @@ JavaVM *global_java_vm() { } char *jni_get_string(JNIEnv *env, jstring str) { - auto array = (jbyteArray) env->CallObjectMethod(str, m_get_bytes); - int length = env->GetArrayLength(array); - char *content = (char *) malloc(length + 1); - env->GetByteArrayRegion(array, 0, length, (jbyte *) content); + const auto array = reinterpret_cast(env->CallObjectMethod(str, m_get_bytes)); + const int length = env->GetArrayLength(array); + const auto content = static_cast(malloc(length + 1)); + env->GetByteArrayRegion(array, 0, length, reinterpret_cast(content)); content[length] = 0; return content; } jstring jni_new_string(JNIEnv *env, const char *str) { - auto length = (int) strlen(str); - jbyteArray array = env->NewByteArray(length); - env->SetByteArrayRegion(array, 0, length, (const jbyte *) str); - return (jstring) env->NewObject(c_string, m_new_string, array); + const auto length = static_cast(strlen(str)); + const auto array = env->NewByteArray(length); + env->SetByteArrayRegion(array, 0, length, reinterpret_cast(str)); + return reinterpret_cast(env->NewObject(c_string, m_new_string, array)); } int jni_catch_exception(JNIEnv *env) { - int result = env->ExceptionCheck(); + const int result = env->ExceptionCheck(); if (result) { env->ExceptionDescribe(); env->ExceptionClear(); @@ -46,9 +47,9 @@ int jni_catch_exception(JNIEnv *env) { return result; } -void jni_attach_thread(struct scoped_jni *jni) { +void jni_attach_thread(scoped_jni *jni) { JavaVM *vm = global_java_vm(); - if (vm->GetEnv((void **) &jni->env, JNI_VERSION_1_6) == JNI_OK) { + if (vm->GetEnv(reinterpret_cast(&jni->env), JNI_VERSION_1_6) == JNI_OK) { jni->require_release = 0; return; } @@ -58,9 +59,9 @@ void jni_attach_thread(struct scoped_jni *jni) { jni->require_release = 1; } -void jni_detach_thread(struct scoped_jni *jni) { +void jni_detach_thread(const scoped_jni *env) { JavaVM *vm = global_java_vm(); - if (jni->require_release) { + if (env->require_release) { vm->DetachCurrentThread(); } } diff --git a/android/core/src/main/cpp/jni_helper.h b/android/core/src/main/cpp/jni_helper.h index a952865..57fbd55 100644 --- a/android/core/src/main/cpp/jni_helper.h +++ b/android/core/src/main/cpp/jni_helper.h @@ -1,9 +1,6 @@ #pragma once #include -#include -#include -#include struct scoped_jni { JNIEnv *env; @@ -18,14 +15,14 @@ extern char *jni_get_string(JNIEnv *env, jstring str); extern int jni_catch_exception(JNIEnv *env); -extern void jni_attach_thread(struct scoped_jni *jni); +extern void jni_attach_thread(scoped_jni *jni); -extern void jni_detach_thread(struct scoped_jni *env); +extern void jni_detach_thread(const scoped_jni *env); extern void release_string(char **str); #define ATTACH_JNI() __attribute__((unused, cleanup(jni_detach_thread))) \ - struct scoped_jni _jni; \ + scoped_jni _jni{}; \ jni_attach_thread(&_jni); \ JNIEnv *env = _jni.env @@ -36,4 +33,4 @@ extern void release_string(char **str); #define new_global(obj) env->NewGlobalRef(obj) #define del_global(obj) env->DeleteGlobalRef(obj) #define get_string(jstr) jni_get_string(env, jstr) -#define new_string(cstr) jni_new_string(env, cstr) \ No newline at end of file +#define new_string(cstr) jni_new_string(env, cstr) diff --git a/android/gradle.properties b/android/gradle.properties index f1c93ba..9b8b8c5 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -2,4 +2,4 @@ org.gradle.jvmargs=-Xmx4G android.useAndroidX=true android.enableJetifier=true kotlin_version=1.9.22 -agp_version=8.9.1 +agp_version=8.9.2 diff --git a/core/hub.go b/core/hub.go index 06095e9..b026b0c 100644 --- a/core/hub.go +++ b/core/hub.go @@ -53,6 +53,7 @@ func handleStartListener() bool { defer runLock.Unlock() isRunning = true updateListeners(true) + closeConnections() return true } @@ -276,6 +277,16 @@ func handleCloseConnections() bool { return true } +func closeConnections() { + statistic.DefaultManager.Range(func(c statistic.Tracker) bool { + err := c.Close() + if err != nil { + return false + } + return true + }) +} + func handleCloseConnection(connectionId string) bool { runLock.Lock() defer runLock.Unlock() diff --git a/lib/application.dart b/lib/application.dart index 0f62f2d..bce5dbe 100644 --- a/lib/application.dart +++ b/lib/application.dart @@ -100,7 +100,8 @@ class ApplicationState extends ConsumerState { return AppStateManager( child: ClashManager( child: ConnectivityManager( - onConnectivityChanged: () { + onConnectivityChanged: () async { + await clashCore.closeConnections(); globalState.appController.updateLocalIp(); globalState.appController.addCheckIpNumDebounce(); }, diff --git a/lib/common/common.dart b/lib/common/common.dart index 7aae94d..11ed06b 100644 --- a/lib/common/common.dart +++ b/lib/common/common.dart @@ -36,4 +36,4 @@ export 'window.dart'; export 'windows.dart'; export 'render.dart'; export 'mixin.dart'; -export 'print.dart'; \ No newline at end of file +export 'print.dart'; diff --git a/lib/common/constant.dart b/lib/common/constant.dart index 908cb8a..42bde58 100644 --- a/lib/common/constant.dart +++ b/lib/common/constant.dart @@ -23,7 +23,8 @@ final baseInfoEdgeInsets = EdgeInsets.symmetric( horizontal: 16.ap, ); -final defaultTextScaleFactor = WidgetsBinding.instance.platformDispatcher.textScaleFactor; +final defaultTextScaleFactor = + WidgetsBinding.instance.platformDispatcher.textScaleFactor; const httpTimeoutDuration = Duration(milliseconds: 5000); const moreDuration = Duration(milliseconds: 100); const animateDuration = Duration(milliseconds: 100); @@ -76,6 +77,10 @@ const viewModeColumnsMap = { ViewMode.desktop: [4, 3], }; +// const proxiesStoreKey = PageStorageKey('proxies'); +// const toolsStoreKey = PageStorageKey('tools'); +// const profilesStoreKey = PageStorageKey('profiles'); + const defaultPrimaryColor = 0XFFD8C0C3; double getWidgetHeight(num lines) { diff --git a/lib/common/function.dart b/lib/common/function.dart index a1e1770..7003c5f 100644 --- a/lib/common/function.dart +++ b/lib/common/function.dart @@ -1,10 +1,12 @@ import 'dart:async'; +import 'package:fl_clash/enum/enum.dart'; + class Debouncer { - final Map _operations = {}; + final Map _operations = {}; call( - dynamic tag, + FunctionTag tag, Function func, { List? args, Duration duration = const Duration(milliseconds: 600), @@ -33,10 +35,10 @@ class Debouncer { } class Throttler { - final Map _operations = {}; + final Map _operations = {}; call( - dynamic tag, + FunctionTag tag, Function func, { List? args, Duration duration = const Duration(milliseconds: 600), diff --git a/lib/common/navigation.dart b/lib/common/navigation.dart index 5d2ccab..c5e2159 100644 --- a/lib/common/navigation.dart +++ b/lib/common/navigation.dart @@ -12,6 +12,7 @@ class Navigation { }) { return [ const NavigationItem( + keep: false, icon: Icon(Icons.space_dashboard), label: PageLabel.dashboard, fragment: DashboardFragment( @@ -65,7 +66,6 @@ class Navigation { icon: Icon(Icons.storage), label: PageLabel.resources, description: "resourcesDesc", - keep: false, fragment: Resources( key: GlobalObjectKey( PageLabel.resources, diff --git a/lib/common/render.dart b/lib/common/render.dart index 8d9cd42..6c9192c 100644 --- a/lib/common/render.dart +++ b/lib/common/render.dart @@ -23,14 +23,14 @@ class Render { pause() { throttler.call( - DebounceTag.renderPause, + FunctionTag.renderPause, _pause, duration: Duration(seconds: 5), ); } resume() { - throttler.cancel(DebounceTag.renderPause); + throttler.cancel(FunctionTag.renderPause); _resume(); } diff --git a/lib/common/string.dart b/lib/common/string.dart index b4ccaeb..1c3be33 100644 --- a/lib/common/string.dart +++ b/lib/common/string.dart @@ -47,6 +47,10 @@ extension StringExtension on String { return false; } } + +// bool containsToLower(String target) { +// return toLowerCase().contains(target); +// } } extension StringExtensionSafe on String? { diff --git a/lib/common/utils.dart b/lib/common/utils.dart index 49a869f..6b9e26d 100644 --- a/lib/common/utils.dart +++ b/lib/common/utils.dart @@ -5,6 +5,7 @@ import 'dart:ui'; import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/enum/enum.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:lpinyin/lpinyin.dart'; class Utils { @@ -230,7 +231,7 @@ class Utils { } int getProfilesColumns(double viewWidth) { - return max((viewWidth / 350).floor(), 1); + return max((viewWidth / 320).floor(), 1); } final _indexPrimary = [ @@ -323,6 +324,15 @@ class Utils { } return ""; } + + SingleActivator controlSingleActivator(LogicalKeyboardKey trigger) { + final control = Platform.isMacOS ? false : true; + return SingleActivator( + trigger, + control: control, + meta: !control, + ); + } } final utils = Utils(); diff --git a/lib/controller.dart b/lib/controller.dart index 5f60b0a..4d99c0a 100644 --- a/lib/controller.dart +++ b/lib/controller.dart @@ -8,6 +8,7 @@ import 'package:archive/archive.dart'; import 'package:fl_clash/clash/clash.dart'; import 'package:fl_clash/common/archive.dart'; import 'package:fl_clash/enum/enum.dart'; +import 'package:fl_clash/plugins/app.dart'; import 'package:fl_clash/providers/providers.dart'; import 'package:fl_clash/state.dart'; import 'package:fl_clash/widgets/dialog.dart'; @@ -30,18 +31,18 @@ class AppController { AppController(this.context, WidgetRef ref) : _ref = ref; updateClashConfigDebounce() { - debouncer.call(DebounceTag.updateClashConfig, () async { + debouncer.call(FunctionTag.updateClashConfig, () async { final isPatch = globalState.appState.needApply ? false : true; await updateClashConfig(isPatch); }); } updateGroupsDebounce() { - debouncer.call(DebounceTag.updateGroups, updateGroups); + debouncer.call(FunctionTag.updateGroups, updateGroups); } addCheckIpNumDebounce() { - debouncer.call(DebounceTag.addCheckIpNum, () { + debouncer.call(FunctionTag.addCheckIpNum, () { _ref.read(checkIpNumProvider.notifier).add(); }); } @@ -49,17 +50,17 @@ class AppController { applyProfileDebounce({ bool silence = false, }) { - debouncer.call(DebounceTag.applyProfile, (silence) { + debouncer.call(FunctionTag.applyProfile, (silence) { applyProfile(silence: silence); }, args: [silence]); } savePreferencesDebounce() { - debouncer.call(DebounceTag.savePreferences, savePreferences); + debouncer.call(FunctionTag.savePreferences, savePreferences); } changeProxyDebounce(String groupName, String proxyName) { - debouncer.call(DebounceTag.changeProxy, + debouncer.call(FunctionTag.changeProxy, (String groupName, String proxyName) async { await changeProxy( groupName: groupName, @@ -385,6 +386,9 @@ class AppController { } handleBackOrExit() async { + if (_ref.read(backBlockProvider)) { + return; + } if (_ref.read(appSettingProvider).minimizeOnExit) { if (system.isDesktop) { await savePreferencesDebounce(); @@ -395,6 +399,14 @@ class AppController { } } + backBlock() { + _ref.read(backBlockProvider.notifier).value = true; + } + + unBackBlock() { + _ref.read(backBlockProvider.notifier).value = false; + } + handleExit() async { try { await updateStatus(false); @@ -498,8 +510,9 @@ class AppController { } init() async { - await _handlePreference(); - await _handlerDisclaimer(); + FlutterError.onError = (details) { + commonPrint.log(details.stack.toString()); + }; await _initCore(); await _initStatus(); updateTray(true); @@ -513,6 +526,8 @@ class AppController { } else { window?.hide(); } + await _handlePreference(); + await _handlerDisclaimer(); _ref.read(initProvider.notifier).value = true; } @@ -690,10 +705,16 @@ class AppController { return List.of(proxies) ..sort( (a, b) { - final aDelay = - _ref.read(getDelayProvider(proxyName: a.name, testUrl: testUrl)); - final bDelay = - _ref.read(getDelayProvider(proxyName: b.name, testUrl: testUrl)); + final aDelay = _ref.read(getDelayProvider( + proxyName: a.name, + testUrl: testUrl, + )); + final bDelay = _ref.read( + getDelayProvider( + proxyName: b.name, + testUrl: testUrl, + ), + ); if (aDelay == null && bDelay == null) { return 0; } @@ -754,6 +775,17 @@ class AppController { ); } + Future> getPackages() async { + if (_ref.read(isMobileViewProvider)) { + await Future.delayed(commonDuration); + } + if (_ref.read(packagesProvider).isEmpty) { + _ref.read(packagesProvider.notifier).value = + await app?.getPackages() ?? []; + } + return _ref.read(packagesProvider); + } + updateStart() { updateStatus(!_ref.read(runTimeProvider.notifier).isStart); } diff --git a/lib/enum/enum.dart b/lib/enum/enum.dart index d6e33b6..e1896d6 100644 --- a/lib/enum/enum.dart +++ b/lib/enum/enum.dart @@ -291,7 +291,7 @@ enum WindowsHelperServiceStatus { running, } -enum DebounceTag { +enum FunctionTag { updateClashConfig, updateStatus, updateGroups, @@ -308,6 +308,9 @@ enum DebounceTag { updatePageIndex, pageChange, proxiesTabChange, + logs, + requests, + } enum DashboardWidget { diff --git a/lib/fragments/about.dart b/lib/fragments/about.dart index c0e9e24..f029c94 100644 --- a/lib/fragments/about.dart +++ b/lib/fragments/about.dart @@ -202,10 +202,7 @@ class Avatar extends StatelessWidget { @override Widget build(BuildContext context) { - return InkWell( - splashColor: Colors.transparent, - highlightColor: Colors.transparent, - hoverColor: Colors.transparent, + return GestureDetector( child: Column( children: [ SizedBox( diff --git a/lib/fragments/access.dart b/lib/fragments/access.dart index 565e1e6..9c8ee0a 100644 --- a/lib/fragments/access.dart +++ b/lib/fragments/access.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:convert'; import 'package:fl_clash/enum/enum.dart'; @@ -22,21 +23,14 @@ class _AccessFragmentState extends ConsumerState { List acceptList = []; List rejectList = []; late ScrollController _controller; + final _completer = Completer(); @override void initState() { super.initState(); _updateInitList(); _controller = ScrollController(); - WidgetsBinding.instance.addPostFrameCallback((_) { - final appState = globalState.appState; - if (appState.packages.isEmpty) { - Future.delayed(const Duration(milliseconds: 300), () async { - ref.read(packagesProvider.notifier).value = - await app?.getPackages() ?? []; - }); - } - }); + _completer.complete(globalState.appController.getPackages()); } @override @@ -319,31 +313,42 @@ class _AccessFragmentState extends ConsumerState { ), Expanded( flex: 1, - child: packages.isEmpty - ? const Center( - child: CircularProgressIndicator(), - ) - : CommonScrollBar( - controller: _controller, - child: ListView.builder( - controller: _controller, - itemCount: packages.length, - itemExtent: 72, - itemBuilder: (_, index) { - final package = packages[index]; - return PackageListItem( - key: Key(package.packageName), - package: package, - value: valueList.contains(package.packageName), - isActive: accessControl.enable, - onChanged: (value) { - _handleSelected(valueList, package, value); - }, + child: FutureBuilder( + future: _completer.future, + builder: (_, snapshot) { + if (snapshot.connectionState != ConnectionState.done) { + return Center( + child: CircularProgressIndicator(), + ); + } + return packages.isEmpty + ? NullStatus( + label: appLocalizations.noData, + ) + : CommonScrollBar( + controller: _controller, + child: ListView.builder( + controller: _controller, + itemCount: packages.length, + itemExtent: 72, + itemBuilder: (_, index) { + final package = packages[index]; + return PackageListItem( + key: Key(package.packageName), + package: package, + value: valueList + .contains(package.packageName), + isActive: accessControl.enable, + onChanged: (value) { + _handleSelected( + valueList, package, value); + }, + ); + }, + ), ); - }, - ), - ), - ), + }), + ) ], ), ), diff --git a/lib/fragments/backup_and_recovery.dart b/lib/fragments/backup_and_recovery.dart index dc1e594..05728d3 100644 --- a/lib/fragments/backup_and_recovery.dart +++ b/lib/fragments/backup_and_recovery.dart @@ -202,25 +202,25 @@ class BackupAndRecovery extends ConsumerWidget { builder: (_, snapshot) { return Center( child: FadeThroughBox( - child: snapshot.connectionState == - ConnectionState.waiting - ? const SizedBox( - width: 12, - height: 12, - child: CircularProgressIndicator( - strokeWidth: 1, - ), - ) - : Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - color: snapshot.data == true - ? Colors.green - : Colors.red, - ), - width: 12, - height: 12, - ), + child: + snapshot.connectionState != ConnectionState.done + ? const SizedBox( + width: 12, + height: 12, + child: CircularProgressIndicator( + strokeWidth: 1, + ), + ) + : Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: snapshot.data == true + ? Colors.green + : Colors.red, + ), + width: 12, + height: 12, + ), ), ); }, diff --git a/lib/fragments/connection/requests.dart b/lib/fragments/connection/requests.dart index e09aa40..f0b7b61 100644 --- a/lib/fragments/connection/requests.dart +++ b/lib/fragments/connection/requests.dart @@ -111,7 +111,7 @@ class _RequestsFragmentState extends ConsumerState } updateRequestsThrottler() { - throttler.call("request", () { + throttler.call(FunctionTag.requests, () { final isEquality = connectionListEquality.equals( _requests, _requestsStateNotifier.value.connections, @@ -120,9 +120,11 @@ class _RequestsFragmentState extends ConsumerState return; } WidgetsBinding.instance.addPostFrameCallback((_) { - _requestsStateNotifier.value = _requestsStateNotifier.value.copyWith( - connections: _requests, - ); + if(mounted){ + _requestsStateNotifier.value = _requestsStateNotifier.value.copyWith( + connections: _requests, + ); + } }); }, duration: commonDuration); } diff --git a/lib/fragments/dashboard/dashboard.dart b/lib/fragments/dashboard/dashboard.dart index 862e1ff..21fcc40 100644 --- a/lib/fragments/dashboard/dashboard.dart +++ b/lib/fragments/dashboard/dashboard.dart @@ -6,6 +6,7 @@ import 'package:fl_clash/providers/providers.dart'; import 'package:fl_clash/widgets/widgets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; + import 'widgets/start_button.dart'; class DashboardFragment extends ConsumerStatefulWidget { @@ -66,7 +67,16 @@ class _DashboardFragmentState extends ConsumerState valueListenable: key.currentState!.isEditNotifier, builder: (_, isEdit, ___) { return isEdit - ? Icon(Icons.save) + ? SystemBackBlock( + child: CommonPopScope( + child: Icon(Icons.save), + onPop: () { + key.currentState!.isEditNotifier.value = + !key.currentState!.isEditNotifier.value; + return false; + }, + ), + ) : Icon( Icons.edit, ); diff --git a/lib/fragments/dashboard/widgets/network_detection.dart b/lib/fragments/dashboard/widgets/network_detection.dart index 248f16c..8b6065f 100644 --- a/lib/fragments/dashboard/widgets/network_detection.dart +++ b/lib/fragments/dashboard/widgets/network_detection.dart @@ -1,23 +1,11 @@ -import 'dart:async'; - -import 'package:dio/dio.dart'; import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/enum/enum.dart'; import 'package:fl_clash/models/models.dart'; -import 'package:fl_clash/providers/app.dart'; import 'package:fl_clash/state.dart'; import 'package:fl_clash/widgets/widgets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -final _networkDetectionState = ValueNotifier( - const NetworkDetectionState( - isTesting: false, - isLoading: true, - ipInfo: null, - ), -); - class NetworkDetection extends ConsumerStatefulWidget { const NetworkDetection({super.key}); @@ -26,101 +14,6 @@ class NetworkDetection extends ConsumerStatefulWidget { } class _NetworkDetectionState extends ConsumerState { - bool? _preIsStart; - Timer? _setTimeoutTimer; - CancelToken? cancelToken; - - @override - void initState() { - ref.listenManual(checkIpNumProvider, (prev, next) { - if (prev != next) { - _startCheck(); - } - }); - if (!_networkDetectionState.value.isTesting && - _networkDetectionState.value.isLoading) { - _startCheck(); - } - super.initState(); - } - - _startCheck() async { - if (cancelToken != null) { - cancelToken!.cancel(); - cancelToken = null; - } - debouncer.call( - DebounceTag.checkIp, - _checkIp, - ); - } - - _checkIp() async { - final appState = globalState.appState; - final isInit = appState.isInit; - if (!isInit) return; - final isStart = appState.runTime != null; - if (_preIsStart == false && - _preIsStart == isStart && - _networkDetectionState.value.ipInfo != null) { - return; - } - _clearSetTimeoutTimer(); - _networkDetectionState.value = _networkDetectionState.value.copyWith( - isLoading: true, - ipInfo: null, - ); - _preIsStart = isStart; - if (cancelToken != null) { - cancelToken!.cancel(); - cancelToken = null; - } - cancelToken = CancelToken(); - try { - _networkDetectionState.value = _networkDetectionState.value.copyWith( - isTesting: true, - ); - final ipInfo = await request.checkIp(cancelToken: cancelToken); - _networkDetectionState.value = _networkDetectionState.value.copyWith( - isTesting: false, - ); - if (ipInfo != null) { - _networkDetectionState.value = _networkDetectionState.value.copyWith( - isLoading: false, - ipInfo: ipInfo, - ); - return; - } - _clearSetTimeoutTimer(); - _setTimeoutTimer = Timer(const Duration(milliseconds: 300), () { - _networkDetectionState.value = _networkDetectionState.value.copyWith( - isLoading: false, - ipInfo: null, - ); - }); - } catch (e) { - if (e.toString() == "cancelled") { - _networkDetectionState.value = _networkDetectionState.value.copyWith( - isLoading: true, - ipInfo: null, - ); - } - } - } - - @override - void dispose() { - _clearSetTimeoutTimer(); - super.dispose(); - } - - _clearSetTimeoutTimer() { - if (_setTimeoutTimer != null) { - _setTimeoutTimer?.cancel(); - _setTimeoutTimer = null; - } - } - _countryCodeToEmoji(String countryCode) { final String code = countryCode.toUpperCase(); if (code.length != 2) { @@ -136,7 +29,7 @@ class _NetworkDetectionState extends ConsumerState { return SizedBox( height: getWidgetHeight(1), child: ValueListenableBuilder( - valueListenable: _networkDetectionState, + valueListenable: detectionState.state, builder: (_, state, __) { final ipInfo = state.ipInfo; final isLoading = state.isLoading; diff --git a/lib/fragments/dashboard/widgets/start_button.dart b/lib/fragments/dashboard/widgets/start_button.dart index 66c1491..c1adf39 100644 --- a/lib/fragments/dashboard/widgets/start_button.dart +++ b/lib/fragments/dashboard/widgets/start_button.dart @@ -38,7 +38,7 @@ class _StartButtonState extends State isStart = !isStart; updateController(); debouncer.call( - DebounceTag.updateStatus, + FunctionTag.updateStatus, () { globalState.appController.updateStatus(isStart); }, diff --git a/lib/fragments/developer.dart b/lib/fragments/developer.dart index bf676c7..1c178ce 100644 --- a/lib/fragments/developer.dart +++ b/lib/fragments/developer.dart @@ -93,8 +93,6 @@ class DeveloperView extends ConsumerWidget { padding: const EdgeInsets.only( left: 16, right: 16, - top: 4, - bottom: 4, ), title: Text(appLocalizations.developerMode), delegate: SwitchDelegate( diff --git a/lib/fragments/hotkey.dart b/lib/fragments/hotkey.dart index 6feab46..e037923 100644 --- a/lib/fragments/hotkey.dart +++ b/lib/fragments/hotkey.dart @@ -103,7 +103,7 @@ class _HotKeyRecorderState extends State { modifiers: modifiers, key: key.usbHidUsage, ); - return true; + return false; } @override @@ -157,59 +157,65 @@ class _HotKeyRecorderState extends State { @override Widget build(BuildContext context) { - return CommonDialog( - title: IntlExt.actionMessage(widget.hotKeyAction.action.name), - actions: [ - TextButton( - onPressed: () { - _handleRemove(); - }, - child: Text(appLocalizations.remove), - ), - const SizedBox( - width: 8, - ), - TextButton( - onPressed: () { - _handleConfirm(); - }, - child: Text( - appLocalizations.confirm, + return Focus( + onKeyEvent: (_, __) { + return KeyEventResult.handled; + }, + autofocus: true, + child: CommonDialog( + title: IntlExt.actionMessage(widget.hotKeyAction.action.name), + actions: [ + TextButton( + onPressed: () { + _handleRemove(); + }, + child: Text(appLocalizations.remove), ), - ), - ], - child: ValueListenableBuilder( - valueListenable: hotKeyActionNotifier, - builder: (_, hotKeyAction, ___) { - final key = hotKeyAction.key; - final modifiers = hotKeyAction.modifiers; - return SizedBox( - width: dialogCommonWidth, - child: key != null - ? Wrap( - spacing: 8, - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - for (final modifier in modifiers) + const SizedBox( + width: 8, + ), + TextButton( + onPressed: () { + _handleConfirm(); + }, + child: Text( + appLocalizations.confirm, + ), + ), + ], + child: ValueListenableBuilder( + valueListenable: hotKeyActionNotifier, + builder: (_, hotKeyAction, ___) { + final key = hotKeyAction.key; + final modifiers = hotKeyAction.modifiers; + return SizedBox( + width: dialogCommonWidth, + child: key != null + ? Wrap( + spacing: 8, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + for (final modifier in modifiers) + KeyboardKeyBox( + keyboardKey: modifier.physicalKeys.first, + ), + if (modifiers.isNotEmpty) + Text( + "+", + style: context.textTheme.titleMedium, + ), KeyboardKeyBox( - keyboardKey: modifier.physicalKeys.first, + keyboardKey: PhysicalKeyboardKey(key), ), - if (modifiers.isNotEmpty) - Text( - "+", - style: context.textTheme.titleMedium, - ), - KeyboardKeyBox( - keyboardKey: PhysicalKeyboardKey(key), - ), - ], - ) - : Text( - appLocalizations.pressKeyboard, - style: context.textTheme.titleMedium, - ), - ); - }, + ], + ) + : Text( + appLocalizations.pressKeyboard, + style: context.textTheme.titleMedium, + ), + ); + }, + ), ), ); } diff --git a/lib/fragments/logs.dart b/lib/fragments/logs.dart index 6f75302..784647c 100644 --- a/lib/fragments/logs.dart +++ b/lib/fragments/logs.dart @@ -131,7 +131,7 @@ class _LogsFragmentState extends ConsumerState with PageMixin { } updateLogsThrottler() { - throttler.call("logs", () { + throttler.call(FunctionTag.logs, () { final isEquality = logListEquality.equals( _logs, _logsStateNotifier.value.logs, diff --git a/lib/fragments/profiles/override_profile.dart b/lib/fragments/profiles/override_profile.dart index b6b4cbf..5eebce8 100644 --- a/lib/fragments/profiles/override_profile.dart +++ b/lib/fragments/profiles/override_profile.dart @@ -305,8 +305,6 @@ class OverrideSwitch extends ConsumerWidget { padding: const EdgeInsets.only( left: 16, right: 16, - top: 4, - bottom: 4, ), title: Text(appLocalizations.enableOverride), delegate: SwitchDelegate( diff --git a/lib/fragments/profiles/profiles.dart b/lib/fragments/profiles/profiles.dart index c34055d..c6e7a6f 100644 --- a/lib/fragments/profiles/profiles.dart +++ b/lib/fragments/profiles/profiles.dart @@ -349,12 +349,10 @@ class ProfileItem extends StatelessWidget { ), PopupMenuItemData( icon: Icons.delete_outlined, - iconSize: 20, label: appLocalizations.delete, onPressed: () { _handleDeleteProfile(context); }, - type: PopupMenuItemType.danger, ), ], ), diff --git a/lib/fragments/proxies/common.dart b/lib/fragments/proxies/common.dart index 34ed1a0..6fd6a5a 100644 --- a/lib/fragments/proxies/common.dart +++ b/lib/fragments/proxies/common.dart @@ -6,7 +6,7 @@ import 'package:fl_clash/state.dart'; double get listHeaderHeight { final measure = globalState.measure; - return 28 + measure.titleMediumHeight + 4 + measure.bodyMediumHeight; + return 20 + measure.titleMediumHeight + 4 + measure.bodyMediumHeight; } double getItemHeight(ProxyCardType proxyCardType) { diff --git a/lib/fragments/proxies/list.dart b/lib/fragments/proxies/list.dart index 5cb82e6..ac74d4d 100644 --- a/lib/fragments/proxies/list.dart +++ b/lib/fragments/proxies/list.dart @@ -114,12 +114,16 @@ class _ProxiesListFragmentState extends State { required int columns, required Set currentUnfoldSet, required ProxyCardType type, + required String query, }) { final items = []; final GroupNameProxiesMap groupNameProxiesMap = {}; for (final groupName in groupNames) { - final group = - ref.read(groupsProvider.select((state) => state.getGroup(groupName))); + final group = ref.read( + groupsProvider.select( + (state) => state.getGroup(groupName), + ), + ); if (group == null) { continue; } @@ -140,7 +144,9 @@ class _ProxiesListFragmentState extends State { ]); if (isExpand) { final sortedProxies = globalState.appController.getSortProxies( - group.all, + group.all + .where((item) => item.name.toLowerCase().contains(query)) + .toList(), group.testUrl, ); groupNameProxiesMap[groupName] = sortedProxies; @@ -250,6 +256,7 @@ class _ProxiesListFragmentState extends State { return Consumer( builder: (_, ref, __) { final state = ref.watch(proxiesListSelectorStateProvider); + ref.watch(themeSettingProvider.select((state) => state.textScale)); if (state.groupNames.isEmpty) { return NullStatus( label: appLocalizations.nullProxies, @@ -261,6 +268,7 @@ class _ProxiesListFragmentState extends State { currentUnfoldSet: state.currentUnfoldSet, columns: state.columns, type: state.proxyCardType, + query: state.query, ); final itemsOffset = _getItemHeightList(items, state.proxyCardType); return CommonScrollBar( @@ -484,7 +492,7 @@ class _ListHeaderState extends State return CommonCard( enterAnimated: widget.enterAnimated, key: widget.key, - radius: 14, + radius: 16.ap, type: CommonCardType.filled, child: Padding( padding: const EdgeInsets.symmetric( @@ -587,7 +595,10 @@ class _ListHeaderState extends State const SizedBox( width: 6, ), - ], + ] else + SizedBox( + width: 4, + ), AnimatedBuilder( animation: _animationController.view, builder: (_, __) { diff --git a/lib/fragments/proxies/proxies.dart b/lib/fragments/proxies/proxies.dart index 0848ffb..6c50f41 100644 --- a/lib/fragments/proxies/proxies.dart +++ b/lib/fragments/proxies/proxies.dart @@ -2,10 +2,12 @@ import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/enum/enum.dart'; import 'package:fl_clash/fragments/proxies/list.dart'; import 'package:fl_clash/fragments/proxies/providers.dart'; +import 'package:fl_clash/models/common.dart'; import 'package:fl_clash/providers/providers.dart'; import 'package:fl_clash/widgets/widgets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; + import 'common.dart'; import 'setting.dart'; import 'tab.dart'; @@ -25,70 +27,98 @@ class _ProxiesFragmentState extends ConsumerState @override get actions => [ - if (_hasProviders) - IconButton( - onPressed: () { - showExtend( - context, - builder: (_, type) { - return ProvidersView( - type: type, - ); - }, - ); - }, - icon: const Icon( - Icons.poll_outlined, - ), - ), - _isTab - ? IconButton( + CommonPopupBox( + targetBuilder: (open) { + return IconButton( + onPressed: () { + open( + offset: Offset(0, 20), + ); + }, + icon: Icon( + Icons.more_vert, + ), + ); + }, + popup: CommonPopupMenu( + minWidth: 180, + items: [ + PopupMenuItemData( + icon: Icons.tune, + label: appLocalizations.settings, onPressed: () { - _proxiesTabKey.currentState?.scrollToGroupSelected(); - }, - icon: const Icon( - Icons.adjust_outlined, - ), - ) - : IconButton( - onPressed: () { - showExtend( - context, + showSheet( + context: context, + props: SheetProps( + isScrollControlled: true, + ), builder: (_, type) { return AdaptiveSheetScaffold( type: type, - body: const _IconConfigView(), - title: appLocalizations.iconConfiguration, + body: const ProxiesSetting(), + title: appLocalizations.settings, ); }, ); }, - icon: const Icon( - Icons.style_outlined, + ), + if (_hasProviders) + PopupMenuItemData( + icon: Icons.poll_outlined, + label: appLocalizations.providers, + onPressed: () { + showExtend( + context, + builder: (_, type) { + return ProvidersView( + type: type, + ); + }, + ); + }, ), - ), - IconButton( - onPressed: () { - showSheet( - context: context, - props: SheetProps( - isScrollControlled: true, - ), - builder: (_, type) { - return AdaptiveSheetScaffold( - type: type, - body: const ProxiesSetting(), - title: appLocalizations.settings, - ); - }, - ); - }, - icon: const Icon( - Icons.tune, + _isTab + ? PopupMenuItemData( + icon: Icons.adjust_outlined, + label: "聚焦", + onPressed: () { + _proxiesTabKey.currentState?.scrollToGroupSelected(); + }, + ) + : PopupMenuItemData( + icon: Icons.style_outlined, + label: appLocalizations.iconConfiguration, + onPressed: () { + showExtend( + context, + builder: (_, type) { + return AdaptiveSheetScaffold( + type: type, + body: const _IconConfigView(), + title: appLocalizations.iconConfiguration, + ); + }, + ); + }, + ), + ], ), ) ]; + @override + get onSearch => (value) { + ref.read(proxiesQueryProvider.notifier).value = value; + }; + + @override + void dispose() { + super.dispose(); + WidgetsBinding.instance.addPostFrameCallback((_) { + ref.read(proxiesQueryProvider.notifier).value = ""; + }); + } + @override get floatingActionButton => _isTab ? DelayTestButton( @@ -103,6 +133,70 @@ class _ProxiesFragmentState extends ConsumerState @override void initState() { + [ + if (_hasProviders) + IconButton( + onPressed: () { + showExtend( + context, + builder: (_, type) { + return ProvidersView( + type: type, + ); + }, + ); + }, + icon: const Icon( + Icons.poll_outlined, + ), + ), + _isTab + ? IconButton( + onPressed: () { + _proxiesTabKey.currentState?.scrollToGroupSelected(); + }, + icon: const Icon( + Icons.adjust_outlined, + ), + ) + : IconButton( + onPressed: () { + showExtend( + context, + builder: (_, type) { + return AdaptiveSheetScaffold( + type: type, + body: const _IconConfigView(), + title: appLocalizations.iconConfiguration, + ); + }, + ); + }, + icon: const Icon( + Icons.style_outlined, + ), + ), + IconButton( + onPressed: () { + showSheet( + context: context, + props: SheetProps( + isScrollControlled: true, + ), + builder: (_, type) { + return AdaptiveSheetScaffold( + type: type, + body: const ProxiesSetting(), + title: appLocalizations.settings, + ); + }, + ); + }, + icon: const Icon( + Icons.tune, + ), + ) + ]; ref.listenManual( proxiesActionsStateProvider, fireImmediately: true, @@ -128,8 +222,6 @@ class _ProxiesFragmentState extends ConsumerState (state) => state.type, ), ); - - ref.watch(themeSettingProvider.select((state) => state.textScale)); return switch (proxiesType) { ProxiesType.tab => ProxiesTabFragment( key: _proxiesTabKey, @@ -144,8 +236,9 @@ class _IconConfigView extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final iconMap = - ref.watch(proxiesStyleSettingProvider.select((state) => state.iconMap)); + final iconMap = ref.watch(proxiesStyleSettingProvider.select( + (state) => state.iconMap, + )); return MapInputPage( title: appLocalizations.iconConfiguration, map: iconMap, diff --git a/lib/fragments/proxies/tab.dart b/lib/fragments/proxies/tab.dart index 9d29656..38fcf60 100644 --- a/lib/fragments/proxies/tab.dart +++ b/lib/fragments/proxies/tab.dart @@ -164,7 +164,7 @@ class ProxiesTabFragmentState extends ConsumerState if (prev == next) { return; } - if (prev?.groupNames.length != next.groupNames.length) { + if (!stringListEquality.equals(prev?.groupNames, next.groupNames)) { _destroyTabController(); final index = next.groupNames.indexWhere( (item) => item == next.currentGroupName, @@ -178,6 +178,7 @@ class ProxiesTabFragmentState extends ConsumerState @override Widget build(BuildContext context) { + ref.watch(themeSettingProvider.select((state) => state.textScale)); final state = ref.watch(groupNamesStateProvider); final groupNames = state.groupNames; if (groupNames.isEmpty) { diff --git a/lib/main.dart b/lib/main.dart index cbccead..6737d4d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -21,9 +21,6 @@ import 'common/common.dart'; Future main() async { globalState.isService = false; WidgetsFlutterBinding.ensureInitialized(); - FlutterError.onError = (details) { - commonPrint.log(details.stack.toString()); - }; final version = await system.version; await clashCore.preload(); await globalState.initApp(version); diff --git a/lib/manager/app_state_manager.dart b/lib/manager/app_state_manager.dart index a9e7d99..daa4859 100644 --- a/lib/manager/app_state_manager.dart +++ b/lib/manager/app_state_manager.dart @@ -32,6 +32,15 @@ class _AppStateManagerState extends ConsumerState } }); }); + ref.listenManual( + checkIpProvider, + (prev, next) { + if (prev != next && next.b) { + detectionState.startCheck(); + } + }, + fireImmediately: true, + ); } @override diff --git a/lib/manager/clash_manager.dart b/lib/manager/clash_manager.dart index d45d62a..6021145 100644 --- a/lib/manager/clash_manager.dart +++ b/lib/manager/clash_manager.dart @@ -61,7 +61,7 @@ class _ClashContainerState extends ConsumerState final appController = globalState.appController; appController.setDelay(delay); debouncer.call( - DebounceTag.updateDelay, + FunctionTag.updateDelay, () async { await appController.updateGroupsDebounce(); }, diff --git a/lib/manager/hotkey_manager.dart b/lib/manager/hotkey_manager.dart index 1f6d540..b44c389 100644 --- a/lib/manager/hotkey_manager.dart +++ b/lib/manager/hotkey_manager.dart @@ -8,7 +8,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:hotkey_manager/hotkey_manager.dart'; -class HotKeyManager extends StatelessWidget { +class HotKeyManager extends ConsumerStatefulWidget { final Widget child; const HotKeyManager({ @@ -16,6 +16,25 @@ class HotKeyManager extends StatelessWidget { required this.child, }); + @override + ConsumerState createState() => _HotKeyManagerState(); +} + +class _HotKeyManagerState extends ConsumerState { + @override + void initState() { + super.initState(); + ref.listenManual( + hotKeyActionsProvider, + (prev, next) { + if (!hotKeyActionListEquality.equals(prev, next)) { + _updateHotKeys(hotKeyActions: next); + } + }, + fireImmediately: true, + ); + } + _handleHotKeyAction(HotAction action) async { switch (action) { case HotAction.mode: @@ -59,22 +78,30 @@ class HotKeyManager extends StatelessWidget { await Future.wait(hotkeyActionHandles); } + _buildShortcuts(Widget child) { + return Shortcuts( + shortcuts: { + utils.controlSingleActivator(LogicalKeyboardKey.keyW): + CloseWindowIntent(), + }, + child: Actions( + actions: { + CloseWindowIntent: CallbackAction( + onInvoke: (_) => globalState.appController.handleBackOrExit(), + ), + DoNothingIntent: CallbackAction( + onInvoke: (_) => null, + ), + }, + child: child, + ), + ); + } + @override Widget build(BuildContext context) { - return Consumer( - builder: (_, ref, child) { - ref.listenManual( - hotKeyActionsProvider, - (prev, next) { - if (!hotKeyActionListEquality.equals(prev, next)) { - _updateHotKeys(hotKeyActions: next); - } - }, - fireImmediately: true, - ); - return child!; - }, - child: child, + return _buildShortcuts( + widget.child, ); } } diff --git a/lib/manager/theme_manager.dart b/lib/manager/theme_manager.dart index 415364a..c6a8982 100644 --- a/lib/manager/theme_manager.dart +++ b/lib/manager/theme_manager.dart @@ -38,7 +38,7 @@ class ThemeManager extends ConsumerWidget { textScaleFactor, ), padding: padding.copyWith( - top: padding.top > height * 0.3 ? 0.0 : padding.top, + top: padding.top > height * 0.3 ? 20.0 : padding.top, ), ), child: LayoutBuilder( diff --git a/lib/manager/vpn_manager.dart b/lib/manager/vpn_manager.dart index 5ad197c..de56a9f 100644 --- a/lib/manager/vpn_manager.dart +++ b/lib/manager/vpn_manager.dart @@ -29,7 +29,7 @@ class _VpnContainerState extends ConsumerState { showTip() { debouncer.call( - DebounceTag.vpnTip, + FunctionTag.vpnTip, () { if (ref.read(runTimeProvider.notifier).isStart) { globalState.showNotifier( diff --git a/lib/manager/window_manager.dart b/lib/manager/window_manager.dart index 821f49a..d1b3195 100644 --- a/lib/manager/window_manager.dart +++ b/lib/manager/window_manager.dart @@ -38,7 +38,7 @@ class _WindowContainerState extends ConsumerState (prev, next) { if (prev != next) { debouncer.call( - DebounceTag.autoLaunch, + FunctionTag.autoLaunch, () { autoLaunch?.updateStatus(next); }, @@ -103,7 +103,7 @@ class _WindowContainerState extends ConsumerState @override Future onTaskbarCreated() async { - globalState.appController.updateTray(true); + // globalState.appController.updateTray(true); super.onTaskbarCreated(); } diff --git a/lib/models/app.dart b/lib/models/app.dart index 5fccfbc..bc6d9f5 100644 --- a/lib/models/app.dart +++ b/lib/models/app.dart @@ -14,6 +14,7 @@ typedef DelayMap = Map>; class AppState with _$AppState { const factory AppState({ @Default(false) bool isInit, + @Default(false) bool backBlock, @Default(PageLabel.dashboard) PageLabel pageLabel, @Default([]) List packages, @Default(0) int sortNum, @@ -30,6 +31,7 @@ class AppState with _$AppState { required FixedList logs, required FixedList traffics, required Traffic totalTraffic, + @Default("") String proxiesQuery, @Default(false) bool needApply, }) = _AppState; } diff --git a/lib/models/common.dart b/lib/models/common.dart index eb796ae..55210ed 100644 --- a/lib/models/common.dart +++ b/lib/models/common.dart @@ -8,7 +8,6 @@ import 'package:flutter/material.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'generated/common.freezed.dart'; - part 'generated/common.g.dart'; @freezed @@ -129,10 +128,10 @@ extension LogsStateExt on LogsState { final lowQuery = query.toLowerCase(); return logs.where( (log) { - final payload = log.payload.toLowerCase(); final logLevelName = log.logLevel.name; return {logLevelName}.containsAll(keywords) && - ((payload.contains(lowQuery)) || logLevelName.contains(lowQuery)); + ((log.payload.toLowerCase().contains(lowQuery)) || + logLevelName.contains(lowQuery)); }, ).toList(); } @@ -504,15 +503,11 @@ class PopupMenuItemData { this.icon, required this.label, required this.onPressed, - this.type, - this.iconSize, }); - final double? iconSize; final String label; final VoidCallback? onPressed; final IconData? icon; - final PopupMenuItemType? type; } @freezed @@ -528,3 +523,7 @@ class TextPainterParams with _$TextPainterParams { factory TextPainterParams.fromJson(Map json) => _$TextPainterParamsFromJson(json); } + +class CloseWindowIntent extends Intent { + const CloseWindowIntent(); +} diff --git a/lib/models/generated/app.freezed.dart b/lib/models/generated/app.freezed.dart index fd01404..752fd58 100644 --- a/lib/models/generated/app.freezed.dart +++ b/lib/models/generated/app.freezed.dart @@ -17,6 +17,7 @@ final _privateConstructorUsedError = UnsupportedError( /// @nodoc mixin _$AppState { bool get isInit => throw _privateConstructorUsedError; + bool get backBlock => throw _privateConstructorUsedError; PageLabel get pageLabel => throw _privateConstructorUsedError; List get packages => throw _privateConstructorUsedError; int get sortNum => throw _privateConstructorUsedError; @@ -34,6 +35,7 @@ mixin _$AppState { FixedList get logs => throw _privateConstructorUsedError; FixedList get traffics => throw _privateConstructorUsedError; Traffic get totalTraffic => throw _privateConstructorUsedError; + String get proxiesQuery => throw _privateConstructorUsedError; bool get needApply => throw _privateConstructorUsedError; /// Create a copy of AppState @@ -50,6 +52,7 @@ abstract class $AppStateCopyWith<$Res> { @useResult $Res call( {bool isInit, + bool backBlock, PageLabel pageLabel, List packages, int sortNum, @@ -66,6 +69,7 @@ abstract class $AppStateCopyWith<$Res> { FixedList logs, FixedList traffics, Traffic totalTraffic, + String proxiesQuery, bool needApply}); } @@ -85,6 +89,7 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState> @override $Res call({ Object? isInit = null, + Object? backBlock = null, Object? pageLabel = null, Object? packages = null, Object? sortNum = null, @@ -101,6 +106,7 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState> Object? logs = null, Object? traffics = null, Object? totalTraffic = null, + Object? proxiesQuery = null, Object? needApply = null, }) { return _then(_value.copyWith( @@ -108,6 +114,10 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState> ? _value.isInit : isInit // ignore: cast_nullable_to_non_nullable as bool, + backBlock: null == backBlock + ? _value.backBlock + : backBlock // ignore: cast_nullable_to_non_nullable + as bool, pageLabel: null == pageLabel ? _value.pageLabel : pageLabel // ignore: cast_nullable_to_non_nullable @@ -172,6 +182,10 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState> ? _value.totalTraffic : totalTraffic // ignore: cast_nullable_to_non_nullable as Traffic, + proxiesQuery: null == proxiesQuery + ? _value.proxiesQuery + : proxiesQuery // ignore: cast_nullable_to_non_nullable + as String, needApply: null == needApply ? _value.needApply : needApply // ignore: cast_nullable_to_non_nullable @@ -190,6 +204,7 @@ abstract class _$$AppStateImplCopyWith<$Res> @useResult $Res call( {bool isInit, + bool backBlock, PageLabel pageLabel, List packages, int sortNum, @@ -206,6 +221,7 @@ abstract class _$$AppStateImplCopyWith<$Res> FixedList logs, FixedList traffics, Traffic totalTraffic, + String proxiesQuery, bool needApply}); } @@ -223,6 +239,7 @@ class __$$AppStateImplCopyWithImpl<$Res> @override $Res call({ Object? isInit = null, + Object? backBlock = null, Object? pageLabel = null, Object? packages = null, Object? sortNum = null, @@ -239,6 +256,7 @@ class __$$AppStateImplCopyWithImpl<$Res> Object? logs = null, Object? traffics = null, Object? totalTraffic = null, + Object? proxiesQuery = null, Object? needApply = null, }) { return _then(_$AppStateImpl( @@ -246,6 +264,10 @@ class __$$AppStateImplCopyWithImpl<$Res> ? _value.isInit : isInit // ignore: cast_nullable_to_non_nullable as bool, + backBlock: null == backBlock + ? _value.backBlock + : backBlock // ignore: cast_nullable_to_non_nullable + as bool, pageLabel: null == pageLabel ? _value.pageLabel : pageLabel // ignore: cast_nullable_to_non_nullable @@ -310,6 +332,10 @@ class __$$AppStateImplCopyWithImpl<$Res> ? _value.totalTraffic : totalTraffic // ignore: cast_nullable_to_non_nullable as Traffic, + proxiesQuery: null == proxiesQuery + ? _value.proxiesQuery + : proxiesQuery // ignore: cast_nullable_to_non_nullable + as String, needApply: null == needApply ? _value.needApply : needApply // ignore: cast_nullable_to_non_nullable @@ -323,6 +349,7 @@ class __$$AppStateImplCopyWithImpl<$Res> class _$AppStateImpl implements _AppState { const _$AppStateImpl( {this.isInit = false, + this.backBlock = false, this.pageLabel = PageLabel.dashboard, final List packages = const [], this.sortNum = 0, @@ -339,6 +366,7 @@ class _$AppStateImpl implements _AppState { required this.logs, required this.traffics, required this.totalTraffic, + this.proxiesQuery = "", this.needApply = false}) : _packages = packages, _delayMap = delayMap, @@ -350,6 +378,9 @@ class _$AppStateImpl implements _AppState { final bool isInit; @override @JsonKey() + final bool backBlock; + @override + @JsonKey() final PageLabel pageLabel; final List _packages; @override @@ -413,11 +444,14 @@ class _$AppStateImpl implements _AppState { final Traffic totalTraffic; @override @JsonKey() + final String proxiesQuery; + @override + @JsonKey() final bool needApply; @override String toString() { - return 'AppState(isInit: $isInit, pageLabel: $pageLabel, packages: $packages, sortNum: $sortNum, viewSize: $viewSize, delayMap: $delayMap, groups: $groups, checkIpNum: $checkIpNum, brightness: $brightness, runTime: $runTime, providers: $providers, localIp: $localIp, requests: $requests, version: $version, logs: $logs, traffics: $traffics, totalTraffic: $totalTraffic, needApply: $needApply)'; + return 'AppState(isInit: $isInit, backBlock: $backBlock, pageLabel: $pageLabel, packages: $packages, sortNum: $sortNum, viewSize: $viewSize, delayMap: $delayMap, groups: $groups, checkIpNum: $checkIpNum, brightness: $brightness, runTime: $runTime, providers: $providers, localIp: $localIp, requests: $requests, version: $version, logs: $logs, traffics: $traffics, totalTraffic: $totalTraffic, proxiesQuery: $proxiesQuery, needApply: $needApply)'; } @override @@ -426,6 +460,8 @@ class _$AppStateImpl implements _AppState { (other.runtimeType == runtimeType && other is _$AppStateImpl && (identical(other.isInit, isInit) || other.isInit == isInit) && + (identical(other.backBlock, backBlock) || + other.backBlock == backBlock) && (identical(other.pageLabel, pageLabel) || other.pageLabel == pageLabel) && const DeepCollectionEquality().equals(other._packages, _packages) && @@ -450,31 +486,36 @@ class _$AppStateImpl implements _AppState { other.traffics == traffics) && (identical(other.totalTraffic, totalTraffic) || other.totalTraffic == totalTraffic) && + (identical(other.proxiesQuery, proxiesQuery) || + other.proxiesQuery == proxiesQuery) && (identical(other.needApply, needApply) || other.needApply == needApply)); } @override - int get hashCode => Object.hash( - runtimeType, - isInit, - pageLabel, - const DeepCollectionEquality().hash(_packages), - sortNum, - viewSize, - const DeepCollectionEquality().hash(_delayMap), - const DeepCollectionEquality().hash(_groups), - checkIpNum, - brightness, - runTime, - const DeepCollectionEquality().hash(_providers), - localIp, - requests, - version, - logs, - traffics, - totalTraffic, - needApply); + int get hashCode => Object.hashAll([ + runtimeType, + isInit, + backBlock, + pageLabel, + const DeepCollectionEquality().hash(_packages), + sortNum, + viewSize, + const DeepCollectionEquality().hash(_delayMap), + const DeepCollectionEquality().hash(_groups), + checkIpNum, + brightness, + runTime, + const DeepCollectionEquality().hash(_providers), + localIp, + requests, + version, + logs, + traffics, + totalTraffic, + proxiesQuery, + needApply + ]); /// Create a copy of AppState /// with the given fields replaced by the non-null parameter values. @@ -488,6 +529,7 @@ class _$AppStateImpl implements _AppState { abstract class _AppState implements AppState { const factory _AppState( {final bool isInit, + final bool backBlock, final PageLabel pageLabel, final List packages, final int sortNum, @@ -504,11 +546,14 @@ abstract class _AppState implements AppState { required final FixedList logs, required final FixedList traffics, required final Traffic totalTraffic, + final String proxiesQuery, final bool needApply}) = _$AppStateImpl; @override bool get isInit; @override + bool get backBlock; + @override PageLabel get pageLabel; @override List get packages; @@ -541,6 +586,8 @@ abstract class _AppState implements AppState { @override Traffic get totalTraffic; @override + String get proxiesQuery; + @override bool get needApply; /// Create a copy of AppState diff --git a/lib/models/generated/selector.freezed.dart b/lib/models/generated/selector.freezed.dart index 34db08f..b8f7c44 100644 --- a/lib/models/generated/selector.freezed.dart +++ b/lib/models/generated/selector.freezed.dart @@ -2142,6 +2142,7 @@ mixin _$ProxiesListSelectorState { ProxyCardType get proxyCardType => throw _privateConstructorUsedError; num get sortNum => throw _privateConstructorUsedError; int get columns => throw _privateConstructorUsedError; + String get query => throw _privateConstructorUsedError; /// Create a copy of ProxiesListSelectorState /// with the given fields replaced by the non-null parameter values. @@ -2162,7 +2163,8 @@ abstract class $ProxiesListSelectorStateCopyWith<$Res> { ProxiesSortType proxiesSortType, ProxyCardType proxyCardType, num sortNum, - int columns}); + int columns, + String query}); } /// @nodoc @@ -2187,6 +2189,7 @@ class _$ProxiesListSelectorStateCopyWithImpl<$Res, Object? proxyCardType = null, Object? sortNum = null, Object? columns = null, + Object? query = null, }) { return _then(_value.copyWith( groupNames: null == groupNames @@ -2213,6 +2216,10 @@ class _$ProxiesListSelectorStateCopyWithImpl<$Res, ? _value.columns : columns // ignore: cast_nullable_to_non_nullable as int, + query: null == query + ? _value.query + : query // ignore: cast_nullable_to_non_nullable + as String, ) as $Val); } } @@ -2232,7 +2239,8 @@ abstract class _$$ProxiesListSelectorStateImplCopyWith<$Res> ProxiesSortType proxiesSortType, ProxyCardType proxyCardType, num sortNum, - int columns}); + int columns, + String query}); } /// @nodoc @@ -2256,6 +2264,7 @@ class __$$ProxiesListSelectorStateImplCopyWithImpl<$Res> Object? proxyCardType = null, Object? sortNum = null, Object? columns = null, + Object? query = null, }) { return _then(_$ProxiesListSelectorStateImpl( groupNames: null == groupNames @@ -2282,6 +2291,10 @@ class __$$ProxiesListSelectorStateImplCopyWithImpl<$Res> ? _value.columns : columns // ignore: cast_nullable_to_non_nullable as int, + query: null == query + ? _value.query + : query // ignore: cast_nullable_to_non_nullable + as String, )); } } @@ -2295,7 +2308,8 @@ class _$ProxiesListSelectorStateImpl implements _ProxiesListSelectorState { required this.proxiesSortType, required this.proxyCardType, required this.sortNum, - required this.columns}) + required this.columns, + required this.query}) : _groupNames = groupNames, _currentUnfoldSet = currentUnfoldSet; @@ -2323,10 +2337,12 @@ class _$ProxiesListSelectorStateImpl implements _ProxiesListSelectorState { final num sortNum; @override final int columns; + @override + final String query; @override String toString() { - return 'ProxiesListSelectorState(groupNames: $groupNames, currentUnfoldSet: $currentUnfoldSet, proxiesSortType: $proxiesSortType, proxyCardType: $proxyCardType, sortNum: $sortNum, columns: $columns)'; + return 'ProxiesListSelectorState(groupNames: $groupNames, currentUnfoldSet: $currentUnfoldSet, proxiesSortType: $proxiesSortType, proxyCardType: $proxyCardType, sortNum: $sortNum, columns: $columns, query: $query)'; } @override @@ -2343,7 +2359,8 @@ class _$ProxiesListSelectorStateImpl implements _ProxiesListSelectorState { (identical(other.proxyCardType, proxyCardType) || other.proxyCardType == proxyCardType) && (identical(other.sortNum, sortNum) || other.sortNum == sortNum) && - (identical(other.columns, columns) || other.columns == columns)); + (identical(other.columns, columns) || other.columns == columns) && + (identical(other.query, query) || other.query == query)); } @override @@ -2354,7 +2371,8 @@ class _$ProxiesListSelectorStateImpl implements _ProxiesListSelectorState { proxiesSortType, proxyCardType, sortNum, - columns); + columns, + query); /// Create a copy of ProxiesListSelectorState /// with the given fields replaced by the non-null parameter values. @@ -2373,7 +2391,8 @@ abstract class _ProxiesListSelectorState implements ProxiesListSelectorState { required final ProxiesSortType proxiesSortType, required final ProxyCardType proxyCardType, required final num sortNum, - required final int columns}) = _$ProxiesListSelectorStateImpl; + required final int columns, + required final String query}) = _$ProxiesListSelectorStateImpl; @override List get groupNames; @@ -2387,6 +2406,8 @@ abstract class _ProxiesListSelectorState implements ProxiesListSelectorState { num get sortNum; @override int get columns; + @override + String get query; /// Create a copy of ProxiesListSelectorState /// with the given fields replaced by the non-null parameter values. diff --git a/lib/models/selector.dart b/lib/models/selector.dart index 11d1d83..a241f7f 100644 --- a/lib/models/selector.dart +++ b/lib/models/selector.dart @@ -25,7 +25,7 @@ class VM3 with _$VM3 { } @freezed -class VM4 with _$VM4 { +class VM4 with _$VM4 { const factory VM4({ required A a, required B b, @@ -34,7 +34,6 @@ class VM4 with _$VM4 { }) = _VM4; } - @freezed class StartButtonSelectorState with _$StartButtonSelectorState { const factory StartButtonSelectorState({ @@ -125,6 +124,7 @@ class ProxiesListSelectorState with _$ProxiesListSelectorState { required ProxyCardType proxyCardType, required num sortNum, required int columns, + required String query, }) = _ProxiesListSelectorState; } diff --git a/lib/pages/editor.dart b/lib/pages/editor.dart index bd25441..5b0a745 100644 --- a/lib/pages/editor.dart +++ b/lib/pages/editor.dart @@ -122,12 +122,15 @@ class _EditorPageState extends ConsumerState { (value) => CommonPopupBox( targetBuilder: (open) { return IconButton( - onPressed: open, + onPressed: () { + open( + offset: Offset(0, 20), + ); + }, icon: const Icon(Icons.more_vert), ); }, popup: CommonPopupMenu( - minWidth: 180, items: [ PopupMenuItemData( icon: Icons.search, @@ -151,6 +154,7 @@ class _EditorPageState extends ConsumerState { ], body: CodeEditor( findController: _findController, + maxLengthSingleLineRendering: 200, findBuilder: (context, controller, readOnly) => FindPanel( controller: controller, readOnly: readOnly, @@ -190,7 +194,7 @@ class _EditorPageState extends ConsumerState { shortcutsActivatorsBuilder: DefaultCodeShortcutsActivatorsBuilder(), controller: _controller, style: CodeEditorStyle( - fontSize: 14.ap, + fontSize: context.textTheme.bodyLarge?.fontSize?.ap, fontFamily: FontFamily.jetBrainsMono.value, codeTheme: CodeHighlightTheme( languages: { diff --git a/lib/providers/app.dart b/lib/providers/app.dart index 89bf3ae..0305df2 100644 --- a/lib/providers/app.dart +++ b/lib/providers/app.dart @@ -286,6 +286,21 @@ class CheckIpNum extends _$CheckIpNum with AutoDisposeNotifierMixin { add() => state++; } +@riverpod +class BackBlock extends _$BackBlock with AutoDisposeNotifierMixin { + @override + bool build() { + return globalState.appState.backBlock; + } + + @override + onUpdate(value) { + globalState.appState = globalState.appState.copyWith( + backBlock: value, + ); + } +} + @riverpod class Version extends _$Version with AutoDisposeNotifierMixin { @override @@ -356,3 +371,18 @@ class NeedApply extends _$NeedApply with AutoDisposeNotifierMixin { ); } } + +@riverpod +class ProxiesQuery extends _$ProxiesQuery with AutoDisposeNotifierMixin { + @override + String build() { + return globalState.appState.proxiesQuery; + } + + @override + onUpdate(value) { + globalState.appState = globalState.appState.copyWith( + proxiesQuery: value, + ); + } +} diff --git a/lib/providers/generated/app.g.dart b/lib/providers/generated/app.g.dart index 14524c1..dbb4c4c 100644 --- a/lib/providers/generated/app.g.dart +++ b/lib/providers/generated/app.g.dart @@ -276,6 +276,20 @@ final checkIpNumProvider = ); typedef _$CheckIpNum = AutoDisposeNotifier; +String _$backBlockHash() => r'c0223e0776b72d3a8c8842fc32fdb5287353999f'; + +/// See also [BackBlock]. +@ProviderFor(BackBlock) +final backBlockProvider = AutoDisposeNotifierProvider.internal( + BackBlock.new, + name: r'backBlockProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$backBlockHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$BackBlock = AutoDisposeNotifier; String _$versionHash() => r'8c0ee019d20df3f112c38ae4dc4abd61148d3809'; /// See also [Version]. @@ -335,5 +349,20 @@ final needApplyProvider = AutoDisposeNotifierProvider.internal( ); typedef _$NeedApply = AutoDisposeNotifier; +String _$proxiesQueryHash() => r'9f3907e06534b6882684bec47ca3ba2988297e19'; + +/// See also [ProxiesQuery]. +@ProviderFor(ProxiesQuery) +final proxiesQueryProvider = + AutoDisposeNotifierProvider.internal( + ProxiesQuery.new, + name: r'proxiesQueryProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$proxiesQueryHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$ProxiesQuery = AutoDisposeNotifier; // ignore_for_file: type=lint // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/providers/generated/state.g.dart b/lib/providers/generated/state.g.dart index ab3f932..3ff9ec1 100644 --- a/lib/providers/generated/state.g.dart +++ b/lib/providers/generated/state.g.dart @@ -236,7 +236,7 @@ final profilesSelectorStateProvider = typedef ProfilesSelectorStateRef = AutoDisposeProviderRef; String _$proxiesListSelectorStateHash() => - r'0e63ea2fb141e086156a2ed8452584e2375c5aa5'; + r'5e6bbe1a0cecbdea6c9c62e6ccf314968deac264'; /// See also [proxiesListSelectorState]. @ProviderFor(proxiesListSelectorState) @@ -292,7 +292,7 @@ final groupNamesStateProvider = AutoDisposeProvider.internal( // ignore: unused_element typedef GroupNamesStateRef = AutoDisposeProviderRef; String _$proxyGroupSelectorStateHash() => - r'5bc86d13286c6c859f0b874235a281122cc612ba'; + r'50940ff452859b02af0095cb7c4bcda813847645'; /// Copied from Dart SDK class _SystemHash { @@ -1781,6 +1781,22 @@ final layoutChangeProvider = AutoDisposeProvider.internal( @Deprecated('Will be removed in 3.0. Use Ref instead') // ignore: unused_element typedef LayoutChangeRef = AutoDisposeProviderRef; +String _$checkIpHash() => r'07ebf8d032349e2b3adda483e68b1936ffbed68d'; + +/// See also [checkIp]. +@ProviderFor(checkIp) +final checkIpProvider = AutoDisposeProvider>.internal( + checkIp, + name: r'checkIpProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$checkIpHash, + dependencies: null, + allTransitiveDependencies: null, +); + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +typedef CheckIpRef = AutoDisposeProviderRef>; String _$genColorSchemeHash() => r'b18f15c938a8132ee4ed02cdfc02f3b9f01724e2'; /// See also [genColorScheme]. diff --git a/lib/providers/state.dart b/lib/providers/state.dart index 9359f3b..6b2821f 100644 --- a/lib/providers/state.dart +++ b/lib/providers/state.dart @@ -210,7 +210,10 @@ ProfilesSelectorState profilesSelectorState(Ref ref) { final currentProfileId = ref.watch(currentProfileIdProvider); final profiles = ref.watch(profilesProvider); final columns = ref.watch( - viewWidthProvider.select((state) => utils.getProfilesColumns(state))); + viewWidthProvider.select( + (state) => utils.getProfilesColumns(state), + ), + ); return ProfilesSelectorState( profiles: profiles, currentProfileId: currentProfileId, @@ -227,6 +230,8 @@ ProxiesListSelectorState proxiesListSelectorState(Ref ref) { final proxiesStyle = ref.watch(proxiesStyleSettingProvider); final sortNum = ref.watch(sortNumProvider); final columns = ref.watch(getProxiesColumnsProvider); + final query = + ref.watch(proxiesQueryProvider.select((state) => state.toLowerCase())); return ProxiesListSelectorState( groupNames: groupNames, currentUnfoldSet: currentUnfoldSet, @@ -234,6 +239,7 @@ ProxiesListSelectorState proxiesListSelectorState(Ref ref) { proxyCardType: proxiesStyle.cardType, sortNum: sortNum, columns: columns, + query: query, ); } @@ -280,13 +286,19 @@ ProxyGroupSelectorState proxyGroupSelectorState(Ref ref, String groupName) { ); final sortNum = ref.watch(sortNumProvider); final columns = ref.watch(getProxiesColumnsProvider); + final query = + ref.watch(proxiesQueryProvider.select((state) => state.toLowerCase())); + final proxies = group?.all.where((item) { + return item.name.contains(query); + }).toList() ?? + []; return ProxyGroupSelectorState( testUrl: group?.testUrl, proxiesSortType: proxiesStyle.sortType, proxyCardType: proxiesStyle.cardType, sortNum: sortNum, groupType: group?.type ?? GroupType.Selector, - proxies: group?.all ?? [], + proxies: proxies, columns: columns, ); } @@ -521,6 +533,21 @@ VM2? layoutChange(Ref ref) { ); } +@riverpod +VM2 checkIp(Ref ref) { + final checkIpNum = ref.watch(checkIpNumProvider); + final containsDetection = ref.watch( + dashboardStateProvider.select( + (state) => + state.dashboardWidgets.contains(DashboardWidget.networkDetection), + ), + ); + return VM2( + a: checkIpNum, + b: containsDetection, + ); +} + @riverpod ColorScheme genColorScheme( Ref ref, diff --git a/lib/state.dart b/lib/state.dart index 8891ad6..cefc2b0 100644 --- a/lib/state.dart +++ b/lib/state.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'package:animations/animations.dart'; +import 'package:dio/dio.dart'; import 'package:dynamic_color/dynamic_color.dart'; import 'package:fl_clash/clash/clash.dart'; import 'package:fl_clash/common/theme.dart'; @@ -289,3 +290,94 @@ class GlobalState { } final globalState = GlobalState(); + +class DetectionState { + static DetectionState? _instance; + bool? _preIsStart; + Timer? _setTimeoutTimer; + CancelToken? cancelToken; + + final state = ValueNotifier( + const NetworkDetectionState( + isTesting: false, + isLoading: true, + ipInfo: null, + ), + ); + + DetectionState._internal(); + + factory DetectionState() { + _instance ??= DetectionState._internal(); + return _instance!; + } + + startCheck() { + debouncer.call( + FunctionTag.checkIp, + _checkIp, + ); + } + + _checkIp() async { + final appState = globalState.appState; + final isInit = appState.isInit; + if (!isInit) return; + final isStart = appState.runTime != null; + if (_preIsStart == false && + _preIsStart == isStart && + state.value.ipInfo != null) { + return; + } + _clearSetTimeoutTimer(); + state.value = state.value.copyWith( + isLoading: true, + ipInfo: null, + ); + _preIsStart = isStart; + if (cancelToken != null) { + cancelToken!.cancel(); + cancelToken = null; + } + cancelToken = CancelToken(); + try { + state.value = state.value.copyWith( + isTesting: true, + ); + final ipInfo = await request.checkIp(cancelToken: cancelToken); + state.value = state.value.copyWith( + isTesting: false, + ); + if (ipInfo != null) { + state.value = state.value.copyWith( + isLoading: false, + ipInfo: ipInfo, + ); + return; + } + _clearSetTimeoutTimer(); + _setTimeoutTimer = Timer(const Duration(milliseconds: 300), () { + state.value = state.value.copyWith( + isLoading: false, + ipInfo: null, + ); + }); + } catch (e) { + if (e.toString() == "cancelled") { + state.value = state.value.copyWith( + isLoading: true, + ipInfo: null, + ); + } + } + } + + _clearSetTimeoutTimer() { + if (_setTimeoutTimer != null) { + _setTimeoutTimer?.cancel(); + _setTimeoutTimer = null; + } + } +} + +final detectionState = DetectionState(); diff --git a/lib/widgets/input.dart b/lib/widgets/input.dart index 2cc5831..96fca73 100644 --- a/lib/widgets/input.dart +++ b/lib/widgets/input.dart @@ -10,7 +10,7 @@ import 'card.dart'; import 'float_layout.dart'; import 'list.dart'; -class OptionsDialog extends StatefulWidget { +class OptionsDialog extends StatelessWidget { final String title; final List options; final T value; @@ -24,48 +24,35 @@ class OptionsDialog extends StatefulWidget { required this.value, }); - @override - State> createState() => _OptionsDialogState(); -} - -class _OptionsDialogState extends State> { - final _defaultValue = ""; - - @override - void initState() { - super.initState(); - WidgetsBinding.instance.addPostFrameCallback((_) { - final context = - GlobalObjectKey(widget.value ?? _defaultValue).currentContext; - if (context != null) { - Scrollable.ensureVisible(context); - } - }); - } - @override Widget build(BuildContext context) { return CommonDialog( - title: widget.title, + title: title, padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 16, ), child: Wrap( children: [ - for (final option in widget.options) - ListItem.radio( - key: GlobalObjectKey(option ?? _defaultValue), - delegate: RadioDelegate( - value: option, - groupValue: widget.value, - onChanged: (T? value) { - Navigator.of(context).pop(value); - }, - ), - title: Text( - widget.textBuilder(option), - ), + for (final option in options) + Builder( + builder: (context) { + if (value == option) { + WidgetsBinding.instance.addPostFrameCallback((_) { + Scrollable.ensureVisible(context); + }); + } + return ListItem.radio( + delegate: RadioDelegate( + value: option, + groupValue: value, + onChanged: (T? value) { + Navigator.of(context).pop(value); + }, + ), + title: Text(textBuilder(option)), + ); + }, ), ], ), diff --git a/lib/widgets/pop_scope.dart b/lib/widgets/pop_scope.dart index bc2dd06..6916541 100644 --- a/lib/widgets/pop_scope.dart +++ b/lib/widgets/pop_scope.dart @@ -1,4 +1,6 @@ import 'dart:async'; + +import 'package:fl_clash/state.dart'; import 'package:flutter/widgets.dart'; class CommonPopScope extends StatelessWidget { @@ -34,3 +36,38 @@ class CommonPopScope extends StatelessWidget { ); } } + +class SystemBackBlock extends StatefulWidget { + final Widget child; + + const SystemBackBlock({ + super.key, + required this.child, + }); + + @override + State createState() => _SystemBackBlockState(); +} + +class _SystemBackBlockState extends State { + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + globalState.appController.backBlock(); + }); + } + + @override + void dispose() { + super.dispose(); + WidgetsBinding.instance.addPostFrameCallback((_) { + globalState.appController.unBackBlock(); + }); + } + + @override + Widget build(BuildContext context) { + return widget.child; + } +} diff --git a/lib/widgets/popup.dart b/lib/widgets/popup.dart index c5f593c..65f866b 100644 --- a/lib/widgets/popup.dart +++ b/lib/widgets/popup.dart @@ -201,12 +201,16 @@ class OverflowAwareLayoutDelegate extends SingleChildLayoutDelegate { class CommonPopupMenu extends StatelessWidget { final List items; - final double? minWidth; + final double minWidth; + final double minItemVerticalPadding; + final double fontSize; const CommonPopupMenu({ super.key, required this.items, - this.minWidth, + this.minWidth = 160, + this.minItemVerticalPadding = 16, + this.fontSize = 15, }); Widget _popupMenuItem( @@ -214,16 +218,11 @@ class CommonPopupMenu extends StatelessWidget { required PopupMenuItemData item, required int index, }) { - final isDanger = item.type == PopupMenuItemType.danger; final onPressed = item.onPressed; final disabled = onPressed == null; - final color = isDanger - ? disabled - ? context.colorScheme.error.opacity30 - : context.colorScheme.error - : disabled - ? context.colorScheme.onSurface.opacity30 - : context.colorScheme.onSurface; + final color = disabled + ? context.colorScheme.onSurface.opacity30 + : context.colorScheme.onSurface; return InkWell( onTap: onPressed != null ? () { @@ -233,13 +232,13 @@ class CommonPopupMenu extends StatelessWidget { : null, child: Container( constraints: BoxConstraints( - minWidth: minWidth ?? 120, + minWidth: minWidth, ), padding: EdgeInsets.only( left: 16, right: 64, - top: 14, - bottom: 14, + top: minItemVerticalPadding, + bottom: minItemVerticalPadding, ), child: Row( mainAxisSize: MainAxisSize.max, @@ -247,7 +246,7 @@ class CommonPopupMenu extends StatelessWidget { if (item.icon != null) ...[ Icon( item.icon, - size: item.iconSize ?? 18, + size: fontSize + 4, color: color, ), SizedBox( @@ -259,6 +258,7 @@ class CommonPopupMenu extends StatelessWidget { item.label, style: context.textTheme.bodyMedium?.copyWith( color: color, + fontSize: fontSize, ), ), ), diff --git a/lib/widgets/scaffold.dart b/lib/widgets/scaffold.dart index df858a9..0005c0c 100644 --- a/lib/widgets/scaffold.dart +++ b/lib/widgets/scaffold.dart @@ -305,20 +305,24 @@ class CommonScaffoldState extends State { ); } - Widget _buildAppBarWrap(Widget appBar) { - if (_isEdit) { - return CommonPopScope( - onPop: () { - if (_isEdit) { - _appBarState.value.editState?.onExit(); - return false; - } - return true; - }, - child: appBar, + Widget _buildAppBarWrap(Widget child) { + final appBar = _isSearch ? _buildSearchingAppBarTheme(child) : child; + if (_isEdit || _isSearch) { + return SystemBackBlock( + child: CommonPopScope( + onPop: () { + if (_isEdit || _isSearch) { + _handleExitSearching(); + _appBarState.value.editState?.onExit(); + return false; + } + return true; + }, + child: appBar, + ), ); } - return _isSearch ? _buildSearchingAppBarTheme(appBar) : appBar; + return appBar; } PreferredSizeWidget _buildAppBar() { @@ -431,6 +435,7 @@ class CommonScaffoldState extends State { final scaffold = Scaffold( appBar: _buildAppBar(), body: body, + resizeToAvoidBottomInset: true, backgroundColor: widget.backgroundColor, floatingActionButton: ValueListenableBuilder( valueListenable: _floatingActionButton, diff --git a/lib/widgets/super_grid.dart b/lib/widgets/super_grid.dart index 8d03394..ee30517 100644 --- a/lib/widgets/super_grid.dart +++ b/lib/widgets/super_grid.dart @@ -56,6 +56,7 @@ class SuperGridState extends State with TickerProviderStateMixin { final ValueNotifier _animating = ValueNotifier(false); final _dragWidgetSizeNotifier = ValueNotifier(Size.zero); + final _dragIndexNotifier = ValueNotifier(-1); late AnimationController _transformController; @@ -304,7 +305,7 @@ class SuperGridState extends State with TickerProviderStateMixin { } _handleDragEnd(DraggableDetails details) async { - debouncer.cancel(DebounceTag.handleWill); + debouncer.cancel(FunctionTag.handleWill); if (_targetIndex == -1) { return; } @@ -313,7 +314,12 @@ class SuperGridState extends State with TickerProviderStateMixin { stiffness: 100, damping: 10, ); - final simulation = SpringSimulation(spring, 0, 1, 0); + final simulation = SpringSimulation( + spring, + 0, + 1, + 0, + ); _fakeDragWidgetAnimation = Tween( begin: details.offset - _parentOffset, end: _targetOffset, @@ -369,7 +375,6 @@ class SuperGridState extends State with TickerProviderStateMixin { } _handleDelete(int index) async { - await _transformCompleter?.future; _preTransformState(); final indexWhere = _tempIndexList.indexWhere((i) => i == index); _tempIndexList.removeAt(indexWhere); @@ -496,7 +501,7 @@ class SuperGridState extends State with TickerProviderStateMixin { }, onWillAcceptWithDetails: (_) { debouncer.call( - DebounceTag.handleWill, + FunctionTag.handleWill, _handleWill, args: [index], ); @@ -504,21 +509,31 @@ class SuperGridState extends State with TickerProviderStateMixin { }, ); final shakeTarget = ValueListenableBuilder( - valueListenable: _dragIndexNotifier, - builder: (_, dragIndex, child) { - if (dragIndex == index) { + valueListenable: _animating, + builder: (_, animating, child) { + if (animating) { + return target; + } else { return child!; } - return _shakeWrap( - _DeletableContainer( - onDelete: () { - _handleDelete(index); - }, - child: child!, - ), - ); }, - child: target, + child: ValueListenableBuilder( + valueListenable: _dragIndexNotifier, + builder: (_, dragIndex, child) { + if (dragIndex == index) { + return child!; + } + return _shakeWrap( + _DeletableContainer( + onDelete: () { + _handleDelete(index); + }, + child: child!, + ), + ); + }, + child: target, + ), ); final draggableChild = system.isDesktop ? Draggable( diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 536feea..47ba770 100755 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,6 +9,7 @@ import app_links import connectivity_plus import device_info_plus import dynamic_color +import file_picker import file_selector_macos import hotkey_manager_macos import mobile_scanner @@ -27,6 +28,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin")) + FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) HotkeyManagerMacosPlugin.register(with: registry.registrar(forPlugin: "HotkeyManagerMacosPlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 9fe12f3..1481a34 100755 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -2,12 +2,13 @@ PODS: - app_links (1.0.0): - FlutterMacOS - connectivity_plus (0.0.1): - - Flutter - FlutterMacOS - device_info_plus (0.0.1): - FlutterMacOS - dynamic_color (0.0.2): - FlutterMacOS + - file_picker (0.0.1): + - FlutterMacOS - file_selector_macos (0.0.1): - FlutterMacOS - FlutterMacOS (1.0.0) @@ -15,7 +16,8 @@ PODS: - hotkey_manager_macos (0.0.1): - FlutterMacOS - HotKey - - mobile_scanner (6.0.2): + - mobile_scanner (7.0.0): + - Flutter - FlutterMacOS - package_info_plus (0.0.1): - FlutterMacOS @@ -41,13 +43,14 @@ PODS: DEPENDENCIES: - app_links (from `Flutter/ephemeral/.symlinks/plugins/app_links/macos`) - - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin`) + - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) - dynamic_color (from `Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos`) + - file_picker (from `Flutter/ephemeral/.symlinks/plugins/file_picker/macos`) - file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - hotkey_manager_macos (from `Flutter/ephemeral/.symlinks/plugins/hotkey_manager_macos/macos`) - - mobile_scanner (from `Flutter/ephemeral/.symlinks/plugins/mobile_scanner/macos`) + - mobile_scanner (from `Flutter/ephemeral/.symlinks/plugins/mobile_scanner/darwin`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`) @@ -66,11 +69,13 @@ EXTERNAL SOURCES: app_links: :path: Flutter/ephemeral/.symlinks/plugins/app_links/macos connectivity_plus: - :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin + :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos device_info_plus: :path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos dynamic_color: :path: Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos + file_picker: + :path: Flutter/ephemeral/.symlinks/plugins/file_picker/macos file_selector_macos: :path: Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos FlutterMacOS: @@ -78,7 +83,7 @@ EXTERNAL SOURCES: hotkey_manager_macos: :path: Flutter/ephemeral/.symlinks/plugins/hotkey_manager_macos/macos mobile_scanner: - :path: Flutter/ephemeral/.symlinks/plugins/mobile_scanner/macos + :path: Flutter/ephemeral/.symlinks/plugins/mobile_scanner/darwin package_info_plus: :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos path_provider_foundation: @@ -100,14 +105,15 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: app_links: afe860c55c7ef176cea7fb630a2b7d7736de591d - connectivity_plus: 2256d3e20624a7749ed21653aafe291a46446fee + connectivity_plus: 4adf20a405e25b42b9c9f87feff8f4b6fde18a4e device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76 dynamic_color: b820c000cc68df65e7ba7ff177cb98404ce56651 + file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 HotKey: e96d8a2ddbf4591131e2bb3f54e69554d90cdca6 hotkey_manager_macos: a4317849af96d2430fa89944d3c58977ca089fbe - mobile_scanner: 0e365ed56cad24f28c0fd858ca04edefb40dfac3 + mobile_scanner: 9157936403f5a0644ca3779a38ff8404c5434a93 package_info_plus: f0052d280d17aa382b932f399edf32507174e870 path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f diff --git a/pubspec.lock b/pubspec.lock index ceeea69..f45e2e4 100755 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,31 +5,26 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" + sha256: dc27559385e905ad30838356c5f5d574014ba39872d732111cd07ac0beff4c57 url: "https://pub.dev" source: hosted - version: "76.0.0" - _macros: - dependency: transitive - description: dart - source: sdk - version: "0.3.3" + version: "80.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" + sha256: "192d1c5b944e7e53b24b5586db760db934b177d4147c42fbca8c8c5f1eb8d11e" url: "https://pub.dev" source: hosted - version: "6.11.0" + version: "7.3.0" analyzer_plugin: dependency: transitive description: name: analyzer_plugin - sha256: "9661b30b13a685efaee9f02e5d01ed9f2b423bd889d28a304d02d704aee69161" + sha256: "1d460d14e3c2ae36dc2b32cef847c4479198cf87704f63c3c3c8150ee50c3916" url: "https://pub.dev" source: hosted - version: "0.11.3" + version: "0.12.0" animations: dependency: "direct main" description: @@ -82,10 +77,10 @@ packages: dependency: "direct dev" description: name: args - sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.7.0" async: dependency: transitive description: @@ -106,50 +101,50 @@ packages: dependency: transitive description: name: build - sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0 url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" build_config: dependency: transitive description: name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" build_daemon: dependency: transitive description: name: build_daemon - sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" + sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.0.4" build_resolvers: dependency: transitive description: name: build_resolvers - sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" + sha256: b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0 url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.4" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" + sha256: "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99" url: "https://pub.dev" source: hosted - version: "2.4.13" + version: "2.4.15" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 + sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021" url: "https://pub.dev" source: hosted - version: "7.3.2" + version: "8.0.0" built_collection: dependency: transitive description: @@ -162,10 +157,10 @@ packages: dependency: transitive description: name: built_value - sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb + sha256: ea90e81dc4a25a043d9bee692d20ed6d1c4a1662a28c03a96417446c093ed6b4 url: "https://pub.dev" source: hosted - version: "8.9.2" + version: "8.9.5" cached_network_image: dependency: "direct main" description: @@ -250,10 +245,10 @@ packages: dependency: "direct main" description: name: connectivity_plus - sha256: e0817759ec6d2d8e57eb234e6e57d2173931367a865850c7acea40d4b4f9c27d + sha256: "051849e2bd7c7b3bc5844ea0d096609ddc3a859890ec3a9ac4a65a2620cc1f99" url: "https://pub.dev" source: hosted - version: "6.1.1" + version: "6.1.4" connectivity_plus_platform_interface: dependency: transitive description: @@ -290,50 +285,50 @@ packages: dependency: "direct dev" description: name: custom_lint - sha256: "3486c470bb93313a9417f926c7dd694a2e349220992d7b9d14534dc49c15bba9" + sha256: "021897cce2b6c783b2521543e362e7fe1a2eaab17bf80514d8de37f99942ed9e" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.3" custom_lint_builder: dependency: transitive description: name: custom_lint_builder - sha256: "42cdc41994eeeddab0d7a722c7093ec52bd0761921eeb2cbdbf33d192a234759" + sha256: e4235b9d8cef59afe621eba086d245205c8a0a6c70cd470be7cb17494d6df32d url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.3" custom_lint_core: dependency: transitive description: name: custom_lint_core - sha256: "02450c3e45e2a6e8b26c4d16687596ab3c4644dd5792e3313aa9ceba5a49b7f5" + sha256: "6dcee8a017181941c51a110da7e267c1d104dc74bec8862eeb8c85b5c8759a9e" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.1" custom_lint_visitor: dependency: transitive description: name: custom_lint_visitor - sha256: bfe9b7a09c4775a587b58d10ebb871d4fe618237639b1e84d5ec62d7dfef25f9 + sha256: "36282d85714af494ee2d7da8c8913630aa6694da99f104fb2ed4afcf8fc857d8" url: "https://pub.dev" source: hosted - version: "1.0.0+6.11.0" + version: "1.0.0+7.3.0" dart_style: dependency: transitive description: name: dart_style - sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab" + sha256: "27eb0ae77836989a3bc541ce55595e8ceee0992807f14511552a898ddd0d88ac" url: "https://pub.dev" source: hosted - version: "2.3.7" + version: "3.0.1" dbus: dependency: transitive description: name: dbus - sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" url: "https://pub.dev" source: hosted - version: "0.7.10" + version: "0.7.11" defer_pointer: dependency: "direct main" description: @@ -346,10 +341,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: "306b78788d1bb569edb7c55d622953c2414ca12445b41c9117963e03afc5c513" + sha256: "0c6396126421b590089447154c5f98a5de423b70cfb15b1578fd018843ee6f53" url: "https://pub.dev" source: hosted - version: "11.3.3" + version: "11.4.0" device_info_plus_platform_interface: dependency: transitive description: @@ -370,10 +365,10 @@ packages: dependency: transitive description: name: dio_web_adapter - sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8" + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.1.1" dynamic_color: dependency: "direct main" description: @@ -418,10 +413,10 @@ packages: dependency: "direct dev" description: name: ffigen - sha256: a0ca4853028c6a9e4d9a0a40bb744fceb898c89d75931d08e87b3987d0087060 + sha256: "72d732c33557fc0ca9b46379d3deff2dadbdc539696dc0b270189e2989be20ef" url: "https://pub.dev" source: hosted - version: "15.0.0" + version: "18.1.0" file: dependency: transitive description: @@ -434,10 +429,10 @@ packages: dependency: "direct main" description: name: file_picker - sha256: c2376a6aae82358a9f9ccdd7d1f4006d08faa39a2767cce01031d9f593a8bd3b + sha256: "8986dec4581b4bcd4b6df5d75a2ea0bede3db802f500635d05fa8be298f9467f" url: "https://pub.dev" source: hosted - version: "8.1.6" + version: "10.1.2" file_selector_linux: dependency: transitive description: @@ -466,10 +461,10 @@ packages: dependency: transitive description: name: file_selector_windows - sha256: "8f5d2f6590d51ecd9179ba39c64f722edc15226cc93dcc8698466ad36a4a85a4" + sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b" url: "https://pub.dev" source: hosted - version: "0.9.3+3" + version: "0.9.3+4" fixnum: dependency: transitive description: @@ -508,10 +503,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398" + sha256: f948e346c12f8d5480d2825e03de228d0eb8c3a737e4cdaa122267b89c022b5e url: "https://pub.dev" source: hosted - version: "2.0.23" + version: "2.0.28" flutter_riverpod: dependency: "direct main" description: @@ -534,10 +529,10 @@ packages: dependency: "direct dev" description: name: freezed - sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e" + sha256: "59a584c24b3acdc5250bb856d0d3e9c0b798ed14a4af1ddb7dc1c7b41df91c9c" url: "https://pub.dev" source: hosted - version: "2.5.7" + version: "2.5.8" freezed_annotation: dependency: "direct main" description: @@ -558,10 +553,10 @@ packages: dependency: transitive description: name: glob - sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" graphs: dependency: transitive description: @@ -630,26 +625,26 @@ packages: dependency: transitive description: name: http - sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.3.0" http_multi_server: dependency: transitive description: name: http_multi_server - sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.2.2" http_parser: dependency: transitive description: name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.2" image_picker: dependency: "direct main" description: @@ -662,10 +657,10 @@ packages: dependency: transitive description: name: image_picker_android - sha256: fa8141602fde3f7e2f81dbf043613eb44dfa325fa0bcf93c0f142c9f7a2c193e + sha256: "317a5d961cec5b34e777b9252393f2afbd23084aa6e60fcf601dcf6341b9ebeb" url: "https://pub.dev" source: hosted - version: "0.8.12+18" + version: "0.8.12+23" image_picker_for_web: dependency: transitive description: @@ -678,34 +673,34 @@ packages: dependency: transitive description: name: image_picker_ios - sha256: "4f0568120c6fcc0aaa04511cb9f9f4d29fc3d0139884b1d06be88dcec7641d6b" + sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100" url: "https://pub.dev" source: hosted - version: "0.8.12+1" + version: "0.8.12+2" image_picker_linux: dependency: transitive description: name: image_picker_linux - sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa" + sha256: "34a65f6740df08bbbeb0a1abd8e6d32107941fd4868f67a507b25601651022c9" url: "https://pub.dev" source: hosted - version: "0.2.1+1" + version: "0.2.1+2" image_picker_macos: dependency: transitive description: name: image_picker_macos - sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62" + sha256: "1b90ebbd9dcf98fb6c1d01427e49a55bd96b5d67b8c67cf955d60a5de74207c1" url: "https://pub.dev" source: hosted - version: "0.2.1+1" + version: "0.2.1+2" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface - sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80" + sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.10.1" image_picker_windows: dependency: transitive description: @@ -750,10 +745,10 @@ packages: dependency: transitive description: name: js - sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" url: "https://pub.dev" source: hosted - version: "0.7.1" + version: "0.7.2" json_annotation: dependency: "direct main" description: @@ -766,10 +761,10 @@ packages: dependency: "direct dev" description: name: json_serializable - sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c + sha256: c50ef5fc083d5b5e12eef489503ba3bf5ccc899e487d691584699b4bdefeea8c url: "https://pub.dev" source: hosted - version: "6.9.0" + version: "6.9.5" launch_at_startup: dependency: "direct main" description: @@ -806,10 +801,10 @@ packages: dependency: transitive description: name: lints - sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" + sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.1.1" logging: dependency: transitive description: @@ -826,14 +821,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.3" - macros: - dependency: transitive - description: - name: macros - sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" - url: "https://pub.dev" - source: hosted - version: "0.1.3-main.0" matcher: dependency: transitive description: @@ -878,10 +865,10 @@ packages: dependency: "direct main" description: name: mobile_scanner - sha256: "728828a798d1a2ee506beb652ca23d974c542c96ed03dcbd5eaf97bef96cdaad" + sha256: "72f06a071aa8b14acea3ab43ea7949eefe4a2469731ae210e006ba330a033a8c" url: "https://pub.dev" source: hosted - version: "6.0.2" + version: "7.0.0" nm: dependency: transitive description: @@ -902,26 +889,26 @@ packages: dependency: transitive description: name: package_config - sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67" + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.2.0" package_info_plus: dependency: "direct main" description: name: package_info_plus - sha256: "70c421fe9d9cc1a9a7f3b05ae56befd469fe4f8daa3b484823141a55442d858d" + sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191" url: "https://pub.dev" source: hosted - version: "8.1.2" + version: "8.3.0" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - sha256: a5ef9986efc7bf772f2696183a3992615baa76c1ffb1189318dd8803778fb05b + sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.2.0" path: dependency: "direct main" description: @@ -942,10 +929,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2" + sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 url: "https://pub.dev" source: hosted - version: "2.2.15" + version: "2.2.17" path_provider_foundation: dependency: transitive description: @@ -982,10 +969,10 @@ packages: dependency: transitive description: name: petitparser - sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646" url: "https://pub.dev" source: hosted - version: "6.0.2" + version: "6.1.0" platform: dependency: transitive description: @@ -1021,18 +1008,18 @@ packages: dependency: transitive description: name: pub_semver - sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd" + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.2.0" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 + sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.5.0" quiver: dependency: transitive description: @@ -1069,10 +1056,10 @@ packages: dependency: transitive description: name: riverpod_analyzer_utils - sha256: c6b8222b2b483cb87ae77ad147d6408f400c64f060df7a225b127f4afef4f8c8 + sha256: "837a6dc33f490706c7f4632c516bcd10804ee4d9ccc8046124ca56388715fdf3" url: "https://pub.dev" source: hosted - version: "0.5.8" + version: "0.5.9" riverpod_annotation: dependency: "direct main" description: @@ -1085,18 +1072,18 @@ packages: dependency: "direct dev" description: name: riverpod_generator - sha256: "63546d70952015f0981361636bf8f356d9cfd9d7f6f0815e3c07789a41233188" + sha256: "120d3310f687f43e7011bb213b90a436f1bbc300f0e4b251a72c39bccb017a4f" url: "https://pub.dev" source: hosted - version: "2.6.3" + version: "2.6.4" riverpod_lint: dependency: "direct dev" description: name: riverpod_lint - sha256: "83e4caa337a9840469b7b9bd8c2351ce85abad80f570d84146911b32086fbd99" + sha256: b05408412b0f75dec954e032c855bc28349eeed2d2187f94519e1ddfdf8b3693 url: "https://pub.dev" source: hosted - version: "2.6.3" + version: "2.6.4" rxdart: dependency: transitive description: @@ -1149,18 +1136,18 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: "688ee90fbfb6989c980254a56cb26ebe9bb30a3a2dff439a78894211f73de67a" + sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" url: "https://pub.dev" source: hosted - version: "2.5.1" + version: "2.5.3" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "02a7d8a9ef346c9af715811b01fbd8e27845ad2c41148eefd31321471b41863d" + sha256: "20cbd561f743a342c76c151d6ddb93a9ce6005751e7aa458baad3858bfbfb6ac" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.10" shared_preferences_foundation: dependency: transitive description: @@ -1189,10 +1176,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.3" shared_preferences_windows: dependency: transitive description: @@ -1205,18 +1192,18 @@ packages: dependency: transitive description: name: shelf - sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.2" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.0" shortid: dependency: transitive description: @@ -1234,18 +1221,18 @@ packages: dependency: transitive description: name: source_gen - sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" + sha256: "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b" url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "2.0.0" source_helper: dependency: transitive description: name: source_helper - sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" + sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c" url: "https://pub.dev" source: hosted - version: "1.3.4" + version: "1.3.5" source_span: dependency: transitive description: @@ -1266,34 +1253,34 @@ packages: dependency: transitive description: name: sqflite - sha256: "2d7299468485dca85efeeadf5d38986909c5eb0cd71fd3db2c2f000e6c9454bb" + sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03 url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" sqflite_android: dependency: transitive description: name: sqflite_android - sha256: "78f489aab276260cdd26676d2169446c7ecd3484bbd5fead4ca14f3ed4dd9ee3" + sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.1" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: "761b9740ecbd4d3e66b8916d784e581861fd3c3553eda85e167bc49fdb68f709" + sha256: "84731e8bfd8303a3389903e01fb2141b6e59b5973cacbb0929021df08dddbe8b" url: "https://pub.dev" source: hosted - version: "2.5.4+6" + version: "2.5.5" sqflite_darwin: dependency: transitive description: name: sqflite_darwin - sha256: "96a698e2bc82bd770a4d6aab00b42396a7c63d9e33513a56945cbccb594c2474" + sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" sqflite_platform_interface: dependency: transitive description: @@ -1330,10 +1317,10 @@ packages: dependency: transitive description: name: stream_transform - sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" string_scanner: dependency: transitive description: @@ -1346,10 +1333,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225" + sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6" url: "https://pub.dev" source: hosted - version: "3.3.0+3" + version: "3.3.1" term_glyph: dependency: transitive description: @@ -1378,10 +1365,10 @@ packages: dependency: "direct main" description: name: tray_manager - sha256: c2da0f0f1ddb455e721cf68d05d1281fec75cf5df0a1d3cb67b6ca0bdfd5709d + sha256: ad18c4cd73003097d182884bacb0578ad2865f3ab842a0ad00f6d043ed49eaf0 url: "https://pub.dev" source: hosted - version: "0.4.0" + version: "0.5.0" typed_data: dependency: transitive description: @@ -1410,18 +1397,18 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193" + sha256: "8582d7f6fe14d2652b4c45c9b6c14c0b678c2af2d083a11b604caeba51930d79" url: "https://pub.dev" source: hosted - version: "6.3.14" + version: "6.3.16" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "16a513b6c12bb419304e72ea0ae2ab4fed569920d1c7cb850263fe3acc824626" + sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb" url: "https://pub.dev" source: hosted - version: "6.3.2" + version: "6.3.3" url_launcher_linux: dependency: transitive description: @@ -1450,18 +1437,18 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" + sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.4.1" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "44cf3aabcedde30f2dba119a9dea3b0f2672fbe6fa96e85536251d678216b3c4" + sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "3.1.4" uuid: dependency: transitive description: @@ -1490,34 +1477,34 @@ packages: dependency: transitive description: name: watcher - sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" web: dependency: transitive description: name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" web_socket: dependency: transitive description: name: web_socket - sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + sha256: bfe6f435f6ec49cb6c01da1e275ae4228719e59a6b067048c51e72d9d63bcc4b url: "https://pub.dev" source: hosted - version: "0.1.6" + version: "1.0.0" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.3" webdav_client: dependency: "direct main" description: @@ -1557,14 +1544,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.3" - windows_single_instance: - dependency: "direct main" - description: - name: windows_single_instance - sha256: "50d5dcd6bec90b4a5ed588b1822b1aad21b39fc96da843e61c734b3caccfd2fc" - url: "https://pub.dev" - source: hosted - version: "1.0.1" xdg_directories: dependency: transitive description: @@ -1585,18 +1564,18 @@ packages: dependency: transitive description: name: yaml - sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.3" yaml_edit: dependency: transitive description: name: yaml_edit - sha256: e9c1a3543d2da0db3e90270dbb1e4eebc985ee5e3ffe468d83224472b2194a5f + sha256: fb38626579fb345ad00e674e2af3a5c9b0cc4b9bfb8fd7f7ff322c7c9e62aef5 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" sdks: dart: ">=3.7.0 <4.0.0" - flutter: ">=3.24.0" + flutter: ">=3.29.0" diff --git a/pubspec.yaml b/pubspec.yaml index be770ec..5999ad1 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: fl_clash description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free. publish_to: 'none' -version: 0.8.84+202505013 +version: 0.8.85+202505091 environment: sdk: '>=3.1.0 <4.0.0' @@ -13,7 +13,7 @@ dependencies: intl: any path_provider: ^2.1.0 path: ^1.9.0 - shared_preferences: ^2.5.1 + shared_preferences: ^2.5.3 window_manager: ^0.4.3 dynamic_color: ^1.7.0 proxy: @@ -21,13 +21,12 @@ dependencies: window_ext: path: plugins/window_ext launch_at_startup: ^0.5.1 - windows_single_instance: ^1.0.1 json_annotation: ^4.9.0 - file_picker: ^8.0.3 - mobile_scanner: ^6.0.2 + file_picker: ^10.1.2 + mobile_scanner: ^7.0.0 app_links: ^6.4.0 win32_registry: ^2.0.0 - tray_manager: ^0.4.0 + tray_manager: ^0.5.0 collection: ^1.18.0 animations: ^2.0.11 package_info_plus: ^8.0.0 @@ -58,7 +57,7 @@ dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^5.0.0 - ffigen: ^15.0.0 + ffigen: ^18.1.0 json_serializable: ^6.7.1 build_runner: ^2.4.13 args: ^2.4.2 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 4396ef1..b663ed9 100755 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -17,7 +17,6 @@ #include #include #include -#include void RegisterPlugins(flutter::PluginRegistry* registry) { AppLinksPluginCApiRegisterWithRegistrar( @@ -42,6 +41,4 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("WindowExtPluginCApi")); WindowManagerPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("WindowManagerPlugin")); - WindowsSingleInstancePluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("WindowsSingleInstancePlugin")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 977794d..d81e255 100755 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -14,7 +14,6 @@ list(APPEND FLUTTER_PLUGIN_LIST url_launcher_windows window_ext window_manager - windows_single_instance ) list(APPEND FLUTTER_FFI_PLUGIN_LIST