Skip to content

Commit 901f70b

Browse files
committed
keyboard navigation for waiting room
1 parent 37bc26b commit 901f70b

1 file changed

Lines changed: 62 additions & 26 deletions

File tree

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

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,7 @@ const formatPrivacySignalList = (
9393
const TakeoverPrompt: React.FC = () => {
9494
const theme = useTheme()
9595
const [pending, setPending] = useState(false)
96-
const [takeoverHover, setTakeoverHover] = useState(false)
97-
const [exitHover, setExitHover] = useState(false)
96+
const [focusedIndex, setFocusedIndex] = useState(0) // 0 = Take over, 1 = Exit
9897

9998
const handleTakeover = useCallback(() => {
10099
if (pending) return
@@ -108,41 +107,79 @@ const TakeoverPrompt: React.FC = () => {
108107
const name = key.name ?? ''
109108
const isConfirm = name === 'return' || name === 'enter'
110109
const isExit = name === 'escape' || name === 'esc'
111-
if (!isConfirm && !isExit) return
112-
key.preventDefault?.()
113-
if (isConfirm) {
114-
handleTakeover()
115-
} else {
110+
const isTab = name === 'tab'
111+
const isShiftTab = key.shift === true && isTab
112+
const isRight = name === 'right'
113+
const isLeft = name === 'left'
114+
115+
if (isExit) {
116+
key.preventDefault?.()
116117
exitFreebuffCleanly()
118+
return
119+
}
120+
121+
if (isConfirm) {
122+
key.preventDefault?.()
123+
if (focusedIndex === 0) {
124+
handleTakeover()
125+
} else {
126+
exitFreebuffCleanly()
127+
}
128+
return
129+
}
130+
131+
if (isRight || isTab) {
132+
key.preventDefault?.()
133+
setFocusedIndex((prev) => (prev + 1) % 2)
134+
return
135+
}
136+
137+
if (isLeft || isShiftTab) {
138+
key.preventDefault?.()
139+
setFocusedIndex((prev) => (prev - 1 + 2) % 2)
140+
return
117141
}
118142
},
119-
[handleTakeover],
143+
[focusedIndex, handleTakeover],
120144
),
121145
)
122146

147+
const isTakeoverFocused = focusedIndex === 0
148+
const isExitFocused = focusedIndex === 1
149+
123150
return (
124-
<>
151+
<box
152+
style={{
153+
flexDirection: 'column',
154+
alignItems: 'center',
155+
gap: 1,
156+
width: '100%',
157+
}}
158+
>
125159
<text
126-
style={{ fg: theme.foreground, marginBottom: 1 }}
160+
style={{ fg: theme.foreground }}
127161
attributes={TextAttributes.BOLD}
128162
>
129163
Freebuff is already running
130164
</text>
131-
<text style={{ fg: theme.muted, wrapMode: 'word' }}>
132-
Only one freebuff instance can run at a time. Take over the other
133-
instance here, or exit and keep using the one already running.
165+
166+
<text style={{ fg: theme.muted }}>
167+
Only one freebuff instance is allowed at a time.
134168
</text>
169+
135170
<box style={{ flexDirection: 'row', gap: 2, marginTop: 1 }}>
136171
<Button
137172
onClick={handleTakeover}
138-
onMouseOver={() => setTakeoverHover(true)}
139-
onMouseOut={() => setTakeoverHover(false)}
173+
onMouseOver={() => setFocusedIndex(0)}
140174
style={{ paddingLeft: 1, paddingRight: 1 }}
175+
border={['top', 'bottom', 'left', 'right']}
176+
borderStyle="single"
177+
borderColor={theme.primary}
141178
>
142179
<text
143180
style={{
144-
fg: takeoverHover ? theme.background : theme.foreground,
145-
bg: takeoverHover ? theme.primary : undefined,
181+
fg: isTakeoverFocused ? theme.background : theme.foreground,
182+
bg: isTakeoverFocused ? theme.primary : undefined,
146183
}}
147184
attributes={TextAttributes.BOLD}
148185
>
@@ -151,22 +188,21 @@ const TakeoverPrompt: React.FC = () => {
151188
</Button>
152189
<Button
153190
onClick={exitFreebuffCleanly}
154-
onMouseOver={() => setExitHover(true)}
155-
onMouseOut={() => setExitHover(false)}
191+
onMouseOver={() => setFocusedIndex(1)}
156192
style={{ paddingLeft: 1, paddingRight: 1 }}
193+
border={['top', 'bottom', 'left', 'right']}
194+
borderStyle="single"
195+
borderColor={isExitFocused ? theme.foreground : theme.muted}
157196
>
158197
<text
159-
style={{ fg: exitHover ? theme.foreground : theme.muted }}
160-
attributes={exitHover ? TextAttributes.BOLD : TextAttributes.NONE}
198+
style={{ fg: isExitFocused ? theme.foreground : theme.muted }}
199+
attributes={isExitFocused ? TextAttributes.BOLD : TextAttributes.NONE}
161200
>
162201
Exit
163202
</text>
164203
</Button>
165204
</box>
166-
<text style={{ fg: theme.muted, marginTop: 1 }}>
167-
Enter takes over · Esc exits
168-
</text>
169-
</>
205+
</box>
170206
)
171207
}
172208

@@ -258,7 +294,7 @@ export const WaitingRoomScreen: React.FC<WaitingRoomScreenProps> = ({
258294
>
259295
<text
260296
style={{ fg: exitHover ? theme.foreground : theme.muted }}
261-
attributes={exitHover ? TextAttributes.BOLD : TextAttributes.NONE}
297+
attributes={TextAttributes.BOLD}
262298
>
263299
264300
</text>

0 commit comments

Comments
 (0)