Skip to content

Commit

Permalink
feat: add accelerators for some tray menu items (#1580)
Browse files Browse the repository at this point in the history
  • Loading branch information
WhiteDG committed Jun 3, 2024
1 parent 448b275 commit 0718940
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 35 deletions.
4 changes: 4 additions & 0 deletions src-tauri/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ use serde::{Deserialize, Serialize};

use crate::APP_HANDLE;

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, specta::Type, tauri_specta::Event)]
pub struct ConfigUpdatedEvent;

#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum ProxyProtocol {
HTTP,
Expand Down Expand Up @@ -33,6 +36,7 @@ pub struct ProxyConfig {
#[serde(rename_all = "camelCase")]
pub struct Config {
pub hotkey: Option<String>,
pub display_window_hotkey: Option<String>,
pub ocr_hotkey: Option<String>,
pub writing_hotkey: Option<String>,
pub writing_newline_hotkey: Option<String>,
Expand Down
24 changes: 21 additions & 3 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ use get_selected_text::get_selected_text;
use parking_lot::Mutex;
use serde_json::json;
use std::env;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::{AtomicBool, Ordering};
use sysinfo::{CpuExt, System, SystemExt};
use tauri_plugin_aptabase::EventTracker;
use tauri_plugin_autostart::MacosLauncher;
use tauri_plugin_updater::UpdaterExt;
use tauri_specta::Event;
use tray::{PinnedFromTrayEvent, PinnedFromWindowEvent};
use windows::{get_translator_window, CheckUpdateEvent, CheckUpdateResultEvent};

use crate::config::{clear_config_cache, get_config_content};
use crate::config::{clear_config_cache, get_config_content, ConfigUpdatedEvent};
use crate::fetch::fetch_stream;
use crate::lang::detect_lang;
use crate::ocr::{cut_image, finish_ocr, screenshot, start_ocr};
Expand Down Expand Up @@ -308,7 +310,10 @@ fn main() {
])
.events(tauri_specta::collect_events![
CheckUpdateEvent,
CheckUpdateResultEvent
CheckUpdateResultEvent,
PinnedFromWindowEvent,
PinnedFromTrayEvent,
ConfigUpdatedEvent
])
.config(specta::ts::ExportConfig::default().formatter(specta::ts::formatter::prettier));

Expand Down Expand Up @@ -431,6 +436,19 @@ fn main() {
}
});
register_events(app);

let handle = app_handle.clone();
PinnedFromWindowEvent::listen_any(app_handle, move |event| {
let pinned = event.payload.pinned();
ALWAYS_ON_TOP.store(*pinned, Ordering::Release);
tray::create_tray(&handle).unwrap();
});

let handle = app_handle.clone();
ConfigUpdatedEvent::listen_any(app_handle, move |_event| {
clear_config_cache();
tray::create_tray(&handle).unwrap();
});
Ok(())
})
.invoke_handler(invoke_handler)
Expand Down
47 changes: 24 additions & 23 deletions src-tauri/src/tray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,33 @@ use crate::windows::{
use crate::{ALWAYS_ON_TOP, UPDATE_RESULT};

use serde::{Deserialize, Serialize};
use serde_json::json;
use tauri::{
menu::{Menu, MenuItem},
menu::{Menu, MenuItem, PredefinedMenuItem},
tray::ClickType,
Manager, Runtime,
};
use tauri_specta::Event;

#[derive(Debug, Serialize, Deserialize, Clone)]
pub(crate) struct PinnedEventPayload {
#[derive(Serialize, Deserialize, Debug, Clone, specta::Type, tauri_specta::Event)]
pub struct PinnedFromTrayEvent {
pinned: bool,
}

#[derive(Serialize, Deserialize, Debug, Clone, specta::Type, tauri_specta::Event)]
pub struct PinnedFromWindowEvent {
pinned: bool,
}

impl PinnedFromWindowEvent {
pub fn pinned(&self) -> &bool {
&self.pinned
}
}

pub static TRAY_EVENT_REGISTERED: AtomicBool = AtomicBool::new(false);

pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
let config = get_config().unwrap();
let mut ocr_text = String::from("OCR");
if let Some(ocr_hotkey) = config.ocr_hotkey {
ocr_text = format!("OCR ({})", ocr_hotkey);
}
let check_for_updates_i = MenuItem::with_id(
app,
"check_for_updates",
Expand All @@ -41,15 +48,16 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
.set_text("💡 New version available!")
.unwrap();
}
let settings_i = MenuItem::with_id(app, "settings", "Settings", true, None::<String>)?;
let ocr_i = MenuItem::with_id(app, "ocr", ocr_text, true, None::<String>)?;
let show_i = MenuItem::with_id(app, "show", "Show", true, None::<String>)?;
let hide_i = MenuItem::with_id(app, "hide", "Hide", true, None::<String>)?;
let settings_i = MenuItem::with_id(app, "settings", "Settings", true, Some("CmdOrCtrl+,"))?;
let ocr_i = MenuItem::with_id(app, "ocr", "OCR", true, config.ocr_hotkey)?;
let show_i = MenuItem::with_id(app, "show", "Show", true, config.display_window_hotkey)?;
let hide_i = PredefinedMenuItem::hide(app, Some("Hide"))?;
let pin_i = MenuItem::with_id(app, "pin", "Pin", true, None::<String>)?;
if ALWAYS_ON_TOP.load(Ordering::Acquire) {
pin_i.set_text("Unpin").unwrap();
}
let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<String>)?;
let quit_i = PredefinedMenuItem::quit(app, Some("Quit"))?;
let separator_i = PredefinedMenuItem::separator(app)?;
let menu = Menu::with_items(
app,
&[
Expand All @@ -59,6 +67,7 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
&show_i,
&hide_i,
&pin_i,
&separator_i,
&quit_i,
],
)?;
Expand Down Expand Up @@ -92,9 +101,8 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
"pin" => {
let pinned = set_translator_window_always_on_top();
let handle = app.app_handle();
handle
.emit("pinned-from-tray", json!({ "pinned": pinned }))
.unwrap_or_default();
let pinned_from_tray_event = PinnedFromTrayEvent { pinned };
pinned_from_tray_event.emit(handle).unwrap_or_default();
create_tray(app).unwrap();
}
"quit" => app.exit(0),
Expand All @@ -106,13 +114,6 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
}
});
tray.set_show_menu_on_left_click(false)?;
let app_handle = app.app_handle();
let app_handle_clone = app.app_handle().clone();
app_handle.listen_any("pinned-from-window", move |msg| {
let payload: PinnedEventPayload = serde_json::from_str(&msg.payload()).unwrap();
ALWAYS_ON_TOP.store(payload.pinned, Ordering::Release);
create_tray(&app_handle_clone).unwrap();
});

