Skip to content

Commit d50b60e

Browse files
feat: wire up deeplink2 plugin with desktop app (#1886)
- Add tauri-plugin-deep-link dependency to deeplink2 plugin - Hook into tauri_plugin_deep_link to listen for deep link URLs - Parse deep link URLs and emit DeepLinkEvent - Wire up frontend to listen for DeepLinkEvent and navigate - Update notification route to handle key search param Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: yujonglee <[email protected]>
1 parent 247fed6 commit d50b60e

File tree

5 files changed

+60
-6
lines changed

5 files changed

+60
-6
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/desktop/src/routes/__root.tsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import {
77
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
88
import { lazy, useEffect } from "react";
99

10-
import type { DeepLink } from "@hypr/plugin-deeplink2";
10+
import {
11+
type DeepLink,
12+
events as deeplink2Events,
13+
} from "@hypr/plugin-deeplink2";
1114
import { events as windowsEvents } from "@hypr/plugin-windows";
1215

1316
import { AuthProvider } from "../auth";
@@ -41,7 +44,8 @@ const useNavigationEvents = () => {
4144
const navigate = useNavigate();
4245

4346
useEffect(() => {
44-
let unlisten: (() => void) | undefined;
47+
let unlistenNavigate: (() => void) | undefined;
48+
let unlistenDeepLink: (() => void) | undefined;
4549

4650
const webview = getCurrentWebviewWindow();
4751

@@ -51,11 +55,20 @@ const useNavigationEvents = () => {
5155
navigate({ to: payload.path, search: payload.search ?? undefined });
5256
})
5357
.then((fn) => {
54-
unlisten = fn;
58+
unlistenNavigate = fn;
59+
});
60+
61+
deeplink2Events.deepLinkEvent
62+
.listen(({ payload }) => {
63+
navigate({ to: payload.to, search: payload.search });
64+
})
65+
.then((fn) => {
66+
unlistenDeepLink = fn;
5567
});
5668

5769
return () => {
58-
unlisten?.();
70+
unlistenNavigate?.();
71+
unlistenDeepLink?.();
5972
};
6073
}, [navigate]);
6174
};
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
import { createFileRoute, redirect } from "@tanstack/react-router";
22

3+
import type { NotificationSearch } from "@hypr/plugin-deeplink2";
4+
35
export const Route = createFileRoute("/notification")({
4-
beforeLoad: async () => {
6+
validateSearch: (search): NotificationSearch => {
7+
return {
8+
key: (search as NotificationSearch).key ?? "",
9+
};
10+
},
11+
beforeLoad: async ({ search }) => {
12+
console.log("notification deeplink received", search);
513
throw redirect({ to: "/app/main" });
614
},
715
});

plugins/deeplink2/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ serde_yaml = { workspace = true }
1919

2020
[dependencies]
2121
tauri = { workspace = true, features = ["test"] }
22+
tauri-plugin-deep-link = { workspace = true }
2223
tauri-specta = { workspace = true, features = ["derive", "typescript"] }
2324

2425
serde = { workspace = true }
2526
specta = { workspace = true }
2627
strum = { workspace = true, features = ["derive"] }
2728

2829
thiserror = { workspace = true }
30+
tracing = { workspace = true }
2931
url = { workspace = true }

plugins/deeplink2/src/lib.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ mod types;
55
mod docs;
66

77
pub use error::{Error, Result};
8+
pub use types::{DeepLink, DeepLinkEvent};
9+
10+
use std::str::FromStr;
11+
12+
use tauri_plugin_deep_link::DeepLinkExt;
13+
use tauri_specta::Event;
814

915
const PLUGIN_NAME: &str = "deeplink2";
1016

@@ -22,7 +28,30 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
2228

2329
tauri::plugin::Builder::new(PLUGIN_NAME)
2430
.invoke_handler(specta_builder.invoke_handler())
25-
.setup(|_app, _api| Ok(()))
31+
.setup(|app, _api| {
32+
let app_handle = app.clone();
33+
34+
app.deep_link().on_open_url(move |event| {
35+
for url in event.urls() {
36+
let url_str = url.as_str();
37+
tracing::info!(url = url_str, "deeplink_received");
38+
39+
match DeepLink::from_str(url_str) {
40+
Ok(deep_link) => {
41+
tracing::info!(deep_link = ?deep_link, "deeplink_parsed");
42+
if let Err(e) = DeepLinkEvent(deep_link).emit(&app_handle) {
43+
tracing::error!(error = ?e, "deeplink_event_emit_failed");
44+
}
45+
}
46+
Err(e) => {
47+
tracing::warn!(error = ?e, url = url_str, "deeplink_parse_failed");
48+
}
49+
}
50+
}
51+
});
52+
53+
Ok(())
54+
})
2655
.build()
2756
}
2857

0 commit comments

Comments
 (0)