diff --git a/assets/translations/strings_en.i18n.json b/assets/translations/strings_en.i18n.json index 13d5c71f..c38d57fc 100644 --- a/assets/translations/strings_en.i18n.json +++ b/assets/translations/strings_en.i18n.json @@ -164,6 +164,12 @@ "clearSelection": "Clear selection" }, "config": { + "mode": "Mode", + "modes": { + "none": "None", + "proxy": "Proxy", + "tun": "VPN" + }, "section": { "route": "Route Options", "dns": "DNS Options", @@ -220,7 +226,12 @@ "tray": { "dashboard": "Dashboard", "quit": "Quit", - "systemProxy": "System Proxy" + "status": { + "connect": "Connect", + "connecting": "Connecting", + "disconnect": "Disconnect", + "disconnecting": "Disconnecting" + } }, "failure": { "unexpected": "Unexpected Error", diff --git a/assets/translations/strings_fa.i18n.json b/assets/translations/strings_fa.i18n.json index f0fc4ed0..4f8eab23 100644 --- a/assets/translations/strings_fa.i18n.json +++ b/assets/translations/strings_fa.i18n.json @@ -164,6 +164,12 @@ "clearSelection": "حذف انتخاب‌ها" }, "config": { + "mode": "حالت", + "modes": { + "none": "هیچ یک", + "proxy": "پروکسی", + "tun": "VPN" + }, "section": { "route": "تنظیمات مسیریاب", "dns": "تنظیمات DNS", @@ -220,7 +226,12 @@ "tray": { "dashboard": "داشبورد", "quit": "خروج", - "systemProxy": "پراکسی سیستم" + "status": { + "connect": "اتصال", + "connecting": "در حال اتصال", + "disconnect": "قطع اتصال", + "disconnecting": "در حال قطع اتصال" + } }, "failure": { "unexpected": "خطای غیرمنتظره", diff --git a/assets/translations/strings_ru.i18n.json b/assets/translations/strings_ru.i18n.json index 40cfae55..84e3c020 100644 --- a/assets/translations/strings_ru.i18n.json +++ b/assets/translations/strings_ru.i18n.json @@ -164,6 +164,12 @@ "clearSelection": "Очистить выбор" }, "config": { + "mode": "Режим", + "modes": { + "none": "Никто", + "proxy": "Прокси", + "tun": "VPN" + }, "section": { "route": "Варианты маршрутизации", "dns": "Параметры DNS", @@ -220,7 +226,12 @@ "tray": { "dashboard": "Панель", "quit": "Выход", - "systemProxy": "Системный прокси" + "status": { + "connect": "Соединять", + "connecting": "Подключение", + "disconnect": "Отключить", + "disconnecting": "Отключение" + } }, "failure": { "unexpected": "Неожиданная ошибка", diff --git a/assets/translations/strings_zh.i18n.json b/assets/translations/strings_zh.i18n.json index 52d1d323..42274fd4 100644 --- a/assets/translations/strings_zh.i18n.json +++ b/assets/translations/strings_zh.i18n.json @@ -164,6 +164,12 @@ "clearSelection": "清空选项" }, "config": { + "mode": "模式", + "modes": { + "none": "没有任何", + "proxy": "代理人", + "tun": "VPN" + }, "section": { "route": "路线选项", "dns": "DNS 选项", @@ -220,7 +226,12 @@ "tray": { "dashboard": "控制面板", "quit": "退出", - "systemProxy": "系统代理" + "status": { + "connect": "连接", + "connecting": "正在连接", + "disconnect": "断开", + "disconnecting": "断开连接" + } }, "failure": { "unexpected": "意外错误", diff --git a/lib/bootstrap.dart b/lib/bootstrap.dart index f36bacab..83b34bb8 100644 --- a/lib/bootstrap.dart +++ b/lib/bootstrap.dart @@ -12,7 +12,7 @@ import 'package:hiddify/data/repository/app_repository_impl.dart'; import 'package:hiddify/domain/environment.dart'; import 'package:hiddify/features/common/active_profile/active_profile_notifier.dart'; import 'package:hiddify/features/common/window/window_controller.dart'; -import 'package:hiddify/features/system_tray/system_tray.dart'; +import 'package:hiddify/features/system_tray/system_tray_controller.dart'; import 'package:hiddify/services/auto_start_service.dart'; import 'package:hiddify/services/deep_link_service.dart'; import 'package:hiddify/services/service_providers.dart'; diff --git a/lib/features/common/common_controllers.dart b/lib/features/common/common_controllers.dart index db6e7e2c..25993d89 100644 --- a/lib/features/common/common_controllers.dart +++ b/lib/features/common/common_controllers.dart @@ -3,7 +3,7 @@ import 'package:hiddify/features/common/app_update_notifier.dart'; import 'package:hiddify/features/common/connectivity/connectivity_controller.dart'; import 'package:hiddify/features/common/window/window_controller.dart'; import 'package:hiddify/features/profiles/notifier/notifier.dart'; -import 'package:hiddify/features/system_tray/controller/system_tray_controller.dart'; +import 'package:hiddify/features/system_tray/system_tray_controller.dart'; import 'package:hiddify/services/service_providers.dart'; import 'package:hiddify/utils/platform_utils.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; diff --git a/lib/features/system_tray/system_tray.dart b/lib/features/system_tray/system_tray.dart deleted file mode 100644 index 4d5727f7..00000000 --- a/lib/features/system_tray/system_tray.dart +++ /dev/null @@ -1 +0,0 @@ -export 'controller/system_tray_controller.dart'; diff --git a/lib/features/system_tray/controller/system_tray_controller.dart b/lib/features/system_tray/system_tray_controller.dart similarity index 70% rename from lib/features/system_tray/controller/system_tray_controller.dart rename to lib/features/system_tray/system_tray_controller.dart index 2b3eb10e..28671deb 100644 --- a/lib/features/system_tray/controller/system_tray_controller.dart +++ b/lib/features/system_tray/system_tray_controller.dart @@ -1,8 +1,10 @@ import 'dart:io'; import 'package:hiddify/core/core_providers.dart'; +import 'package:hiddify/data/repository/config_options_store.dart'; import 'package:hiddify/domain/connectivity/connectivity.dart'; import 'package:hiddify/domain/constants.dart'; +import 'package:hiddify/domain/singbox/singbox.dart'; import 'package:hiddify/features/common/connectivity/connectivity_controller.dart'; import 'package:hiddify/features/common/window/window_controller.dart'; import 'package:hiddify/gen/assets.gen.dart'; @@ -29,20 +31,12 @@ class SystemTrayController extends _$SystemTrayController } final connection = await ref.watch(connectivityControllerProvider.future); + final mode = ref.watch(coreModeStoreProvider); + + final t = ref.watch(translationsProvider); loggy.debug('updating system tray'); - await _updateTray(connection); - } - bool _initialized = false; - - String get _trayIconPath { - if (Platform.isWindows) return Assets.images.trayIconIco; - return Assets.images.trayIconPng.path; - } - - Future _updateTray(ConnectionStatus connection) async { - final t = ref.watch(translationsProvider); final trayMenu = Menu( items: [ MenuItem( @@ -51,11 +45,37 @@ class SystemTrayController extends _$SystemTrayController ), MenuItem.separator(), MenuItem.checkbox( - label: t.tray.systemProxy, + label: switch (connection) { + Disconnected() => t.tray.status.connect, + Connecting() => t.tray.status.connecting, + Connected() => t.tray.status.disconnect, + Disconnecting() => t.tray.status.disconnecting, + }, checked: connection.isConnected, disabled: connection.isSwitching, onClick: handleClickSetAsSystemProxy, ), + MenuItem.submenu( + label: t.settings.config.mode, + submenu: Menu( + items: [ + ...CoreMode.values.map( + (e) => MenuItem.checkbox( + checked: e == mode, + key: e.name, + label: e.present(t), + onClick: (menuItem) async { + final newMode = CoreMode.values.byName(menuItem.key!); + loggy.debug("switching core mode: [$newMode]"); + await ref + .read(coreModeStoreProvider.notifier) + .update(newMode); + }, + ), + ), + ], + ), + ), MenuItem.separator(), MenuItem( label: t.tray.quit, @@ -66,6 +86,13 @@ class SystemTrayController extends _$SystemTrayController await trayManager.setContextMenu(trayMenu); } + bool _initialized = false; + + String get _trayIconPath { + if (Platform.isWindows) return Assets.images.trayIconIco; + return Assets.images.trayIconPng.path; + } + @override Future onTrayIconMouseDown() async { await ref.read(windowControllerProvider.notifier).show();