From be9ea4ea8ef236528f0eee2ad3788cc898daee64 Mon Sep 17 00:00:00 2001 From: GyDi Date: Tue, 17 May 2022 01:59:49 +0800 Subject: [PATCH] feat: clash meta core supports --- package.json | 3 +- src-tauri/Cargo.toml | 2 - src-tauri/src/cmds.rs | 8 ++- src-tauri/src/core/mod.rs | 44 ++++++++++--- src-tauri/src/core/multi.rs | 26 ++++++++ src-tauri/src/main.rs | 5 +- src-tauri/tauri.diff.json | 17 +++-- src-tauri/tauri.meta.json | 7 -- src/components/setting/core-switch.tsx | 84 ++++++++++++++++++++++++ src/components/setting/setting-clash.tsx | 19 +++++- src/services/cmds.ts | 4 ++ src/services/types.ts | 3 +- yarn.lock | 9 ++- 13 files changed, 195 insertions(+), 36 deletions(-) create mode 100644 src-tauri/src/core/multi.rs delete mode 100644 src-tauri/tauri.meta.json create mode 100644 src/components/setting/core-switch.tsx diff --git a/package.json b/package.json index 88daf36..e670c94 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "dev": "tauri dev", "dev:diff": "tauri dev -f verge-dev -c src-tauri/tauri.diff.json", - "dev:meta": "tauri dev -f meta-dev -c src-tauri/tauri.meta.json", + "dev:core": "cross-env VITE_MULTI_CORE=1 yarn dev:diff", "build": "tauri build", "tauri": "tauri", "web:dev": "vite", @@ -47,6 +47,7 @@ "@types/react-dom": "^17.0.0", "@vitejs/plugin-react": "^1.3.2", "adm-zip": "^0.5.9", + "cross-env": "^7.0.3", "fs-extra": "^10.0.0", "https-proxy-agent": "^5.0.1", "husky": "^7.0.0", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 9b4c8c8..0798508 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -45,9 +45,7 @@ windows-sys = { version = "0.36", features = ["Win32_System_LibraryLoader", "Win [features] default = ["custom-protocol", "tauri/ayatana-tray"] custom-protocol = ["tauri/custom-protocol"] -meta-dev = ["clash-meta", "verge-dev"] verge-dev = [] -clash-meta = [] debug-yml = [] [profile.release] diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs index bb65a19..f3aa877 100644 --- a/src-tauri/src/cmds.rs +++ b/src-tauri/src/cmds.rs @@ -196,10 +196,16 @@ pub fn patch_verge_config( payload: Verge, app_handle: tauri::AppHandle, core: State<'_, Core>, -) -> Result<(), String> { +) -> CmdResult { wrap_err!(core.patch_verge(payload, &app_handle)) } +/// change clash core +#[tauri::command] +pub fn change_clash_core(core: State<'_, Core>, clash_core: Option) -> CmdResult { + wrap_err!(core.change_core(clash_core)) +} + /// restart the sidecar #[tauri::command] pub fn restart_sidecar(core: State<'_, Core>) -> CmdResult { diff --git a/src-tauri/src/core/mod.rs b/src-tauri/src/core/mod.rs index e7be3bb..5907cf4 100644 --- a/src-tauri/src/core/mod.rs +++ b/src-tauri/src/core/mod.rs @@ -65,22 +65,21 @@ impl Core { /// initialize the core state pub fn init(&self, app_handle: tauri::AppHandle) { + let verge = self.verge.lock(); + let clash_core = verge.clash_core.clone(); + + let mut service = self.service.lock(); + service.set_core(clash_core); + #[cfg(windows)] { - let verge = self.verge.lock(); let enable = verge.enable_service_mode.clone(); - - let mut service = self.service.lock(); service.set_mode(enable.unwrap_or(false)); - - log_if_err!(service.start()); } - #[cfg(not(windows))] - { - let mut service = self.service.lock(); - log_if_err!(service.start()); - } + log_if_err!(service.start()); + drop(verge); + drop(service); log_if_err!(self.activate()); @@ -138,6 +137,31 @@ impl Core { self.activate_enhanced(true) } + /// change the clash core + pub fn change_core(&self, clash_core: Option) -> Result<()> { + let clash_core = clash_core.unwrap_or("clash".into()); + + if &clash_core != "clash" && &clash_core != "clash-meta" { + bail!("invalid clash core name \"{clash_core}\""); + } + + let mut verge = self.verge.lock(); + verge.patch_config(Verge { + clash_core: Some(clash_core.clone()), + ..Verge::default() + })?; + drop(verge); + + let mut service = self.service.lock(); + service.stop()?; + service.set_core(Some(clash_core)); + service.start()?; + drop(service); + + self.activate()?; + self.activate_enhanced(true) + } + /// Patch Clash /// handle the clash config changed pub fn patch_clash(&self, patch: Mapping) -> Result<()> { diff --git a/src-tauri/src/core/multi.rs b/src-tauri/src/core/multi.rs new file mode 100644 index 0000000..d779830 --- /dev/null +++ b/src-tauri/src/core/multi.rs @@ -0,0 +1,26 @@ +use anyhow::{Context, Result}; +use std::env::current_exe; + +pub struct CoreItem { + pub name: String, + pub path: String, +} + +pub struct Multi {} + +impl Multi { + pub fn list() -> Result> { + let paths = current_exe() + .unwrap() + .parent() + .unwrap() + .read_dir() + .context("failed to current dir")?; + + for path in paths { + dbg!(path.unwrap().path().metadata().unwrap().permissions().); + } + + Ok(vec![]) + } +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 8abe5e7..0cec26d 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -100,15 +100,16 @@ fn main() -> std::io::Result<()> { }) .invoke_handler(tauri::generate_handler![ // common - cmds::restart_sidecar, cmds::get_sys_proxy, cmds::get_cur_proxy, - cmds::kill_sidecar, cmds::open_app_dir, cmds::open_logs_dir, + cmds::kill_sidecar, + cmds::restart_sidecar, // clash cmds::get_clash_info, cmds::patch_clash_config, + cmds::change_clash_core, // verge cmds::get_verge_config, cmds::patch_verge_config, diff --git a/src-tauri/tauri.diff.json b/src-tauri/tauri.diff.json index afae5ff..cd2618c 100644 --- a/src-tauri/tauri.diff.json +++ b/src-tauri/tauri.diff.json @@ -1,9 +1,8 @@ -{ - "tauri": { - "bundle": { - "identifier": "top.gydi.clashverge.dev", - "externalBin": ["sidecar/clash", "sidecar/clash-meta"] - } - } - } - \ No newline at end of file +{ + "tauri": { + "bundle": { + "identifier": "top.gydi.clashverge.dev", + "externalBin": ["sidecar/clash", "sidecar/clash-meta"] + } + } +} diff --git a/src-tauri/tauri.meta.json b/src-tauri/tauri.meta.json deleted file mode 100644 index 9f4bb77..0000000 --- a/src-tauri/tauri.meta.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "tauri": { - "bundle": { - "externalBin": ["sidecar/clash", "sidecar/clash-meta"] - } - } -} diff --git a/src/components/setting/core-switch.tsx b/src/components/setting/core-switch.tsx new file mode 100644 index 0000000..b7ebd08 --- /dev/null +++ b/src/components/setting/core-switch.tsx @@ -0,0 +1,84 @@ +import useSWR, { useSWRConfig } from "swr"; +import { useState } from "react"; +import { useLockFn } from "ahooks"; +import { Menu, MenuItem } from "@mui/material"; +import { Settings } from "@mui/icons-material"; +import { changeClashCore, getVergeConfig } from "../../services/cmds"; +import getSystem from "../../utils/get-system"; +import Notice from "../base/base-notice"; + +const OS = getSystem(); + +const VALID_CORE = [ + { name: "Clash", core: "clash" }, + { name: "Clash Meta", core: "clash-meta" }, +]; + +const CoreSwitch = () => { + const { mutate } = useSWRConfig(); + + const { data: vergeConfig } = useSWR("getVergeConfig", getVergeConfig); + + const [anchorEl, setAnchorEl] = useState(null); + const [position, setPosition] = useState({ left: 0, top: 0 }); + + const { clash_core = "clash" } = vergeConfig ?? {}; + + const onCoreChange = useLockFn(async (core: string) => { + if (core === clash_core) return; + + try { + await changeClashCore(core); + mutate("getVergeConfig"); + mutate("getClashConfig"); + mutate("getVersion"); + setAnchorEl(null); + Notice.success(`Successfully switch to ${core}`, 1000); + } catch (err: any) { + Notice.error(err?.message || err.toString()); + } + }); + + return ( + <> + { + const { clientX, clientY } = event; + setPosition({ top: clientY, left: clientX }); + setAnchorEl(event.currentTarget); + }} + /> + + setAnchorEl(null)} + anchorPosition={position} + anchorReference="anchorPosition" + transitionDuration={225} + TransitionProps={ + OS === "macos" ? { style: { transitionDuration: "225ms" } } : {} + } + onContextMenu={(e) => { + setAnchorEl(null); + e.preventDefault(); + }} + > + {VALID_CORE.map((each) => ( + onCoreChange(each.core)} + > + {each.name} + + ))} + + + ); +}; + +export default CoreSwitch; diff --git a/src/components/setting/setting-clash.tsx b/src/components/setting/setting-clash.tsx index 6cd10a6..536cf7c 100644 --- a/src/components/setting/setting-clash.tsx +++ b/src/components/setting/setting-clash.tsx @@ -8,6 +8,7 @@ import { Select, MenuItem, Typography, + Box, } from "@mui/material"; import { ApiType } from "../../services/types"; import { atomClashPort } from "../../services/states"; @@ -16,11 +17,14 @@ import { SettingList, SettingItem } from "./setting"; import { getClashConfig, getVersion, updateConfigs } from "../../services/api"; import Notice from "../base/base-notice"; import GuardState from "./guard-state"; +import CoreSwitch from "./core-switch"; interface Props { onError: (err: Error) => void; } +const MULTI_CORE = !!import.meta.env.VITE_MULTI_CORE; + const SettingClash = ({ onError }: Props) => { const { t } = useTranslation(); const { mutate } = useSWRConfig(); @@ -54,7 +58,7 @@ const SettingClash = ({ onError }: Props) => { } await patchClashConfig({ "mixed-port": port }); setGlobalClashPort(port); - Notice.success("Change Clash port successfully!"); + Notice.success("Change Clash port successfully!", 1000); // update the config mutate("getClashConfig"); @@ -129,7 +133,18 @@ const SettingClash = ({ onError }: Props) => { - + + {t("Clash Core")} + + + ) : ( + t("Clash Core") + ) + } + /> {clashVer} diff --git a/src/services/cmds.ts b/src/services/cmds.ts index 6ef0645..fd7f99a 100644 --- a/src/services/cmds.ts +++ b/src/services/cmds.ts @@ -86,6 +86,10 @@ export async function getSystemProxy() { return invoke("get_sys_proxy"); } +export async function changeClashCore(clashCore: string) { + return invoke("change_clash_core", { clashCore }); +} + export async function restartSidecar() { return invoke("restart_sidecar"); } diff --git a/src/services/types.ts b/src/services/types.ts index 9a38b2d..44b8e7b 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -1,7 +1,7 @@ /** * Some interface for clash api */ - export namespace ApiType { +export namespace ApiType { export interface ConfigData { port: number; mode: string; @@ -125,6 +125,7 @@ export namespace CmdType { export interface VergeConfig { language?: string; + clash_core?: string; theme_mode?: "light" | "dark"; theme_blur?: boolean; traffic_graph?: boolean; diff --git a/yarn.lock b/yarn.lock index ad94a2d..25f7dde 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1201,7 +1201,14 @@ cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" -cross-spawn@^7.0.0: +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + +cross-spawn@^7.0.0, cross-spawn@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==