feat: support ico format for tray icon (#911)

This commit is contained in:
MystiPanda 2024-04-22 20:43:15 +08:00 committed by GitHub
parent 2074da05c8
commit e014fdf3da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 79 additions and 25 deletions

13
src-tauri/Cargo.lock generated
View File

@ -2411,6 +2411,16 @@ dependencies = [
"cc", "cc",
] ]
[[package]]
name = "ico"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "031530fe562d8c8d71c0635013d6d155bbfe8ba0aa4b4d2d24ce8af6b71047bd"
dependencies = [
"byteorder",
"png",
]
[[package]] [[package]]
name = "ico" name = "ico"
version = "0.3.0" version = "0.3.0"
@ -5248,6 +5258,7 @@ dependencies = [
"gtk", "gtk",
"heck 0.4.1", "heck 0.4.1",
"http 0.2.11", "http 0.2.11",
"ico 0.2.0",
"ignore", "ignore",
"indexmap 1.9.3", "indexmap 1.9.3",
"infer 0.9.0", "infer 0.9.0",
@ -5316,7 +5327,7 @@ checksum = "a1554c5857f65dbc377cefb6b97c8ac77b1cb2a90d30d3448114d5d6b48a77fc"
dependencies = [ dependencies = [
"base64 0.21.7", "base64 0.21.7",
"brotli", "brotli",
"ico", "ico 0.3.0",
"json-patch", "json-patch",
"plist", "plist",
"png", "png",

View File

@ -37,7 +37,7 @@ serde = { version = "1.0", features = ["derive"] }
reqwest = { version = "0.12", features = ["json", "rustls-tls"] } reqwest = { version = "0.12", features = ["json", "rustls-tls"] }
sysproxy = { git="https://github.com/zzzgydi/sysproxy-rs", branch = "main" } sysproxy = { git="https://github.com/zzzgydi/sysproxy-rs", branch = "main" }
auto-launch = { git="https://github.com/zzzgydi/auto-launch", 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] [target.'cfg(windows)'.dependencies]
runas = "=1.2.0" runas = "=1.2.0"

View File

@ -299,9 +299,17 @@ pub fn copy_icon_file(path: String, name: String) -> CmdResult<String> {
if !icon_dir.exists() { if !icon_dir.exists() {
let _ = std::fs::create_dir_all(&icon_dir); 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() { 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) { match std::fs::copy(file_path, &dest_path) {
Ok(_) => Ok(dest_path.to_string_lossy().to_string()), Ok(_) => Ok(dest_path.to_string_lossy().to_string()),
Err(err) => Err(err.to_string()), Err(err) => Err(err.to_string()),

View File

@ -182,9 +182,13 @@ impl Tray {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let mut icon = include_bytes!("../../icons/mac-tray-icon-sys.png").to_vec(); let mut icon = include_bytes!("../../icons/mac-tray-icon-sys.png").to_vec();
if *sysproxy_tray_icon { if *sysproxy_tray_icon {
let path = dirs::app_home_dir()?.join("icons").join("sysproxy.png"); let icon_dir_path = dirs::app_home_dir()?.join("icons");
if path.exists() { let png_path = icon_dir_path.join("sysproxy.png");
icon = std::fs::read(path).unwrap(); 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 icon
@ -194,9 +198,13 @@ impl Tray {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let mut icon = include_bytes!("../../icons/mac-tray-icon.png").to_vec(); let mut icon = include_bytes!("../../icons/mac-tray-icon.png").to_vec();
if *common_tray_icon { if *common_tray_icon {
let path = dirs::app_home_dir()?.join("icons").join("common.png"); let icon_dir_path = dirs::app_home_dir()?.join("icons");
if path.exists() { let png_path = icon_dir_path.join("common.png");
icon = std::fs::read(path).unwrap(); 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 icon
@ -208,9 +216,13 @@ impl Tray {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let mut icon = include_bytes!("../../icons/mac-tray-icon-tun.png").to_vec(); let mut icon = include_bytes!("../../icons/mac-tray-icon-tun.png").to_vec();
if *tun_tray_icon { if *tun_tray_icon {
let path = dirs::app_home_dir()?.join("icons").join("tun.png"); let icon_dir_path = dirs::app_home_dir()?.join("icons");
if path.exists() { let png_path = icon_dir_path.join("tun.png");
icon = std::fs::read(path).unwrap(); 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 indication_icon = icon

View File

@ -66,6 +66,10 @@
}, },
"path": { "path": {
"all": true "all": true
},
"fs": {
"exists": true,
"scope": ["$APPDATA/**", "$RESOURCE/../**"]
} }
}, },
"windows": [], "windows": [],

View File

@ -9,6 +9,7 @@ import { open as openDialog } from "@tauri-apps/api/dialog";
import { convertFileSrc } from "@tauri-apps/api/tauri"; import { convertFileSrc } from "@tauri-apps/api/tauri";
import { copyIconFile, getAppDir } from "@/services/cmds"; import { copyIconFile, getAppDir } from "@/services/cmds";
import { join } from "@tauri-apps/api/path"; import { join } from "@tauri-apps/api/path";
import { exists } from "@tauri-apps/api/fs";
export const LayoutViewer = forwardRef<DialogRef>((props, ref) => { export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -26,12 +27,27 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
async function initIconPath() { async function initIconPath() {
const appDir = await getAppDir(); const appDir = await getAppDir();
const icon_dir = await join(appDir, "icons"); const icon_dir = await join(appDir, "icons");
const common_icon = await join(icon_dir, "common.png"); const common_icon_png = await join(icon_dir, "common.png");
const sysproxy_icon = await join(icon_dir, "sysproxy.png"); const common_icon_ico = await join(icon_dir, "common.ico");
const tun_icon = await join(icon_dir, "tun.png"); const sysproxy_icon_png = await join(icon_dir, "sysproxy.png");
setCommonIcon(common_icon); const sysproxy_icon_ico = await join(icon_dir, "sysproxy.ico");
setSysproxyIcon(sysproxy_icon); const tun_icon_png = await join(icon_dir, "tun.png");
setTunIcon(tun_icon); 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, () => ({ useImperativeHandle(ref, () => ({
@ -140,12 +156,13 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
filters: [ filters: [
{ {
name: "Tray Icon Image", name: "Tray Icon Image",
extensions: ["png"], extensions: ["png", "ico"],
}, },
], ],
}); });
if (path?.length) { if (path?.length) {
await copyIconFile(`${path}`, "common.png"); await copyIconFile(`${path}`, "common");
await initIconPath();
onChangeData({ common_tray_icon: true }); onChangeData({ common_tray_icon: true });
patchVerge({ common_tray_icon: true }); patchVerge({ common_tray_icon: true });
} }
@ -184,12 +201,13 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
filters: [ filters: [
{ {
name: "Tray Icon Image", name: "Tray Icon Image",
extensions: ["png"], extensions: ["png", "ico"],
}, },
], ],
}); });
if (path?.length) { if (path?.length) {
await copyIconFile(`${path}`, "sysproxy.png"); await copyIconFile(`${path}`, "sysproxy");
await initIconPath();
onChangeData({ sysproxy_tray_icon: true }); onChangeData({ sysproxy_tray_icon: true });
patchVerge({ sysproxy_tray_icon: true }); patchVerge({ sysproxy_tray_icon: true });
} }
@ -226,12 +244,13 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
filters: [ filters: [
{ {
name: "Tray Icon Image", name: "Tray Icon Image",
extensions: ["png"], extensions: ["png", "ico"],
}, },
], ],
}); });
if (path?.length) { if (path?.length) {
await copyIconFile(`${path}`, "tun.png"); await copyIconFile(`${path}`, "tun");
await initIconPath();
onChangeData({ tun_tray_icon: true }); onChangeData({ tun_tray_icon: true });
patchVerge({ tun_tray_icon: true }); patchVerge({ tun_tray_icon: true });
} }

View File

@ -223,7 +223,7 @@ export async function exitApp() {
export async function copyIconFile( export async function copyIconFile(
path: string, path: string,
name: "common.png" | "sysproxy.png" | "tun.png" name: "common" | "sysproxy" | "tun"
) { ) {
return invoke<void>("copy_icon_file", { path, name }); return invoke<void>("copy_icon_file", { path, name });
} }