Ok(())
}
16 changes: 9 additions & 7 deletions src/common/hooks/usePinned.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useCallback, useEffect } from 'react'
import { isTauri } from '../utils'
import { useGlobalState } from './global'
import { listen, Event, emit } from '@tauri-apps/api/event'
import { events } from '@/tauri/bindings'

export function usePinned() {
const [pinned, setPinned_] = useGlobalState('pinned')
Expand All @@ -11,11 +11,13 @@ export function usePinned() {
return
}
let unlisten: () => void | undefined
listen('pinned-from-tray', (event: Event<{ pinned: boolean }>) => {
setPinned_(event.payload.pinned)
}).then((unlistenFn) => {
unlisten = unlistenFn
})
events.pinnedFromTrayEvent
.listen((event) => {
setPinned_(event.payload.pinned)
})
.then((unlistenFn) => {
unlisten = unlistenFn
})
return () => {
unlisten?.()
}
Expand All @@ -28,7 +30,7 @@ export function usePinned() {
if (!isTauri()) {
return next
}
emit('pinned-from-window', { pinned: next })
events.pinnedFromWindowEvent.emit({ pinned: next })
return next
})
},
Expand Down
9 changes: 9 additions & 0 deletions src/tauri/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,24 @@ export const commands = {
export const events = __makeEvents__<{
checkUpdateEvent: CheckUpdateEvent
checkUpdateResultEvent: CheckUpdateResultEvent
pinnedFromWindowEvent: PinnedFromWindowEvent
pinnedFromTrayEvent: PinnedFromTrayEvent
configUpdatedEvent: ConfigUpdatedEvent
}>({
checkUpdateEvent: 'check-update-event',
checkUpdateResultEvent: 'check-update-result-event',
pinnedFromWindowEvent: 'pinned-from-window-event',
pinnedFromTrayEvent: 'pinned-from-tray-event',
configUpdatedEvent: 'config-updated-event',
})

/** user-defined types **/

export type CheckUpdateEvent = null
export type CheckUpdateResultEvent = UpdateResult
export type ConfigUpdatedEvent = null
export type PinnedFromTrayEvent = { pinned: boolean }
export type PinnedFromWindowEvent = { pinned: boolean }
export type UpdateResult = { version: string; currentVersion: string; body: string | null }

/** tauri-specta globals **/
Expand Down
4 changes: 2 additions & 2 deletions src/tauri/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { isRegistered, register, unregister } from '@tauri-apps/plugin-global-shortcut'
import { getSettings } from '@/common/utils'
import { sendNotification } from '@tauri-apps/plugin-notification'
import { commands } from './bindings'
import { commands, events } from './bindings'
import { ISettings } from '@/common/types'

const modifierKeys = [
Expand Down Expand Up @@ -121,7 +121,7 @@ export async function bindWritingHotkey(oldWritingHotKey?: string) {
}

export function onSettingsSave(oldSettings: ISettings) {
commands.clearConfigCache()
events.configUpdatedEvent.emit()
bindHotkey(oldSettings.hotkey)
bindDisplayWindowHotkey(oldSettings.displayWindowHotkey)
bindOCRHotkey(oldSettings.ocrHotkey)
Expand Down

0 comments on commit 0718940

Please sign in to comment.