summaryrefslogtreecommitdiffhomepage
path: root/packages/app
diff options
context:
space:
mode:
authorBrendan Allan <[email protected]>2026-03-04 15:12:34 +0800
committerGitHub <[email protected]>2026-03-04 15:12:34 +0800
commit5cf235fa6cf7b4c890c68f8ff68a96fcae992abf (patch)
tree25fdfd8ce95ad048fb097822995dcf060e8d6d8b /packages/app
parente4f0825c56300286ec0aa82b1006e4006a17e1e1 (diff)
downloadopencode-5cf235fa6cf7b4c890c68f8ff68a96fcae992abf.tar.gz
opencode-5cf235fa6cf7b4c890c68f8ff68a96fcae992abf.zip
desktop: add electron version (#15663)
Diffstat (limited to 'packages/app')
-rw-r--r--packages/app/src/app.tsx11
-rw-r--r--packages/app/src/components/titlebar.tsx2
-rw-r--r--packages/app/src/pages/layout.tsx2
-rw-r--r--packages/app/src/utils/notification-click.test.ts37
-rw-r--r--packages/app/src/utils/notification-click.ts16
5 files changed, 38 insertions, 30 deletions
diff --git a/packages/app/src/app.tsx b/packages/app/src/app.tsx
index 4a25e8d94..52a1dac6a 100644
--- a/packages/app/src/app.tsx
+++ b/packages/app/src/app.tsx
@@ -7,8 +7,8 @@ import { MarkedProvider } from "@opencode-ai/ui/context/marked"
import { Font } from "@opencode-ai/ui/font"
import { ThemeProvider } from "@opencode-ai/ui/theme"
import { MetaProvider } from "@solidjs/meta"
-import { Navigate, Route, Router } from "@solidjs/router"
-import { ErrorBoundary, type JSX, lazy, type ParentProps, Show, Suspense } from "solid-js"
+import { BaseRouterProps, Navigate, Route, Router } from "@solidjs/router"
+import { Component, ErrorBoundary, type JSX, lazy, type ParentProps, Show, Suspense } from "solid-js"
import { CommandProvider } from "@/context/command"
import { CommentsProvider } from "@/context/comments"
import { FileProvider } from "@/context/file"
@@ -28,6 +28,7 @@ import { TerminalProvider } from "@/context/terminal"
import DirectoryLayout from "@/pages/directory-layout"
import Layout from "@/pages/layout"
import { ErrorPage } from "./pages/error"
+import { Dynamic } from "solid-js/web"
const Home = lazy(() => import("@/pages/home"))
const Session = lazy(() => import("@/pages/session"))
@@ -144,13 +145,15 @@ export function AppInterface(props: {
children?: JSX.Element
defaultServer: ServerConnection.Key
servers?: Array<ServerConnection.Any>
+ router?: Component<BaseRouterProps>
}) {
return (
<ServerProvider defaultServer={props.defaultServer} servers={props.servers}>
<ServerKey>
<GlobalSDKProvider>
<GlobalSyncProvider>
- <Router
+ <Dynamic
+ component={props.router ?? Router}
root={(routerProps) => <RouterRoot appChildren={props.children}>{routerProps.children}</RouterRoot>}
>
<Route path="/" component={HomeRoute} />
@@ -158,7 +161,7 @@ export function AppInterface(props: {
<Route path="/" component={SessionIndexRoute} />
<Route path="/session/:id?" component={SessionRoute} />
</Route>
- </Router>
+ </Dynamic>
</GlobalSyncProvider>
</GlobalSDKProvider>
</ServerKey>
diff --git a/packages/app/src/components/titlebar.tsx b/packages/app/src/components/titlebar.tsx
index 760f40fc0..c2b5a1ef4 100644
--- a/packages/app/src/components/titlebar.tsx
+++ b/packages/app/src/components/titlebar.tsx
@@ -157,6 +157,7 @@ export function Titlebar() {
<header
class="h-10 shrink-0 bg-background-base relative grid grid-cols-[auto_minmax(0,1fr)_auto] items-center"
style={{ "min-height": minHeight() }}
+ data-tauri-drag-region
onMouseDown={drag}
onDblClick={maximize}
>
@@ -276,6 +277,7 @@ export function Titlebar() {
"flex items-center min-w-0 justify-end": true,
"pr-2": !windows(),
}}
+ data-tauri-drag-region
onMouseDown={drag}
>
<div id="opencode-titlebar-right" class="flex items-center gap-1 shrink-0 justify-end" />
diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx
index daf2aaa5c..2fd2f2fe3 100644
--- a/packages/app/src/pages/layout.tsx
+++ b/packages/app/src/pages/layout.tsx
@@ -42,6 +42,7 @@ import { Binary } from "@opencode-ai/util/binary"
import { retry } from "@opencode-ai/util/retry"
import { playSound, soundSrc } from "@/utils/sound"
import { createAim } from "@/utils/aim"
+import { setNavigate } from "@/utils/notification-click"
import { Worktree as WorktreeState } from "@/utils/worktree"
import { useDialog } from "@opencode-ai/ui/context/dialog"
@@ -107,6 +108,7 @@ export default function Layout(props: ParentProps) {
const notification = useNotification()
const permission = usePermission()
const navigate = useNavigate()
+ setNavigate(navigate)
const providers = useProviders()
const dialog = useDialog()
const command = useCommand()
diff --git a/packages/app/src/utils/notification-click.test.ts b/packages/app/src/utils/notification-click.test.ts
index 76535f83a..fa81b0e02 100644
--- a/packages/app/src/utils/notification-click.test.ts
+++ b/packages/app/src/utils/notification-click.test.ts
@@ -1,26 +1,27 @@
-import { describe, expect, test } from "bun:test"
-import { handleNotificationClick } from "./notification-click"
+import { afterEach, describe, expect, test } from "bun:test"
+import { handleNotificationClick, setNavigate } from "./notification-click"
describe("notification click", () => {
- test("focuses and navigates when href exists", () => {
+ afterEach(() => {
+ setNavigate(undefined as any)
+ })
+
+ test("navigates via registered navigate function", () => {
const calls: string[] = []
- handleNotificationClick("/abc/session/123", {
- focus: () => calls.push("focus"),
- location: {
- assign: (href) => calls.push(href),
- },
- })
- expect(calls).toEqual(["focus", "/abc/session/123"])
+ setNavigate((href) => calls.push(href))
+ handleNotificationClick("/abc/session/123")
+ expect(calls).toEqual(["/abc/session/123"])
})
- test("only focuses when href is missing", () => {
+ test("does not navigate when href is missing", () => {
const calls: string[] = []
- handleNotificationClick(undefined, {
- focus: () => calls.push("focus"),
- location: {
- assign: (href) => calls.push(href),
- },
- })
- expect(calls).toEqual(["focus"])
+ setNavigate((href) => calls.push(href))
+ handleNotificationClick(undefined)
+ expect(calls).toEqual([])
+ })
+
+ test("falls back to location.assign without registered navigate", () => {
+ handleNotificationClick("/abc/session/123")
+ // falls back to window.location.assign — no error thrown
})
})
diff --git a/packages/app/src/utils/notification-click.ts b/packages/app/src/utils/notification-click.ts
index 1234cd1d6..94086c595 100644
--- a/packages/app/src/utils/notification-click.ts
+++ b/packages/app/src/utils/notification-click.ts
@@ -1,12 +1,12 @@
-type WindowTarget = {
- focus: () => void
- location: {
- assign: (href: string) => void
- }
+let nav: ((href: string) => void) | undefined
+
+export const setNavigate = (fn: (href: string) => void) => {
+ nav = fn
}
-export const handleNotificationClick = (href?: string, target: WindowTarget = window) => {
- target.focus()
+export const handleNotificationClick = (href?: string) => {
+ window.focus()
if (!href) return
- target.location.assign(href)
+ if (nav) nav(href)
+ else window.location.assign(href)
}