//! Tauri 命令:剪贴板模块 use base64::engine::general_purpose::STANDARD; use base64::Engine as _; use serde::Serialize; use tauri::{AppHandle, State}; use super::manager::{ClipboardManager, ClipboardSettings}; use super::reader::dib_to_png; use super::storage::{ClipboardItem, ClipboardItemDetail}; #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct ClipboardStatus { pub running: bool, pub count: i64, } fn img_to_base64(b: &[u8]) -> Option { dib_to_png(b).map(|png| STANDARD.encode(&png)) } /// 历史查询结果(含总数,用于分页) #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct HistoryPage { pub items: Vec, pub total: i64, } #[tauri::command] pub async fn clipboard_get_history( limit: Option, offset: Option, kind: Option, manager: State<'_, ClipboardManager>, ) -> Result { let storage = manager.storage(); let kind = kind.unwrap_or_else(|| "all".into()); let limit = limit.unwrap_or(50); let offset = offset.unwrap_or(0); let items = storage.get_history(limit, offset, &kind); let total = storage.count_kind(&kind); Ok(HistoryPage { items, total }) } #[tauri::command] pub async fn clipboard_get_pinned( manager: State<'_, ClipboardManager>, ) -> Result, String> { Ok(manager.storage().get_pinned()) } #[tauri::command] pub async fn clipboard_search( query: String, limit: Option, offset: Option, manager: State<'_, ClipboardManager>, ) -> Result { let storage = manager.storage(); let limit = limit.unwrap_or(50); let offset = offset.unwrap_or(0); let items = storage.search(&query, limit, offset); let total = storage.count_search(&query); Ok(HistoryPage { items, total }) } #[tauri::command] pub async fn clipboard_get_item( id: i64, manager: State<'_, ClipboardManager>, ) -> Result, String> { Ok(manager.storage().get_detail(id, img_to_base64)) } #[tauri::command] pub async fn clipboard_set_pinned( id: i64, pinned: bool, manager: State<'_, ClipboardManager>, ) -> Result { Ok(manager.storage().set_pinned(id, pinned)) } #[tauri::command] pub async fn clipboard_delete( id: i64, manager: State<'_, ClipboardManager>, ) -> Result { Ok(manager.storage().delete(id)) } #[tauri::command] pub async fn clipboard_clear(manager: State<'_, ClipboardManager>) -> Result { Ok(manager.storage().clear_non_pinned()) } #[tauri::command] pub async fn clipboard_copy_back( id: i64, manager: State<'_, ClipboardManager>, ) -> Result<(), String> { manager.copy_back(id) } #[tauri::command] pub async fn clipboard_count(manager: State<'_, ClipboardManager>) -> Result { Ok(manager.storage().count()) } #[tauri::command] pub async fn clipboard_get_settings( manager: State<'_, ClipboardManager>, ) -> Result { Ok(manager.get_settings()) } #[tauri::command] pub async fn clipboard_save_settings( settings: ClipboardSettings, app: AppHandle, manager: State<'_, ClipboardManager>, ) -> Result<(), String> { let prev_enabled = manager.get_settings().enabled; let prev_shortcut = manager.get_settings().shortcut.clone(); manager.save_settings(settings.clone()); // 监听开关变化时联动启停 if settings.enabled && !prev_enabled { manager.start(&app); } else if !settings.enabled && prev_enabled { manager.stop(); } // 快捷键变化时重新注册 if settings.shortcut != prev_shortcut { super::popup::register_shortcut(&app, &settings.shortcut)?; } Ok(()) } #[tauri::command] pub async fn clipboard_status( manager: State<'_, ClipboardManager>, ) -> Result { Ok(ClipboardStatus { running: manager.is_running(), count: manager.storage().count(), }) } #[tauri::command] pub async fn clipboard_start(app: AppHandle, manager: State<'_, ClipboardManager>) -> Result<(), String> { manager.start(&app); Ok(()) } #[tauri::command] pub async fn clipboard_stop(manager: State<'_, ClipboardManager>) -> Result<(), String> { manager.stop(); Ok(()) } /// 注册(或切换)快捷弹窗全局快捷键 #[tauri::command] pub async fn clipboard_register_shortcut( shortcut: String, app: AppHandle, ) -> Result<(), String> { super::popup::register_shortcut(&app, &shortcut) } /// 注销快捷弹窗全局快捷键 #[tauri::command] pub async fn clipboard_unregister_shortcut(app: AppHandle) -> Result<(), String> { super::popup::unregister_shortcut(&app); Ok(()) } /// 手动触发显示快捷弹窗(供 UI 按钮调用) #[tauri::command] pub async fn clipboard_show_popup(app: AppHandle) -> Result<(), String> { super::popup::show_popup(&app); Ok(()) } /// 隐藏快捷弹窗 #[tauri::command] pub async fn clipboard_hide_popup(app: AppHandle) -> Result<(), String> { super::popup::hide_popup(&app); Ok(()) } /// 显示已创建的弹窗窗口(前端 onMounted 后调用) #[tauri::command] pub async fn clipboard_show_window(app: AppHandle) -> Result<(), String> { super::popup::show_window(&app); Ok(()) } /// 隐藏弹窗并模拟 Ctrl+V 粘贴到原窗口 #[tauri::command] pub async fn clipboard_paste_to_target(app: AppHandle) -> Result<(), String> { super::popup::paste_to_target(&app); Ok(()) }