Compare commits

...

1 Commits

Author SHA1 Message Date
chen08209
2fbc4170b9 Add some scenes auto close connections
Support proxies query

Optimize more details
2025-05-09 16:11:20 +08:00
63 changed files with 1097 additions and 690 deletions

View File

@@ -73,6 +73,7 @@ android {
applicationIdSuffix '.debug' applicationIdSuffix '.debug'
} }
release { release {
debuggable false
if (isRelease) { if (isRelease) {
signingConfig signingConfigs.release signingConfig signingConfigs.release
} else { } else {

View File

@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.argumentsWithVarargAsSingleArray
plugins { plugins {
id("com.android.library") id("com.android.library")
id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.android")
@@ -15,6 +17,7 @@ android {
buildTypes { buildTypes {
release { release {
isJniDebuggable = false
proguardFiles( proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro" "proguard-rules.pro"

View File

@@ -4,6 +4,8 @@ project("core")
message("CMAKE_SOURCE_DIR ${CMAKE_SOURCE_DIR}") message("CMAKE_SOURCE_DIR ${CMAKE_SOURCE_DIR}")
message("CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}")
if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
add_compile_options(-O3) add_compile_options(-O3)

View File

@@ -1,21 +1,18 @@
#include <jni.h>
#ifdef LIBCLASH #ifdef LIBCLASH
#include <jni.h> #include <jni.h>
#include <string>
#include "jni_helper.h" #include "jni_helper.h"
#include "libclash.h" #include "libclash.h"
extern "C" extern "C"
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_follow_clash_core_Core_startTun(JNIEnv *env, jobject thiz, jint fd, jobject cb) { Java_com_follow_clash_core_Core_startTun(JNIEnv *env, jobject, const jint fd, jobject cb) {
auto interface = new_global(cb); const auto interface = new_global(cb);
startTUN(fd, interface); startTUN(fd, interface);
} }
extern "C" extern "C"
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_follow_clash_core_Core_stopTun(JNIEnv *env, jobject thiz) { Java_com_follow_clash_core_Core_stopTun(JNIEnv *) {
stopTun(); stopTun();
} }
@@ -26,50 +23,50 @@ static jmethodID m_tun_interface_resolve_process;
static void release_jni_object_impl(void *obj) { static void release_jni_object_impl(void *obj) {
ATTACH_JNI(); ATTACH_JNI();
del_global((jobject) obj); del_global(static_cast<jobject>(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(); ATTACH_JNI();
env->CallVoidMethod((jobject) tun_interface, env->CallVoidMethod(static_cast<jobject>(tun_interface),
(jmethodID) m_tun_interface_protect, m_tun_interface_protect,
(jint) fd); fd);
} }
static const char* static const char *
call_tun_interface_resolve_process_impl(void *tun_interface, int protocol, call_tun_interface_resolve_process_impl(void *tun_interface, int protocol,
const char *source, const char *source,
const char *target, const char *target,
int uid) { const int uid) {
ATTACH_JNI(); ATTACH_JNI();
jstring packageName = (jstring)env->CallObjectMethod((jobject) tun_interface, const auto packageName = reinterpret_cast<jstring>(env->CallObjectMethod(static_cast<jobject>(tun_interface),
(jmethodID) m_tun_interface_resolve_process, m_tun_interface_resolve_process,
(jint) protocol, protocol,
(jstring) new_string(source), new_string(source),
(jstring) new_string(target), new_string(target),
(jint) uid); uid));
return get_string(packageName); return get_string(packageName);
} }
extern "C" extern "C"
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved) { JNI_OnLoad(JavaVM *vm, void *) {
JNIEnv *env = nullptr; JNIEnv *env = nullptr;
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) { if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR; return JNI_ERR;
} }
initialize_jni(vm, env); 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_protect = find_method(c_tun_interface, "protect", "(I)V");
m_tun_interface_resolve_process = find_method(c_tun_interface, "resolverProcess", 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, registerCallbacks(&call_tun_interface_protect_impl,
&call_tun_interface_resolve_process_impl, &call_tun_interface_resolve_process_impl,
&release_jni_object_impl); &release_jni_object_impl);
return JNI_VERSION_1_6; return JNI_VERSION_1_6;
} }
#endif #endif

View File

@@ -1,5 +1,6 @@
#include "jni_helper.h" #include "jni_helper.h"
#include <cstdlib>
#include <malloc.h> #include <malloc.h>
#include <cstring> #include <cstring>
@@ -12,7 +13,7 @@ static jmethodID m_get_bytes;
void initialize_jni(JavaVM *vm, JNIEnv *env) { void initialize_jni(JavaVM *vm, JNIEnv *env) {
global_vm = vm; global_vm = vm;
c_string = (jclass) new_global(find_class("java/lang/String")); c_string = reinterpret_cast<jclass>(new_global(find_class("java/lang/String")));
m_new_string = find_method(c_string, "<init>", "([B)V"); m_new_string = find_method(c_string, "<init>", "([B)V");
m_get_bytes = find_method(c_string, "getBytes", "()[B"); 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) { char *jni_get_string(JNIEnv *env, jstring str) {
auto array = (jbyteArray) env->CallObjectMethod(str, m_get_bytes); const auto array = reinterpret_cast<jbyteArray>(env->CallObjectMethod(str, m_get_bytes));
int length = env->GetArrayLength(array); const int length = env->GetArrayLength(array);
char *content = (char *) malloc(length + 1); const auto content = static_cast<char *>(malloc(length + 1));
env->GetByteArrayRegion(array, 0, length, (jbyte *) content); env->GetByteArrayRegion(array, 0, length, reinterpret_cast<jbyte *>(content));
content[length] = 0; content[length] = 0;
return content; return content;
} }
jstring jni_new_string(JNIEnv *env, const char *str) { jstring jni_new_string(JNIEnv *env, const char *str) {
auto length = (int) strlen(str); const auto length = static_cast<int>(strlen(str));
jbyteArray array = env->NewByteArray(length); const auto array = env->NewByteArray(length);
env->SetByteArrayRegion(array, 0, length, (const jbyte *) str); env->SetByteArrayRegion(array, 0, length, reinterpret_cast<const jbyte *>(str));
return (jstring) env->NewObject(c_string, m_new_string, array); return reinterpret_cast<jstring>(env->NewObject(c_string, m_new_string, array));
} }
int jni_catch_exception(JNIEnv *env) { int jni_catch_exception(JNIEnv *env) {
int result = env->ExceptionCheck(); const int result = env->ExceptionCheck();
if (result) { if (result) {
env->ExceptionDescribe(); env->ExceptionDescribe();
env->ExceptionClear(); env->ExceptionClear();
@@ -46,9 +47,9 @@ int jni_catch_exception(JNIEnv *env) {
return result; return result;
} }
void jni_attach_thread(struct scoped_jni *jni) { void jni_attach_thread(scoped_jni *jni) {
JavaVM *vm = global_java_vm(); JavaVM *vm = global_java_vm();
if (vm->GetEnv((void **) &jni->env, JNI_VERSION_1_6) == JNI_OK) { if (vm->GetEnv(reinterpret_cast<void **>(&jni->env), JNI_VERSION_1_6) == JNI_OK) {
jni->require_release = 0; jni->require_release = 0;
return; return;
} }
@@ -58,9 +59,9 @@ void jni_attach_thread(struct scoped_jni *jni) {
jni->require_release = 1; 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(); JavaVM *vm = global_java_vm();
if (jni->require_release) { if (env->require_release) {
vm->DetachCurrentThread(); vm->DetachCurrentThread();
} }
} }

View File

@@ -1,9 +1,6 @@
#pragma once #pragma once
#include <jni.h> #include <jni.h>
#include <cstdint>
#include <cstdlib>
#include <malloc.h>
struct scoped_jni { struct scoped_jni {
JNIEnv *env; JNIEnv *env;
@@ -18,14 +15,14 @@ extern char *jni_get_string(JNIEnv *env, jstring str);
extern int jni_catch_exception(JNIEnv *env); 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); extern void release_string(char **str);
#define ATTACH_JNI() __attribute__((unused, cleanup(jni_detach_thread))) \ #define ATTACH_JNI() __attribute__((unused, cleanup(jni_detach_thread))) \
struct scoped_jni _jni; \ scoped_jni _jni{}; \
jni_attach_thread(&_jni); \ jni_attach_thread(&_jni); \
JNIEnv *env = _jni.env JNIEnv *env = _jni.env
@@ -36,4 +33,4 @@ extern void release_string(char **str);
#define new_global(obj) env->NewGlobalRef(obj) #define new_global(obj) env->NewGlobalRef(obj)
#define del_global(obj) env->DeleteGlobalRef(obj) #define del_global(obj) env->DeleteGlobalRef(obj)
#define get_string(jstr) jni_get_string(env, jstr) #define get_string(jstr) jni_get_string(env, jstr)
#define new_string(cstr) jni_new_string(env, cstr) #define new_string(cstr) jni_new_string(env, cstr)

View File

@@ -2,4 +2,4 @@ org.gradle.jvmargs=-Xmx4G
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
kotlin_version=1.9.22 kotlin_version=1.9.22
agp_version=8.9.1 agp_version=8.9.2

View File

@@ -53,6 +53,7 @@ func handleStartListener() bool {
defer runLock.Unlock() defer runLock.Unlock()
isRunning = true isRunning = true
updateListeners(true) updateListeners(true)
closeConnections()
return true return true
} }
@@ -276,6 +277,16 @@ func handleCloseConnections() bool {
return true 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 { func handleCloseConnection(connectionId string) bool {
runLock.Lock() runLock.Lock()
defer runLock.Unlock() defer runLock.Unlock()

View File

@@ -100,7 +100,8 @@ class ApplicationState extends ConsumerState<Application> {
return AppStateManager( return AppStateManager(
child: ClashManager( child: ClashManager(
child: ConnectivityManager( child: ConnectivityManager(
onConnectivityChanged: () { onConnectivityChanged: () async {
await clashCore.closeConnections();
globalState.appController.updateLocalIp(); globalState.appController.updateLocalIp();
globalState.appController.addCheckIpNumDebounce(); globalState.appController.addCheckIpNumDebounce();
}, },

View File

@@ -36,4 +36,4 @@ export 'window.dart';
export 'windows.dart'; export 'windows.dart';
export 'render.dart'; export 'render.dart';
export 'mixin.dart'; export 'mixin.dart';
export 'print.dart'; export 'print.dart';

View File

@@ -23,7 +23,8 @@ final baseInfoEdgeInsets = EdgeInsets.symmetric(
horizontal: 16.ap, horizontal: 16.ap,
); );
final defaultTextScaleFactor = WidgetsBinding.instance.platformDispatcher.textScaleFactor; final defaultTextScaleFactor =
WidgetsBinding.instance.platformDispatcher.textScaleFactor;
const httpTimeoutDuration = Duration(milliseconds: 5000); const httpTimeoutDuration = Duration(milliseconds: 5000);
const moreDuration = Duration(milliseconds: 100); const moreDuration = Duration(milliseconds: 100);
const animateDuration = Duration(milliseconds: 100); const animateDuration = Duration(milliseconds: 100);
@@ -76,6 +77,10 @@ const viewModeColumnsMap = {
ViewMode.desktop: [4, 3], ViewMode.desktop: [4, 3],
}; };
// const proxiesStoreKey = PageStorageKey<String>('proxies');
// const toolsStoreKey = PageStorageKey<String>('tools');
// const profilesStoreKey = PageStorageKey<String>('profiles');
const defaultPrimaryColor = 0XFFD8C0C3; const defaultPrimaryColor = 0XFFD8C0C3;
double getWidgetHeight(num lines) { double getWidgetHeight(num lines) {

View File

@@ -1,10 +1,12 @@
import 'dart:async'; import 'dart:async';
import 'package:fl_clash/enum/enum.dart';
class Debouncer { class Debouncer {
final Map<dynamic, Timer?> _operations = {}; final Map<FunctionTag, Timer?> _operations = {};
call( call(
dynamic tag, FunctionTag tag,
Function func, { Function func, {
List<dynamic>? args, List<dynamic>? args,
Duration duration = const Duration(milliseconds: 600), Duration duration = const Duration(milliseconds: 600),
@@ -33,10 +35,10 @@ class Debouncer {
} }
class Throttler { class Throttler {
final Map<dynamic, Timer?> _operations = {}; final Map<FunctionTag, Timer?> _operations = {};
call( call(
dynamic tag, FunctionTag tag,
Function func, { Function func, {
List<dynamic>? args, List<dynamic>? args,
Duration duration = const Duration(milliseconds: 600), Duration duration = const Duration(milliseconds: 600),

View File

@@ -12,6 +12,7 @@ class Navigation {
}) { }) {
return [ return [
const NavigationItem( const NavigationItem(
keep: false,
icon: Icon(Icons.space_dashboard), icon: Icon(Icons.space_dashboard),
label: PageLabel.dashboard, label: PageLabel.dashboard,
fragment: DashboardFragment( fragment: DashboardFragment(
@@ -65,7 +66,6 @@ class Navigation {
icon: Icon(Icons.storage), icon: Icon(Icons.storage),
label: PageLabel.resources, label: PageLabel.resources,
description: "resourcesDesc", description: "resourcesDesc",
keep: false,
fragment: Resources( fragment: Resources(
key: GlobalObjectKey( key: GlobalObjectKey(
PageLabel.resources, PageLabel.resources,

View File

@@ -23,14 +23,14 @@ class Render {
pause() { pause() {
throttler.call( throttler.call(
DebounceTag.renderPause, FunctionTag.renderPause,
_pause, _pause,
duration: Duration(seconds: 5), duration: Duration(seconds: 5),
); );
} }
resume() { resume() {
throttler.cancel(DebounceTag.renderPause); throttler.cancel(FunctionTag.renderPause);
_resume(); _resume();
} }

View File

@@ -47,6 +47,10 @@ extension StringExtension on String {
return false; return false;
} }
} }
// bool containsToLower(String target) {
// return toLowerCase().contains(target);
// }
} }
extension StringExtensionSafe on String? { extension StringExtensionSafe on String? {

View File

@@ -5,6 +5,7 @@ import 'dart:ui';
import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart'; import 'package:fl_clash/enum/enum.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lpinyin/lpinyin.dart'; import 'package:lpinyin/lpinyin.dart';
class Utils { class Utils {
@@ -230,7 +231,7 @@ class Utils {
} }
int getProfilesColumns(double viewWidth) { int getProfilesColumns(double viewWidth) {
return max((viewWidth / 350).floor(), 1); return max((viewWidth / 320).floor(), 1);
} }
final _indexPrimary = [ final _indexPrimary = [
@@ -323,6 +324,15 @@ class Utils {
} }
return ""; return "";
} }
SingleActivator controlSingleActivator(LogicalKeyboardKey trigger) {
final control = Platform.isMacOS ? false : true;
return SingleActivator(
trigger,
control: control,
meta: !control,
);
}
} }
final utils = Utils(); final utils = Utils();

View File

@@ -8,6 +8,7 @@ import 'package:archive/archive.dart';
import 'package:fl_clash/clash/clash.dart'; import 'package:fl_clash/clash/clash.dart';
import 'package:fl_clash/common/archive.dart'; import 'package:fl_clash/common/archive.dart';
import 'package:fl_clash/enum/enum.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/providers/providers.dart';
import 'package:fl_clash/state.dart'; import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/dialog.dart'; import 'package:fl_clash/widgets/dialog.dart';
@@ -30,18 +31,18 @@ class AppController {
AppController(this.context, WidgetRef ref) : _ref = ref; AppController(this.context, WidgetRef ref) : _ref = ref;
updateClashConfigDebounce() { updateClashConfigDebounce() {
debouncer.call(DebounceTag.updateClashConfig, () async { debouncer.call(FunctionTag.updateClashConfig, () async {
final isPatch = globalState.appState.needApply ? false : true; final isPatch = globalState.appState.needApply ? false : true;
await updateClashConfig(isPatch); await updateClashConfig(isPatch);
}); });
} }
updateGroupsDebounce() { updateGroupsDebounce() {
debouncer.call(DebounceTag.updateGroups, updateGroups); debouncer.call(FunctionTag.updateGroups, updateGroups);
} }
addCheckIpNumDebounce() { addCheckIpNumDebounce() {
debouncer.call(DebounceTag.addCheckIpNum, () { debouncer.call(FunctionTag.addCheckIpNum, () {
_ref.read(checkIpNumProvider.notifier).add(); _ref.read(checkIpNumProvider.notifier).add();
}); });
} }
@@ -49,17 +50,17 @@ class AppController {
applyProfileDebounce({ applyProfileDebounce({
bool silence = false, bool silence = false,
}) { }) {
debouncer.call(DebounceTag.applyProfile, (silence) { debouncer.call(FunctionTag.applyProfile, (silence) {
applyProfile(silence: silence); applyProfile(silence: silence);
}, args: [silence]); }, args: [silence]);
} }
savePreferencesDebounce() { savePreferencesDebounce() {
debouncer.call(DebounceTag.savePreferences, savePreferences); debouncer.call(FunctionTag.savePreferences, savePreferences);
} }
changeProxyDebounce(String groupName, String proxyName) { changeProxyDebounce(String groupName, String proxyName) {
debouncer.call(DebounceTag.changeProxy, debouncer.call(FunctionTag.changeProxy,
(String groupName, String proxyName) async { (String groupName, String proxyName) async {
await changeProxy( await changeProxy(
groupName: groupName, groupName: groupName,
@@ -385,6 +386,9 @@ class AppController {
} }
handleBackOrExit() async { handleBackOrExit() async {
if (_ref.read(backBlockProvider)) {
return;
}
if (_ref.read(appSettingProvider).minimizeOnExit) { if (_ref.read(appSettingProvider).minimizeOnExit) {
if (system.isDesktop) { if (system.isDesktop) {
await savePreferencesDebounce(); await savePreferencesDebounce();
@@ -395,6 +399,14 @@ class AppController {
} }
} }
backBlock() {
_ref.read(backBlockProvider.notifier).value = true;
}
unBackBlock() {
_ref.read(backBlockProvider.notifier).value = false;
}
handleExit() async { handleExit() async {
try { try {
await updateStatus(false); await updateStatus(false);
@@ -498,8 +510,9 @@ class AppController {
} }
init() async { init() async {
await _handlePreference(); FlutterError.onError = (details) {
await _handlerDisclaimer(); commonPrint.log(details.stack.toString());
};
await _initCore(); await _initCore();
await _initStatus(); await _initStatus();
updateTray(true); updateTray(true);
@@ -513,6 +526,8 @@ class AppController {
} else { } else {
window?.hide(); window?.hide();
} }
await _handlePreference();
await _handlerDisclaimer();
_ref.read(initProvider.notifier).value = true; _ref.read(initProvider.notifier).value = true;
} }
@@ -690,10 +705,16 @@ class AppController {
return List.of(proxies) return List.of(proxies)
..sort( ..sort(
(a, b) { (a, b) {
final aDelay = final aDelay = _ref.read(getDelayProvider(
_ref.read(getDelayProvider(proxyName: a.name, testUrl: testUrl)); proxyName: a.name,
final bDelay = testUrl: testUrl,
_ref.read(getDelayProvider(proxyName: b.name, testUrl: testUrl)); ));
final bDelay = _ref.read(
getDelayProvider(
proxyName: b.name,
testUrl: testUrl,
),
);
if (aDelay == null && bDelay == null) { if (aDelay == null && bDelay == null) {
return 0; return 0;
} }
@@ -754,6 +775,17 @@ class AppController {
); );
} }
Future<List<Package>> 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() { updateStart() {
updateStatus(!_ref.read(runTimeProvider.notifier).isStart); updateStatus(!_ref.read(runTimeProvider.notifier).isStart);
} }

View File

@@ -291,7 +291,7 @@ enum WindowsHelperServiceStatus {
running, running,
} }
enum DebounceTag { enum FunctionTag {
updateClashConfig, updateClashConfig,
updateStatus, updateStatus,
updateGroups, updateGroups,
@@ -308,6 +308,9 @@ enum DebounceTag {
updatePageIndex, updatePageIndex,
pageChange, pageChange,
proxiesTabChange, proxiesTabChange,
logs,
requests,
} }
enum DashboardWidget { enum DashboardWidget {

View File

@@ -202,10 +202,7 @@ class Avatar extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InkWell( return GestureDetector(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
child: Column( child: Column(
children: [ children: [
SizedBox( SizedBox(

View File

@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:fl_clash/enum/enum.dart'; import 'package:fl_clash/enum/enum.dart';
@@ -22,21 +23,14 @@ class _AccessFragmentState extends ConsumerState<AccessFragment> {
List<String> acceptList = []; List<String> acceptList = [];
List<String> rejectList = []; List<String> rejectList = [];
late ScrollController _controller; late ScrollController _controller;
final _completer = Completer();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_updateInitList(); _updateInitList();
_controller = ScrollController(); _controller = ScrollController();
WidgetsBinding.instance.addPostFrameCallback((_) { _completer.complete(globalState.appController.getPackages());
final appState = globalState.appState;
if (appState.packages.isEmpty) {
Future.delayed(const Duration(milliseconds: 300), () async {
ref.read(packagesProvider.notifier).value =
await app?.getPackages() ?? [];
});
}
});
} }
@override @override
@@ -319,31 +313,42 @@ class _AccessFragmentState extends ConsumerState<AccessFragment> {
), ),
Expanded( Expanded(
flex: 1, flex: 1,
child: packages.isEmpty child: FutureBuilder(
? const Center( future: _completer.future,
child: CircularProgressIndicator(), builder: (_, snapshot) {
) if (snapshot.connectionState != ConnectionState.done) {
: CommonScrollBar( return Center(
controller: _controller, child: CircularProgressIndicator(),
child: ListView.builder( );
controller: _controller, }
itemCount: packages.length, return packages.isEmpty
itemExtent: 72, ? NullStatus(
itemBuilder: (_, index) { label: appLocalizations.noData,
final package = packages[index]; )
return PackageListItem( : CommonScrollBar(
key: Key(package.packageName), controller: _controller,
package: package, child: ListView.builder(
value: valueList.contains(package.packageName), controller: _controller,
isActive: accessControl.enable, itemCount: packages.length,
onChanged: (value) { itemExtent: 72,
_handleSelected(valueList, package, value); 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);
},
);
},
),
); );
}, }),
), )
),
),
], ],
), ),
), ),

View File

@@ -202,25 +202,25 @@ class BackupAndRecovery extends ConsumerWidget {
builder: (_, snapshot) { builder: (_, snapshot) {
return Center( return Center(
child: FadeThroughBox( child: FadeThroughBox(
child: snapshot.connectionState == child:
ConnectionState.waiting snapshot.connectionState != ConnectionState.done
? const SizedBox( ? const SizedBox(
width: 12, width: 12,
height: 12, height: 12,
child: CircularProgressIndicator( child: CircularProgressIndicator(
strokeWidth: 1, strokeWidth: 1,
), ),
) )
: Container( : Container(
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: snapshot.data == true color: snapshot.data == true
? Colors.green ? Colors.green
: Colors.red, : Colors.red,
), ),
width: 12, width: 12,
height: 12, height: 12,
), ),
), ),
); );
}, },

View File

@@ -111,7 +111,7 @@ class _RequestsFragmentState extends ConsumerState<RequestsFragment>
} }
updateRequestsThrottler() { updateRequestsThrottler() {
throttler.call("request", () { throttler.call(FunctionTag.requests, () {
final isEquality = connectionListEquality.equals( final isEquality = connectionListEquality.equals(
_requests, _requests,
_requestsStateNotifier.value.connections, _requestsStateNotifier.value.connections,
@@ -120,9 +120,11 @@ class _RequestsFragmentState extends ConsumerState<RequestsFragment>
return; return;
} }
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
_requestsStateNotifier.value = _requestsStateNotifier.value.copyWith( if(mounted){
connections: _requests, _requestsStateNotifier.value = _requestsStateNotifier.value.copyWith(
); connections: _requests,
);
}
}); });
}, duration: commonDuration); }, duration: commonDuration);
} }

View File

@@ -6,6 +6,7 @@ import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/widgets/widgets.dart'; import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'widgets/start_button.dart'; import 'widgets/start_button.dart';
class DashboardFragment extends ConsumerStatefulWidget { class DashboardFragment extends ConsumerStatefulWidget {
@@ -66,7 +67,16 @@ class _DashboardFragmentState extends ConsumerState<DashboardFragment>
valueListenable: key.currentState!.isEditNotifier, valueListenable: key.currentState!.isEditNotifier,
builder: (_, isEdit, ___) { builder: (_, isEdit, ___) {
return 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( : Icon(
Icons.edit, Icons.edit,
); );

View File

@@ -1,23 +1,11 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart'; import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.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/state.dart';
import 'package:fl_clash/widgets/widgets.dart'; import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
final _networkDetectionState = ValueNotifier<NetworkDetectionState>(
const NetworkDetectionState(
isTesting: false,
isLoading: true,
ipInfo: null,
),
);
class NetworkDetection extends ConsumerStatefulWidget { class NetworkDetection extends ConsumerStatefulWidget {
const NetworkDetection({super.key}); const NetworkDetection({super.key});
@@ -26,101 +14,6 @@ class NetworkDetection extends ConsumerStatefulWidget {
} }
class _NetworkDetectionState extends ConsumerState<NetworkDetection> { class _NetworkDetectionState extends ConsumerState<NetworkDetection> {
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) { _countryCodeToEmoji(String countryCode) {
final String code = countryCode.toUpperCase(); final String code = countryCode.toUpperCase();
if (code.length != 2) { if (code.length != 2) {
@@ -136,7 +29,7 @@ class _NetworkDetectionState extends ConsumerState<NetworkDetection> {
return SizedBox( return SizedBox(
height: getWidgetHeight(1), height: getWidgetHeight(1),
child: ValueListenableBuilder<NetworkDetectionState>( child: ValueListenableBuilder<NetworkDetectionState>(
valueListenable: _networkDetectionState, valueListenable: detectionState.state,
builder: (_, state, __) { builder: (_, state, __) {
final ipInfo = state.ipInfo; final ipInfo = state.ipInfo;
final isLoading = state.isLoading; final isLoading = state.isLoading;

View File

@@ -38,7 +38,7 @@ class _StartButtonState extends State<StartButton>
isStart = !isStart; isStart = !isStart;
updateController(); updateController();
debouncer.call( debouncer.call(
DebounceTag.updateStatus, FunctionTag.updateStatus,
() { () {
globalState.appController.updateStatus(isStart); globalState.appController.updateStatus(isStart);
}, },

View File

@@ -93,8 +93,6 @@ class DeveloperView extends ConsumerWidget {
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 16, left: 16,
right: 16, right: 16,
top: 4,
bottom: 4,
), ),
title: Text(appLocalizations.developerMode), title: Text(appLocalizations.developerMode),
delegate: SwitchDelegate( delegate: SwitchDelegate(

View File

@@ -103,7 +103,7 @@ class _HotKeyRecorderState extends State<HotKeyRecorder> {
modifiers: modifiers, modifiers: modifiers,
key: key.usbHidUsage, key: key.usbHidUsage,
); );
return true; return false;
} }
@override @override
@@ -157,59 +157,65 @@ class _HotKeyRecorderState extends State<HotKeyRecorder> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CommonDialog( return Focus(
title: IntlExt.actionMessage(widget.hotKeyAction.action.name), onKeyEvent: (_, __) {
actions: [ return KeyEventResult.handled;
TextButton( },
onPressed: () { autofocus: true,
_handleRemove(); child: CommonDialog(
}, title: IntlExt.actionMessage(widget.hotKeyAction.action.name),
child: Text(appLocalizations.remove), actions: [
), TextButton(
const SizedBox( onPressed: () {
width: 8, _handleRemove();
), },
TextButton( child: Text(appLocalizations.remove),
onPressed: () {
_handleConfirm();
},
child: Text(
appLocalizations.confirm,
), ),
), const SizedBox(
], width: 8,
child: ValueListenableBuilder( ),
valueListenable: hotKeyActionNotifier, TextButton(
builder: (_, hotKeyAction, ___) { onPressed: () {
final key = hotKeyAction.key; _handleConfirm();
final modifiers = hotKeyAction.modifiers; },
return SizedBox( child: Text(
width: dialogCommonWidth, appLocalizations.confirm,
child: key != null ),
? Wrap( ),
spacing: 8, ],
crossAxisAlignment: WrapCrossAlignment.center, child: ValueListenableBuilder(
children: [ valueListenable: hotKeyActionNotifier,
for (final modifier in modifiers) 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( KeyboardKeyBox(
keyboardKey: modifier.physicalKeys.first, keyboardKey: PhysicalKeyboardKey(key),
), ),
if (modifiers.isNotEmpty) ],
Text( )
"+", : Text(
style: context.textTheme.titleMedium, appLocalizations.pressKeyboard,
), style: context.textTheme.titleMedium,
KeyboardKeyBox( ),
keyboardKey: PhysicalKeyboardKey(key), );
), },
], ),
)
: Text(
appLocalizations.pressKeyboard,
style: context.textTheme.titleMedium,
),
);
},
), ),
); );
} }

View File

@@ -131,7 +131,7 @@ class _LogsFragmentState extends ConsumerState<LogsFragment> with PageMixin {
} }
updateLogsThrottler() { updateLogsThrottler() {
throttler.call("logs", () { throttler.call(FunctionTag.logs, () {
final isEquality = logListEquality.equals( final isEquality = logListEquality.equals(
_logs, _logs,
_logsStateNotifier.value.logs, _logsStateNotifier.value.logs,

View File

@@ -305,8 +305,6 @@ class OverrideSwitch extends ConsumerWidget {
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 16, left: 16,
right: 16, right: 16,
top: 4,
bottom: 4,
), ),
title: Text(appLocalizations.enableOverride), title: Text(appLocalizations.enableOverride),
delegate: SwitchDelegate( delegate: SwitchDelegate(

View File

@@ -349,12 +349,10 @@ class ProfileItem extends StatelessWidget {
), ),
PopupMenuItemData( PopupMenuItemData(
icon: Icons.delete_outlined, icon: Icons.delete_outlined,
iconSize: 20,
label: appLocalizations.delete, label: appLocalizations.delete,
onPressed: () { onPressed: () {
_handleDeleteProfile(context); _handleDeleteProfile(context);
}, },
type: PopupMenuItemType.danger,
), ),
], ],
), ),

View File

@@ -6,7 +6,7 @@ import 'package:fl_clash/state.dart';
double get listHeaderHeight { double get listHeaderHeight {
final measure = globalState.measure; final measure = globalState.measure;
return 28 + measure.titleMediumHeight + 4 + measure.bodyMediumHeight; return 20 + measure.titleMediumHeight + 4 + measure.bodyMediumHeight;
} }
double getItemHeight(ProxyCardType proxyCardType) { double getItemHeight(ProxyCardType proxyCardType) {

View File

@@ -114,12 +114,16 @@ class _ProxiesListFragmentState extends State<ProxiesListFragment> {
required int columns, required int columns,
required Set<String> currentUnfoldSet, required Set<String> currentUnfoldSet,
required ProxyCardType type, required ProxyCardType type,
required String query,
}) { }) {
final items = <Widget>[]; final items = <Widget>[];
final GroupNameProxiesMap groupNameProxiesMap = {}; final GroupNameProxiesMap groupNameProxiesMap = {};
for (final groupName in groupNames) { for (final groupName in groupNames) {
final group = final group = ref.read(
ref.read(groupsProvider.select((state) => state.getGroup(groupName))); groupsProvider.select(
(state) => state.getGroup(groupName),
),
);
if (group == null) { if (group == null) {
continue; continue;
} }
@@ -140,7 +144,9 @@ class _ProxiesListFragmentState extends State<ProxiesListFragment> {
]); ]);
if (isExpand) { if (isExpand) {
final sortedProxies = globalState.appController.getSortProxies( final sortedProxies = globalState.appController.getSortProxies(
group.all, group.all
.where((item) => item.name.toLowerCase().contains(query))
.toList(),
group.testUrl, group.testUrl,
); );
groupNameProxiesMap[groupName] = sortedProxies; groupNameProxiesMap[groupName] = sortedProxies;
@@ -250,6 +256,7 @@ class _ProxiesListFragmentState extends State<ProxiesListFragment> {
return Consumer( return Consumer(
builder: (_, ref, __) { builder: (_, ref, __) {
final state = ref.watch(proxiesListSelectorStateProvider); final state = ref.watch(proxiesListSelectorStateProvider);
ref.watch(themeSettingProvider.select((state) => state.textScale));
if (state.groupNames.isEmpty) { if (state.groupNames.isEmpty) {
return NullStatus( return NullStatus(
label: appLocalizations.nullProxies, label: appLocalizations.nullProxies,
@@ -261,6 +268,7 @@ class _ProxiesListFragmentState extends State<ProxiesListFragment> {
currentUnfoldSet: state.currentUnfoldSet, currentUnfoldSet: state.currentUnfoldSet,
columns: state.columns, columns: state.columns,
type: state.proxyCardType, type: state.proxyCardType,
query: state.query,
); );
final itemsOffset = _getItemHeightList(items, state.proxyCardType); final itemsOffset = _getItemHeightList(items, state.proxyCardType);
return CommonScrollBar( return CommonScrollBar(
@@ -484,7 +492,7 @@ class _ListHeaderState extends State<ListHeader>
return CommonCard( return CommonCard(
enterAnimated: widget.enterAnimated, enterAnimated: widget.enterAnimated,
key: widget.key, key: widget.key,
radius: 14, radius: 16.ap,
type: CommonCardType.filled, type: CommonCardType.filled,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
@@ -587,7 +595,10 @@ class _ListHeaderState extends State<ListHeader>
const SizedBox( const SizedBox(
width: 6, width: 6,
), ),
], ] else
SizedBox(
width: 4,
),
AnimatedBuilder( AnimatedBuilder(
animation: _animationController.view, animation: _animationController.view,
builder: (_, __) { builder: (_, __) {

View File

@@ -2,10 +2,12 @@ import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart'; import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/fragments/proxies/list.dart'; import 'package:fl_clash/fragments/proxies/list.dart';
import 'package:fl_clash/fragments/proxies/providers.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/providers/providers.dart';
import 'package:fl_clash/widgets/widgets.dart'; import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'common.dart'; import 'common.dart';
import 'setting.dart'; import 'setting.dart';
import 'tab.dart'; import 'tab.dart';
@@ -25,70 +27,98 @@ class _ProxiesFragmentState extends ConsumerState<ProxiesFragment>
@override @override
get actions => [ get actions => [
if (_hasProviders) CommonPopupBox(
IconButton( targetBuilder: (open) {
onPressed: () { return IconButton(
showExtend( onPressed: () {
context, open(
builder: (_, type) { offset: Offset(0, 20),
return ProvidersView( );
type: type, },
); icon: Icon(
}, Icons.more_vert,
); ),
}, );
icon: const Icon( },
Icons.poll_outlined, popup: CommonPopupMenu(
), minWidth: 180,
), items: [
_isTab PopupMenuItemData(
? IconButton( icon: Icons.tune,
label: appLocalizations.settings,
onPressed: () { onPressed: () {
_proxiesTabKey.currentState?.scrollToGroupSelected(); showSheet(
}, context: context,
icon: const Icon( props: SheetProps(
Icons.adjust_outlined, isScrollControlled: true,
), ),
)
: IconButton(
onPressed: () {
showExtend(
context,
builder: (_, type) { builder: (_, type) {
return AdaptiveSheetScaffold( return AdaptiveSheetScaffold(
type: type, type: type,
body: const _IconConfigView(), body: const ProxiesSetting(),
title: appLocalizations.iconConfiguration, 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,
);
},
);
},
), ),
), _isTab
IconButton( ? PopupMenuItemData(
onPressed: () { icon: Icons.adjust_outlined,
showSheet( label: "聚焦",
context: context, onPressed: () {
props: SheetProps( _proxiesTabKey.currentState?.scrollToGroupSelected();
isScrollControlled: true, },
), )
builder: (_, type) { : PopupMenuItemData(
return AdaptiveSheetScaffold( icon: Icons.style_outlined,
type: type, label: appLocalizations.iconConfiguration,
body: const ProxiesSetting(), onPressed: () {
title: appLocalizations.settings, showExtend(
); context,
}, builder: (_, type) {
); return AdaptiveSheetScaffold(
}, type: type,
icon: const Icon( body: const _IconConfigView(),
Icons.tune, 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 @override
get floatingActionButton => _isTab get floatingActionButton => _isTab
? DelayTestButton( ? DelayTestButton(
@@ -103,6 +133,70 @@ class _ProxiesFragmentState extends ConsumerState<ProxiesFragment>
@override @override
void initState() { 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( ref.listenManual(
proxiesActionsStateProvider, proxiesActionsStateProvider,
fireImmediately: true, fireImmediately: true,
@@ -128,8 +222,6 @@ class _ProxiesFragmentState extends ConsumerState<ProxiesFragment>
(state) => state.type, (state) => state.type,
), ),
); );
ref.watch(themeSettingProvider.select((state) => state.textScale));
return switch (proxiesType) { return switch (proxiesType) {
ProxiesType.tab => ProxiesTabFragment( ProxiesType.tab => ProxiesTabFragment(
key: _proxiesTabKey, key: _proxiesTabKey,
@@ -144,8 +236,9 @@ class _IconConfigView extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final iconMap = final iconMap = ref.watch(proxiesStyleSettingProvider.select(
ref.watch(proxiesStyleSettingProvider.select((state) => state.iconMap)); (state) => state.iconMap,
));
return MapInputPage( return MapInputPage(
title: appLocalizations.iconConfiguration, title: appLocalizations.iconConfiguration,
map: iconMap, map: iconMap,

View File

@@ -164,7 +164,7 @@ class ProxiesTabFragmentState extends ConsumerState<ProxiesTabFragment>
if (prev == next) { if (prev == next) {
return; return;
} }
if (prev?.groupNames.length != next.groupNames.length) { if (!stringListEquality.equals(prev?.groupNames, next.groupNames)) {
_destroyTabController(); _destroyTabController();
final index = next.groupNames.indexWhere( final index = next.groupNames.indexWhere(
(item) => item == next.currentGroupName, (item) => item == next.currentGroupName,
@@ -178,6 +178,7 @@ class ProxiesTabFragmentState extends ConsumerState<ProxiesTabFragment>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
ref.watch(themeSettingProvider.select((state) => state.textScale));
final state = ref.watch(groupNamesStateProvider); final state = ref.watch(groupNamesStateProvider);
final groupNames = state.groupNames; final groupNames = state.groupNames;
if (groupNames.isEmpty) { if (groupNames.isEmpty) {

View File

@@ -21,9 +21,6 @@ import 'common/common.dart';
Future<void> main() async { Future<void> main() async {
globalState.isService = false; globalState.isService = false;
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
FlutterError.onError = (details) {
commonPrint.log(details.stack.toString());
};
final version = await system.version; final version = await system.version;
await clashCore.preload(); await clashCore.preload();
await globalState.initApp(version); await globalState.initApp(version);

View File

@@ -32,6 +32,15 @@ class _AppStateManagerState extends ConsumerState<AppStateManager>
} }
}); });
}); });
ref.listenManual(
checkIpProvider,
(prev, next) {
if (prev != next && next.b) {
detectionState.startCheck();
}
},
fireImmediately: true,
);
} }
@override @override

View File

@@ -61,7 +61,7 @@ class _ClashContainerState extends ConsumerState<ClashManager>
final appController = globalState.appController; final appController = globalState.appController;
appController.setDelay(delay); appController.setDelay(delay);
debouncer.call( debouncer.call(
DebounceTag.updateDelay, FunctionTag.updateDelay,
() async { () async {
await appController.updateGroupsDebounce(); await appController.updateGroupsDebounce();
}, },

View File

@@ -8,7 +8,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hotkey_manager/hotkey_manager.dart'; import 'package:hotkey_manager/hotkey_manager.dart';
class HotKeyManager extends StatelessWidget { class HotKeyManager extends ConsumerStatefulWidget {
final Widget child; final Widget child;
const HotKeyManager({ const HotKeyManager({
@@ -16,6 +16,25 @@ class HotKeyManager extends StatelessWidget {
required this.child, required this.child,
}); });
@override
ConsumerState<HotKeyManager> createState() => _HotKeyManagerState();
}
class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
@override
void initState() {
super.initState();
ref.listenManual(
hotKeyActionsProvider,
(prev, next) {
if (!hotKeyActionListEquality.equals(prev, next)) {
_updateHotKeys(hotKeyActions: next);
}
},
fireImmediately: true,
);
}
_handleHotKeyAction(HotAction action) async { _handleHotKeyAction(HotAction action) async {
switch (action) { switch (action) {
case HotAction.mode: case HotAction.mode:
@@ -59,22 +78,30 @@ class HotKeyManager extends StatelessWidget {
await Future.wait(hotkeyActionHandles); await Future.wait(hotkeyActionHandles);
} }
_buildShortcuts(Widget child) {
return Shortcuts(
shortcuts: {
utils.controlSingleActivator(LogicalKeyboardKey.keyW):
CloseWindowIntent(),
},
child: Actions(
actions: {
CloseWindowIntent: CallbackAction<CloseWindowIntent>(
onInvoke: (_) => globalState.appController.handleBackOrExit(),
),
DoNothingIntent: CallbackAction<DoNothingIntent>(
onInvoke: (_) => null,
),
},
child: child,
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer( return _buildShortcuts(
builder: (_, ref, child) { widget.child,
ref.listenManual(
hotKeyActionsProvider,
(prev, next) {
if (!hotKeyActionListEquality.equals(prev, next)) {
_updateHotKeys(hotKeyActions: next);
}
},
fireImmediately: true,
);
return child!;
},
child: child,
); );
} }
} }

View File

@@ -38,7 +38,7 @@ class ThemeManager extends ConsumerWidget {
textScaleFactor, textScaleFactor,
), ),
padding: padding.copyWith( 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( child: LayoutBuilder(

View File

@@ -29,7 +29,7 @@ class _VpnContainerState extends ConsumerState<VpnManager> {
showTip() { showTip() {
debouncer.call( debouncer.call(
DebounceTag.vpnTip, FunctionTag.vpnTip,
() { () {
if (ref.read(runTimeProvider.notifier).isStart) { if (ref.read(runTimeProvider.notifier).isStart) {
globalState.showNotifier( globalState.showNotifier(

View File

@@ -38,7 +38,7 @@ class _WindowContainerState extends ConsumerState<WindowManager>
(prev, next) { (prev, next) {
if (prev != next) { if (prev != next) {
debouncer.call( debouncer.call(
DebounceTag.autoLaunch, FunctionTag.autoLaunch,
() { () {
autoLaunch?.updateStatus(next); autoLaunch?.updateStatus(next);
}, },
@@ -103,7 +103,7 @@ class _WindowContainerState extends ConsumerState<WindowManager>
@override @override
Future<void> onTaskbarCreated() async { Future<void> onTaskbarCreated() async {
globalState.appController.updateTray(true); // globalState.appController.updateTray(true);
super.onTaskbarCreated(); super.onTaskbarCreated();
} }

View File

@@ -14,6 +14,7 @@ typedef DelayMap = Map<String, Map<String, int?>>;
class AppState with _$AppState { class AppState with _$AppState {
const factory AppState({ const factory AppState({
@Default(false) bool isInit, @Default(false) bool isInit,
@Default(false) bool backBlock,
@Default(PageLabel.dashboard) PageLabel pageLabel, @Default(PageLabel.dashboard) PageLabel pageLabel,
@Default([]) List<Package> packages, @Default([]) List<Package> packages,
@Default(0) int sortNum, @Default(0) int sortNum,
@@ -30,6 +31,7 @@ class AppState with _$AppState {
required FixedList<Log> logs, required FixedList<Log> logs,
required FixedList<Traffic> traffics, required FixedList<Traffic> traffics,
required Traffic totalTraffic, required Traffic totalTraffic,
@Default("") String proxiesQuery,
@Default(false) bool needApply, @Default(false) bool needApply,
}) = _AppState; }) = _AppState;
} }

View File

@@ -8,7 +8,6 @@ import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
part 'generated/common.freezed.dart'; part 'generated/common.freezed.dart';
part 'generated/common.g.dart'; part 'generated/common.g.dart';
@freezed @freezed
@@ -129,10 +128,10 @@ extension LogsStateExt on LogsState {
final lowQuery = query.toLowerCase(); final lowQuery = query.toLowerCase();
return logs.where( return logs.where(
(log) { (log) {
final payload = log.payload.toLowerCase();
final logLevelName = log.logLevel.name; final logLevelName = log.logLevel.name;
return {logLevelName}.containsAll(keywords) && return {logLevelName}.containsAll(keywords) &&
((payload.contains(lowQuery)) || logLevelName.contains(lowQuery)); ((log.payload.toLowerCase().contains(lowQuery)) ||
logLevelName.contains(lowQuery));
}, },
).toList(); ).toList();
} }
@@ -504,15 +503,11 @@ class PopupMenuItemData {
this.icon, this.icon,
required this.label, required this.label,
required this.onPressed, required this.onPressed,
this.type,
this.iconSize,
}); });
final double? iconSize;
final String label; final String label;
final VoidCallback? onPressed; final VoidCallback? onPressed;
final IconData? icon; final IconData? icon;
final PopupMenuItemType? type;
} }
@freezed @freezed
@@ -528,3 +523,7 @@ class TextPainterParams with _$TextPainterParams {
factory TextPainterParams.fromJson(Map<String, Object?> json) => factory TextPainterParams.fromJson(Map<String, Object?> json) =>
_$TextPainterParamsFromJson(json); _$TextPainterParamsFromJson(json);
} }
class CloseWindowIntent extends Intent {
const CloseWindowIntent();
}

View File

@@ -17,6 +17,7 @@ final _privateConstructorUsedError = UnsupportedError(
/// @nodoc /// @nodoc
mixin _$AppState { mixin _$AppState {
bool get isInit => throw _privateConstructorUsedError; bool get isInit => throw _privateConstructorUsedError;
bool get backBlock => throw _privateConstructorUsedError;
PageLabel get pageLabel => throw _privateConstructorUsedError; PageLabel get pageLabel => throw _privateConstructorUsedError;
List<Package> get packages => throw _privateConstructorUsedError; List<Package> get packages => throw _privateConstructorUsedError;
int get sortNum => throw _privateConstructorUsedError; int get sortNum => throw _privateConstructorUsedError;
@@ -34,6 +35,7 @@ mixin _$AppState {
FixedList<Log> get logs => throw _privateConstructorUsedError; FixedList<Log> get logs => throw _privateConstructorUsedError;
FixedList<Traffic> get traffics => throw _privateConstructorUsedError; FixedList<Traffic> get traffics => throw _privateConstructorUsedError;
Traffic get totalTraffic => throw _privateConstructorUsedError; Traffic get totalTraffic => throw _privateConstructorUsedError;
String get proxiesQuery => throw _privateConstructorUsedError;
bool get needApply => throw _privateConstructorUsedError; bool get needApply => throw _privateConstructorUsedError;
/// Create a copy of AppState /// Create a copy of AppState
@@ -50,6 +52,7 @@ abstract class $AppStateCopyWith<$Res> {
@useResult @useResult
$Res call( $Res call(
{bool isInit, {bool isInit,
bool backBlock,
PageLabel pageLabel, PageLabel pageLabel,
List<Package> packages, List<Package> packages,
int sortNum, int sortNum,
@@ -66,6 +69,7 @@ abstract class $AppStateCopyWith<$Res> {
FixedList<Log> logs, FixedList<Log> logs,
FixedList<Traffic> traffics, FixedList<Traffic> traffics,
Traffic totalTraffic, Traffic totalTraffic,
String proxiesQuery,
bool needApply}); bool needApply});
} }
@@ -85,6 +89,7 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
@override @override
$Res call({ $Res call({
Object? isInit = null, Object? isInit = null,
Object? backBlock = null,
Object? pageLabel = null, Object? pageLabel = null,
Object? packages = null, Object? packages = null,
Object? sortNum = null, Object? sortNum = null,
@@ -101,6 +106,7 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
Object? logs = null, Object? logs = null,
Object? traffics = null, Object? traffics = null,
Object? totalTraffic = null, Object? totalTraffic = null,
Object? proxiesQuery = null,
Object? needApply = null, Object? needApply = null,
}) { }) {
return _then(_value.copyWith( return _then(_value.copyWith(
@@ -108,6 +114,10 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
? _value.isInit ? _value.isInit
: isInit // ignore: cast_nullable_to_non_nullable : isInit // ignore: cast_nullable_to_non_nullable
as bool, as bool,
backBlock: null == backBlock
? _value.backBlock
: backBlock // ignore: cast_nullable_to_non_nullable
as bool,
pageLabel: null == pageLabel pageLabel: null == pageLabel
? _value.pageLabel ? _value.pageLabel
: pageLabel // ignore: cast_nullable_to_non_nullable : pageLabel // ignore: cast_nullable_to_non_nullable
@@ -172,6 +182,10 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
? _value.totalTraffic ? _value.totalTraffic
: totalTraffic // ignore: cast_nullable_to_non_nullable : totalTraffic // ignore: cast_nullable_to_non_nullable
as Traffic, as Traffic,
proxiesQuery: null == proxiesQuery
? _value.proxiesQuery
: proxiesQuery // ignore: cast_nullable_to_non_nullable
as String,
needApply: null == needApply needApply: null == needApply
? _value.needApply ? _value.needApply
: needApply // ignore: cast_nullable_to_non_nullable : needApply // ignore: cast_nullable_to_non_nullable
@@ -190,6 +204,7 @@ abstract class _$$AppStateImplCopyWith<$Res>
@useResult @useResult
$Res call( $Res call(
{bool isInit, {bool isInit,
bool backBlock,
PageLabel pageLabel, PageLabel pageLabel,
List<Package> packages, List<Package> packages,
int sortNum, int sortNum,
@@ -206,6 +221,7 @@ abstract class _$$AppStateImplCopyWith<$Res>
FixedList<Log> logs, FixedList<Log> logs,
FixedList<Traffic> traffics, FixedList<Traffic> traffics,
Traffic totalTraffic, Traffic totalTraffic,
String proxiesQuery,
bool needApply}); bool needApply});
} }
@@ -223,6 +239,7 @@ class __$$AppStateImplCopyWithImpl<$Res>
@override @override
$Res call({ $Res call({
Object? isInit = null, Object? isInit = null,
Object? backBlock = null,
Object? pageLabel = null, Object? pageLabel = null,
Object? packages = null, Object? packages = null,
Object? sortNum = null, Object? sortNum = null,
@@ -239,6 +256,7 @@ class __$$AppStateImplCopyWithImpl<$Res>
Object? logs = null, Object? logs = null,
Object? traffics = null, Object? traffics = null,
Object? totalTraffic = null, Object? totalTraffic = null,
Object? proxiesQuery = null,
Object? needApply = null, Object? needApply = null,
}) { }) {
return _then(_$AppStateImpl( return _then(_$AppStateImpl(
@@ -246,6 +264,10 @@ class __$$AppStateImplCopyWithImpl<$Res>
? _value.isInit ? _value.isInit
: isInit // ignore: cast_nullable_to_non_nullable : isInit // ignore: cast_nullable_to_non_nullable
as bool, as bool,
backBlock: null == backBlock
? _value.backBlock
: backBlock // ignore: cast_nullable_to_non_nullable
as bool,
pageLabel: null == pageLabel pageLabel: null == pageLabel
? _value.pageLabel ? _value.pageLabel
: pageLabel // ignore: cast_nullable_to_non_nullable : pageLabel // ignore: cast_nullable_to_non_nullable
@@ -310,6 +332,10 @@ class __$$AppStateImplCopyWithImpl<$Res>
? _value.totalTraffic ? _value.totalTraffic
: totalTraffic // ignore: cast_nullable_to_non_nullable : totalTraffic // ignore: cast_nullable_to_non_nullable
as Traffic, as Traffic,
proxiesQuery: null == proxiesQuery
? _value.proxiesQuery
: proxiesQuery // ignore: cast_nullable_to_non_nullable
as String,
needApply: null == needApply needApply: null == needApply
? _value.needApply ? _value.needApply
: needApply // ignore: cast_nullable_to_non_nullable : needApply // ignore: cast_nullable_to_non_nullable
@@ -323,6 +349,7 @@ class __$$AppStateImplCopyWithImpl<$Res>
class _$AppStateImpl implements _AppState { class _$AppStateImpl implements _AppState {
const _$AppStateImpl( const _$AppStateImpl(
{this.isInit = false, {this.isInit = false,
this.backBlock = false,
this.pageLabel = PageLabel.dashboard, this.pageLabel = PageLabel.dashboard,
final List<Package> packages = const [], final List<Package> packages = const [],
this.sortNum = 0, this.sortNum = 0,
@@ -339,6 +366,7 @@ class _$AppStateImpl implements _AppState {
required this.logs, required this.logs,
required this.traffics, required this.traffics,
required this.totalTraffic, required this.totalTraffic,
this.proxiesQuery = "",
this.needApply = false}) this.needApply = false})
: _packages = packages, : _packages = packages,
_delayMap = delayMap, _delayMap = delayMap,
@@ -350,6 +378,9 @@ class _$AppStateImpl implements _AppState {
final bool isInit; final bool isInit;
@override @override
@JsonKey() @JsonKey()
final bool backBlock;
@override
@JsonKey()
final PageLabel pageLabel; final PageLabel pageLabel;
final List<Package> _packages; final List<Package> _packages;
@override @override
@@ -413,11 +444,14 @@ class _$AppStateImpl implements _AppState {
final Traffic totalTraffic; final Traffic totalTraffic;
@override @override
@JsonKey() @JsonKey()
final String proxiesQuery;
@override
@JsonKey()
final bool needApply; final bool needApply;
@override @override
String toString() { 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 @override
@@ -426,6 +460,8 @@ class _$AppStateImpl implements _AppState {
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$AppStateImpl && other is _$AppStateImpl &&
(identical(other.isInit, isInit) || other.isInit == isInit) && (identical(other.isInit, isInit) || other.isInit == isInit) &&
(identical(other.backBlock, backBlock) ||
other.backBlock == backBlock) &&
(identical(other.pageLabel, pageLabel) || (identical(other.pageLabel, pageLabel) ||
other.pageLabel == pageLabel) && other.pageLabel == pageLabel) &&
const DeepCollectionEquality().equals(other._packages, _packages) && const DeepCollectionEquality().equals(other._packages, _packages) &&
@@ -450,31 +486,36 @@ class _$AppStateImpl implements _AppState {
other.traffics == traffics) && other.traffics == traffics) &&
(identical(other.totalTraffic, totalTraffic) || (identical(other.totalTraffic, totalTraffic) ||
other.totalTraffic == totalTraffic) && other.totalTraffic == totalTraffic) &&
(identical(other.proxiesQuery, proxiesQuery) ||
other.proxiesQuery == proxiesQuery) &&
(identical(other.needApply, needApply) || (identical(other.needApply, needApply) ||
other.needApply == needApply)); other.needApply == needApply));
} }
@override @override
int get hashCode => Object.hash( int get hashCode => Object.hashAll([
runtimeType, runtimeType,
isInit, isInit,
pageLabel, backBlock,
const DeepCollectionEquality().hash(_packages), pageLabel,
sortNum, const DeepCollectionEquality().hash(_packages),
viewSize, sortNum,
const DeepCollectionEquality().hash(_delayMap), viewSize,
const DeepCollectionEquality().hash(_groups), const DeepCollectionEquality().hash(_delayMap),
checkIpNum, const DeepCollectionEquality().hash(_groups),
brightness, checkIpNum,
runTime, brightness,
const DeepCollectionEquality().hash(_providers), runTime,
localIp, const DeepCollectionEquality().hash(_providers),
requests, localIp,
version, requests,
logs, version,
traffics, logs,
totalTraffic, traffics,
needApply); totalTraffic,
proxiesQuery,
needApply
]);
/// Create a copy of AppState /// Create a copy of AppState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@@ -488,6 +529,7 @@ class _$AppStateImpl implements _AppState {
abstract class _AppState implements AppState { abstract class _AppState implements AppState {
const factory _AppState( const factory _AppState(
{final bool isInit, {final bool isInit,
final bool backBlock,
final PageLabel pageLabel, final PageLabel pageLabel,
final List<Package> packages, final List<Package> packages,
final int sortNum, final int sortNum,
@@ -504,11 +546,14 @@ abstract class _AppState implements AppState {
required final FixedList<Log> logs, required final FixedList<Log> logs,
required final FixedList<Traffic> traffics, required final FixedList<Traffic> traffics,
required final Traffic totalTraffic, required final Traffic totalTraffic,
final String proxiesQuery,
final bool needApply}) = _$AppStateImpl; final bool needApply}) = _$AppStateImpl;
@override @override
bool get isInit; bool get isInit;
@override @override
bool get backBlock;
@override
PageLabel get pageLabel; PageLabel get pageLabel;
@override @override
List<Package> get packages; List<Package> get packages;
@@ -541,6 +586,8 @@ abstract class _AppState implements AppState {
@override @override
Traffic get totalTraffic; Traffic get totalTraffic;
@override @override
String get proxiesQuery;
@override
bool get needApply; bool get needApply;
/// Create a copy of AppState /// Create a copy of AppState

View File

@@ -2142,6 +2142,7 @@ mixin _$ProxiesListSelectorState {
ProxyCardType get proxyCardType => throw _privateConstructorUsedError; ProxyCardType get proxyCardType => throw _privateConstructorUsedError;
num get sortNum => throw _privateConstructorUsedError; num get sortNum => throw _privateConstructorUsedError;
int get columns => throw _privateConstructorUsedError; int get columns => throw _privateConstructorUsedError;
String get query => throw _privateConstructorUsedError;
/// Create a copy of ProxiesListSelectorState /// Create a copy of ProxiesListSelectorState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@@ -2162,7 +2163,8 @@ abstract class $ProxiesListSelectorStateCopyWith<$Res> {
ProxiesSortType proxiesSortType, ProxiesSortType proxiesSortType,
ProxyCardType proxyCardType, ProxyCardType proxyCardType,
num sortNum, num sortNum,
int columns}); int columns,
String query});
} }
/// @nodoc /// @nodoc
@@ -2187,6 +2189,7 @@ class _$ProxiesListSelectorStateCopyWithImpl<$Res,
Object? proxyCardType = null, Object? proxyCardType = null,
Object? sortNum = null, Object? sortNum = null,
Object? columns = null, Object? columns = null,
Object? query = null,
}) { }) {
return _then(_value.copyWith( return _then(_value.copyWith(
groupNames: null == groupNames groupNames: null == groupNames
@@ -2213,6 +2216,10 @@ class _$ProxiesListSelectorStateCopyWithImpl<$Res,
? _value.columns ? _value.columns
: columns // ignore: cast_nullable_to_non_nullable : columns // ignore: cast_nullable_to_non_nullable
as int, as int,
query: null == query
? _value.query
: query // ignore: cast_nullable_to_non_nullable
as String,
) as $Val); ) as $Val);
} }
} }
@@ -2232,7 +2239,8 @@ abstract class _$$ProxiesListSelectorStateImplCopyWith<$Res>
ProxiesSortType proxiesSortType, ProxiesSortType proxiesSortType,
ProxyCardType proxyCardType, ProxyCardType proxyCardType,
num sortNum, num sortNum,
int columns}); int columns,
String query});
} }
/// @nodoc /// @nodoc
@@ -2256,6 +2264,7 @@ class __$$ProxiesListSelectorStateImplCopyWithImpl<$Res>
Object? proxyCardType = null, Object? proxyCardType = null,
Object? sortNum = null, Object? sortNum = null,
Object? columns = null, Object? columns = null,
Object? query = null,
}) { }) {
return _then(_$ProxiesListSelectorStateImpl( return _then(_$ProxiesListSelectorStateImpl(
groupNames: null == groupNames groupNames: null == groupNames
@@ -2282,6 +2291,10 @@ class __$$ProxiesListSelectorStateImplCopyWithImpl<$Res>
? _value.columns ? _value.columns
: columns // ignore: cast_nullable_to_non_nullable : columns // ignore: cast_nullable_to_non_nullable
as int, 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.proxiesSortType,
required this.proxyCardType, required this.proxyCardType,
required this.sortNum, required this.sortNum,
required this.columns}) required this.columns,
required this.query})
: _groupNames = groupNames, : _groupNames = groupNames,
_currentUnfoldSet = currentUnfoldSet; _currentUnfoldSet = currentUnfoldSet;
@@ -2323,10 +2337,12 @@ class _$ProxiesListSelectorStateImpl implements _ProxiesListSelectorState {
final num sortNum; final num sortNum;
@override @override
final int columns; final int columns;
@override
final String query;
@override @override
String toString() { 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 @override
@@ -2343,7 +2359,8 @@ class _$ProxiesListSelectorStateImpl implements _ProxiesListSelectorState {
(identical(other.proxyCardType, proxyCardType) || (identical(other.proxyCardType, proxyCardType) ||
other.proxyCardType == proxyCardType) && other.proxyCardType == proxyCardType) &&
(identical(other.sortNum, sortNum) || other.sortNum == sortNum) && (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 @override
@@ -2354,7 +2371,8 @@ class _$ProxiesListSelectorStateImpl implements _ProxiesListSelectorState {
proxiesSortType, proxiesSortType,
proxyCardType, proxyCardType,
sortNum, sortNum,
columns); columns,
query);
/// Create a copy of ProxiesListSelectorState /// Create a copy of ProxiesListSelectorState
/// with the given fields replaced by the non-null parameter values. /// 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 ProxiesSortType proxiesSortType,
required final ProxyCardType proxyCardType, required final ProxyCardType proxyCardType,
required final num sortNum, required final num sortNum,
required final int columns}) = _$ProxiesListSelectorStateImpl; required final int columns,
required final String query}) = _$ProxiesListSelectorStateImpl;
@override @override
List<String> get groupNames; List<String> get groupNames;
@@ -2387,6 +2406,8 @@ abstract class _ProxiesListSelectorState implements ProxiesListSelectorState {
num get sortNum; num get sortNum;
@override @override
int get columns; int get columns;
@override
String get query;
/// Create a copy of ProxiesListSelectorState /// Create a copy of ProxiesListSelectorState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.

View File

@@ -25,7 +25,7 @@ class VM3<A, B, C> with _$VM3<A, B, C> {
} }
@freezed @freezed
class VM4<A, B, C,D> with _$VM4<A, B, C,D> { class VM4<A, B, C, D> with _$VM4<A, B, C, D> {
const factory VM4({ const factory VM4({
required A a, required A a,
required B b, required B b,
@@ -34,7 +34,6 @@ class VM4<A, B, C,D> with _$VM4<A, B, C,D> {
}) = _VM4; }) = _VM4;
} }
@freezed @freezed
class StartButtonSelectorState with _$StartButtonSelectorState { class StartButtonSelectorState with _$StartButtonSelectorState {
const factory StartButtonSelectorState({ const factory StartButtonSelectorState({
@@ -125,6 +124,7 @@ class ProxiesListSelectorState with _$ProxiesListSelectorState {
required ProxyCardType proxyCardType, required ProxyCardType proxyCardType,
required num sortNum, required num sortNum,
required int columns, required int columns,
required String query,
}) = _ProxiesListSelectorState; }) = _ProxiesListSelectorState;
} }

View File

@@ -122,12 +122,15 @@ class _EditorPageState extends ConsumerState<EditorPage> {
(value) => CommonPopupBox( (value) => CommonPopupBox(
targetBuilder: (open) { targetBuilder: (open) {
return IconButton( return IconButton(
onPressed: open, onPressed: () {
open(
offset: Offset(0, 20),
);
},
icon: const Icon(Icons.more_vert), icon: const Icon(Icons.more_vert),
); );
}, },
popup: CommonPopupMenu( popup: CommonPopupMenu(
minWidth: 180,
items: [ items: [
PopupMenuItemData( PopupMenuItemData(
icon: Icons.search, icon: Icons.search,
@@ -151,6 +154,7 @@ class _EditorPageState extends ConsumerState<EditorPage> {
], ],
body: CodeEditor( body: CodeEditor(
findController: _findController, findController: _findController,
maxLengthSingleLineRendering: 200,
findBuilder: (context, controller, readOnly) => FindPanel( findBuilder: (context, controller, readOnly) => FindPanel(
controller: controller, controller: controller,
readOnly: readOnly, readOnly: readOnly,
@@ -190,7 +194,7 @@ class _EditorPageState extends ConsumerState<EditorPage> {
shortcutsActivatorsBuilder: DefaultCodeShortcutsActivatorsBuilder(), shortcutsActivatorsBuilder: DefaultCodeShortcutsActivatorsBuilder(),
controller: _controller, controller: _controller,
style: CodeEditorStyle( style: CodeEditorStyle(
fontSize: 14.ap, fontSize: context.textTheme.bodyLarge?.fontSize?.ap,
fontFamily: FontFamily.jetBrainsMono.value, fontFamily: FontFamily.jetBrainsMono.value,
codeTheme: CodeHighlightTheme( codeTheme: CodeHighlightTheme(
languages: { languages: {

View File

@@ -286,6 +286,21 @@ class CheckIpNum extends _$CheckIpNum with AutoDisposeNotifierMixin {
add() => state++; 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 @riverpod
class Version extends _$Version with AutoDisposeNotifierMixin { class Version extends _$Version with AutoDisposeNotifierMixin {
@override @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,
);
}
}

View File

@@ -276,6 +276,20 @@ final checkIpNumProvider =
); );
typedef _$CheckIpNum = AutoDisposeNotifier<int>; typedef _$CheckIpNum = AutoDisposeNotifier<int>;
String _$backBlockHash() => r'c0223e0776b72d3a8c8842fc32fdb5287353999f';
/// See also [BackBlock].
@ProviderFor(BackBlock)
final backBlockProvider = AutoDisposeNotifierProvider<BackBlock, bool>.internal(
BackBlock.new,
name: r'backBlockProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$backBlockHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$BackBlock = AutoDisposeNotifier<bool>;
String _$versionHash() => r'8c0ee019d20df3f112c38ae4dc4abd61148d3809'; String _$versionHash() => r'8c0ee019d20df3f112c38ae4dc4abd61148d3809';
/// See also [Version]. /// See also [Version].
@@ -335,5 +349,20 @@ final needApplyProvider = AutoDisposeNotifierProvider<NeedApply, bool>.internal(
); );
typedef _$NeedApply = AutoDisposeNotifier<bool>; typedef _$NeedApply = AutoDisposeNotifier<bool>;
String _$proxiesQueryHash() => r'9f3907e06534b6882684bec47ca3ba2988297e19';
/// See also [ProxiesQuery].
@ProviderFor(ProxiesQuery)
final proxiesQueryProvider =
AutoDisposeNotifierProvider<ProxiesQuery, String>.internal(
ProxiesQuery.new,
name: r'proxiesQueryProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$proxiesQueryHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$ProxiesQuery = AutoDisposeNotifier<String>;
// ignore_for_file: type=lint // 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 // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

View File

@@ -236,7 +236,7 @@ final profilesSelectorStateProvider =
typedef ProfilesSelectorStateRef typedef ProfilesSelectorStateRef
= AutoDisposeProviderRef<ProfilesSelectorState>; = AutoDisposeProviderRef<ProfilesSelectorState>;
String _$proxiesListSelectorStateHash() => String _$proxiesListSelectorStateHash() =>
r'0e63ea2fb141e086156a2ed8452584e2375c5aa5'; r'5e6bbe1a0cecbdea6c9c62e6ccf314968deac264';
/// See also [proxiesListSelectorState]. /// See also [proxiesListSelectorState].
@ProviderFor(proxiesListSelectorState) @ProviderFor(proxiesListSelectorState)
@@ -292,7 +292,7 @@ final groupNamesStateProvider = AutoDisposeProvider<GroupNamesState>.internal(
// ignore: unused_element // ignore: unused_element
typedef GroupNamesStateRef = AutoDisposeProviderRef<GroupNamesState>; typedef GroupNamesStateRef = AutoDisposeProviderRef<GroupNamesState>;
String _$proxyGroupSelectorStateHash() => String _$proxyGroupSelectorStateHash() =>
r'5bc86d13286c6c859f0b874235a281122cc612ba'; r'50940ff452859b02af0095cb7c4bcda813847645';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {
@@ -1781,6 +1781,22 @@ final layoutChangeProvider = AutoDisposeProvider<VM2?>.internal(
@Deprecated('Will be removed in 3.0. Use Ref instead') @Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element // ignore: unused_element
typedef LayoutChangeRef = AutoDisposeProviderRef<VM2?>; typedef LayoutChangeRef = AutoDisposeProviderRef<VM2?>;
String _$checkIpHash() => r'07ebf8d032349e2b3adda483e68b1936ffbed68d';
/// See also [checkIp].
@ProviderFor(checkIp)
final checkIpProvider = AutoDisposeProvider<VM2<int, bool>>.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<VM2<int, bool>>;
String _$genColorSchemeHash() => r'b18f15c938a8132ee4ed02cdfc02f3b9f01724e2'; String _$genColorSchemeHash() => r'b18f15c938a8132ee4ed02cdfc02f3b9f01724e2';
/// See also [genColorScheme]. /// See also [genColorScheme].

View File

@@ -210,7 +210,10 @@ ProfilesSelectorState profilesSelectorState(Ref ref) {
final currentProfileId = ref.watch(currentProfileIdProvider); final currentProfileId = ref.watch(currentProfileIdProvider);
final profiles = ref.watch(profilesProvider); final profiles = ref.watch(profilesProvider);
final columns = ref.watch( final columns = ref.watch(
viewWidthProvider.select((state) => utils.getProfilesColumns(state))); viewWidthProvider.select(
(state) => utils.getProfilesColumns(state),
),
);
return ProfilesSelectorState( return ProfilesSelectorState(
profiles: profiles, profiles: profiles,
currentProfileId: currentProfileId, currentProfileId: currentProfileId,
@@ -227,6 +230,8 @@ ProxiesListSelectorState proxiesListSelectorState(Ref ref) {
final proxiesStyle = ref.watch(proxiesStyleSettingProvider); final proxiesStyle = ref.watch(proxiesStyleSettingProvider);
final sortNum = ref.watch(sortNumProvider); final sortNum = ref.watch(sortNumProvider);
final columns = ref.watch(getProxiesColumnsProvider); final columns = ref.watch(getProxiesColumnsProvider);
final query =
ref.watch(proxiesQueryProvider.select((state) => state.toLowerCase()));
return ProxiesListSelectorState( return ProxiesListSelectorState(
groupNames: groupNames, groupNames: groupNames,
currentUnfoldSet: currentUnfoldSet, currentUnfoldSet: currentUnfoldSet,
@@ -234,6 +239,7 @@ ProxiesListSelectorState proxiesListSelectorState(Ref ref) {
proxyCardType: proxiesStyle.cardType, proxyCardType: proxiesStyle.cardType,
sortNum: sortNum, sortNum: sortNum,
columns: columns, columns: columns,
query: query,
); );
} }
@@ -280,13 +286,19 @@ ProxyGroupSelectorState proxyGroupSelectorState(Ref ref, String groupName) {
); );
final sortNum = ref.watch(sortNumProvider); final sortNum = ref.watch(sortNumProvider);
final columns = ref.watch(getProxiesColumnsProvider); 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( return ProxyGroupSelectorState(
testUrl: group?.testUrl, testUrl: group?.testUrl,
proxiesSortType: proxiesStyle.sortType, proxiesSortType: proxiesStyle.sortType,
proxyCardType: proxiesStyle.cardType, proxyCardType: proxiesStyle.cardType,
sortNum: sortNum, sortNum: sortNum,
groupType: group?.type ?? GroupType.Selector, groupType: group?.type ?? GroupType.Selector,
proxies: group?.all ?? [], proxies: proxies,
columns: columns, columns: columns,
); );
} }
@@ -521,6 +533,21 @@ VM2? layoutChange(Ref ref) {
); );
} }
@riverpod
VM2<int, bool> 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 @riverpod
ColorScheme genColorScheme( ColorScheme genColorScheme(
Ref ref, Ref ref,

View File

@@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:animations/animations.dart'; import 'package:animations/animations.dart';
import 'package:dio/dio.dart';
import 'package:dynamic_color/dynamic_color.dart'; import 'package:dynamic_color/dynamic_color.dart';
import 'package:fl_clash/clash/clash.dart'; import 'package:fl_clash/clash/clash.dart';
import 'package:fl_clash/common/theme.dart'; import 'package:fl_clash/common/theme.dart';
@@ -289,3 +290,94 @@ class GlobalState {
} }
final globalState = GlobalState(); final globalState = GlobalState();
class DetectionState {
static DetectionState? _instance;
bool? _preIsStart;
Timer? _setTimeoutTimer;
CancelToken? cancelToken;
final state = ValueNotifier<NetworkDetectionState>(
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();

View File

@@ -10,7 +10,7 @@ import 'card.dart';
import 'float_layout.dart'; import 'float_layout.dart';
import 'list.dart'; import 'list.dart';
class OptionsDialog<T> extends StatefulWidget { class OptionsDialog<T> extends StatelessWidget {
final String title; final String title;
final List<T> options; final List<T> options;
final T value; final T value;
@@ -24,48 +24,35 @@ class OptionsDialog<T> extends StatefulWidget {
required this.value, required this.value,
}); });
@override
State<OptionsDialog<T>> createState() => _OptionsDialogState();
}
class _OptionsDialogState<T> extends State<OptionsDialog<T>> {
final _defaultValue = "";
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
final context =
GlobalObjectKey(widget.value ?? _defaultValue).currentContext;
if (context != null) {
Scrollable.ensureVisible(context);
}
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CommonDialog( return CommonDialog(
title: widget.title, title: title,
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 8, horizontal: 8,
vertical: 16, vertical: 16,
), ),
child: Wrap( child: Wrap(
children: [ children: [
for (final option in widget.options) for (final option in options)
ListItem.radio( Builder(
key: GlobalObjectKey(option ?? _defaultValue), builder: (context) {
delegate: RadioDelegate( if (value == option) {
value: option, WidgetsBinding.instance.addPostFrameCallback((_) {
groupValue: widget.value, Scrollable.ensureVisible(context);
onChanged: (T? value) { });
Navigator.of(context).pop(value); }
}, return ListItem.radio(
), delegate: RadioDelegate(
title: Text( value: option,
widget.textBuilder(option), groupValue: value,
), onChanged: (T? value) {
Navigator.of(context).pop(value);
},
),
title: Text(textBuilder(option)),
);
},
), ),
], ],
), ),

View File

@@ -1,4 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:fl_clash/state.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
class CommonPopScope extends StatelessWidget { 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<SystemBackBlock> createState() => _SystemBackBlockState();
}
class _SystemBackBlockState extends State<SystemBackBlock> {
@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;
}
}

View File

@@ -201,12 +201,16 @@ class OverflowAwareLayoutDelegate extends SingleChildLayoutDelegate {
class CommonPopupMenu extends StatelessWidget { class CommonPopupMenu extends StatelessWidget {
final List<PopupMenuItemData> items; final List<PopupMenuItemData> items;
final double? minWidth; final double minWidth;
final double minItemVerticalPadding;
final double fontSize;
const CommonPopupMenu({ const CommonPopupMenu({
super.key, super.key,
required this.items, required this.items,
this.minWidth, this.minWidth = 160,
this.minItemVerticalPadding = 16,
this.fontSize = 15,
}); });
Widget _popupMenuItem( Widget _popupMenuItem(
@@ -214,16 +218,11 @@ class CommonPopupMenu extends StatelessWidget {
required PopupMenuItemData item, required PopupMenuItemData item,
required int index, required int index,
}) { }) {
final isDanger = item.type == PopupMenuItemType.danger;
final onPressed = item.onPressed; final onPressed = item.onPressed;
final disabled = onPressed == null; final disabled = onPressed == null;
final color = isDanger final color = disabled
? disabled ? context.colorScheme.onSurface.opacity30
? context.colorScheme.error.opacity30 : context.colorScheme.onSurface;
: context.colorScheme.error
: disabled
? context.colorScheme.onSurface.opacity30
: context.colorScheme.onSurface;
return InkWell( return InkWell(
onTap: onPressed != null onTap: onPressed != null
? () { ? () {
@@ -233,13 +232,13 @@ class CommonPopupMenu extends StatelessWidget {
: null, : null,
child: Container( child: Container(
constraints: BoxConstraints( constraints: BoxConstraints(
minWidth: minWidth ?? 120, minWidth: minWidth,
), ),
padding: EdgeInsets.only( padding: EdgeInsets.only(
left: 16, left: 16,
right: 64, right: 64,
top: 14, top: minItemVerticalPadding,
bottom: 14, bottom: minItemVerticalPadding,
), ),
child: Row( child: Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
@@ -247,7 +246,7 @@ class CommonPopupMenu extends StatelessWidget {
if (item.icon != null) ...[ if (item.icon != null) ...[
Icon( Icon(
item.icon, item.icon,
size: item.iconSize ?? 18, size: fontSize + 4,
color: color, color: color,
), ),
SizedBox( SizedBox(
@@ -259,6 +258,7 @@ class CommonPopupMenu extends StatelessWidget {
item.label, item.label,
style: context.textTheme.bodyMedium?.copyWith( style: context.textTheme.bodyMedium?.copyWith(
color: color, color: color,
fontSize: fontSize,
), ),
), ),
), ),

View File

@@ -305,20 +305,24 @@ class CommonScaffoldState extends State<CommonScaffold> {
); );
} }
Widget _buildAppBarWrap(Widget appBar) { Widget _buildAppBarWrap(Widget child) {
if (_isEdit) { final appBar = _isSearch ? _buildSearchingAppBarTheme(child) : child;
return CommonPopScope( if (_isEdit || _isSearch) {
onPop: () { return SystemBackBlock(
if (_isEdit) { child: CommonPopScope(
_appBarState.value.editState?.onExit(); onPop: () {
return false; if (_isEdit || _isSearch) {
} _handleExitSearching();
return true; _appBarState.value.editState?.onExit();
}, return false;
child: appBar, }
return true;
},
child: appBar,
),
); );
} }
return _isSearch ? _buildSearchingAppBarTheme(appBar) : appBar; return appBar;
} }
PreferredSizeWidget _buildAppBar() { PreferredSizeWidget _buildAppBar() {
@@ -431,6 +435,7 @@ class CommonScaffoldState extends State<CommonScaffold> {
final scaffold = Scaffold( final scaffold = Scaffold(
appBar: _buildAppBar(), appBar: _buildAppBar(),
body: body, body: body,
resizeToAvoidBottomInset: true,
backgroundColor: widget.backgroundColor, backgroundColor: widget.backgroundColor,
floatingActionButton: ValueListenableBuilder<Widget?>( floatingActionButton: ValueListenableBuilder<Widget?>(
valueListenable: _floatingActionButton, valueListenable: _floatingActionButton,

View File

@@ -56,6 +56,7 @@ class SuperGridState extends State<SuperGrid> with TickerProviderStateMixin {
final ValueNotifier<bool> _animating = ValueNotifier(false); final ValueNotifier<bool> _animating = ValueNotifier(false);
final _dragWidgetSizeNotifier = ValueNotifier(Size.zero); final _dragWidgetSizeNotifier = ValueNotifier(Size.zero);
final _dragIndexNotifier = ValueNotifier(-1); final _dragIndexNotifier = ValueNotifier(-1);
late AnimationController _transformController; late AnimationController _transformController;
@@ -304,7 +305,7 @@ class SuperGridState extends State<SuperGrid> with TickerProviderStateMixin {
} }
_handleDragEnd(DraggableDetails details) async { _handleDragEnd(DraggableDetails details) async {
debouncer.cancel(DebounceTag.handleWill); debouncer.cancel(FunctionTag.handleWill);
if (_targetIndex == -1) { if (_targetIndex == -1) {
return; return;
} }
@@ -313,7 +314,12 @@ class SuperGridState extends State<SuperGrid> with TickerProviderStateMixin {
stiffness: 100, stiffness: 100,
damping: 10, damping: 10,
); );
final simulation = SpringSimulation(spring, 0, 1, 0); final simulation = SpringSimulation(
spring,
0,
1,
0,
);
_fakeDragWidgetAnimation = Tween( _fakeDragWidgetAnimation = Tween(
begin: details.offset - _parentOffset, begin: details.offset - _parentOffset,
end: _targetOffset, end: _targetOffset,
@@ -369,7 +375,6 @@ class SuperGridState extends State<SuperGrid> with TickerProviderStateMixin {
} }
_handleDelete(int index) async { _handleDelete(int index) async {
await _transformCompleter?.future;
_preTransformState(); _preTransformState();
final indexWhere = _tempIndexList.indexWhere((i) => i == index); final indexWhere = _tempIndexList.indexWhere((i) => i == index);
_tempIndexList.removeAt(indexWhere); _tempIndexList.removeAt(indexWhere);
@@ -496,7 +501,7 @@ class SuperGridState extends State<SuperGrid> with TickerProviderStateMixin {
}, },
onWillAcceptWithDetails: (_) { onWillAcceptWithDetails: (_) {
debouncer.call( debouncer.call(
DebounceTag.handleWill, FunctionTag.handleWill,
_handleWill, _handleWill,
args: [index], args: [index],
); );
@@ -504,21 +509,31 @@ class SuperGridState extends State<SuperGrid> with TickerProviderStateMixin {
}, },
); );
final shakeTarget = ValueListenableBuilder( final shakeTarget = ValueListenableBuilder(
valueListenable: _dragIndexNotifier, valueListenable: _animating,
builder: (_, dragIndex, child) { builder: (_, animating, child) {
if (dragIndex == index) { if (animating) {
return target;
} else {
return child!; 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 final draggableChild = system.isDesktop
? Draggable( ? Draggable(

View File

@@ -9,6 +9,7 @@ import app_links
import connectivity_plus import connectivity_plus
import device_info_plus import device_info_plus
import dynamic_color import dynamic_color
import file_picker
import file_selector_macos import file_selector_macos
import hotkey_manager_macos import hotkey_manager_macos
import mobile_scanner import mobile_scanner
@@ -27,6 +28,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin")) DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
HotkeyManagerMacosPlugin.register(with: registry.registrar(forPlugin: "HotkeyManagerMacosPlugin")) HotkeyManagerMacosPlugin.register(with: registry.registrar(forPlugin: "HotkeyManagerMacosPlugin"))
MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin"))

View File

@@ -2,12 +2,13 @@ PODS:
- app_links (1.0.0): - app_links (1.0.0):
- FlutterMacOS - FlutterMacOS
- connectivity_plus (0.0.1): - connectivity_plus (0.0.1):
- Flutter
- FlutterMacOS - FlutterMacOS
- device_info_plus (0.0.1): - device_info_plus (0.0.1):
- FlutterMacOS - FlutterMacOS
- dynamic_color (0.0.2): - dynamic_color (0.0.2):
- FlutterMacOS - FlutterMacOS
- file_picker (0.0.1):
- FlutterMacOS
- file_selector_macos (0.0.1): - file_selector_macos (0.0.1):
- FlutterMacOS - FlutterMacOS
- FlutterMacOS (1.0.0) - FlutterMacOS (1.0.0)
@@ -15,7 +16,8 @@ PODS:
- hotkey_manager_macos (0.0.1): - hotkey_manager_macos (0.0.1):
- FlutterMacOS - FlutterMacOS
- HotKey - HotKey
- mobile_scanner (6.0.2): - mobile_scanner (7.0.0):
- Flutter
- FlutterMacOS - FlutterMacOS
- package_info_plus (0.0.1): - package_info_plus (0.0.1):
- FlutterMacOS - FlutterMacOS
@@ -41,13 +43,14 @@ PODS:
DEPENDENCIES: DEPENDENCIES:
- app_links (from `Flutter/ephemeral/.symlinks/plugins/app_links/macos`) - 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`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
- dynamic_color (from `Flutter/ephemeral/.symlinks/plugins/dynamic_color/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`) - file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`)
- FlutterMacOS (from `Flutter/ephemeral`) - FlutterMacOS (from `Flutter/ephemeral`)
- hotkey_manager_macos (from `Flutter/ephemeral/.symlinks/plugins/hotkey_manager_macos/macos`) - 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`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
- screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`) - screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`)
@@ -66,11 +69,13 @@ EXTERNAL SOURCES:
app_links: app_links:
:path: Flutter/ephemeral/.symlinks/plugins/app_links/macos :path: Flutter/ephemeral/.symlinks/plugins/app_links/macos
connectivity_plus: connectivity_plus:
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos
device_info_plus: device_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos :path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
dynamic_color: dynamic_color:
:path: Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos :path: Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos
file_picker:
:path: Flutter/ephemeral/.symlinks/plugins/file_picker/macos
file_selector_macos: file_selector_macos:
:path: Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos :path: Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos
FlutterMacOS: FlutterMacOS:
@@ -78,7 +83,7 @@ EXTERNAL SOURCES:
hotkey_manager_macos: hotkey_manager_macos:
:path: Flutter/ephemeral/.symlinks/plugins/hotkey_manager_macos/macos :path: Flutter/ephemeral/.symlinks/plugins/hotkey_manager_macos/macos
mobile_scanner: mobile_scanner:
:path: Flutter/ephemeral/.symlinks/plugins/mobile_scanner/macos :path: Flutter/ephemeral/.symlinks/plugins/mobile_scanner/darwin
package_info_plus: package_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
path_provider_foundation: path_provider_foundation:
@@ -100,14 +105,15 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
app_links: afe860c55c7ef176cea7fb630a2b7d7736de591d app_links: afe860c55c7ef176cea7fb630a2b7d7736de591d
connectivity_plus: 2256d3e20624a7749ed21653aafe291a46446fee connectivity_plus: 4adf20a405e25b42b9c9f87feff8f4b6fde18a4e
device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76 device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76
dynamic_color: b820c000cc68df65e7ba7ff177cb98404ce56651 dynamic_color: b820c000cc68df65e7ba7ff177cb98404ce56651
file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a
file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31 file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
HotKey: e96d8a2ddbf4591131e2bb3f54e69554d90cdca6 HotKey: e96d8a2ddbf4591131e2bb3f54e69554d90cdca6
hotkey_manager_macos: a4317849af96d2430fa89944d3c58977ca089fbe hotkey_manager_macos: a4317849af96d2430fa89944d3c58977ca089fbe
mobile_scanner: 0e365ed56cad24f28c0fd858ca04edefb40dfac3 mobile_scanner: 9157936403f5a0644ca3779a38ff8404c5434a93
package_info_plus: f0052d280d17aa382b932f399edf32507174e870 package_info_plus: f0052d280d17aa382b932f399edf32507174e870
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f

View File

@@ -5,31 +5,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: _fe_analyzer_shared name: _fe_analyzer_shared
sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" sha256: dc27559385e905ad30838356c5f5d574014ba39872d732111cd07ac0beff4c57
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "76.0.0" version: "80.0.0"
_macros:
dependency: transitive
description: dart
source: sdk
version: "0.3.3"
analyzer: analyzer:
dependency: transitive dependency: transitive
description: description:
name: analyzer name: analyzer
sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" sha256: "192d1c5b944e7e53b24b5586db760db934b177d4147c42fbca8c8c5f1eb8d11e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.11.0" version: "7.3.0"
analyzer_plugin: analyzer_plugin:
dependency: transitive dependency: transitive
description: description:
name: analyzer_plugin name: analyzer_plugin
sha256: "9661b30b13a685efaee9f02e5d01ed9f2b423bd889d28a304d02d704aee69161" sha256: "1d460d14e3c2ae36dc2b32cef847c4479198cf87704f63c3c3c8150ee50c3916"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.11.3" version: "0.12.0"
animations: animations:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -82,10 +77,10 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: args name: args
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.6.0" version: "2.7.0"
async: async:
dependency: transitive dependency: transitive
description: description:
@@ -106,50 +101,50 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: build name: build
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.1" version: "2.4.2"
build_config: build_config:
dependency: transitive dependency: transitive
description: description:
name: build_config name: build_config
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.1.2"
build_daemon: build_daemon:
dependency: transitive dependency: transitive
description: description:
name: build_daemon name: build_daemon
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.0.4"
build_resolvers: build_resolvers:
dependency: transitive dependency: transitive
description: description:
name: build_resolvers name: build_resolvers
sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" sha256: b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.2" version: "2.4.4"
build_runner: build_runner:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: build_runner name: build_runner
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" sha256: "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.13" version: "2.4.15"
build_runner_core: build_runner_core:
dependency: transitive dependency: transitive
description: description:
name: build_runner_core name: build_runner_core
sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.3.2" version: "8.0.0"
built_collection: built_collection:
dependency: transitive dependency: transitive
description: description:
@@ -162,10 +157,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: built_value name: built_value
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb sha256: ea90e81dc4a25a043d9bee692d20ed6d1c4a1662a28c03a96417446c093ed6b4
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.9.2" version: "8.9.5"
cached_network_image: cached_network_image:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -250,10 +245,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: connectivity_plus name: connectivity_plus
sha256: e0817759ec6d2d8e57eb234e6e57d2173931367a865850c7acea40d4b4f9c27d sha256: "051849e2bd7c7b3bc5844ea0d096609ddc3a859890ec3a9ac4a65a2620cc1f99"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.1" version: "6.1.4"
connectivity_plus_platform_interface: connectivity_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
@@ -290,50 +285,50 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: custom_lint name: custom_lint
sha256: "3486c470bb93313a9417f926c7dd694a2e349220992d7b9d14534dc49c15bba9" sha256: "021897cce2b6c783b2521543e362e7fe1a2eaab17bf80514d8de37f99942ed9e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.0" version: "0.7.3"
custom_lint_builder: custom_lint_builder:
dependency: transitive dependency: transitive
description: description:
name: custom_lint_builder name: custom_lint_builder
sha256: "42cdc41994eeeddab0d7a722c7093ec52bd0761921eeb2cbdbf33d192a234759" sha256: e4235b9d8cef59afe621eba086d245205c8a0a6c70cd470be7cb17494d6df32d
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.0" version: "0.7.3"
custom_lint_core: custom_lint_core:
dependency: transitive dependency: transitive
description: description:
name: custom_lint_core name: custom_lint_core
sha256: "02450c3e45e2a6e8b26c4d16687596ab3c4644dd5792e3313aa9ceba5a49b7f5" sha256: "6dcee8a017181941c51a110da7e267c1d104dc74bec8862eeb8c85b5c8759a9e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.0" version: "0.7.1"
custom_lint_visitor: custom_lint_visitor:
dependency: transitive dependency: transitive
description: description:
name: custom_lint_visitor name: custom_lint_visitor
sha256: bfe9b7a09c4775a587b58d10ebb871d4fe618237639b1e84d5ec62d7dfef25f9 sha256: "36282d85714af494ee2d7da8c8913630aa6694da99f104fb2ed4afcf8fc857d8"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0+6.11.0" version: "1.0.0+7.3.0"
dart_style: dart_style:
dependency: transitive dependency: transitive
description: description:
name: dart_style name: dart_style
sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab" sha256: "27eb0ae77836989a3bc541ce55595e8ceee0992807f14511552a898ddd0d88ac"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.7" version: "3.0.1"
dbus: dbus:
dependency: transitive dependency: transitive
description: description:
name: dbus name: dbus
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.10" version: "0.7.11"
defer_pointer: defer_pointer:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -346,10 +341,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: device_info_plus name: device_info_plus
sha256: "306b78788d1bb569edb7c55d622953c2414ca12445b41c9117963e03afc5c513" sha256: "0c6396126421b590089447154c5f98a5de423b70cfb15b1578fd018843ee6f53"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "11.3.3" version: "11.4.0"
device_info_plus_platform_interface: device_info_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
@@ -370,10 +365,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: dio_web_adapter name: dio_web_adapter
sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8" sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.0" version: "2.1.1"
dynamic_color: dynamic_color:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -418,10 +413,10 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: ffigen name: ffigen
sha256: a0ca4853028c6a9e4d9a0a40bb744fceb898c89d75931d08e87b3987d0087060 sha256: "72d732c33557fc0ca9b46379d3deff2dadbdc539696dc0b270189e2989be20ef"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "15.0.0" version: "18.1.0"
file: file:
dependency: transitive dependency: transitive
description: description:
@@ -434,10 +429,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: file_picker name: file_picker
sha256: c2376a6aae82358a9f9ccdd7d1f4006d08faa39a2767cce01031d9f593a8bd3b sha256: "8986dec4581b4bcd4b6df5d75a2ea0bede3db802f500635d05fa8be298f9467f"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.1.6" version: "10.1.2"
file_selector_linux: file_selector_linux:
dependency: transitive dependency: transitive
description: description:
@@ -466,10 +461,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: file_selector_windows name: file_selector_windows
sha256: "8f5d2f6590d51ecd9179ba39c64f722edc15226cc93dcc8698466ad36a4a85a4" sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.9.3+3" version: "0.9.3+4"
fixnum: fixnum:
dependency: transitive dependency: transitive
description: description:
@@ -508,10 +503,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: flutter_plugin_android_lifecycle name: flutter_plugin_android_lifecycle
sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398" sha256: f948e346c12f8d5480d2825e03de228d0eb8c3a737e4cdaa122267b89c022b5e
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.23" version: "2.0.28"
flutter_riverpod: flutter_riverpod:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -534,10 +529,10 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: freezed name: freezed
sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e" sha256: "59a584c24b3acdc5250bb856d0d3e9c0b798ed14a4af1ddb7dc1c7b41df91c9c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.7" version: "2.5.8"
freezed_annotation: freezed_annotation:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -558,10 +553,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: glob name: glob
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.3"
graphs: graphs:
dependency: transitive dependency: transitive
description: description:
@@ -630,26 +625,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: http name: http
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.2" version: "1.3.0"
http_multi_server: http_multi_server:
dependency: transitive dependency: transitive
description: description:
name: http_multi_server name: http_multi_server
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.2.1" version: "3.2.2"
http_parser: http_parser:
dependency: transitive dependency: transitive
description: description:
name: http_parser name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.1.2"
image_picker: image_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -662,10 +657,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: image_picker_android name: image_picker_android
sha256: fa8141602fde3f7e2f81dbf043613eb44dfa325fa0bcf93c0f142c9f7a2c193e sha256: "317a5d961cec5b34e777b9252393f2afbd23084aa6e60fcf601dcf6341b9ebeb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.12+18" version: "0.8.12+23"
image_picker_for_web: image_picker_for_web:
dependency: transitive dependency: transitive
description: description:
@@ -678,34 +673,34 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: image_picker_ios name: image_picker_ios
sha256: "4f0568120c6fcc0aaa04511cb9f9f4d29fc3d0139884b1d06be88dcec7641d6b" sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.12+1" version: "0.8.12+2"
image_picker_linux: image_picker_linux:
dependency: transitive dependency: transitive
description: description:
name: image_picker_linux name: image_picker_linux
sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa" sha256: "34a65f6740df08bbbeb0a1abd8e6d32107941fd4868f67a507b25601651022c9"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.1+1" version: "0.2.1+2"
image_picker_macos: image_picker_macos:
dependency: transitive dependency: transitive
description: description:
name: image_picker_macos name: image_picker_macos
sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62" sha256: "1b90ebbd9dcf98fb6c1d01427e49a55bd96b5d67b8c67cf955d60a5de74207c1"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.1+1" version: "0.2.1+2"
image_picker_platform_interface: image_picker_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: image_picker_platform_interface name: image_picker_platform_interface
sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80" sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.10.0" version: "2.10.1"
image_picker_windows: image_picker_windows:
dependency: transitive dependency: transitive
description: description:
@@ -750,10 +745,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: js name: js
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.1" version: "0.7.2"
json_annotation: json_annotation:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -766,10 +761,10 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: json_serializable name: json_serializable
sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c sha256: c50ef5fc083d5b5e12eef489503ba3bf5ccc899e487d691584699b4bdefeea8c
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.9.0" version: "6.9.5"
launch_at_startup: launch_at_startup:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -806,10 +801,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: lints name: lints
sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.0.0" version: "5.1.1"
logging: logging:
dependency: transitive dependency: transitive
description: description:
@@ -826,14 +821,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.3" 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: matcher:
dependency: transitive dependency: transitive
description: description:
@@ -878,10 +865,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: mobile_scanner name: mobile_scanner
sha256: "728828a798d1a2ee506beb652ca23d974c542c96ed03dcbd5eaf97bef96cdaad" sha256: "72f06a071aa8b14acea3ab43ea7949eefe4a2469731ae210e006ba330a033a8c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.2" version: "7.0.0"
nm: nm:
dependency: transitive dependency: transitive
description: description:
@@ -902,26 +889,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: package_config name: package_config
sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67" sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.2.0"
package_info_plus: package_info_plus:
dependency: "direct main" dependency: "direct main"
description: description:
name: package_info_plus name: package_info_plus
sha256: "70c421fe9d9cc1a9a7f3b05ae56befd469fe4f8daa3b484823141a55442d858d" sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.1.2" version: "8.3.0"
package_info_plus_platform_interface: package_info_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: package_info_plus_platform_interface name: package_info_plus_platform_interface
sha256: a5ef9986efc7bf772f2696183a3992615baa76c1ffb1189318dd8803778fb05b sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.2" version: "3.2.0"
path: path:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -942,10 +929,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: path_provider_android name: path_provider_android
sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2" sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.15" version: "2.2.17"
path_provider_foundation: path_provider_foundation:
dependency: transitive dependency: transitive
description: description:
@@ -982,10 +969,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: petitparser name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.2" version: "6.1.0"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@@ -1021,18 +1008,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: pub_semver name: pub_semver
sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd" sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.5" version: "2.2.0"
pubspec_parse: pubspec_parse:
dependency: transitive dependency: transitive
description: description:
name: pubspec_parse name: pubspec_parse
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.0" version: "1.5.0"
quiver: quiver:
dependency: transitive dependency: transitive
description: description:
@@ -1069,10 +1056,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: riverpod_analyzer_utils name: riverpod_analyzer_utils
sha256: c6b8222b2b483cb87ae77ad147d6408f400c64f060df7a225b127f4afef4f8c8 sha256: "837a6dc33f490706c7f4632c516bcd10804ee4d9ccc8046124ca56388715fdf3"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.8" version: "0.5.9"
riverpod_annotation: riverpod_annotation:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -1085,18 +1072,18 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: riverpod_generator name: riverpod_generator
sha256: "63546d70952015f0981361636bf8f356d9cfd9d7f6f0815e3c07789a41233188" sha256: "120d3310f687f43e7011bb213b90a436f1bbc300f0e4b251a72c39bccb017a4f"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.6.3" version: "2.6.4"
riverpod_lint: riverpod_lint:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: riverpod_lint name: riverpod_lint
sha256: "83e4caa337a9840469b7b9bd8c2351ce85abad80f570d84146911b32086fbd99" sha256: b05408412b0f75dec954e032c855bc28349eeed2d2187f94519e1ddfdf8b3693
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.6.3" version: "2.6.4"
rxdart: rxdart:
dependency: transitive dependency: transitive
description: description:
@@ -1149,18 +1136,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: shared_preferences name: shared_preferences
sha256: "688ee90fbfb6989c980254a56cb26ebe9bb30a3a2dff439a78894211f73de67a" sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.1" version: "2.5.3"
shared_preferences_android: shared_preferences_android:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_android name: shared_preferences_android
sha256: "02a7d8a9ef346c9af715811b01fbd8e27845ad2c41148eefd31321471b41863d" sha256: "20cbd561f743a342c76c151d6ddb93a9ce6005751e7aa458baad3858bfbfb6ac"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.0" version: "2.4.10"
shared_preferences_foundation: shared_preferences_foundation:
dependency: transitive dependency: transitive
description: description:
@@ -1189,10 +1176,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_web name: shared_preferences_web
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.2" version: "2.4.3"
shared_preferences_windows: shared_preferences_windows:
dependency: transitive dependency: transitive
description: description:
@@ -1205,18 +1192,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shelf name: shelf
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.1" version: "1.4.2"
shelf_web_socket: shelf_web_socket:
dependency: transitive dependency: transitive
description: description:
name: shelf_web_socket name: shelf_web_socket
sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.1" version: "3.0.0"
shortid: shortid:
dependency: transitive dependency: transitive
description: description:
@@ -1234,18 +1221,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: source_gen name: source_gen
sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" sha256: "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.5.0" version: "2.0.0"
source_helper: source_helper:
dependency: transitive dependency: transitive
description: description:
name: source_helper name: source_helper
sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.4" version: "1.3.5"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
@@ -1266,34 +1253,34 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: sqflite name: sqflite
sha256: "2d7299468485dca85efeeadf5d38986909c5eb0cd71fd3db2c2f000e6c9454bb" sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.1" version: "2.4.2"
sqflite_android: sqflite_android:
dependency: transitive dependency: transitive
description: description:
name: sqflite_android name: sqflite_android
sha256: "78f489aab276260cdd26676d2169446c7ecd3484bbd5fead4ca14f3ed4dd9ee3" sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.0" version: "2.4.1"
sqflite_common: sqflite_common:
dependency: transitive dependency: transitive
description: description:
name: sqflite_common name: sqflite_common
sha256: "761b9740ecbd4d3e66b8916d784e581861fd3c3553eda85e167bc49fdb68f709" sha256: "84731e8bfd8303a3389903e01fb2141b6e59b5973cacbb0929021df08dddbe8b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.4+6" version: "2.5.5"
sqflite_darwin: sqflite_darwin:
dependency: transitive dependency: transitive
description: description:
name: sqflite_darwin name: sqflite_darwin
sha256: "96a698e2bc82bd770a4d6aab00b42396a7c63d9e33513a56945cbccb594c2474" sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.1" version: "2.4.2"
sqflite_platform_interface: sqflite_platform_interface:
dependency: transitive dependency: transitive
description: description:
@@ -1330,10 +1317,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: stream_transform name: stream_transform
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.1.1"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
@@ -1346,10 +1333,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: synchronized name: synchronized
sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225" sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.3.0+3" version: "3.3.1"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
@@ -1378,10 +1365,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: tray_manager name: tray_manager
sha256: c2da0f0f1ddb455e721cf68d05d1281fec75cf5df0a1d3cb67b6ca0bdfd5709d sha256: ad18c4cd73003097d182884bacb0578ad2865f3ab842a0ad00f6d043ed49eaf0
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.0" version: "0.5.0"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@@ -1410,18 +1397,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_android name: url_launcher_android
sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193" sha256: "8582d7f6fe14d2652b4c45c9b6c14c0b678c2af2d083a11b604caeba51930d79"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.14" version: "6.3.16"
url_launcher_ios: url_launcher_ios:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_ios name: url_launcher_ios
sha256: "16a513b6c12bb419304e72ea0ae2ab4fed569920d1c7cb850263fe3acc824626" sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.2" version: "6.3.3"
url_launcher_linux: url_launcher_linux:
dependency: transitive dependency: transitive
description: description:
@@ -1450,18 +1437,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_web name: url_launcher_web
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.3" version: "2.4.1"
url_launcher_windows: url_launcher_windows:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_windows name: url_launcher_windows
sha256: "44cf3aabcedde30f2dba119a9dea3b0f2672fbe6fa96e85536251d678216b3c4" sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.3" version: "3.1.4"
uuid: uuid:
dependency: transitive dependency: transitive
description: description:
@@ -1490,34 +1477,34 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: watcher name: watcher
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "1.1.1"
web: web:
dependency: transitive dependency: transitive
description: description:
name: web name: web
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "1.1.1"
web_socket: web_socket:
dependency: transitive dependency: transitive
description: description:
name: web_socket name: web_socket
sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" sha256: bfe6f435f6ec49cb6c01da1e275ae4228719e59a6b067048c51e72d9d63bcc4b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.6" version: "1.0.0"
web_socket_channel: web_socket_channel:
dependency: transitive dependency: transitive
description: description:
name: web_socket_channel name: web_socket_channel
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.1" version: "3.0.3"
webdav_client: webdav_client:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -1557,14 +1544,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.3" 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: xdg_directories:
dependency: transitive dependency: transitive
description: description:
@@ -1585,18 +1564,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: yaml name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.2" version: "3.1.3"
yaml_edit: yaml_edit:
dependency: transitive dependency: transitive
description: description:
name: yaml_edit name: yaml_edit
sha256: e9c1a3543d2da0db3e90270dbb1e4eebc985ee5e3ffe468d83224472b2194a5f sha256: fb38626579fb345ad00e674e2af3a5c9b0cc4b9bfb8fd7f7ff322c7c9e62aef5
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.1" version: "2.2.2"
sdks: sdks:
dart: ">=3.7.0 <4.0.0" dart: ">=3.7.0 <4.0.0"
flutter: ">=3.24.0" flutter: ">=3.29.0"

View File

@@ -1,7 +1,7 @@
name: fl_clash name: fl_clash
description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free. description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free.
publish_to: 'none' publish_to: 'none'
version: 0.8.84+202505013 version: 0.8.85+202505091
environment: environment:
sdk: '>=3.1.0 <4.0.0' sdk: '>=3.1.0 <4.0.0'
@@ -13,7 +13,7 @@ dependencies:
intl: any intl: any
path_provider: ^2.1.0 path_provider: ^2.1.0
path: ^1.9.0 path: ^1.9.0
shared_preferences: ^2.5.1 shared_preferences: ^2.5.3
window_manager: ^0.4.3 window_manager: ^0.4.3
dynamic_color: ^1.7.0 dynamic_color: ^1.7.0
proxy: proxy:
@@ -21,13 +21,12 @@ dependencies:
window_ext: window_ext:
path: plugins/window_ext path: plugins/window_ext
launch_at_startup: ^0.5.1 launch_at_startup: ^0.5.1
windows_single_instance: ^1.0.1
json_annotation: ^4.9.0 json_annotation: ^4.9.0
file_picker: ^8.0.3 file_picker: ^10.1.2
mobile_scanner: ^6.0.2 mobile_scanner: ^7.0.0
app_links: ^6.4.0 app_links: ^6.4.0
win32_registry: ^2.0.0 win32_registry: ^2.0.0
tray_manager: ^0.4.0 tray_manager: ^0.5.0
collection: ^1.18.0 collection: ^1.18.0
animations: ^2.0.11 animations: ^2.0.11
package_info_plus: ^8.0.0 package_info_plus: ^8.0.0
@@ -58,7 +57,7 @@ dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_lints: ^5.0.0 flutter_lints: ^5.0.0
ffigen: ^15.0.0 ffigen: ^18.1.0
json_serializable: ^6.7.1 json_serializable: ^6.7.1
build_runner: ^2.4.13 build_runner: ^2.4.13
args: ^2.4.2 args: ^2.4.2

View File

@@ -17,7 +17,6 @@
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
#include <window_ext/window_ext_plugin_c_api.h> #include <window_ext/window_ext_plugin_c_api.h>
#include <window_manager/window_manager_plugin.h> #include <window_manager/window_manager_plugin.h>
#include <windows_single_instance/windows_single_instance_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
AppLinksPluginCApiRegisterWithRegistrar( AppLinksPluginCApiRegisterWithRegistrar(
@@ -42,6 +41,4 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("WindowExtPluginCApi")); registry->GetRegistrarForPlugin("WindowExtPluginCApi"));
WindowManagerPluginRegisterWithRegistrar( WindowManagerPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("WindowManagerPlugin")); registry->GetRegistrarForPlugin("WindowManagerPlugin"));
WindowsSingleInstancePluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("WindowsSingleInstancePlugin"));
} }

View File

@@ -14,7 +14,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_windows url_launcher_windows
window_ext window_ext
window_manager window_manager
windows_single_instance
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST