tui: show queued status for user messages waiting for assistant response

This commit is contained in:
Dax Raad 2025-10-20 19:19:11 -04:00
parent 900a19556c
commit 0a111cf915
2 changed files with 23 additions and 3 deletions

View file

@ -50,6 +50,7 @@ for (const [os, arch] of targets) {
conditions: ["browser"],
tsconfig: "./tsconfig.json",
plugins: [solidPlugin],
sourcemap: true,
compile: {
target: `bun-${os}-${arch}` as any,
outfile: `dist/${name}/bin/opencode`,

View file

@ -65,6 +65,11 @@ export function Session() {
const session = createMemo(() => sync.session.get(route.sessionID)!)
const messages = createMemo(() => sync.data.message[route.sessionID] ?? [])
const permissions = createMemo(() => sync.data.permission[route.sessionID] ?? [])
const pending = createMemo(() => {
return messages().findLast((x) => x.role === "assistant" && !x.time?.completed)?.id
})
const dimensions = useTerminalDimensions()
const [sidebar, setSidebar] = createSignal<"show" | "hide" | "auto">("auto")
@ -466,6 +471,7 @@ export function Session() {
}
message={message as UserMessage}
parts={sync.data.part[message.id] ?? []}
pending={pending()}
/>
</Match>
<Match when={message.role === "assistant"}>
@ -509,11 +515,19 @@ const MIME_BADGE: Record<string, string> = {
"application/x-directory": "dir",
}
function UserMessage(props: { message: UserMessage; parts: Part[]; onMouseUp: () => void; index: number }) {
function UserMessage(props: {
message: UserMessage
parts: Part[]
onMouseUp: () => void
index: number
pending?: string
}) {
const text = createMemo(() => props.parts.flatMap((x) => (x.type === "text" && !x.synthetic ? [x] : []))[0])
const files = createMemo(() => props.parts.flatMap((x) => (x.type === "file" ? [x] : [])))
const sync = useSync()
const [hover, setHover] = createSignal(false)
const queued = createMemo(() => props.pending && props.message.id > props.pending)
const color = createMemo(() => (queued() ? Theme.accent : Theme.secondary))
return (
<Show when={text()}>
@ -533,7 +547,7 @@ function UserMessage(props: { message: UserMessage; parts: Part[]; onMouseUp: ()
marginTop={props.index === 0 ? 0 : 1}
backgroundColor={hover() ? Theme.backgroundElement : Theme.backgroundPanel}
customBorderChars={SplitBorder.customBorderChars}
borderColor={Theme.secondary}
borderColor={color()}
flexShrink={0}
>
<text>{text()?.text}</text>
@ -558,7 +572,12 @@ function UserMessage(props: { message: UserMessage; parts: Part[]; onMouseUp: ()
</Show>
<text>
{sync.data.config.username ?? "You"}{" "}
<span style={{ fg: Theme.textMuted }}>({Locale.time(props.message.time.created)})</span>
<Show
when={queued()}
fallback={<span style={{ fg: Theme.textMuted }}>({Locale.time(props.message.time.created)})</span>}
>
<span style={{ bg: Theme.accent, fg: Theme.backgroundPanel, bold: true }}> QUEUED </span>
</Show>
</text>
</box>
</Show>