mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-14 03:56:55 +03:00
feat(tui): copy session ID from tab menu (#50181)
Co-authored-by: kitlangton <7587245+kitlangton@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
c555559ac1
commit
58fcad77a8
@@ -23,6 +23,7 @@ import { Portal, useRenderer, useTerminalDimensions } from "@opentui/solid"
|
||||
import { useConfig } from "../config"
|
||||
import { useSessionTabs } from "../context/session-tabs"
|
||||
import { useData } from "../context/data"
|
||||
import { useClipboard } from "../context/clipboard"
|
||||
import { useTheme } from "../context/theme"
|
||||
import {
|
||||
adaptiveSessionTabLayout,
|
||||
@@ -44,6 +45,7 @@ import { SESSION_SIDEBAR_WIDTH, SESSION_TABS_COMPACT_BREAKPOINT } from "../ui/la
|
||||
import { projectName } from "../util/project"
|
||||
import { marqueeCycleWidth, marqueeOverflows, marqueeTextParts } from "../util/marquee"
|
||||
import { useDialog } from "../ui/dialog"
|
||||
import { useToast } from "../ui/toast"
|
||||
import { DialogSessionRename } from "./dialog-session-rename"
|
||||
import { Keymap } from "../context/keymap"
|
||||
import { registerOpencodeSpinner } from "./register-spinner"
|
||||
@@ -75,7 +77,7 @@ const FADE_WIDTH = 4
|
||||
const ADD_TAB_WIDTH = 3
|
||||
const MARQUEE_DELAY = 600
|
||||
const MARQUEE_INTERVAL = 80
|
||||
const CONTEXT_MENU_WIDTH = 16
|
||||
const CONTEXT_MENU_WIDTH = 20
|
||||
const MIDDLE_MOUSE_BUTTON = 1
|
||||
const RIGHT_MOUSE_BUTTON = 2
|
||||
const MOUSE_CLOSE_HOLD_MS = 5_000
|
||||
@@ -370,6 +372,8 @@ function TabContextMenu(props: { state: TabContextMenuState; tabs: SessionTabsCo
|
||||
const background = () => theme.background.raised.base
|
||||
const actionHovered = () => theme.background.raised.high
|
||||
const dialog = useDialog()
|
||||
const clipboard = useClipboard()
|
||||
const toast = useToast()
|
||||
onCleanup(Keymap.use().mode.push("menu"))
|
||||
Keymap.createLayer(() => ({
|
||||
mode: "menu",
|
||||
@@ -387,6 +391,14 @@ function TabContextMenu(props: { state: TabContextMenuState; tabs: SessionTabsCo
|
||||
run: () =>
|
||||
props.tabs.rename ? props.tabs.rename(sessionID) : DialogSessionRename.show(dialog, sessionID, title),
|
||||
},
|
||||
{
|
||||
title: "Copy session ID",
|
||||
run: () =>
|
||||
void clipboard
|
||||
.write(sessionID)
|
||||
.then(() => toast.show({ message: "Session ID copied to clipboard", variant: "info" }))
|
||||
.catch(toast.error),
|
||||
},
|
||||
{ title: "Close", run: () => props.tabs.close(sessionID) },
|
||||
]
|
||||
: []),
|
||||
|
||||
@@ -34,6 +34,7 @@ for (const orientation of ["horizontal", "vertical"] as const) {
|
||||
const [active, setActive] = createSignal("second")
|
||||
const [newTab, setNewTab] = createSignal(false)
|
||||
const settings: Info = { tabs: { enabled: true } }
|
||||
const copied: string[] = []
|
||||
let config!: ReturnType<typeof useConfig>
|
||||
let theme!: ReturnType<typeof useTheme>
|
||||
function Colors() {
|
||||
@@ -61,7 +62,10 @@ for (const orientation of ["horizontal", "vertical"] as const) {
|
||||
} satisfies SessionTabsController
|
||||
const app = await testRender(
|
||||
() => (
|
||||
<TestTuiContexts paths={{ state: temporary.path }}>
|
||||
<TestTuiContexts
|
||||
paths={{ state: temporary.path }}
|
||||
clipboard={{ read: async () => undefined, write: async (text) => void copied.push(text) }}
|
||||
>
|
||||
<TuiAppProvider value={{ name: "test", version: "test", channel: "test" }}>
|
||||
<StorageProvider>
|
||||
<ConfigProvider
|
||||
@@ -202,10 +206,12 @@ for (const orientation of ["horizontal", "vertical"] as const) {
|
||||
await app.mockMouse.click(column, row, MouseButton.RIGHT)
|
||||
await app.waitForFrame((frame) => frame.includes("Rename"))
|
||||
expect(app.captureCharFrame().split("\n")[row + 1]!.indexOf("Rename")).toBe(column + 1)
|
||||
expect(app.captureCharFrame()).toContain("Copy session ID")
|
||||
expect(app.captureCharFrame()).toContain("Close")
|
||||
expect(app.captureCharFrame()).not.toContain("Keep open")
|
||||
expect(active()).toBe("second")
|
||||
app.mockInput.pressKey("c", { ctrl: true })
|
||||
await app.mockMouse.click(column + 1, row + 2)
|
||||
expect(copied).toEqual(["first"])
|
||||
await app.waitForFrame((frame) => !frame.includes("Rename"))
|
||||
|
||||
setNewTab(true)
|
||||
|
||||
Reference in New Issue
Block a user