@@ -93,8 +93,7 @@ const formatPrivacySignalList = (
9393const 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