diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index e2165395..314affed 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1262,6 +1262,7 @@ dependencies = [ "serde_json", "tauri", "tauri-build", + "tokio", "window-shadows", "window-vibrancy", ] @@ -3088,14 +3089,27 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", "num_cpus", "pin-project-lite", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", ] [[package]] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 8244e9b9..d6a48282 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -25,6 +25,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" window-shadows = "0.2.2" # windows 阴影和圆角 window-vibrancy = "0.4.3" # windows 磨砂背景 tauri-v1.x版本最好使用0.4.3版本 +tokio = { version = "1.36.0", features = ["macros", "windows-sys", "rt-multi-thread", "time"] } [features] # this feature is used for production builds or when `devPath` points to the filesystem diff --git a/src-tauri/src/common/plugins.rs b/src-tauri/src/common/plugins.rs index 958f2619..62dff2c8 100644 --- a/src-tauri/src/common/plugins.rs +++ b/src-tauri/src/common/plugins.rs @@ -1,3 +1,4 @@ +use std::sync::Mutex; use tauri::{AppHandle, Manager, Runtime}; use window_shadows::set_shadow; @@ -31,4 +32,58 @@ pub fn set_tray_icon(app: AppHandle) { #[tauri::command] pub fn exit(app: AppHandle) { app.exit(0) +} + +pub struct TrayState { + // 用来缓存上一次线程的句柄 + pub id: Mutex>> +} + +/// 设置托盘图标闪烁 +// TODO 现在只能实现两张图片交换实现闪烁效果 (nyh -> 2024-03-23 17:57:45) +#[tauri::command] +pub fn tray_blink( + app: AppHandle, + state: tauri::State, + is_run: bool, // 是否运行 + ms: Option, // 可选, 时间间隔,单位毫秒 + icon_path_1: Option, // 可选,图标1 + icon_path_2: Option, // 可选,图标2 +) { + // 如果存在就取消上一次的线程 + match state.id.lock().as_deref_mut().map(|x| x.as_mut()) { + Ok(Some(v)) => v.abort(), + _ => (), + } + + // 是否停止运行,如果停止,则取消上一次线程后的返回 + if !is_run { + return; + } + + // 缓存线程 id 到 tauri state + *state.id.lock().unwrap() = Some(tokio::spawn(async move { + let path1 = &icon_path_1.unwrap(); + let path2 = &icon_path_2.unwrap(); + let mut count = 0; + + loop { + // 如果 ms 不存在 则默认 500ms + tokio::time::sleep(std::time::Duration::from_millis(ms.unwrap_or_else(|| 500))).await; + count += 1; + + // 两张图片交替显示, 所以对2取模运算 + let path = if count % 2 == 0 { + path2 + } else { + path1 + }; + + // tauri api 进行图标设置 + app + .tray_handle() + .set_icon(tauri::Icon::File(std::path::PathBuf::from(path))) + .unwrap(); + } + })); } \ No newline at end of file diff --git a/src-tauri/src/common/tray.rs b/src-tauri/src/common/tray.rs index f4c75693..e1746a26 100644 --- a/src-tauri/src/common/tray.rs +++ b/src-tauri/src/common/tray.rs @@ -29,6 +29,9 @@ fn red_icon(app: &AppHandle) { pub fn handler(app: &AppHandle, event: SystemTrayEvent) { match event { SystemTrayEvent::LeftClick { .. } => { + // 当我点击闪烁的图标的时候就停止闪烁 + let window = app.get_window("tray").unwrap(); + window.emit("stop", false).unwrap(); open_home(app); red_icon(app); }, diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index a34d8abd..82f058af 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,25 +1,32 @@ // Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +use std::sync::Mutex; use tauri::{SystemTray}; use crate::common::window::set_window_attribute; -use crate::common::plugins::{ exit, reset_set_window, set_tray_icon }; +use crate::common::plugins::{ exit, reset_set_window, set_tray_icon, tray_blink, TrayState }; mod common; -fn main() { +#[tokio::main] +async fn main() { let context = tauri::generate_context!(); let system_tray = SystemTray::new(); + // 初始化状态 + let state = TrayState { + id: Mutex::new(None) + }; tauri::Builder::default() .setup(|app| { set_window_attribute(app); Ok(()) }) + .manage(state) // 将状态注入到应用 .menu(tauri::Menu::new())// 使用空菜单来替换默认的操作系统菜单 .system_tray(system_tray)// 将 `tauri.conf.json` 上配置的图标添加到系统托盘 .on_system_tray_event(common::tray::handler) // 注册系统托盘事件处理程序 - .invoke_handler(tauri::generate_handler![reset_set_window, set_tray_icon, exit]) // 使用定义的插件 + .invoke_handler(tauri::generate_handler![reset_set_window, set_tray_icon, exit, tray_blink]) // 使用定义的插件 .on_window_event(|event| match event.event() { tauri::WindowEvent::CloseRequested { api, .. } => { event.window().hide().unwrap(); diff --git a/src-tauri/tray/msg-sub.png b/src-tauri/tray/msg-sub.png new file mode 100644 index 00000000..f04a4fc6 Binary files /dev/null and b/src-tauri/tray/msg-sub.png differ diff --git a/src-tauri/tray/msg.png b/src-tauri/tray/msg.png new file mode 100644 index 00000000..f5761dad Binary files /dev/null and b/src-tauri/tray/msg.png differ diff --git a/src/components/rightBox/Details.vue b/src/components/rightBox/Details.vue index 66397ea4..63630772 100644 --- a/src/components/rightBox/Details.vue +++ b/src/components/rightBox/Details.vue @@ -73,7 +73,7 @@ 群成员:({{ options.length }}人) - +