summaryrefslogtreecommitdiffhomepage
path: root/packages/desktop/src/components
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-12-17 03:47:44 -0600
committerAdam <[email protected]>2025-12-17 03:47:49 -0600
commit494e6fff019bb502fff88a07d6c519c063af9a02 (patch)
treecda9a1f68c013c7a542cbc4f82c7b7b63f9fa0a1 /packages/desktop/src/components
parent0c7a297b1d3d9cdf8a060c4ed75160152da2b981 (diff)
downloadopencode-494e6fff019bb502fff88a07d6c519c063af9a02.tar.gz
opencode-494e6fff019bb502fff88a07d6c519c063af9a02.zip
feat(desktop): share sessions
Diffstat (limited to 'packages/desktop/src/components')
-rw-r--r--packages/desktop/src/components/header.tsx36
1 files changed, 35 insertions, 1 deletions
diff --git a/packages/desktop/src/components/header.tsx b/packages/desktop/src/components/header.tsx
index cc4d01816..d70bfee24 100644
--- a/packages/desktop/src/components/header.tsx
+++ b/packages/desktop/src/components/header.tsx
@@ -1,27 +1,34 @@
import { useGlobalSync } from "@/context/global-sync"
+import { useGlobalSDK } from "@/context/global-sdk"
import { useLayout } from "@/context/layout"
import { Session } from "@opencode-ai/sdk/v2/client"
import { Button } from "@opencode-ai/ui/button"
import { Icon } from "@opencode-ai/ui/icon"
import { Mark } from "@opencode-ai/ui/logo"
+import { Popover } from "@opencode-ai/ui/popover"
import { Select } from "@opencode-ai/ui/select"
+import { TextField } from "@opencode-ai/ui/text-field"
import { Tooltip } from "@opencode-ai/ui/tooltip"
import { base64Decode } from "@opencode-ai/util/encode"
import { getFilename } from "@opencode-ai/util/path"
import { A, useParams } from "@solidjs/router"
-import { createMemo, Show } from "solid-js"
+import { createMemo, createResource, Show } from "solid-js"
+import { IconButton } from "@opencode-ai/ui/icon-button"
+import { iife } from "@opencode-ai/util/iife"
export function Header(props: {
navigateToProject: (directory: string) => void
navigateToSession: (session: Session | undefined) => void
}) {
const globalSync = useGlobalSync()
+ const globalSDK = useGlobalSDK()
const layout = useLayout()
const params = useParams()
const currentDirectory = createMemo(() => base64Decode(params.dir ?? ""))
const store = createMemo(() => globalSync.child(currentDirectory())[0])
const sessions = createMemo(() => store().session ?? [])
const currentSession = createMemo(() => sessions().find((s) => s.id === params.id))
+ const shareEnabled = createMemo(() => store().config.share !== "disabled")
return (
<header class="h-12 shrink-0 bg-background-base border-b border-border-weak-base flex" data-tauri-drag-region>
@@ -105,6 +112,33 @@ export function Header(props: {
</div>
</Button>
</Tooltip>
+ <Show when={shareEnabled() && currentSession()}>
+ <Popover
+ title="Share session"
+ trigger={
+ <Tooltip class="shrink-0" value="Share session">
+ <IconButton icon="share" variant="ghost" class="" />
+ </Tooltip>
+ }
+ >
+ {iife(() => {
+ const [url] = createResource(
+ () => currentSession(),
+ async (session) => {
+ if (!session) return
+ let shareURL = session.share?.url
+ if (!shareURL) {
+ shareURL = await globalSDK.client.session
+ .share({ sessionID: session.id, directory: currentDirectory() })
+ .then((r) => r.data?.share?.url)
+ }
+ return shareURL
+ },
+ )
+ return <Show when={url()}>{(url) => <TextField value={url()} readOnly copyable class="w-72" />}</Show>
+ })}
+ </Popover>
+ </Show>
</div>
</Show>
</div>