解决开启关闭后UI界面状态不同步问题
Some checks failed
Build Android APK / 编译 libcore.aar (push) Has been cancelled
Build Android APK / 编译 Android APK (release) (push) Has been cancelled
Build Android APK / 创建 GitHub Release (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Linux) (push) Has been cancelled
Build Multi-Platform / 构建 Android APK (push) Has been cancelled
Build Multi-Platform / 构建 Windows (push) Has been cancelled
Build Multi-Platform / 构建 macOS (push) Has been cancelled
Build Multi-Platform / 构建 Linux (push) Has been cancelled
Build Multi-Platform / 构建 iOS (push) Has been cancelled
Build Multi-Platform / 创建 Release (push) Has been cancelled
Build Multi-Platform / 编译 libcore (iOS/tvOS) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Android) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (Windows) (push) Has been cancelled
Build Multi-Platform / 编译 libcore (macOS) (push) Has been cancelled
Build Windows / 编译 libcore (Windows) (push) Has been cancelled
Build Windows / build (push) Has been cancelled

(cherry picked from commit 23a4a5ce2e46ffbd3b8188333dfa7f4559984e4c)
This commit is contained in:
Rust 2025-10-30 22:33:48 -07:00 committed by speakeloudest
parent 5c8f0ca1fc
commit 74df08144f
3 changed files with 118 additions and 65 deletions

View File

