From 8f8f32c3a66e4020856bc487847fb3e41295d947 Mon Sep 17 00:00:00 2001 From: Manikandan Sundararajan <10191300+itsrainingmani@users.noreply.github.com> Date: Thu, 15 Jan 2026 06:27:12 -0500 Subject: [PATCH 1/6] feat(desktop): implement session unshare button --- .../src/components/session/session-header.tsx | 184 ++++++++++++++---- 1 file changed, 149 insertions(+), 35 deletions(-) diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx index 4b083771fb8..4982047ff66 100644 --- a/packages/app/src/components/session/session-header.tsx +++ b/packages/app/src/components/session/session-header.tsx @@ -1,15 +1,18 @@ -import { createMemo, createResource, Show } from "solid-js" +import { createEffect, createMemo, onCleanup, Show } from "solid-js" +import type { JSX } from "solid-js" +import { createStore } from "solid-js/store" import { Portal } from "solid-js/web" import { useParams } from "@solidjs/router" import { useLayout } from "@/context/layout" import { useCommand } from "@/context/command" // import { useServer } from "@/context/server" // import { useDialog } from "@opencode-ai/ui/context/dialog" +import { usePlatform } from "@/context/platform" import { useSync } from "@/context/sync" import { useGlobalSDK } from "@/context/global-sdk" import { getFilename } from "@opencode-ai/util/path" import { base64Decode } from "@opencode-ai/util/encode" -import { iife } from "@opencode-ai/util/iife" + import { Icon } from "@opencode-ai/ui/icon" import { IconButton } from "@opencode-ai/ui/icon-button" import { Button } from "@opencode-ai/ui/button" @@ -25,6 +28,7 @@ export function SessionHeader() { // const server = useServer() // const dialog = useDialog() const sync = useSync() + const platform = usePlatform() const projectDirectory = createMemo(() => base64Decode(params.dir ?? "")) const project = createMemo(() => { @@ -44,6 +48,79 @@ export function SessionHeader() { const sessionKey = createMemo(() => `${params.dir}${params.id ? "/" + params.id : ""}`) const view = createMemo(() => layout.view(sessionKey())) + const [state, setState] = createStore({ + share: false, + unshare: false, + copied: false, + timer: undefined as number | undefined, + }) + const shareUrl = () => currentSession()?.share?.url ?? "" + const shared = createMemo(() => !!shareUrl()) + + createEffect(() => { + const url = shareUrl() + if (url) return + if (state.timer) window.clearTimeout(state.timer) + setState({ copied: false, timer: undefined }) + }) + + onCleanup(() => { + if (state.timer) window.clearTimeout(state.timer) + }) + + function shareSession() { + const session = currentSession() + if (!session || state.share) return + setState("share", true) + globalSDK.client.session + .share({ sessionID: session.id, directory: projectDirectory() }) + .catch((error) => { + console.error("Failed to share session", error) + }) + .finally(() => { + setState("share", false) + }) + } + + function unshareSession() { + const session = currentSession() + if (!session || state.unshare) return + setState("unshare", true) + globalSDK.client.session + .unshare({ sessionID: session.id, directory: projectDirectory() }) + .catch((error) => { + console.error("Failed to unshare session", error) + }) + .finally(() => { + setState("unshare", false) + }) + } + + function copyLink() { + const url = shareUrl() + if (!url) return + navigator.clipboard + .writeText(url) + .then(() => { + if (state.timer) window.clearTimeout(state.timer) + setState("copied", true) + const timer = window.setTimeout(() => { + setState("copied", false) + setState("timer", undefined) + }, 3000) + setState("timer", timer) + }) + .catch((error) => { + console.error("Failed to copy share link", error) + }) + } + + function viewShare() { + const url = shareUrl() + if (!url) return + platform.openLink(url) + } + const centerMount = createMemo(() => document.getElementById("opencode-titlebar-center")) const rightMount = createMemo(() => document.getElementById("opencode-titlebar-right")) @@ -80,7 +157,7 @@ export function SessionHeader() { {(mount) => ( - +
{/* - - - - } - > - {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: projectDirectory() }) - .then((r) => r.data?.share?.url) - .catch((e) => { - console.error("Failed to share session", e) - return undefined - }) +
+ + + + } + > +
+ + +
} - return shareURL - }, - { initialValue: "" }, - ) - return ( - - {(shareUrl) => } + > +
+ +
+ + +
+
- ) - })} -
+
+
+ + + + + +
From b4edff01c1a345fd98e720bb5a8f1a4dd34eada0 Mon Sep 17 00:00:00 2001 From: Manikandan Sundararajan <10191300+itsrainingmani@users.noreply.github.com> Date: Thu, 15 Jan 2026 06:42:32 -0500 Subject: [PATCH 2/6] refactor: simplify share session state management - Move share state and functions to top level of SessionHeader - Remove iife wrapper and unused createEffect/iife imports --- packages/app/src/components/session/session-header.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx index 4982047ff66..1e9d521a609 100644 --- a/packages/app/src/components/session/session-header.tsx +++ b/packages/app/src/components/session/session-header.tsx @@ -1,5 +1,4 @@ import { createEffect, createMemo, onCleanup, Show } from "solid-js" -import type { JSX } from "solid-js" import { createStore } from "solid-js/store" import { Portal } from "solid-js/web" import { useParams } from "@solidjs/router" From db540f8f1051f4141d211c75da011cfe8cb2514d Mon Sep 17 00:00:00 2001 From: Manikandan Sundararajan <10191300+itsrainingmani@users.noreply.github.com> Date: Fri, 16 Jan 2026 19:09:17 -0500 Subject: [PATCH 3/6] implement updated design for share / unpublish --- packages/app/src/components/session/session-header.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx index 1e9d521a609..3903c596cca 100644 --- a/packages/app/src/components/session/session-header.tsx +++ b/packages/app/src/components/session/session-header.tsx @@ -156,7 +156,7 @@ export function SessionHeader() { {(mount) => ( - +
{/* - + Date: Fri, 16 Jan 2026 23:19:15 -0500 Subject: [PATCH 6/6] make Publish & View button sizing more consistent --- .../src/components/session/session-header.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx index 808f1bba376..a7f8a884731 100644 --- a/packages/app/src/components/session/session-header.tsx +++ b/packages/app/src/components/session/session-header.tsx @@ -266,7 +266,7 @@ export function SessionHeader() { -