From 98fca5792a087207a02eb438b0894b6665f90ec7 Mon Sep 17 00:00:00 2001 From: problematicconsumer Date: Thu, 18 Jan 2024 22:53:17 +0330 Subject: [PATCH] Add reset tunnel option on ios --- assets/translations/strings_en.i18n.json | 3 ++- assets/translations/strings_es.i18n.json | 3 ++- assets/translations/strings_fa.i18n.json | 3 ++- assets/translations/strings_ru.i18n.json | 3 ++- assets/translations/strings_tr.i18n.json | 3 ++- assets/translations/strings_zh-CN.i18n.json | 3 ++- ios/Runner/Handlers/MethodHandler.swift | 3 +++ .../notifier/platform_settings_notifier.dart | 20 +++++++++++++++++++ .../widgets/advanced_setting_tiles.dart | 9 +++++++++ lib/singbox/service/ffi_singbox_service.dart | 7 +++++++ .../service/platform_singbox_service.dart | 18 +++++++++++++++++ lib/singbox/service/singbox_service.dart | 2 ++ 12 files changed, 71 insertions(+), 6 deletions(-) diff --git a/assets/translations/strings_en.i18n.json b/assets/translations/strings_en.i18n.json index 2f35b4f4..2f664944 100644 --- a/assets/translations/strings_en.i18n.json +++ b/assets/translations/strings_en.i18n.json @@ -172,7 +172,8 @@ "debugMode": "Debug Mode", "debugModeMsg": "Restart the app for applying this change", "memoryLimit": "Memory Limit", - "memoryLimitMsg": "Enable if you're experiencing out of memory errors or frequent app crash" + "memoryLimitMsg": "Enable if you're experiencing out of memory errors or frequent app crash", + "resetTunnel": "Reset VPN Profile" }, "network": { "perAppProxyPageTitle": "Per-app Proxy", diff --git a/assets/translations/strings_es.i18n.json b/assets/translations/strings_es.i18n.json index 45782c81..9a333384 100644 --- a/assets/translations/strings_es.i18n.json +++ b/assets/translations/strings_es.i18n.json @@ -166,7 +166,8 @@ "sectionTitle": "Avanzado", "debugMode": "Modo de depuración", "memoryLimit": "Limite de memoria", - "memoryLimitMsg": "Habilítelo si experimenta errores de falta de memoria o fallas frecuentes de la aplicación" + "memoryLimitMsg": "Habilítelo si experimenta errores de falta de memoria o fallas frecuentes de la aplicación", + "resetTunnel": "Restablecer perfil VPN" }, "network": { "perAppProxyModes": { diff --git a/assets/translations/strings_fa.i18n.json b/assets/translations/strings_fa.i18n.json index 2316349f..5b185f6a 100644 --- a/assets/translations/strings_fa.i18n.json +++ b/assets/translations/strings_fa.i18n.json @@ -172,7 +172,8 @@ "debugMode": "دیباگ مود", "debugModeMsg": "برای اعمال این تغییر اپ را ری‌استارت کنید", "memoryLimit": "محدودیت مموری", - "memoryLimitMsg": "اگر با خطاهای کمبود حافظه یا خرابی مکرر برنامه مواجه شدید، فعال کنید" + "memoryLimitMsg": "اگر با خطاهای کمبود حافظه یا خرابی مکرر برنامه مواجه شدید، فعال کنید", + "resetTunnel": "بازنشانی نمایه VPN" }, "network": { "perAppProxyPageTitle": "پراکسی برنامه‌ها", diff --git a/assets/translations/strings_ru.i18n.json b/assets/translations/strings_ru.i18n.json index 4a7a533e..f0af6150 100644 --- a/assets/translations/strings_ru.i18n.json +++ b/assets/translations/strings_ru.i18n.json @@ -172,7 +172,8 @@ "debugMode": "Режим отладки", "debugModeMsg": "Чтобы применить изменения, перезапустите приложение.", "memoryLimit": "Ограничение памяти", - "memoryLimitMsg": "Включите, если у вас возникают ошибки нехватки памяти или частые сбои приложения." + "memoryLimitMsg": "Включите, если у вас возникают ошибки нехватки памяти или частые сбои приложения.", + "resetTunnel": "Сбросить профиль VPN" }, "network": { "perAppProxyPageTitle": "Раздельное проксирование", diff --git a/assets/translations/strings_tr.i18n.json b/assets/translations/strings_tr.i18n.json index 88cc4261..48b8b8c8 100644 --- a/assets/translations/strings_tr.i18n.json +++ b/assets/translations/strings_tr.i18n.json @@ -172,7 +172,8 @@ "debugMode": "Hata ayıklama modu", "debugModeMsg": "Bu değişikliği uygulamak için uygulamayı yeniden başlatın", "memoryLimit": "Bellek Sınırı", - "memoryLimitMsg": "Yetersiz bellek hataları veya sık sık uygulama çökmesi yaşıyorsanız etkinleştirin" + "memoryLimitMsg": "Yetersiz bellek hataları veya sık sık uygulama çökmesi yaşıyorsanız etkinleştirin", + "resetTunnel": "VPN Profilini Sıfırla" }, "network": { "perAppProxyPageTitle": "Uygulama başına Proxy", diff --git a/assets/translations/strings_zh-CN.i18n.json b/assets/translations/strings_zh-CN.i18n.json index 064bc4c5..407bf198 100644 --- a/assets/translations/strings_zh-CN.i18n.json +++ b/assets/translations/strings_zh-CN.i18n.json @@ -172,7 +172,8 @@ "debugMode": "调试模式", "debugModeMsg": "重新启动应用程序以应用此更改", "memoryLimit": "内存限制", - "memoryLimitMsg": "如果您遇到内存不足错误或频繁应用程序崩溃,请启用" + "memoryLimitMsg": "如果您遇到内存不足错误或频繁应用程序崩溃,请启用", + "resetTunnel": "重置 VPN 配置文件" }, "network": { "perAppProxyPageTitle": "分应用代理", diff --git a/ios/Runner/Handlers/MethodHandler.swift b/ios/Runner/Handlers/MethodHandler.swift index 10b76798..34a9bbd9 100644 --- a/ios/Runner/Handlers/MethodHandler.swift +++ b/ios/Runner/Handlers/MethodHandler.swift @@ -121,6 +121,9 @@ public class MethodHandler: NSObject, FlutterPlugin { case "stop": VPNManager.shared.disconnect() result(true) + case "reset": + VPNManager.shared.reset() + result(true) case "url_test": guard let args = call.arguments as? [String:Any?] diff --git a/lib/features/settings/notifier/platform_settings_notifier.dart b/lib/features/settings/notifier/platform_settings_notifier.dart index 2afb3af1..8ac1ac04 100644 --- a/lib/features/settings/notifier/platform_settings_notifier.dart +++ b/lib/features/settings/notifier/platform_settings_notifier.dart @@ -1,4 +1,6 @@ import 'package:hiddify/features/settings/data/settings_data_providers.dart'; +import 'package:hiddify/singbox/service/singbox_service_provider.dart'; +import 'package:hiddify/utils/custom_loggers.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'platform_settings_notifier.g.dart'; @@ -23,3 +25,21 @@ class IgnoreBatteryOptimizations extends _$IgnoreBatteryOptimizations { ref.invalidateSelf(); } } + +@riverpod +class ResetTunnel extends _$ResetTunnel with AppLogger { + @override + Future build() async {} + + Future run() async { + state = const AsyncLoading(); + state = await AsyncValue.guard( + () => ref.read(singboxServiceProvider).resetTunnel().getOrElse( + (err) { + loggy.warning("error resetting tunnel", err); + throw err; + }, + ).run(), + ); + } +} diff --git a/lib/features/settings/widgets/advanced_setting_tiles.dart b/lib/features/settings/widgets/advanced_setting_tiles.dart index 75ed4bc4..097aabcd 100644 --- a/lib/features/settings/widgets/advanced_setting_tiles.dart +++ b/lib/features/settings/widgets/advanced_setting_tiles.dart @@ -6,6 +6,7 @@ import 'package:hiddify/core/preferences/general_preferences.dart'; import 'package:hiddify/core/router/router.dart'; import 'package:hiddify/features/common/general_pref_tiles.dart'; import 'package:hiddify/features/per_app_proxy/model/per_app_proxy_mode.dart'; +import 'package:hiddify/features/settings/notifier/platform_settings_notifier.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; class AdvancedSettingTiles extends HookConsumerWidget { @@ -72,6 +73,14 @@ class AdvancedSettingTiles extends HookConsumerWidget { await ref.read(disableMemoryLimitProvider.notifier).update(!value); }, ), + if (Platform.isIOS) + ListTile( + title: Text(t.settings.advanced.resetTunnel), + leading: const Icon(Icons.restart_alt), + onTap: () async { + await ref.read(resetTunnelProvider.notifier).run(); + }, + ), SwitchListTile( title: Text(t.settings.advanced.debugMode), value: debug, diff --git a/lib/singbox/service/ffi_singbox_service.dart b/lib/singbox/service/ffi_singbox_service.dart index a3a695bc..a026f2d4 100644 --- a/lib/singbox/service/ffi_singbox_service.dart +++ b/lib/singbox/service/ffi_singbox_service.dart @@ -224,6 +224,13 @@ class FFISingboxService with InfraLogger implements SingboxService { ); } + @override + TaskEither resetTunnel() { + throw UnimplementedError( + "reset tunnel function unavailable on platform", + ); + } + @override Stream watchStatus() => _status; diff --git a/lib/singbox/service/platform_singbox_service.dart b/lib/singbox/service/platform_singbox_service.dart index 4dbc0fe4..aeeb1d9e 100644 --- a/lib/singbox/service/platform_singbox_service.dart +++ b/lib/singbox/service/platform_singbox_service.dart @@ -147,6 +147,24 @@ class PlatformSingboxService with InfraLogger implements SingboxService { ); } + @override + TaskEither resetTunnel() { + return TaskEither( + () async { + // only available on iOS (and macOS later) + if (!Platform.isIOS) { + throw UnimplementedError( + "reset tunnel function unavailable on platform", + ); + } + + loggy.debug("resetting tunnel"); + await _methodChannel.invokeMethod("reset"); + return right(unit); + }, + ); + } + @override Stream> watchOutbounds() { const channel = EventChannel("com.hiddify.app/groups"); diff --git a/lib/singbox/service/singbox_service.dart b/lib/singbox/service/singbox_service.dart index bc21718b..7535a50e 100644 --- a/lib/singbox/service/singbox_service.dart +++ b/lib/singbox/service/singbox_service.dart @@ -52,6 +52,8 @@ abstract interface class SingboxService { bool disableMemoryLimit, ); + TaskEither resetTunnel(); + Stream> watchOutbounds(); TaskEither selectOutbound(String groupTag, String outboundTag);