From 901c6b63ad4b80be4a264da0b1456e76a9c4a2ef Mon Sep 17 00:00:00 2001 From: lars-berger Date: Wed, 27 Nov 2024 20:41:28 +0800 Subject: [PATCH] feat: add "Edit" system tray option for linking directly to widget config form (#163) --- Cargo.lock | 1 + packages/desktop/Cargo.toml | 1 + packages/desktop/src/sys_tray.rs | 57 ++++++++++++++++--- .../settings-ui/src/configs/WidgetConfigs.tsx | 18 +++++- packages/settings-ui/src/index.tsx | 7 ++- 5 files changed, 71 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ac7d230..0f35b253 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6811,6 +6811,7 @@ version = "0.0.0" dependencies = [ "anyhow", "async-trait", + "base64 0.22.1", "clap", "cocoa 0.25.0", "crossbeam", diff --git a/packages/desktop/Cargo.toml b/packages/desktop/Cargo.toml index 01e0197d..9a07c69a 100644 --- a/packages/desktop/Cargo.toml +++ b/packages/desktop/Cargo.toml @@ -15,6 +15,7 @@ tauri-build = { version = "2.0", features = [] } [dependencies] anyhow = "1" async-trait = "0.1" +base64 = "0.22" clap = { version = "4", features = ["derive"] } crossbeam = "0.8" reqwest = { version = "0.11", features = ["json"] } diff --git a/packages/desktop/src/sys_tray.rs b/packages/desktop/src/sys_tray.rs index d83d580b..5061a16e 100644 --- a/packages/desktop/src/sys_tray.rs +++ b/packages/desktop/src/sys_tray.rs @@ -1,6 +1,7 @@ use std::{collections::HashMap, path::PathBuf, str::FromStr, sync::Arc}; use anyhow::{bail, Context}; +use base64::prelude::*; use tauri::{ image::Image, menu::{CheckMenuItem, Menu, MenuBuilder, Submenu, SubmenuBuilder}, @@ -25,6 +26,9 @@ enum MenuEvent { ReloadConfigs, OpenSettings, Exit, + EditWidget { + path: PathBuf, + }, ToggleWidgetPreset { enable: bool, preset: String, @@ -44,6 +48,9 @@ impl ToString for MenuEvent { MenuEvent::ReloadConfigs => "reload_configs".to_string(), MenuEvent::OpenSettings => "open_settings".to_string(), MenuEvent::Exit => "exit".to_string(), + MenuEvent::EditWidget { path } => { + format!("edit_widget_{}", path.to_unicode_string()) + } MenuEvent::ToggleWidgetPreset { enable, preset, @@ -83,6 +90,9 @@ impl FromStr for MenuEvent { ["reload", "configs"] => Ok(Self::ReloadConfigs), ["open", "settings"] => Ok(Self::OpenSettings), ["exit"] => Ok(Self::Exit), + ["edit", "widget", path @ ..] => Ok(Self::EditWidget { + path: PathBuf::from(path.join("_")), + }), ["toggle", "widget", "config", enable @ ("true" | "false"), preset, path @ ..] => { Ok(Self::ToggleWidgetPreset { enable: *enable == "true", @@ -278,11 +288,16 @@ impl SysTray { .open_config_dir() .context("Failed to open config folder."), MenuEvent::ReloadConfigs => config.reload().await, - MenuEvent::OpenSettings => Self::open_settings_window(&app_handle), + MenuEvent::OpenSettings => { + Self::open_settings_window(&app_handle, None) + } MenuEvent::Exit => { app_handle.exit(0); Ok(()) } + MenuEvent::EditWidget { path } => { + Self::open_settings_window(&app_handle, Some(&path)) + } MenuEvent::ToggleWidgetPreset { enable, path, @@ -311,28 +326,50 @@ impl SysTray { }); } - fn open_settings_window(app_handle: &AppHandle) -> anyhow::Result<()> { + fn open_settings_window( + app_handle: &AppHandle, + config_path: Option<&PathBuf>, + ) -> anyhow::Result<()> { // Get existing settings window if it's already open. let settings_window = app_handle.get_webview_window("settings"); + let route = match config_path { + None => "/index.html".to_string(), + Some(path) => { + format!( + "/index.html#/widget/{}", + BASE64_STANDARD.encode(path.to_unicode_string()) + ) + } + }; + match &settings_window { None => { WebviewWindowBuilder::new( app_handle, "settings", - WebviewUrl::default(), + WebviewUrl::App(route.into()), ) .title("Settings - Zebar") .focused(true) + .visible(true) .inner_size(900., 600.) .build() .context("Failed to build the settings window.")?; Ok(()) } - Some(window) => window - .set_focus() - .context("Failed to focus the settings window."), + Some(window) => { + window + .eval(&format!("location.replace('{}')", route)) + .context("Failed to navigate to widget edit page.")?; + + window + .set_focus() + .context("Failed to focus the settings window.")?; + + Ok(()) + } } } @@ -379,7 +416,13 @@ impl SysTray { } }; - let mut presets_menu = SubmenuBuilder::new(&self.app_handle, label); + let mut presets_menu = SubmenuBuilder::new(&self.app_handle, label) + .text( + MenuEvent::EditWidget { + path: config_path.clone(), + }, + "Edit", + ); // Add each widget config to the menu. for preset in &widget_config.presets { diff --git a/packages/settings-ui/src/configs/WidgetConfigs.tsx b/packages/settings-ui/src/configs/WidgetConfigs.tsx index c8b617cf..780023cf 100644 --- a/packages/settings-ui/src/configs/WidgetConfigs.tsx +++ b/packages/settings-ui/src/configs/WidgetConfigs.tsx @@ -6,6 +6,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from '@glzr/components'; +import { useParams } from '@solidjs/router'; import { IconChevronDown } from '@tabler/icons-solidjs'; import { invoke } from '@tauri-apps/api/core'; import { listen, type Event } from '@tauri-apps/api/event'; @@ -24,6 +25,8 @@ import { WidgetConfigSidebar } from './WidgetConfigSidebar'; import { WidgetConfigForm } from './WidgetConfigForm'; export function WidgetConfigs() { + const params = useParams(); + const [configs, { mutate: mutateWidgetConfigs }] = createResource( async () => invoke>('widget_configs'), { initialValue: {} }, @@ -34,11 +37,9 @@ export function WidgetConfigs() { { initialValue: {} }, ); - createEffect(() => console.log('widgetStates', widgetStates())); - const [selectedConfigPath, setSelectedConfigPath] = createSignal< string | null - >(null); + >(params.path ? atob(params.path) : null); const [selectedPreset, setSelectedPreset] = createSignal( null, @@ -84,6 +85,17 @@ export function WidgetConfigs() { }); }); + // Update selected config path when params change. This occurs when + // "Edit" is selected from the system tray menu. + createEffect( + on( + () => params.path, + () => { + setSelectedConfigPath(params.path ? atob(params.path) : null); + }, + ), + ); + // Select the first config alphabetically on initial load. createEffect( on( diff --git a/packages/settings-ui/src/index.tsx b/packages/settings-ui/src/index.tsx index df03f6e3..f8bac784 100644 --- a/packages/settings-ui/src/index.tsx +++ b/packages/settings-ui/src/index.tsx @@ -1,15 +1,16 @@ /* @refresh reload */ import './index.css'; -import { Route, Router } from '@solidjs/router'; +import { HashRouter, Route } from '@solidjs/router'; import { render } from 'solid-js/web'; import { WidgetConfigs } from './configs/WidgetConfigs'; render( () => ( - + - + + ), document.getElementById('root')!, );