refactor: unify shortcut command routing

This commit is contained in:
lucaronin
2026-04-11 10:39:08 +02:00
parent c24f60c594
commit b1bc056afb
15 changed files with 793 additions and 297 deletions

View File

@@ -3,6 +3,7 @@ use crate::menu;
use crate::settings::Settings;
use crate::vault_list;
use crate::vault_list::VaultList;
use serde::Deserialize;
use super::parse_build_label;
@@ -41,23 +42,29 @@ pub async fn check_mcp_status() -> Result<crate::mcp::McpStatus, String> {
// ── Menu commands ───────────────────────────────────────────────────────────
#[cfg(desktop)]
#[tauri::command]
pub fn update_menu_state(
app_handle: tauri::AppHandle,
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MenuStateUpdate {
has_active_note: bool,
has_modified_files: Option<bool>,
has_conflicts: Option<bool>,
has_restorable_deleted_note: Option<bool>,
}
#[cfg(desktop)]
#[tauri::command]
pub fn update_menu_state(
app_handle: tauri::AppHandle,
state: MenuStateUpdate,
) -> Result<(), String> {
menu::set_note_items_enabled(&app_handle, has_active_note);
if let Some(v) = has_modified_files {
menu::set_note_items_enabled(&app_handle, state.has_active_note);
if let Some(v) = state.has_modified_files {
menu::set_git_commit_items_enabled(&app_handle, v);
}
if let Some(v) = has_conflicts {
if let Some(v) = state.has_conflicts {
menu::set_git_conflict_items_enabled(&app_handle, v);
}
if let Some(v) = has_restorable_deleted_note {
if let Some(v) = state.has_restorable_deleted_note {
menu::set_restore_deleted_item_enabled(&app_handle, v);
}
Ok(())
@@ -67,14 +74,23 @@ pub fn update_menu_state(
#[tauri::command]
pub fn update_menu_state(
_app_handle: tauri::AppHandle,
_has_active_note: bool,
_has_modified_files: Option<bool>,
_has_conflicts: Option<bool>,
_has_restorable_deleted_note: Option<bool>,
_state: MenuStateUpdate,
) -> Result<(), String> {
Ok(())
}
#[cfg(desktop)]
#[tauri::command]
pub fn trigger_menu_command(app_handle: tauri::AppHandle, id: String) -> Result<(), String> {
menu::emit_custom_menu_event(&app_handle, &id)
}
#[cfg(mobile)]
#[tauri::command]
pub fn trigger_menu_command(_app_handle: tauri::AppHandle, _id: String) -> Result<(), String> {
Err("Native menu commands are not available on mobile".into())
}
// ── Settings & config commands ──────────────────────────────────────────────
#[tauri::command]

View File

@@ -113,6 +113,77 @@ fn setup_app(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
fn with_invoke_handler(builder: tauri::Builder<tauri::Wry>) -> tauri::Builder<tauri::Wry> {
builder.invoke_handler(tauri::generate_handler![
commands::list_vault,
commands::list_vault_folders,
commands::get_note_content,
commands::save_note_content,
commands::update_frontmatter,
commands::delete_frontmatter_property,
commands::rename_note,
commands::rename_note_filename,
commands::auto_rename_untitled,
commands::detect_renames,
commands::update_wikilinks_for_renames,
commands::get_file_history,
commands::get_modified_files,
commands::get_file_diff,
commands::get_file_diff_at_commit,
commands::get_vault_pulse,
commands::git_commit,
commands::get_build_number,
commands::get_last_commit_info,
commands::git_pull,
commands::git_push,
commands::git_remote_status,
commands::get_conflict_files,
commands::get_conflict_mode,
commands::git_resolve_conflict,
commands::git_commit_conflict_resolution,
commands::git_discard_file,
commands::is_git_repo,
commands::init_git_repo,
commands::check_claude_cli,
commands::stream_claude_chat,
commands::stream_claude_agent,
commands::reload_vault,
commands::reload_vault_entry,
commands::sync_note_title,
commands::save_image,
commands::copy_image_to_vault,
commands::delete_note,
commands::batch_delete_notes,
commands::migrate_is_a_to_type,
commands::create_vault_folder,
commands::batch_archive_notes,
commands::get_settings,
commands::update_menu_state,
commands::trigger_menu_command,
commands::save_settings,
commands::load_vault_list,
commands::save_vault_list,
commands::github_list_repos,
commands::github_create_repo,
commands::clone_repo,
commands::github_device_flow_start,
commands::github_device_flow_poll,
commands::github_get_user,
commands::search_vault,
commands::create_empty_vault,
commands::create_getting_started_vault,
commands::check_vault_exists,
commands::get_default_vault_path,
commands::register_mcp_tools,
commands::check_mcp_status,
commands::repair_vault,
commands::reinit_telemetry,
commands::list_views,
commands::save_view_cmd,
commands::delete_view_cmd
])
}
#[cfg(desktop)]
fn handle_run_event(app_handle: &tauri::AppHandle, event: &tauri::RunEvent) {
use tauri::Manager;
@@ -134,75 +205,8 @@ pub fn run() {
#[cfg(desktop)]
let builder = builder.manage(WsBridgeChild(Mutex::new(None)));
builder
with_invoke_handler(builder)
.setup(setup_app)
.invoke_handler(tauri::generate_handler![
commands::list_vault,
commands::list_vault_folders,
commands::get_note_content,
commands::save_note_content,
commands::update_frontmatter,
commands::delete_frontmatter_property,
commands::rename_note,
commands::rename_note_filename,
commands::auto_rename_untitled,
commands::detect_renames,
commands::update_wikilinks_for_renames,
commands::get_file_history,
commands::get_modified_files,
commands::get_file_diff,
commands::get_file_diff_at_commit,
commands::get_vault_pulse,
commands::git_commit,
commands::get_build_number,
commands::get_last_commit_info,
commands::git_pull,
commands::git_push,
commands::git_remote_status,
commands::get_conflict_files,
commands::get_conflict_mode,
commands::git_resolve_conflict,
commands::git_commit_conflict_resolution,
commands::git_discard_file,
commands::is_git_repo,
commands::init_git_repo,
commands::check_claude_cli,
commands::stream_claude_chat,
commands::stream_claude_agent,
commands::reload_vault,
commands::reload_vault_entry,
commands::sync_note_title,
commands::save_image,
commands::copy_image_to_vault,
commands::delete_note,
commands::batch_delete_notes,
commands::migrate_is_a_to_type,
commands::create_vault_folder,
commands::batch_archive_notes,
commands::get_settings,
commands::update_menu_state,
commands::save_settings,
commands::load_vault_list,
commands::save_vault_list,
commands::github_list_repos,
commands::github_create_repo,
commands::clone_repo,
commands::github_device_flow_start,
commands::github_device_flow_poll,
commands::github_get_user,
commands::search_vault,
commands::create_empty_vault,
commands::create_getting_started_vault,
commands::check_vault_exists,
commands::get_default_vault_path,
commands::register_mcp_tools,
commands::check_mcp_status,
commands::repair_vault,
commands::reinit_telemetry,
commands::list_views,
commands::save_view_cmd,
commands::delete_view_cmd
])
.build(tauri::generate_context!())
.expect("error while building tauri application")
.run(|app_handle, event| {

View File

@@ -78,6 +78,7 @@ const CUSTOM_IDS: &[&str] = &[
GO_ALL_NOTES,
GO_ARCHIVED,
GO_CHANGES,
GO_INBOX,
NOTE_TOGGLE_ORGANIZED,
NOTE_ARCHIVE,
NOTE_DELETE,
@@ -213,6 +214,7 @@ fn build_view_menu(app: &App) -> MenuResult {
.build(app)?;
let toggle_properties = MenuItemBuilder::new("Toggle Properties Panel")
.id(VIEW_TOGGLE_PROPERTIES)
.accelerator("CmdOrCtrl+Shift+I")
.build(app)?;
let command_palette = MenuItemBuilder::new("Command Palette")
.id(VIEW_COMMAND_PALETTE)
@@ -404,14 +406,21 @@ pub fn setup_menu(app: &App) -> Result<(), Box<dyn std::error::Error>> {
app.on_menu_event(|app_handle, event| {
let id = event.id().0.as_str();
if CUSTOM_IDS.contains(&id) {
let _ = app_handle.emit("menu-event", id);
}
let _ = emit_custom_menu_event(app_handle, id);
});
Ok(())
}
pub fn emit_custom_menu_event(app_handle: &AppHandle, id: &str) -> Result<(), String> {
if !CUSTOM_IDS.contains(&id) {
return Err(format!("Unknown custom menu event: {id}"));
}
app_handle
.emit("menu-event", id)
.map_err(|err| format!("Failed to emit menu-event {id}: {err}"))
}
fn set_items_enabled(app_handle: &AppHandle, ids: &[&str], enabled: bool) {
let Some(menu) = app_handle.menu() else {
return;