Skip to content

Commit 11efda3

Browse files
authored
[feat]: show indicator for in progress chats in the sessions list (anomalyco#5417)
1 parent a5cb4e4 commit 11efda3

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Keybind } from "@/util/keybind"
88
import { useTheme } from "../context/theme"
99
import { useSDK } from "../context/sdk"
1010
import { DialogSessionRename } from "./dialog-session-rename"
11+
import "opentui-spinner/solid"
1112

1213
export function DialogSessionList() {
1314
const dialog = useDialog()
@@ -22,6 +23,8 @@ export function DialogSessionList() {
2223

2324
const currentSessionID = createMemo(() => (route.data.type === "session" ? route.data.sessionID : undefined))
2425

26+
const spinnerFrames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
27+
2528
const options = createMemo(() => {
2629
const today = new Date().toDateString()
2730
return sync.data.session
@@ -34,12 +37,15 @@ export function DialogSessionList() {
3437
category = "Today"
3538
}
3639
const isDeleting = toDelete() === x.id
40+
const status = sync.data.session_status[x.id]
41+
const isWorking = status?.type === "busy"
3742
return {
3843
title: isDeleting ? `Press ${deleteKeybind} again to confirm` : x.title,
3944
bg: isDeleting ? theme.error : undefined,
4045
value: x.id,
4146
category,
4247
footer: Locale.time(x.time.updated),
48+
gutter: isWorking ? <spinner frames={spinnerFrames} interval={80} color={theme.primary} /> : undefined,
4349
}
4450
})
4551
.slice(0, 150)

packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export interface DialogSelectOption<T = any> {
3636
category?: string
3737
disabled?: boolean
3838
bg?: RGBA
39+
gutter?: JSX.Element
3940
onSelect?: (ctx: DialogContext, trigger?: "prompt") => void
4041
}
4142

@@ -239,7 +240,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
239240
moveTo(index)
240241
}}
241242
backgroundColor={active() ? (option.bg ?? theme.primary) : RGBA.fromInts(0, 0, 0, 0)}
242-
paddingLeft={current() ? 1 : 3}
243+
paddingLeft={current() || option.gutter ? 1 : 3}
243244
paddingRight={3}
244245
gap={1}
245246
>
@@ -249,6 +250,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
249250
description={option.description !== category ? option.description : undefined}
250251
active={active()}
251252
current={current()}
253+
gutter={option.gutter}
252254
/>
253255
</box>
254256
)
@@ -282,6 +284,7 @@ function Option(props: {
282284
active?: boolean
283285
current?: boolean
284286
footer?: JSX.Element | string
287+
gutter?: JSX.Element
285288
onMouseOver?: () => void
286289
}) {
287290
const { theme } = useTheme()
@@ -294,6 +297,11 @@ function Option(props: {
294297
295298
</text>
296299
</Show>
300+
<Show when={!props.current && props.gutter}>
301+
<box flexShrink={0} marginRight={0.5}>
302+
{props.gutter}
303+
</box>
304+
</Show>
297305
<text
298306
flexGrow={1}
299307
fg={props.active ? fg : props.current ? theme.primary : theme.text}

0 commit comments

Comments
 (0)