Add prompt to make Stirling your default PDF app (#4890)

# Description of Changes
- Adds a reusable banner component/system to the core app
- Adds banner at the top of the desktop app if Stirling isn't your
default PDF editor, with a button to make it your default
- Adds a permanent button in the settings to do it manually (in case
you've dismissed the banner)
- Simplifies the file loading logic to fix a bug where the input file
could be duplicated occasionally. Now, the TS just receives files from
one buffer, regardless of how they've been passed to the app in Rust.

## Caveats
I've only been able to get the setting of default apps working properly
on Mac. The Windows build isn't signed (yet) so we can't use the proper
API for it, so currently it just sends you to the Settings UI. I've also
not been able to test it on Linux at all.
This commit is contained in:
James Brunton
2025-11-17 16:05:33 +00:00
committed by GitHub
parent 28eb9baa02
commit a415c457e9
22 changed files with 759 additions and 139 deletions
+38 -7
View File
@@ -3,7 +3,16 @@ use tauri::{RunEvent, WindowEvent, Emitter, Manager};
mod utils;
mod commands;
use commands::{start_backend, check_backend_health, get_opened_files, clear_opened_files, cleanup_backend, add_opened_file};
use commands::{
start_backend,
check_backend_health,
get_opened_files,
clear_opened_files,
cleanup_backend,
add_opened_file,
is_default_pdf_handler,
set_as_default_pdf_handler,
};
use utils::{add_log, get_tauri_logs};
#[cfg_attr(mobile, tauri::mobile_entry_point)]
@@ -23,9 +32,6 @@ pub fn run() {
// Store file for later retrieval (in case frontend isn't ready yet)
add_opened_file(arg.clone());
// Also emit event for immediate handling if frontend is ready
let _ = app.emit("file-opened", arg.clone());
// Bring the existing window to front
if let Some(window) = app.get_webview_window("main") {
let _ = window.set_focus();
@@ -33,13 +39,34 @@ pub fn run() {
}
}
}
// Emit a generic notification that files were added (frontend will re-read storage)
let _ = app.emit("files-changed", ());
}))
.setup(|_app| {
add_log("🚀 Tauri app setup started".to_string());
// Process command line arguments on first launch
let args: Vec<String> = std::env::args().collect();
for arg in args.iter().skip(1) {
if std::path::Path::new(arg).exists() {
add_log(format!("📂 Initial file from command line: {}", arg));
add_opened_file(arg.clone());
}
}
add_log("🔍 DEBUG: Setup completed".to_string());
Ok(())
})
.invoke_handler(tauri::generate_handler![start_backend, check_backend_health, get_opened_files, clear_opened_files, get_tauri_logs])
.invoke_handler(tauri::generate_handler![
start_backend,
check_backend_health,
get_opened_files,
clear_opened_files,
get_tauri_logs,
is_default_pdf_handler,
set_as_default_pdf_handler,
])
.build(tauri::generate_context!())
.expect("error while building tauri application")
.run(|app_handle, event| {
@@ -58,6 +85,7 @@ pub fn run() {
#[cfg(target_os = "macos")]
RunEvent::Opened { urls } => {
add_log(format!("📂 Tauri file opened event: {:?}", urls));
let mut added_files = false;
for url in urls {
let url_str = url.as_str();
if url_str.starts_with("file://") {
@@ -65,11 +93,14 @@ pub fn run() {
if file_path.ends_with(".pdf") {
add_log(format!("📂 Processing opened PDF: {}", file_path));
add_opened_file(file_path.to_string());
// Use unified event name for consistency across platforms
let _ = app_handle.emit("file-opened", file_path.to_string());
added_files = true;
}
}
}
// Emit a generic notification that files were added (frontend will re-read storage)
if added_files {
let _ = app_handle.emit("files-changed", ());
}
}
_ => {
// Only log unhandled events in debug mode to reduce noise