@ -103,9 +103,6 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
// //
final kr_lastMapCenter = LatLng(35.0, 105.0).obs; final kr_lastMapCenter = LatLng(35.0, 105.0).obs;
//
bool kr_isSwitching = false;
// "闪连"Checkbox添加一个响应式变量 false // "闪连"Checkbox添加一个响应式变量 false
final isQuickConnectEnabled = false.obs; final isQuickConnectEnabled = false.obs;
@ -206,7 +203,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
KRLogUtil.kr_i('开始执行闪连自动连接', tag: 'QuickConnect'); KRLogUtil.kr_i('开始执行闪连自动连接', tag: 'QuickConnect');
// //
if (kr_isSwitching) { if (KRSingBoxImp.instance.kr_status == SingboxStarted) {
KRLogUtil.kr_w('连接操作正在进行中,跳过自动连接', tag: 'QuickConnect'); KRLogUtil.kr_w('连接操作正在进行中,跳过自动连接', tag: 'QuickConnect');
return; return;
} }
@ -503,6 +500,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
void _bindConnectionStatus() { void _bindConnectionStatus() {
// //
ever(KRSingBoxImp.instance.kr_status, (status) { ever(KRSingBoxImp.instance.kr_status, (status) {
print('🔵 Controller 收到状态变化: ${status.runtimeType}');
KRLogUtil.kr_i('🔄 连接状态变化: $status', tag: 'HomeController'); KRLogUtil.kr_i('🔄 连接状态变化: $status', tag: 'HomeController');
KRLogUtil.kr_i('📊 当前状态类型: ${status.runtimeType}', tag: 'HomeController'); KRLogUtil.kr_i('📊 当前状态类型: ${status.runtimeType}', tag: 'HomeController');
@ -656,54 +654,79 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
***/ ***/
} }
void kr_toggleSwitch(bool value) async { /// 🔧 : hiddify-app toggleConnection
// Future<void> kr_toggleSwitch(bool value) async {
if (kr_isSwitching) { final currentStatus = KRSingBoxImp.instance.kr_status.value;
KRLogUtil.kr_i('正在切换中,忽略本次操作', tag: 'HomeController');
KRLogUtil.kr_i('🔵 toggleSwitch 被调用: value=$value, currentStatus=$currentStatus', tag: 'HomeController');
print('🔵 toggleSwitch: value=$value, currentStatus=$currentStatus');
// 🔧 : hiddify-app "switching status, debounce"
if (currentStatus is SingboxStarting || currentStatus is SingboxStopping) {
KRLogUtil.kr_i('🔄 正在切换中,忽略本次操作 (当前状态: $currentStatus)', tag: 'HomeController');
print('🔵 忽略操作:正在切换中');
return; return;
} }
try { try {
kr_isSwitching = true;
KRLogUtil.kr_i('🔄 开始切换连接状态: $value', tag: 'HomeController');
if (value) { if (value) {
//
KRLogUtil.kr_i('🔄 开始连接...', tag: 'HomeController');
print('🔵 执行 kr_start()');
await KRSingBoxImp.instance.kr_start(); await KRSingBoxImp.instance.kr_start();
KRLogUtil.kr_i('✅ 连接命令已发送', tag: 'HomeController');
print('🔵 kr_start() 完成');
// UI及时更新 // 🔧 : 3
Future.delayed(const Duration(milliseconds: 300), () { await _waitForStatus(SingboxStarted, maxSeconds: 3);
kr_forceSyncConnectionStatus();
});
//
Future.delayed(const Duration(seconds: 2), () {
kr_forceSyncConnectionStatus();
});
} else { } else {
KRLogUtil.kr_i('🛑 准备停止连接...', tag: 'HomeController'); //
// KRLogUtil.kr_i('🛑 开始断开连接...', tag: 'HomeController');
print('🔵 执行 kr_stop()');
await KRSingBoxImp.instance.kr_stop().timeout( await KRSingBoxImp.instance.kr_stop().timeout(
const Duration(seconds: 10), const Duration(seconds: 10),
onTimeout: () { onTimeout: () {
KRLogUtil.kr_e('⚠️ 停止操作超时', tag: 'HomeController'); KRLogUtil.kr_e('⚠️ 停止操作超时', tag: 'HomeController');
//
kr_forceSyncConnectionStatus();
throw TimeoutException('Stop operation timeout'); throw TimeoutException('Stop operation timeout');
}, },
); );
KRLogUtil.kr_i('✅ 停止命令已发送', tag: 'HomeController'); KRLogUtil.kr_i('✅ 断开命令已发送', tag: 'HomeController');
print('🔵 kr_stop() 完成');
// 🔧 : 2
await _waitForStatus(SingboxStopped, maxSeconds: 2);
} }
} catch (e) { } catch (e) {
KRLogUtil.kr_e('切换失败: $e', tag: 'HomeController'); KRLogUtil.kr_e('❌ 切换失败: $e', tag: 'HomeController');
// print('🔵 切换失败: $e');
Future.delayed(const Duration(milliseconds: 100), () { //
kr_forceSyncConnectionStatus(); kr_forceSyncConnectionStatus();
});
} finally {
//
KRLogUtil.kr_i('🔓 重置切换标志', tag: 'HomeController');
kr_isSwitching = false;
} }
print('🔵 toggleSwitch 完成,当前 kr_isConnected=${kr_isConnected.value}');
}
/// 🔧
Future<void> _waitForStatus(Type expectedType, {int maxSeconds = 3}) async {
print('🔵 等待状态变为: $expectedType');
final startTime = DateTime.now();
while (DateTime.now().difference(startTime).inSeconds < maxSeconds) {
final currentStatus = KRSingBoxImp.instance.kr_status.value;
print('🔵 当前状态: ${currentStatus.runtimeType}');
if (currentStatus.runtimeType == expectedType) {
print('🔵 状态已达到: $expectedType');
// kr_isConnected
kr_forceSyncConnectionStatus();
return;
}
await Future.delayed(const Duration(milliseconds: 100));
}
print('🔵 等待超时,强制同步状态');
kr_forceSyncConnectionStatus();
} }
/// ///

View File

@ -7,6 +7,7 @@ import 'package:kaer_with_panels/app/widgets/kr_country_flag.dart';
import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart'; import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart';
import 'package:kaer_with_panels/app/localization/app_translations.dart'; import 'package:kaer_with_panels/app/localization/app_translations.dart';
import 'package:kaer_with_panels/app/services/singbox_imp/kr_sing_box_imp.dart'; import 'package:kaer_with_panels/app/services/singbox_imp/kr_sing_box_imp.dart';
import 'package:kaer_with_panels/singbox/model/singbox_status.dart';
import '../controllers/kr_home_controller.dart'; import '../controllers/kr_home_controller.dart';
import '../models/kr_home_views_status.dart'; import '../models/kr_home_views_status.dart';
@ -209,13 +210,31 @@ class KRHomeConnectionInfoView extends GetView<KRHomeController> {
), ),
], ],
), ),
CupertinoSwitch( // 🔧 : 使
value: controller.kr_isConnected.value, Obx(() {
onChanged: (bool value) { // 🔧 : observable
controller.kr_toggleSwitch(value); final _ = KRSingBoxImp.instance.kr_status.value; //
}, final isConnected = controller.kr_isConnected.value; // 使 controller
activeColor: Colors.blue,
), //
final status = KRSingBoxImp.instance.kr_status.value;
final isSwitching = status is SingboxStarting || status is SingboxStopping;
// 🔧
print('🔵 Switch UI 更新: status=${status.runtimeType}, isConnected=$isConnected, isSwitching=$isSwitching');
return CupertinoSwitch(
value: isConnected,
// 🔧 : onChanged nullSwitch
onChanged: isSwitching
? null
: (bool value) {
print('🔵 Switch onChanged 触发: 请求=$value, 当前状态=$status');
controller.kr_toggleSwitch(value);
},
activeColor: Colors.blue,
);
}),
], ],
), ),
], ],

