From e014fdf3dab9e20fe4cadd483dfe657fb3619ef9 Mon Sep 17 00:00:00 2001 From: MystiPanda Date: Mon, 22 Apr 2024 20:43:15 +0800 Subject: [PATCH] feat: support ico format for tray icon (#911) --- src-tauri/Cargo.lock | 13 +++++- src-tauri/Cargo.toml | 2 +- src-tauri/src/cmds.rs | 10 ++++- src-tauri/src/core/tray.rs | 30 +++++++++---- src-tauri/tauri.conf.json | 4 ++ src/components/setting/mods/layout-viewer.tsx | 43 +++++++++++++------ src/services/cmds.ts | 2 +- 7 files changed, 79 insertions(+), 25 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 7411cb2..ddae417 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2411,6 +2411,16 @@ dependencies = [ "cc", ] +[[package]] +name = "ico" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031530fe562d8c8d71c0635013d6d155bbfe8ba0aa4b4d2d24ce8af6b71047bd" +dependencies = [ + "byteorder", + "png", +] + [[package]] name = "ico" version = "0.3.0" @@ -5248,6 +5258,7 @@ dependencies = [ "gtk", "heck 0.4.1", "http 0.2.11", + "ico 0.2.0", "ignore", "indexmap 1.9.3", "infer 0.9.0", @@ -5316,7 +5327,7 @@ checksum = "a1554c5857f65dbc377cefb6b97c8ac77b1cb2a90d30d3448114d5d6b48a77fc" dependencies = [ "base64 0.21.7", "brotli", - "ico", + "ico 0.3.0", "json-patch", "plist", "png", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 350a237..ff1d09e 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -37,7 +37,7 @@ serde = { version = "1.0", features = ["derive"] } reqwest = { version = "0.12", features = ["json", "rustls-tls"] } sysproxy = { git="https://github.com/zzzgydi/sysproxy-rs", branch = "main" } auto-launch = { git="https://github.com/zzzgydi/auto-launch", branch = "main" } -tauri = { version = "1.6", features = [ "path-all", "protocol-asset", "dialog-open", "notification-all", "icon-png", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all", "devtools"] } +tauri = { version = "1.6", features = [ "fs-exists", "path-all", "protocol-asset", "dialog-open", "notification-all", "icon-png", "icon-ico", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all", "devtools"] } [target.'cfg(windows)'.dependencies] runas = "=1.2.0" diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs index eb6c001..8f5d430 100644 --- a/src-tauri/src/cmds.rs +++ b/src-tauri/src/cmds.rs @@ -299,9 +299,17 @@ pub fn copy_icon_file(path: String, name: String) -> CmdResult { if !icon_dir.exists() { let _ = std::fs::create_dir_all(&icon_dir); } - let dest_path = icon_dir.join(name); + let ext = match file_path.extension() { + Some(e) => e.to_string_lossy().to_string(), + None => "ico".to_string(), + }; + let png_dest_path = icon_dir.join(format!("{name}.png")); + let ico_dest_path = icon_dir.join(format!("{name}.ico")); + let dest_path = icon_dir.join(format!("{name}.{ext}")); if file_path.exists() { + std::fs::remove_file(png_dest_path).unwrap_or_default(); + std::fs::remove_file(ico_dest_path).unwrap_or_default(); match std::fs::copy(file_path, &dest_path) { Ok(_) => Ok(dest_path.to_string_lossy().to_string()), Err(err) => Err(err.to_string()), diff --git a/src-tauri/src/core/tray.rs b/src-tauri/src/core/tray.rs index a0e0e16..055b3d5 100644 --- a/src-tauri/src/core/tray.rs +++ b/src-tauri/src/core/tray.rs @@ -182,9 +182,13 @@ impl Tray { #[cfg(target_os = "macos")] let mut icon = include_bytes!("../../icons/mac-tray-icon-sys.png").to_vec(); if *sysproxy_tray_icon { - let path = dirs::app_home_dir()?.join("icons").join("sysproxy.png"); - if path.exists() { - icon = std::fs::read(path).unwrap(); + let icon_dir_path = dirs::app_home_dir()?.join("icons"); + let png_path = icon_dir_path.join("sysproxy.png"); + let ico_path = icon_dir_path.join("sysproxy.ico"); + if ico_path.exists() { + icon = std::fs::read(ico_path).unwrap(); + } else if png_path.exists() { + icon = std::fs::read(png_path).unwrap(); } } icon @@ -194,9 +198,13 @@ impl Tray { #[cfg(target_os = "macos")] let mut icon = include_bytes!("../../icons/mac-tray-icon.png").to_vec(); if *common_tray_icon { - let path = dirs::app_home_dir()?.join("icons").join("common.png"); - if path.exists() { - icon = std::fs::read(path).unwrap(); + let icon_dir_path = dirs::app_home_dir()?.join("icons"); + let png_path = icon_dir_path.join("common.png"); + let ico_path = icon_dir_path.join("common.ico"); + if ico_path.exists() { + icon = std::fs::read(ico_path).unwrap(); + } else if png_path.exists() { + icon = std::fs::read(png_path).unwrap(); } } icon @@ -208,9 +216,13 @@ impl Tray { #[cfg(target_os = "macos")] let mut icon = include_bytes!("../../icons/mac-tray-icon-tun.png").to_vec(); if *tun_tray_icon { - let path = dirs::app_home_dir()?.join("icons").join("tun.png"); - if path.exists() { - icon = std::fs::read(path).unwrap(); + let icon_dir_path = dirs::app_home_dir()?.join("icons"); + let png_path = icon_dir_path.join("tun.png"); + let ico_path = icon_dir_path.join("tun.ico"); + if ico_path.exists() { + icon = std::fs::read(ico_path).unwrap(); + } else if png_path.exists() { + icon = std::fs::read(png_path).unwrap(); } } indication_icon = icon diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index f6e062b..9bcd97e 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -66,6 +66,10 @@ }, "path": { "all": true + }, + "fs": { + "exists": true, + "scope": ["$APPDATA/**", "$RESOURCE/../**"] } }, "windows": [], diff --git a/src/components/setting/mods/layout-viewer.tsx b/src/components/setting/mods/layout-viewer.tsx index 154d2ba..222c7a1 100644 --- a/src/components/setting/mods/layout-viewer.tsx +++ b/src/components/setting/mods/layout-viewer.tsx @@ -9,6 +9,7 @@ import { open as openDialog } from "@tauri-apps/api/dialog"; import { convertFileSrc } from "@tauri-apps/api/tauri"; import { copyIconFile, getAppDir } from "@/services/cmds"; import { join } from "@tauri-apps/api/path"; +import { exists } from "@tauri-apps/api/fs"; export const LayoutViewer = forwardRef((props, ref) => { const { t } = useTranslation(); @@ -26,12 +27,27 @@ export const LayoutViewer = forwardRef((props, ref) => { async function initIconPath() { const appDir = await getAppDir(); const icon_dir = await join(appDir, "icons"); - const common_icon = await join(icon_dir, "common.png"); - const sysproxy_icon = await join(icon_dir, "sysproxy.png"); - const tun_icon = await join(icon_dir, "tun.png"); - setCommonIcon(common_icon); - setSysproxyIcon(sysproxy_icon); - setTunIcon(tun_icon); + const common_icon_png = await join(icon_dir, "common.png"); + const common_icon_ico = await join(icon_dir, "common.ico"); + const sysproxy_icon_png = await join(icon_dir, "sysproxy.png"); + const sysproxy_icon_ico = await join(icon_dir, "sysproxy.ico"); + const tun_icon_png = await join(icon_dir, "tun.png"); + const tun_icon_ico = await join(icon_dir, "tun.ico"); + if (await exists(common_icon_ico)) { + setCommonIcon(common_icon_ico); + } else { + setCommonIcon(common_icon_png); + } + if (await exists(sysproxy_icon_ico)) { + setSysproxyIcon(sysproxy_icon_ico); + } else { + setSysproxyIcon(sysproxy_icon_png); + } + if (await exists(tun_icon_ico)) { + setTunIcon(tun_icon_ico); + } else { + setTunIcon(tun_icon_png); + } } useImperativeHandle(ref, () => ({ @@ -140,12 +156,13 @@ export const LayoutViewer = forwardRef((props, ref) => { filters: [ { name: "Tray Icon Image", - extensions: ["png"], + extensions: ["png", "ico"], }, ], }); if (path?.length) { - await copyIconFile(`${path}`, "common.png"); + await copyIconFile(`${path}`, "common"); + await initIconPath(); onChangeData({ common_tray_icon: true }); patchVerge({ common_tray_icon: true }); } @@ -184,12 +201,13 @@ export const LayoutViewer = forwardRef((props, ref) => { filters: [ { name: "Tray Icon Image", - extensions: ["png"], + extensions: ["png", "ico"], }, ], }); if (path?.length) { - await copyIconFile(`${path}`, "sysproxy.png"); + await copyIconFile(`${path}`, "sysproxy"); + await initIconPath(); onChangeData({ sysproxy_tray_icon: true }); patchVerge({ sysproxy_tray_icon: true }); } @@ -226,12 +244,13 @@ export const LayoutViewer = forwardRef((props, ref) => { filters: [ { name: "Tray Icon Image", - extensions: ["png"], + extensions: ["png", "ico"], }, ], }); if (path?.length) { - await copyIconFile(`${path}`, "tun.png"); + await copyIconFile(`${path}`, "tun"); + await initIconPath(); onChangeData({ tun_tray_icon: true }); patchVerge({ tun_tray_icon: true }); } diff --git a/src/services/cmds.ts b/src/services/cmds.ts index ceae091..9b7ac1b 100644 --- a/src/services/cmds.ts +++ b/src/services/cmds.ts @@ -223,7 +223,7 @@ export async function exitApp() { export async function copyIconFile( path: string, - name: "common.png" | "sysproxy.png" | "tun.png" + name: "common" | "sysproxy" | "tun" ) { return invoke("copy_icon_file", { path, name }); }