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