tray.dart 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import 'dart:io';
  2. import 'package:get/get.dart';
  3. import 'package:naiyouwl/app/bean/proxie.dart';
  4. import 'package:naiyouwl/app/controller/controllers.dart';
  5. import 'package:naiyouwl/app/utils/utils.dart';
  6. import 'package:tray_manager/tray_manager.dart';
  7. import 'package:url_launcher/url_launcher.dart';
  8. import 'package:window_manager/window_manager.dart';
  9. class TrayController extends GetxController with TrayListener {
  10. late Menu trayMenu;
  11. var disabledTun = false.obs;
  12. var show = false.obs;
  13. Future<void> initTray() async {
  14. await trayManager.setIcon('assets/images/logo/logo.ico');
  15. // await trayManager.setTitle('Clash For Flutter');
  16. updateTray();
  17. trayManager.addListener(this);
  18. }
  19. Future<void> updateTray() async {
  20. final visible = await windowManager.isVisible();
  21. final disabled = !controllers.service.isRunning;
  22. var disabledSerivce = false;
  23. if(Platform.isWindows){
  24. disabledSerivce = true;
  25. }
  26. trayMenu = Menu(items: [
  27. MenuItem.checkbox(label: 'tray_show'.tr, checked: visible, onClick: handleClickShow),
  28. MenuItem.separator(),
  29. MenuItem.submenu(
  30. label: 'proxie_group_title'.tr,
  31. disabled: disabled,
  32. submenu: Menu(
  33. items: controllers.global.proxieGroups
  34. .map((it) => MenuItem.submenu(
  35. label: it.name,
  36. submenu: Menu(
  37. items: (it.all ?? [])
  38. .map((t) => MenuItem.checkbox(
  39. label: t,
  40. checked: t == it.now,
  41. disabled: it.type != 'Selector',
  42. onClick: (m) => handleClickProxieItem(it, m),
  43. ))
  44. .toList(),
  45. ),
  46. ))
  47. .toList()),
  48. ),
  49. // MenuItem(
  50. // label: 'tray_restart_clash_core'.tr,
  51. // disabled: !controllers.service.isCanOperationCore,
  52. // onClick: handleClickRestartClashCore,
  53. // ),
  54. MenuItem.checkbox(
  55. label: 'setting_set_as_system_proxy'.tr,
  56. checked: controllers.config.config.value.setSystemProxy,
  57. disabled: disabled || controllers.global.systemProxySwitchIng.value,
  58. onClick: handleClickSetAsSystemProxy,
  59. ),
  60. MenuItem.checkbox(
  61. label: 'route_tun_title'.tr,
  62. checked: disabledTun.value,
  63. disabled: false,
  64. onClick: handleClickSetAsTunProxy,
  65. ),
  66. MenuItem.checkbox(
  67. label: 'setting_service_open'.tr,
  68. checked: controllers.service.serviceMode.value,
  69. disabled: disabledSerivce == false ? !controllers.service.isCanOperationService : disabledSerivce,
  70. onClick: handleClickServiceModeSwitch,
  71. ),
  72. MenuItem.submenu(
  73. label: 'tray_copy_command_line_proxy'.tr,
  74. disabled: disabled,
  75. submenu: Menu(items: [
  76. MenuItem(label: 'bash', onClick: handleClickCopyCommandLineProxy),
  77. MenuItem(label: 'cmd', onClick: handleClickCopyCommandLineProxy),
  78. MenuItem(label: 'powershell', onClick: handleClickCopyCommandLineProxy),
  79. ])),
  80. MenuItem.separator(),
  81. // MenuItem(label: 'tray_about'.tr, onClick: handleClickAbout),
  82. MenuItem(label: 'tray_exit'.tr, onClick: handleClickExit),
  83. ]);
  84. await trayManager.setContextMenu(trayMenu);
  85. }
  86. @override
  87. void onTrayIconMouseDown() async {
  88. await controllers.window.showWindow();
  89. }
  90. @override
  91. void onTrayIconRightMouseDown() async {
  92. show.value = true;
  93. await updateTray();
  94. await trayManager.popUpContextMenu();
  95. show.value = false;
  96. }
  97. Future<void> handleClickShow(MenuItem menuItem) async {
  98. show.value = false;
  99. if (menuItem.checked == true) {
  100. await controllers.window.hideWindow();
  101. } else {
  102. await controllers.window.showWindow();
  103. }
  104. }
  105. Future<void> handleClickProxieItem(ProxieProxiesItem proxie, MenuItem menuItem) async {
  106. await controllers.global.handleSetProxieGroup(proxie, menuItem.label!);
  107. }
  108. Future<void> handleClickSetAsSystemProxy(MenuItem menuItem) async {
  109. await controllers.global.systemProxySwitch(menuItem.checked != true);
  110. }
  111. Future<void> handleClickSetAsTunProxy(MenuItem menuItem) async {
  112. disabledTun.value = menuItem.checked != true;
  113. await controllers.global.TunProxySwitch(menuItem.checked != true);
  114. }
  115. Future<void> handleClickCopyCommandLineProxy(MenuItem menuItem) async {
  116. final title = menuItem.label!;
  117. final proxyConfig = controllers.core.proxyConfig;
  118. await copyCommandLineProxy(title, http: proxyConfig.http, https: proxyConfig.https);
  119. }
  120. Future<void> handleClickAbout(MenuItem menuItem) async {
  121. //await launchUrl(Uri.parse('https://github.com/csj8520/clash_for_flutter'));
  122. }
  123. Future<void> handleClickExit(MenuItem menuItem) async {
  124. await controllers.global.handleExit();
  125. }
  126. Future<void> handleClickRestartClashCore(MenuItem menuItem) async {
  127. controllers.global.allowStatusUpdate = true;
  128. await controllers.service.reloadClashCore();
  129. }
  130. Future<void> handleClickServiceModeSwitch(MenuItem menuItem) async {
  131. await controllers.service.serviceModeSwitch(menuItem.checked != true);
  132. }
  133. @override
  134. void dispose() {
  135. trayManager.removeListener(this);
  136. super.dispose();
  137. }
  138. }