diff --git a/apps/readest-app/src-tauri/src/lib.rs b/apps/readest-app/src-tauri/src/lib.rs index 1b12ecbf..b7acaccd 100644 --- a/apps/readest-app/src-tauri/src/lib.rs +++ b/apps/readest-app/src-tauri/src/lib.rs @@ -46,6 +46,30 @@ fn allow_file_in_scopes(app: &AppHandle, files: Vec) { } } +fn get_files_from_argv(argv: Vec) -> Vec { + let mut files = Vec::new(); + // NOTICE: `args` may include URL protocol (`your-app-protocol://`) + // or arguments (`--`) if your app supports them. + // files may also be passed as `file://path/to/file` + for (_, maybe_file) in argv.iter().enumerate().skip(1) { + // skip flags like -f or --flag + if maybe_file.starts_with("-") { + continue; + } + // handle `file://` path urls and skip other urls + if let Ok(url) = Url::parse(maybe_file) { + if let Ok(path) = url.to_file_path() { + files.push(path); + } else { + files.push(PathBuf::from(maybe_file)) + } + } else { + files.push(PathBuf::from(maybe_file)) + } + } + files +} + #[cfg(desktop)] fn set_window_open_with_files(app: &AppHandle, files: Vec) { let files = files @@ -127,6 +151,10 @@ pub fn run() { .get_webview_window("main") .expect("no main window") .set_focus(); + let files = get_files_from_argv(argv.clone()); + if !files.is_empty() { + allow_file_in_scopes(app, files.clone()); + } app.emit("single-instance", Payload { args: argv, cwd }) .unwrap(); })); @@ -155,26 +183,7 @@ pub fn run() { .setup(|#[allow(unused_variables)] app| { #[cfg(desktop)] { - let mut files = Vec::new(); - // NOTICE: `args` may include URL protocol (`your-app-protocol://`) - // or arguments (`--`) if your app supports them. - // files may also be passed as `file://path/to/file` - for maybe_file in std::env::args().skip(1) { - // skip flags like -f or --flag - if maybe_file.starts_with("-") { - continue; - } - // handle `file://` path urls and skip other urls - if let Ok(url) = Url::parse(&maybe_file) { - if let Ok(path) = url.to_file_path() { - files.push(path); - } else { - files.push(PathBuf::from(maybe_file)) - } - } else { - files.push(PathBuf::from(maybe_file)) - } - } + let files = get_files_from_argv(std::env::args().collect()); if !files.is_empty() { let app_handle = app.handle().clone(); allow_file_in_scopes(&app_handle, files.clone()); diff --git a/apps/readest-app/src/hooks/useOpenWithBooks.ts b/apps/readest-app/src/hooks/useOpenWithBooks.ts index dc4f8eb4..2f44c7d0 100644 --- a/apps/readest-app/src/hooks/useOpenWithBooks.ts +++ b/apps/readest-app/src/hooks/useOpenWithBooks.ts @@ -1,21 +1,28 @@ import { useEffect, useRef } from 'react'; import { useRouter } from 'next/navigation'; import { onOpenUrl } from '@tauri-apps/plugin-deep-link'; +import { getCurrentWindow } from '@tauri-apps/api/window'; import { isTauriAppPlatform } from '@/services/environment'; import { useLibraryStore } from '@/store/libraryStore'; import { navigateToLibrary } from '@/utils/nav'; +interface SingleInstancePayload { + args: string[]; + cwd: string; +} + export function useOpenWithBooks() { const router = useRouter(); const { setCheckOpenWithBooks } = useLibraryStore(); const listenedOpenWithBooks = useRef(false); const handleOpenWithFileUrl = (url: string) => { + console.log('Handle Open with URL:', url); let filePath = url; if (filePath.startsWith('file://')) { filePath = decodeURI(filePath.replace('file://', '')); } - if (filePath.startsWith('/')) { + if (!/^(https?:|data:|blob:)/i.test(filePath)) { window.OPEN_WITH_FILES = [filePath]; setCheckOpenWithBooks(true); navigateToLibrary(router, `reload=${Date.now()}`); @@ -27,6 +34,13 @@ export function useOpenWithBooks() { if (listenedOpenWithBooks.current) return; listenedOpenWithBooks.current = true; + const unlistenDeeplink = getCurrentWindow().listen('single-instance', ({ event, payload }) => { + console.log('Received deep link:', event, payload); + const { args } = payload as SingleInstancePayload; + if (args?.[1]) { + handleOpenWithFileUrl(args[1]); + } + }); const listenOpenWithFiles = async () => { return await onOpenUrl((urls) => { urls.forEach((url) => { @@ -34,10 +48,10 @@ export function useOpenWithBooks() { }); }); }; - - const unlisten = listenOpenWithFiles(); + const unlistenOpenUrl = listenOpenWithFiles(); return () => { - unlisten.then((f) => f()); + unlistenDeeplink.then((f) => f()); + unlistenOpenUrl.then((f) => f()); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []);