summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/pages/session
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-02-10 10:12:17 -0600
committerAdam <[email protected]>2026-02-10 10:15:37 -0600
commit70c794e9139af1c1a2c43979d8f5e499a1587189 (patch)
tree72aedf7a8113d07fe803cf5678d7da683be2dc81 /packages/app/src/pages/session
parent3929f0b5bd5535fc601b8ce9092929af1adb6629 (diff)
downloadopencode-70c794e9139af1c1a2c43979d8f5e499a1587189.tar.gz
opencode-70c794e9139af1c1a2c43979d8f5e499a1587189.zip
fix(app): regressions
Diffstat (limited to 'packages/app/src/pages/session')
-rw-r--r--packages/app/src/pages/session/scroll-spy.ts1
-rw-r--r--packages/app/src/pages/session/terminal-panel.tsx2
-rw-r--r--packages/app/src/pages/session/use-session-commands.tsx97
3 files changed, 67 insertions, 33 deletions
diff --git a/packages/app/src/pages/session/scroll-spy.ts b/packages/app/src/pages/session/scroll-spy.ts
index 8c52d77dc..6ef4c844c 100644
--- a/packages/app/src/pages/session/scroll-spy.ts
+++ b/packages/app/src/pages/session/scroll-spy.ts
@@ -228,6 +228,7 @@ export const createScrollSpy = (input: Input) => {
node.delete(key)
visible.delete(key)
dirty = true
+ schedule()
}
const markDirty = () => {
diff --git a/packages/app/src/pages/session/terminal-panel.tsx b/packages/app/src/pages/session/terminal-panel.tsx
index 09095d689..2e65fde0e 100644
--- a/packages/app/src/pages/session/terminal-panel.tsx
+++ b/packages/app/src/pages/session/terminal-panel.tsx
@@ -41,7 +41,7 @@ export function TerminalPanel(props: {
direction="vertical"
size={props.height}
min={100}
- max={window.innerHeight * 0.6}
+ max={typeof window === "undefined" ? 1000 : window.innerHeight * 0.6}
collapseThreshold={50}
onResize={props.resize}
onCollapse={props.close}
diff --git a/packages/app/src/pages/session/use-session-commands.tsx b/packages/app/src/pages/session/use-session-commands.tsx
index 09c0fd17c..d52022d73 100644
--- a/packages/app/src/pages/session/use-session-commands.tsx
+++ b/packages/app/src/pages/session/use-session-commands.tsx
@@ -365,48 +365,81 @@ export const useSessionCommands = (input: {
return [
{
id: "session.share",
- title: input.info()?.share?.url ? "Copy share link" : input.language.t("command.session.share"),
+ title: input.info()?.share?.url
+ ? input.language.t("session.share.copy.copyLink")
+ : input.language.t("command.session.share"),
description: input.info()?.share?.url
- ? "Copy share URL to clipboard"
+ ? input.language.t("toast.session.share.success.description")
: input.language.t("command.session.share.description"),
category: input.language.t("command.category.session"),
slash: "share",
disabled: !input.params.id,
onSelect: async () => {
if (!input.params.id) return
- const copy = (url: string, existing: boolean) =>
- navigator.clipboard
- .writeText(url)
- .then(() =>
- showToast({
- title: existing
- ? input.language.t("session.share.copy.copied")
- : input.language.t("toast.session.share.success.title"),
- description: input.language.t("toast.session.share.success.description"),
- variant: "success",
- }),
- )
- .catch(() =>
- showToast({
- title: input.language.t("toast.session.share.copyFailed.title"),
- variant: "error",
- }),
- )
- const url = input.info()?.share?.url
- if (url) {
- await copy(url, true)
- return
+
+ const write = (value: string) => {
+ const body = typeof document === "undefined" ? undefined : document.body
+ if (body) {
+ const textarea = document.createElement("textarea")
+ textarea.value = value
+ textarea.setAttribute("readonly", "")
+ textarea.style.position = "fixed"
+ textarea.style.opacity = "0"
+ textarea.style.pointerEvents = "none"
+ body.appendChild(textarea)
+ textarea.select()
+ const copied = document.execCommand("copy")
+ body.removeChild(textarea)
+ if (copied) return Promise.resolve(true)
+ }
+
+ const clipboard = typeof navigator === "undefined" ? undefined : navigator.clipboard
+ if (!clipboard?.writeText) return Promise.resolve(false)
+ return clipboard.writeText(value).then(
+ () => true,
+ () => false,
+ )
}
- await input.sdk.client.session
- .share({ sessionID: input.params.id })
- .then((res) => copy(res.data!.share!.url, false))
- .catch(() =>
+
+ const copy = async (url: string, existing: boolean) => {
+ const ok = await write(url)
+ if (!ok) {
showToast({
- title: input.language.t("toast.session.share.failed.title"),
- description: input.language.t("toast.session.share.failed.description"),
+ title: input.language.t("toast.session.share.copyFailed.title"),
variant: "error",
- }),
- )
+ })
+ return
+ }
+
+ showToast({
+ title: existing
+ ? input.language.t("session.share.copy.copied")
+ : input.language.t("toast.session.share.success.title"),
+ description: input.language.t("toast.session.share.success.description"),
+ variant: "success",
+ })
+ }
+
+ const existing = input.info()?.share?.url
+ if (existing) {
+ await copy(existing, true)
+ return
+ }
+
+ const url = await input.sdk.client.session
+ .share({ sessionID: input.params.id })
+ .then((res) => res.data?.share?.url)
+ .catch(() => undefined)
+ if (!url) {
+ showToast({
+ title: input.language.t("toast.session.share.failed.title"),
+ description: input.language.t("toast.session.share.failed.description"),
+ variant: "error",
+ })
+ return
+ }
+
+ await copy(url, false)
},
},
{