From 1a91249da2bcc21c85f7a7561e38aa1bf474c282 Mon Sep 17 00:00:00 2001
From: GyDi <segydi@foxmail.com>
Date: Wed, 13 Apr 2022 01:09:51 +0800
Subject: [PATCH] feat: system tray add tun mode

---
 src-tauri/src/cmds.rs       | 14 +++++---------
 src-tauri/src/core/verge.rs | 30 ++++++++++++++++++++++++++++++
 src-tauri/src/main.rs       | 26 ++++++++++++++++----------
 3 files changed, 51 insertions(+), 19 deletions(-)

diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs
index bf1e852..bafc118 100644
--- a/src-tauri/src/cmds.rs
+++ b/src-tauri/src/cmds.rs
@@ -337,15 +337,6 @@ pub fn patch_verge_config(
   let mut verge = verge_state.0.lock().unwrap();
   wrap_err!(verge.patch_config(payload))?;
 
-  // change system tray
-  if system_proxy.is_some() {
-    app_handle
-      .tray_handle()
-      .get_item("system_proxy")
-      .set_selected(system_proxy.unwrap())
-      .unwrap();
-  }
-
   // change tun mode
   if tun_mode.is_some() {
     #[cfg(target_os = "windows")]
@@ -363,6 +354,11 @@ pub fn patch_verge_config(
     wrap_err!(clash.activate_enhanced(&profiles, false, false))?;
   }
 
+  // change system tray
+  if system_proxy.is_some() || tun_mode.is_some() {
+    verge.update_systray(&app_handle).unwrap();
+  }
+
   Ok(())
 }
 
diff --git a/src-tauri/src/core/verge.rs b/src-tauri/src/core/verge.rs
index c2d3d52..eaa789c 100644
--- a/src-tauri/src/core/verge.rs
+++ b/src-tauri/src/core/verge.rs
@@ -8,6 +8,7 @@ use auto_launch::{AutoLaunch, AutoLaunchBuilder};
 use serde::{Deserialize, Serialize};
 use std::sync::Arc;
 use tauri::{async_runtime::Mutex, utils::platform::current_exe};
+use tauri::{AppHandle, Manager};
 
 /// ### `verge.yaml` schema
 #[derive(Default, Debug, Clone, Deserialize, Serialize)]
@@ -291,6 +292,35 @@ impl Verge {
 
     self.config.save_file()
   }
+
+  /// update the system tray state
+  pub fn update_systray(&self, app_handle: &AppHandle) -> Result<()> {
+    // system proxy
+    let system_proxy = self.config.enable_system_proxy.as_ref();
+    system_proxy.map(|system_proxy| {
+      app_handle
+        .tray_handle()
+        .get_item("system_proxy")
+        .set_selected(*system_proxy)
+        .unwrap();
+    });
+
+    // tun mode
+    let tun_mode = self.config.enable_tun_mode.as_ref();
+    tun_mode.map(|tun_mode| {
+      app_handle
+        .tray_handle()
+        .get_item("tun_mode")
+        .set_selected(*tun_mode)
+        .unwrap();
+    });
+
+    // update verge config
+    let window = app_handle.get_window("main").unwrap();
+    window.emit("verge://refresh-verge-config", "yes").unwrap();
+
+    Ok(())
+  }
 }
 
 impl Verge {
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 62707b6..56e9fd9 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -30,6 +30,7 @@ fn main() -> std::io::Result<()> {
   let tray_menu = SystemTrayMenu::new()
     .add_item(CustomMenuItem::new("open_window", "Show"))
     .add_item(CustomMenuItem::new("system_proxy", "System Proxy"))
+    .add_item(CustomMenuItem::new("tun_mode", "Tun Mode"))
     .add_item(CustomMenuItem::new("restart_clash", "Restart Clash"))
     .add_native_item(SystemTrayMenuItem::Separator)
     .add_item(CustomMenuItem::new("quit", "Quit").accelerator("CmdOrControl+Q"));
@@ -60,17 +61,22 @@ fn main() -> std::io::Result<()> {
             enable_system_proxy: Some(new_value),
             ..VergeConfig::default()
           }) {
-            Ok(_) => {
-              app_handle
-                .tray_handle()
-                .get_item(id.as_str())
-                .set_selected(new_value)
-                .unwrap();
+            Ok(_) => verge.update_systray(app_handle).unwrap(),
+            Err(err) => log::error!("{err}"),
+          }
+        }
+        "tun_mode" => {
+          let verge_state = app_handle.state::<states::VergeState>();
+          let mut verge = verge_state.0.lock().unwrap();
 
-              // update verge config
-              let window = app_handle.get_window("main").unwrap();
-              window.emit("verge://refresh-verge-config", "yes").unwrap();
-            }
+          let old_value = verge.config.enable_tun_mode.clone().unwrap_or(false);
+          let new_value = !old_value;
+
+          match verge.patch_config(VergeConfig {
+            enable_tun_mode: Some(new_value),
+            ..VergeConfig::default()
+          }) {
+            Ok(_) => verge.update_systray(app_handle).unwrap(),
             Err(err) => log::error!("{err}"),
           }
         }
-- 
GitLab