diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 353c3efff..1152623be 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -22,6 +22,7 @@ default = [ "tauri/macos-private-api", "tauri/tray-icon", "tauri/test", + "tauri/custom-protocol" ] test-tauri = [ "tauri/wry", @@ -58,7 +59,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.9.34" tar = "0.4" -tauri-plugin-deep-link = "2" +tauri-plugin-deep-link = { version = "2.3.4" } tauri-plugin-dialog = "2.2.1" tauri-plugin-hardware = { path = "./plugins/tauri-plugin-hardware" } tauri-plugin-http = { version = "2", features = ["unsafe-headers"] } @@ -75,7 +76,7 @@ url = "2.5" uuid = { version = "1.7", features = ["v4"] } [dependencies.tauri] -version = "2.5.0" +version = "2.8.5" default-features = false features = ["protocol-asset", "macos-private-api", "test"] @@ -92,4 +93,4 @@ windows-sys = { version = "0.60.2", features = ["Win32_Storage_FileSystem"] } [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] tauri-plugin-updater = "2" once_cell = "1.18" -tauri-plugin-single-instance = { version = "2.0.0", features = ["deep-link"] } +tauri-plugin-single-instance = { version = "2.3.4", features = ["deep-link"] } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 59b1db5c0..185d259db 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -8,7 +8,8 @@ use core::{ }; use jan_utils::generate_app_token; use std::{collections::HashMap, sync::Arc}; -use tauri::{Manager, RunEvent}; +use tauri_plugin_deep_link::DeepLinkExt; +use tauri::{Emitter, Manager, RunEvent}; use tauri_plugin_llamacpp::cleanup_llama_processes; use tokio::sync::Mutex; @@ -22,6 +23,15 @@ pub fn run() { builder = builder.plugin(tauri_plugin_single_instance::init(|_app, argv, _cwd| { println!("a new app instance was opened with {argv:?} and the deep link event was already triggered"); // when defining deep link schemes at runtime, you must also check `argv` here + let arg = argv.iter().find(|arg| arg.starts_with("jan://")); + if let Some(deep_link) = arg { + println!("deep link: {deep_link}"); + // handle the deep link, e.g., emit an event to the webview + _app.app_handle().emit("deep-link", deep_link).unwrap(); + if let Some(window) = _app.app_handle().get_webview_window("main") { + let _ = window.set_focus(); + } + } })); } @@ -153,7 +163,6 @@ pub fn run() { #[cfg(any(windows, target_os = "linux"))] { - use tauri_plugin_deep_link::DeepLinkExt; app.deep_link().register_all()?; } setup_mcp(app); diff --git a/web-app/package.json b/web-app/package.json index 772c625d5..ef6cf6191 100644 --- a/web-app/package.json +++ b/web-app/package.json @@ -40,8 +40,8 @@ "@tanstack/react-router": "^1.116.0", "@tanstack/react-router-devtools": "^1.121.34", "@tanstack/react-virtual": "^3.13.12", - "@tauri-apps/api": "^2.5.0", - "@tauri-apps/plugin-deep-link": "~2", + "@tauri-apps/api": "^2.8.0", + "@tauri-apps/plugin-deep-link": "2.4.3", "@tauri-apps/plugin-dialog": "^2.2.1", "@tauri-apps/plugin-http": "^2.2.1", "@tauri-apps/plugin-opener": "^2.2.7", diff --git a/web-app/src/providers/DataProvider.tsx b/web-app/src/providers/DataProvider.tsx index a734cd39f..1f469fe76 100644 --- a/web-app/src/providers/DataProvider.tsx +++ b/web-app/src/providers/DataProvider.tsx @@ -13,6 +13,7 @@ import { useLocalApiServer } from '@/hooks/useLocalApiServer' import { useAppState } from '@/hooks/useAppState' import { AppEvent, events } from '@janhq/core' import { localStorageKey } from '@/constants/localStorage' +import { SystemEvent } from '@/types/events' export function DataProvider() { const { setProviders, selectedModel, selectedProvider, getProviderByName } = @@ -57,6 +58,18 @@ export function DataProvider() { }) serviceHub.deeplink().getCurrent().then(handleDeepLink) serviceHub.deeplink().onOpenUrl(handleDeepLink) + + // Listen for deep link events + let unsubscribe = () => {} + serviceHub.events().listen(SystemEvent.DEEP_LINK, (event) => { + const deep_link = event.payload as string + handleDeepLink([deep_link]) + }).then((unsub) => { + unsubscribe = unsub + }) + return () => { + unsubscribe() + } // eslint-disable-next-line react-hooks/exhaustive-deps }, [serviceHub]) diff --git a/web-app/src/types/events.ts b/web-app/src/types/events.ts index 7d1af3d27..d49c35cdf 100644 --- a/web-app/src/types/events.ts +++ b/web-app/src/types/events.ts @@ -2,4 +2,5 @@ export enum SystemEvent { MCP_UPDATE = 'mcp-update', KILL_SIDECAR = 'kill-sidecar', MCP_ERROR = 'mcp-error', + DEEP_LINK = 'deep-link', }