Skip to content

Commit 0c2d84e

Browse files
committed
Clean up wait list model UX
1 parent 5dc0215 commit 0c2d84e

2 files changed

Lines changed: 34 additions & 24 deletions

File tree

cli/src/components/freebuff-model-selector.tsx

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import { useTheme } from '../hooks/use-theme'
1313
import type { KeyEvent } from '@opentui/core'
1414

1515
/**
16-
* Lets the user pick which model's queue they're in. Tapping (or pressing the
17-
* row's number key) on a different model triggers a re-POST: the server moves
16+
* Lets the user pick which model's queue they're in. Tapping a different model
17+
* (or cycling to it via Tab / arrow keys) triggers a re-POST: the server moves
1818
* them to the back of the new model's queue.
1919
*
2020
* Each row shows a live "N ahead" count sourced from the server's
@@ -43,6 +43,19 @@ export const FreebuffModelSelector: React.FC = () => {
4343
return out
4444
}, [session])
4545

46+
// Pad the trailing hint ("3 ahead", "No wait", tagline) to a fixed width so
47+
// buttons don't visibly resize when the queue depth ticks down (12 → 9) or
48+
// when the user's selection moves between queues.
49+
const hintWidth = useMemo(
50+
() =>
51+
Math.max(
52+
'No wait'.length,
53+
'999 ahead'.length,
54+
...FREEBUFF_MODELS.map((m) => m.tagline.length),
55+
),
56+
[],
57+
)
58+
4659
const pick = useCallback(
4760
(modelId: string) => {
4861
if (pending) return
@@ -53,17 +66,23 @@ export const FreebuffModelSelector: React.FC = () => {
5366
[pending, selectedModel],
5467
)
5568

56-
// Number-key shortcuts (1-9) so keyboard-only users can switch without
57-
// hunting for a clickable region.
69+
// Tab / Shift+Tab and Left/Right arrow keys cycle through the model buttons.
70+
// Up/Down intentionally do nothing so they don't fight other vertical UI.
5871
useKeyboard(
5972
useCallback(
6073
(key: KeyEvent) => {
6174
if (pending) return
6275
const name = key.name ?? ''
63-
if (!/^[1-9]$/.test(name)) return
64-
const digit = Number(name)
65-
if (digit > FREEBUFF_MODELS.length) return
66-
const target = FREEBUFF_MODELS[digit - 1]
76+
const isForward = name === 'right' || (name === 'tab' && !key.shift)
77+
const isBackward = name === 'left' || (name === 'tab' && key.shift)
78+
if (!isForward && !isBackward) return
79+
const currentIdx = FREEBUFF_MODELS.findIndex((m) => m.id === selectedModel)
80+
if (currentIdx === -1) return
81+
const len = FREEBUFF_MODELS.length
82+
const nextIdx = isForward
83+
? (currentIdx + 1) % len
84+
: (currentIdx - 1 + len) % len
85+
const target = FREEBUFF_MODELS[nextIdx]
6786
if (target && target.id !== selectedModel) {
6887
key.preventDefault?.()
6988
pick(target.id)
@@ -81,18 +100,14 @@ export const FreebuffModelSelector: React.FC = () => {
81100
gap: 0,
82101
}}
83102
>
84-
<text style={{ fg: theme.muted, marginBottom: 1 }}>
85-
Model — tap or press 1-{FREEBUFF_MODELS.length} to switch
86-
</text>
87103
<box
88104
style={{
89105
flexDirection: 'row',
90106
gap: 2,
91107
}}
92108
>
93-
{FREEBUFF_MODELS.map((model, idx) => {
109+
{FREEBUFF_MODELS.map((model) => {
94110
const isSelected = model.id === selectedModel
95-
const isPending = pending === model.id
96111
const isHovered = hoveredId === model.id
97112
const indicator = isSelected ? '●' : '○'
98113
const indicatorColor = isSelected ? theme.primary : theme.muted
@@ -128,16 +143,13 @@ export const FreebuffModelSelector: React.FC = () => {
128143
>
129144
<text>
130145
<span fg={indicatorColor}>{indicator} </span>
131-
<span fg={theme.muted}>{idx + 1}. </span>
132146
<span
133147
fg={labelColor}
134148
attributes={isSelected ? TextAttributes.BOLD : TextAttributes.NONE}
135149
>
136150
{model.displayName}
137151
</span>
138-
<span fg={theme.muted}> {hint}</span>
139-
{isPending && <span fg={theme.muted}> switching…</span>}
140-
152+
<span fg={theme.muted}> {hint.padEnd(hintWidth)}</span>
141153
</text>
142154
</Button>
143155
)

cli/src/components/waiting-room-screen.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,11 @@ export const WaitingRoomScreen: React.FC<WaitingRoomScreenProps> = ({
191191
</span>
192192
<span fg={theme.muted}> / {session.queueDepth}</span>
193193
</text>
194-
<text style={{ fg: theme.foreground, alignSelf: 'flex-start' }}>
195-
<span fg={theme.muted}>Wait </span>
196-
<span fg={theme.primary}>
197-
{session.position === 1
198-
? 'any moment now'
199-
: formatWait(session.estimatedWaitMs)}
200-
</span>
194+
<text style={{ fg: theme.muted, alignSelf: 'flex-start' }}>
195+
<span>Wait </span>
196+
{session.position === 1
197+
? 'any moment now'
198+
: formatWait(session.estimatedWaitMs)}
201199
</text>
202200
<text style={{ fg: theme.muted, alignSelf: 'flex-start' }}>
203201
<span>Elapsed </span>

0 commit comments

Comments
 (0)