View File

@ -548,10 +548,14 @@ class KRSingBoxImp {
/// ///
/// hiddify-app: libcore UI /// hiddify-app: libcore UI
void _kr_subscribeToStatus() { void _kr_subscribeToStatus() {
print('🔵 _kr_subscribeToStatus 被调用,重新订阅状态流');
KRLogUtil.kr_i('🔵 _kr_subscribeToStatus 被调用', tag: 'SingBox');
// //
for (var sub in _kr_subscriptions) { for (var sub in _kr_subscriptions) {
if (sub.hashCode.toString().contains('Status')) { if (sub.hashCode.toString().contains('Status')) {
sub.cancel(); sub.cancel();
print('🔵 已取消旧的状态订阅');
} }
} }
_kr_subscriptions _kr_subscriptions
@ -560,15 +564,19 @@ class KRSingBoxImp {
_kr_subscriptions.add( _kr_subscriptions.add(
kr_singBox.watchStatus().listen( kr_singBox.watchStatus().listen(
(status) { (status) {
print('🔵 收到 Native 状态更新: ${status.runtimeType}');
KRLogUtil.kr_i('📡 收到状态更新: $status', tag: 'SingBox'); KRLogUtil.kr_i('📡 收到状态更新: $status', tag: 'SingBox');
kr_status.value = status; kr_status.value = status;
}, },
onError: (error) { onError: (error) {
print('🔵 状态流错误: $error');
KRLogUtil.kr_e('📡 状态流错误: $error', tag: 'SingBox'); KRLogUtil.kr_e('📡 状态流错误: $error', tag: 'SingBox');
}, },
cancelOnError: false, cancelOnError: false,
), ),
); );
print('🔵 状态流订阅完成');
} }
/// ///
@ -1034,6 +1042,9 @@ class KRSingBoxImp {
KRLogUtil.kr_w('⚠️ 配置文件不存在: $_cutPath', tag: 'SingBox'); KRLogUtil.kr_w('⚠️ 配置文件不存在: $_cutPath', tag: 'SingBox');
} }
// 🔧 :
_kr_subscribeToStatus();
await kr_singBox.start(_cutPath, kr_configName, false).map( await kr_singBox.start(_cutPath, kr_configName, false).map(
(r) { (r) {
KRLogUtil.kr_i('✅ SingBox 启动成功', tag: 'SingBox'); KRLogUtil.kr_i('✅ SingBox 启动成功', tag: 'SingBox');