diff options
| author | Hegyi Áron Ferenc <[email protected]> | 2026-01-29 08:09:53 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-01-29 15:09:53 +0800 |
| commit | 2af326606c936380c303bf56506e3c8bed04b0eb (patch) | |
| tree | 2c1fe35b7f5f77f88869291168e01e7ab220b566 /packages/app/src | |
| parent | 7c0067d59d318bfd6ecd473c36a9e673a4f68ff9 (diff) | |
| download | opencode-2af326606c936380c303bf56506e3c8bed04b0eb.tar.gz opencode-2af326606c936380c303bf56506e3c8bed04b0eb.zip | |
feat(desktop): Add desktop deep link (#10072)
Co-authored-by: Brendan Allan <[email protected]>
Diffstat (limited to 'packages/app/src')
| -rw-r--r-- | packages/app/src/app.tsx | 2 | ||||
| -rw-r--r-- | packages/app/src/pages/layout.tsx | 40 |
2 files changed, 41 insertions, 1 deletions
diff --git a/packages/app/src/app.tsx b/packages/app/src/app.tsx index ba0d1e7aa..11fdb5743 100644 --- a/packages/app/src/app.tsx +++ b/packages/app/src/app.tsx @@ -43,7 +43,7 @@ function UiI18nBridge(props: ParentProps) { declare global { interface Window { - __OPENCODE__?: { updaterEnabled?: boolean; serverPassword?: string } + __OPENCODE__?: { updaterEnabled?: boolean; serverPassword?: string; deepLinks?: string[] } } } diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index afef14c84..73480e8f2 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -1136,6 +1136,46 @@ export default function Layout(props: ParentProps) { if (navigate) navigateToProject(directory) } + const deepLinkEvent = "opencode:deep-link" + + const parseDeepLink = (input: string) => { + if (!input.startsWith("opencode://")) return + const url = new URL(input) + if (url.hostname !== "open-project") return + const directory = url.searchParams.get("directory") + if (!directory) return + return directory + } + + const handleDeepLinks = (urls: string[]) => { + if (!server.isLocal()) return + for (const input of urls) { + const directory = parseDeepLink(input) + if (!directory) continue + openProject(directory) + } + } + + const drainDeepLinks = () => { + const pending = window.__OPENCODE__?.deepLinks ?? [] + if (pending.length === 0) return + if (window.__OPENCODE__) window.__OPENCODE__.deepLinks = [] + handleDeepLinks(pending) + } + + onMount(() => { + const handler = (event: Event) => { + const detail = (event as CustomEvent<{ urls: string[] }>).detail + const urls = detail?.urls ?? [] + if (urls.length === 0) return + handleDeepLinks(urls) + } + + drainDeepLinks() + window.addEventListener(deepLinkEvent, handler as EventListener) + onCleanup(() => window.removeEventListener(deepLinkEvent, handler as EventListener)) + }) + const displayName = (project: LocalProject) => project.name || getFilename(project.worktree) async function renameProject(project: LocalProject, next: string) { |
