diff --git a/src-tauri/src/tray.rs b/src-tauri/src/tray.rs index 7ffde65..84bc850 100644 --- a/src-tauri/src/tray.rs +++ b/src-tauri/src/tray.rs @@ -1,31 +1,126 @@ use tauri::{ - menu::{Menu, MenuItem}, + menu::{CheckMenuItem, Menu, MenuItem, PredefinedMenuItem}, tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent}, - Emitter, Manager, Runtime, + Emitter, Listener, Manager, Runtime, }; +use crate::tool::powerplan::PowerPlanMode; + pub fn create_tray(app: &tauri::AppHandle) -> tauri::Result<()> { // 托盘菜单项目 - let launch_ww_i = MenuItem::with_id(app, "launch_ww", "启动国际服", true, None::<&str>)?; - let launch_pw_i = MenuItem::with_id(app, "launch_pw", "启动国服", true, None::<&str>)?; - let kill_game_i = MenuItem::with_id(app, "kill_game", "关闭CS2", true, None::<&str>)?; - let kill_steam_i = MenuItem::with_id(app, "kill_steam", "关闭Steam", true, None::<&str>)?; - let show_i = MenuItem::with_id(app, "show", "显示主界面", true, None::<&str>)?; - let quit_i = MenuItem::with_id(app, "quit", "退出", true, None::<&str>)?; + let separator = &PredefinedMenuItem::separator(app).unwrap(); + + let show_i = &MenuItem::with_id(app, "show", "显示主界面", true, None::<&str>)?; + let quit_i = &MenuItem::with_id(app, "quit", "退出", true, None::<&str>)?; + + let kill_game_i = &MenuItem::with_id(app, "kill_game", "关闭CS2", true, None::<&str>)?; + let kill_steam_i = &MenuItem::with_id(app, "kill_steam", "关闭Steam", true, None::<&str>)?; + + let launch_ww_i = &MenuItem::with_id(app, "launch_ww", "启动国际服", true, None::<&str>)?; + let launch_pw_i = &MenuItem::with_id(app, "launch_pw", "启动国服", true, None::<&str>)?; + + let power_plan_extreme = CheckMenuItem::with_id( + app, + "power_plan_extreme", + "卓越性能", + true, + false, + None::<&str>, + )?; + let power_plan_high = + CheckMenuItem::with_id(app, "power_plan_high", "高性能", true, false, None::<&str>)?; + let power_plan_balanced = CheckMenuItem::with_id( + app, + "power_plan_balanced", + "平衡", + true, + false, + None::<&str>, + )?; + let power_plan_powersave = CheckMenuItem::with_id( + app, + "power_plan_powersave", + "节能", + true, + false, + None::<&str>, + )?; + + + let current_launch_option = MenuItem::with_id( + app, + "current_launch_option", + "启动项档位", + true, + None::<&str>, + )?; // 创建托盘菜单 let menu = Menu::with_items( app, &[ - &launch_ww_i, - &launch_pw_i, - &kill_game_i, - &kill_steam_i, - &show_i, - &quit_i, + &power_plan_extreme, + &power_plan_high, + &power_plan_balanced, + &power_plan_powersave, + separator, + ¤t_launch_option, + launch_ww_i, + launch_pw_i, + separator, + kill_game_i, + kill_steam_i, + separator, + show_i, + quit_i, ], )?; + let _ = app.listen("tray://get_powerplan", move |event| { + if let Ok(payload) = event.payload().parse::() { + match payload { + x if x == PowerPlanMode::Other as i32 => { + let _ = power_plan_powersave.set_checked(false); + let _ = power_plan_balanced.set_checked(false); + let _ = power_plan_high.set_checked(false); + let _ = power_plan_extreme.set_checked(false); + } + x if x == PowerPlanMode::PowerSaving as i32 => { + let _ = power_plan_powersave.set_checked(true); + let _ = power_plan_balanced.set_checked(false); + let _ = power_plan_high.set_checked(false); + let _ = power_plan_extreme.set_checked(false); + } + x if x == PowerPlanMode::Balanced as i32 => { + let _ = power_plan_powersave.set_checked(false); + let _ = power_plan_balanced.set_checked(true); + let _ = power_plan_high.set_checked(false); + let _ = power_plan_extreme.set_checked(false); + } + x if x == PowerPlanMode::HighPerformance as i32 => { + let _ = power_plan_powersave.set_checked(false); + let _ = power_plan_balanced.set_checked(false); + let _ = power_plan_high.set_checked(true); + let _ = power_plan_extreme.set_checked(false); + } + x if x == PowerPlanMode::Extreme as i32 => { + let _ = power_plan_powersave.set_checked(false); + let _ = power_plan_balanced.set_checked(false); + let _ = power_plan_high.set_checked(false); + let _ = power_plan_extreme.set_checked(true); + } + _ => {} + } + } + }); + + let _ = app.listen("tray://get_current_launch_option", move |event| { + let payload = event.payload(); + if payload != "" { + let _ = current_launch_option.set_text("启动项档位 ".to_string() + payload); + } + }); + let _ = TrayIconBuilder::with_id("tray") .icon(app.default_window_icon().unwrap().clone()) .menu(&menu) @@ -52,7 +147,25 @@ pub fn create_tray(app: &tauri::AppHandle) -> tauri::Result<()> { "kill_steam" => { let _ = app.emit("tray://kill_steam", None::<()>); } - // Add more events here + "power_plan_extreme" => { + let _ = app.emit("tray://set_powerplan", PowerPlanMode::Extreme as i32); + // let _ = power_plan_extreme.set_checked(true); + } + "power_plan_high" => { + let _ = app.emit( + "tray://set_powerplan", + PowerPlanMode::HighPerformance as i32, + ); + // let _ = power_plan_high.set_checked(true); + } + "power_plan_balanced" => { + let _ = app.emit("tray://set_powerplan", PowerPlanMode::Balanced as i32); + // let _ = power_plan_balanced.set_checked(true); + } + "power_plan_powersave" => { + let _ = app.emit("tray://set_powerplan", PowerPlanMode::PowerSaving as i32); + // let _ = power_plan_powersave.set_checked(true); + } _ => {} }) .on_tray_icon_event(|tray, event| { @@ -73,68 +186,3 @@ pub fn create_tray(app: &tauri::AppHandle) -> tauri::Result<()> { Ok(()) } - -// Tray Menu -// let quit = CustomMenuItem::new("quit".to_string(), "Quit"); -// let hide = CustomMenuItem::new("hide".to_string(), "Hide"); -// let tray_menu = SystemTrayMenu::new() // insert the menu items here -// .add_item(hide) -// .add_item(quit); -// .add_native_item(SystemTrayMenuItem::Separator) -// let toggle = MenuItemBuilder::with_id("toggle", "Toggle").build(app)?; -// let menu = MenuBuilder::new(app).items(&[&toggle]).build()?; - -// Setup Tray -// let tray = tauri::tray::TrayIconBuilder::with_id("my-tray").build(app)?; -// let _ = TrayIconBuilder::new() -// .menu(&menu) -// .on_menu_event(move |_, event| { -// match event.id().as_ref() { -// "toggle" => { -// println!("toggle clicked"); -// } -// _ => (), -// } -// // match event { -// // SystemTrayEvent::LeftClick { position: _, size: _, .. } => { -// // let window = app.get_window("main").unwrap(); -// // window.show().unwrap(); -// // window.set_focus().unwrap(); - -// // // thread::sleep(Duration::from_millis(100)); -// // // window.set_always_on_top(false).unwrap(); -// // println!("system tray received a left click"); -// // } -// // SystemTrayEvent::RightClick { position: _, size: _, .. } => { -// // // let window = app.get_window("main").unwrap(); -// // // window.hide().unwrap(); -// // println!("system tray received a right click"); -// // } -// // SystemTrayEvent::DoubleClick { position: _, size: _, .. } => { -// // println!("system tray received a double click"); -// // } -// // SystemTrayEvent::MenuItemClick { id, .. } => -// // match id.as_str() { -// // "quit" => { -// // std::process::exit(0); -// // } -// // "hide" => { -// // let window = app.get_window("main").unwrap(); -// // window.hide().unwrap(); -// // } -// // _ => {} -// // } -// // _ => {} -// // } -// }) -// .on_tray_icon_event(|tray, event| { -// if event.click_type == ClickType::Left { -// let app = tray.app_handle(); -// if let Some(webview_window) = app.get_webview_window("main") { -// let _ = webview_window.show(); -// let _ = webview_window.set_focus(); -// } -// } -// }) -// .build(app) -// .unwrap(); diff --git a/src/app/layout.tsx b/src/app/layout.tsx index d06b567..f718222 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -9,6 +9,7 @@ import { useDebounce } from "ahooks" import { useEffect } from "react" import "./globals.css" import Providers from "./providers" +import { PowerPlans } from "@/components/cstb/PowerPlan" export default function RootLayout({ children }: { children: React.ReactNode }) { const steam = useSteamStore() @@ -35,6 +36,15 @@ export default function RootLayout({ children }: { children: React.ReactNode }) await invoke("kill_game") addToast({ title: "已关闭CS2" }) }) + + void listen("tray://set_powerplan", async (event) => { + if (typeof(event.payload) === "number" && event.payload <= 0 && event.payload > 4) return + await invoke("set_powerplan", { plan: event.payload }) + const current = await invoke("get_powerplan") + tool.setPowerPlan(current) + + addToast({ title: `电源计划已切换 → ${PowerPlans[current].title}` }) + }) }) // 检测steam路径和游戏路径是否有效 diff --git a/src/components/cstb/PowerPlan.tsx b/src/components/cstb/PowerPlan.tsx index 37beae7..867ab0a 100644 --- a/src/components/cstb/PowerPlan.tsx +++ b/src/components/cstb/PowerPlan.tsx @@ -7,7 +7,7 @@ import { Key } from "@react-types/shared" import { useToolStore } from "@/store/tool" import { useEffect } from "react" -const PowerPlans = [ +export const PowerPlans = [ { id: "0", title: "其他", diff --git a/src/components/window/SideBar.tsx b/src/components/window/SideBar.tsx index db26bc6..bd22caa 100644 --- a/src/components/window/SideBar.tsx +++ b/src/components/window/SideBar.tsx @@ -55,7 +55,7 @@ const Avatar = () => { avatar { const SideBar = () => { const app = useAppStore() - void getVersion().then((Value) => { - app.setVersion(Value) - }) + if (typeof window !== "undefined") + void getVersion().then((Value) => { + app.setVersion(Value) + }) return (
{ } const launchStore = new LazyStore('cstb.json', { autoSave: true }); -void launchStore.save() +if (typeof window !== 'undefined') void launchStore.save() const setVersion = (version: string) => { appStore.state.version = version diff --git a/src/store/tool.ts b/src/store/tool.ts index aa8f03e..1c385ce 100644 --- a/src/store/tool.ts +++ b/src/store/tool.ts @@ -1,6 +1,8 @@ import { store } from "@tauri-store/valtio" import { useSnapshot } from "valtio" import { DEFAULT_STORE_CONFIG } from "./config" +import { emit } from "@tauri-apps/api/event" +import { send } from "process" interface LaunchOption { option: string @@ -50,6 +52,13 @@ export const useToolStore = () => { void toolStore.start const state = useSnapshot(toolStore.state) + if (typeof window !== 'undefined') { + setTimeout(() => { + sendCurrentLaunchOptionToTray(state.launchIndex) + sendPowerPlanToTray(state.powerPlan) + }, 500) + } + return { state, store: toolStore, @@ -77,10 +86,18 @@ const setLaunchOptions = (options: LaunchOption[]) => { const setLaunchIndex = (index: number) => { toolStore.state.launchIndex = index + sendCurrentLaunchOptionToTray(index) } +const sendCurrentLaunchOptionToTray = (index: number) => { + emit("tray://get_current_launch_option", toolStore.state.launchOptions[index].name || index + 1) +} const setPowerPlan = (plan: number) => { toolStore.state.powerPlan = plan + sendPowerPlanToTray(plan) +} +const sendPowerPlanToTray = (plan: number) => { + emit("tray://get_powerplan", plan) } const setVideoSetting = (setting: VideoSetting) => {