@@ -6,23 +6,17 @@ import { AdBanner } from './ad-banner'
66import { Button } from './button'
77import { ChoiceAdBanner } from './choice-ad-banner'
88import { ShimmerText } from './shimmer-text'
9- import { endFreebuffSessionBestEffort } from '../hooks/use-freebuff-session'
109import { useGravityAd } from '../hooks/use-gravity-ad'
1110import { useLogo } from '../hooks/use-logo'
1211import { useSheenAnimation } from '../hooks/use-sheen-animation'
1312import { useTerminalDimensions } from '../hooks/use-terminal-dimensions'
1413import { useTheme } from '../hooks/use-theme'
15- import { flushAnalytics } from '../utils/analytics'
16- import { withTimeout } from '../utils/terminal-color-detection'
14+ import { exitFreebuffCleanly } from '../utils/freebuff-exit'
1715import { getLogoAccentColor , getLogoBlockColor } from '../utils/theme-system'
1816
1917import type { FreebuffSessionResponse } from '../types/freebuff-session'
2018import type { KeyEvent } from '@opentui/core'
2119
22- /** Cap on exit cleanup (DELETE /session + flushAnalytics) so a slow network
23- * doesn't block process exit. */
24- const EXIT_CLEANUP_TIMEOUT_MS = 1000
25-
2620interface WaitingRoomScreenProps {
2721 session : FreebuffSessionResponse | null
2822 error : string | null
@@ -82,30 +76,15 @@ export const WaitingRoomScreen: React.FC<WaitingRoomScreenProps> = ({
8276 forceStart : true ,
8377 } )
8478
85- // Release the seat + flush analytics before exit. Used by both Ctrl+C and
86- // the top-right X button so they always do the same cleanup.
87- const handleExit = useCallback ( ( ) => {
88- const cleanup = Promise . allSettled ( [
89- flushAnalytics ( ) ,
90- endFreebuffSessionBestEffort ( ) ,
91- ] )
92- withTimeout ( cleanup , EXIT_CLEANUP_TIMEOUT_MS , undefined ) . finally ( ( ) => {
93- process . exit ( 0 )
94- } )
95- } , [ ] )
96-
9779 // Ctrl+C exits. Stdin is in raw mode, so SIGINT never fires — the key comes
98- // through as a normal OpenTUI key event.
80+ // through as a normal OpenTUI key event. Shared with the top-right X button.
9981 useKeyboard (
100- useCallback (
101- ( key : KeyEvent ) => {
102- if ( key . ctrl && key . name === 'c' ) {
103- key . preventDefault ?.( )
104- handleExit ( )
105- }
106- } ,
107- [ handleExit ] ,
108- ) ,
82+ useCallback ( ( key : KeyEvent ) => {
83+ if ( key . ctrl && key . name === 'c' ) {
84+ key . preventDefault ?.( )
85+ exitFreebuffCleanly ( )
86+ }
87+ } , [ ] ) ,
10988 )
11089
11190 const [ exitHover , setExitHover ] = useState ( false )
@@ -148,7 +127,7 @@ export const WaitingRoomScreen: React.FC<WaitingRoomScreenProps> = ({
148127 } }
149128 >
150129 < Button
151- onClick = { handleExit }
130+ onClick = { exitFreebuffCleanly }
152131 onMouseOver = { ( ) => setExitHover ( true ) }
153132 onMouseOut = { ( ) => setExitHover ( false ) }
154133 style = { { paddingLeft : 1 , paddingRight : 1 } }
@@ -201,7 +180,9 @@ export const WaitingRoomScreen: React.FC<WaitingRoomScreenProps> = ({
201180 { isQueued && session && (
202181 < >
203182 < text style = { { fg : theme . foreground , marginBottom : 1 } } >
204- You're in the waiting room
183+ { session . position === 1
184+ ? "You're next in line"
185+ : "You're in the waiting room" }
205186 </ text >
206187
207188 < box
@@ -211,34 +192,25 @@ export const WaitingRoomScreen: React.FC<WaitingRoomScreenProps> = ({
211192 gap : 0 ,
212193 } }
213194 >
214- { session . position === 1 ? (
215- < >
216- < text style = { { fg : theme . primary , alignSelf : 'flex-start' } } >
217- < ShimmerText text = "Next in line" />
218- </ text >
219- < text style = { { fg : theme . muted , alignSelf : 'flex-start' } } >
220- { session . queueDepth === 1
221- ? 'just you in line right now'
222- : `${ session . queueDepth } people in line` }
223- </ text >
224- </ >
225- ) : (
226- < text style = { { fg : theme . foreground , alignSelf : 'flex-start' } } >
227- < span fg = { theme . muted } > Position </ span >
228- < span fg = { theme . primary } attributes = { TextAttributes . BOLD } >
229- { session . position }
230- </ span >
231- < span fg = { theme . muted } > / { session . queueDepth } </ span >
232- </ text >
233- ) }
234- { session . position !== 1 && (
235- < text style = { { fg : theme . foreground , alignSelf : 'flex-start' } } >
236- < span fg = { theme . muted } > Wait </ span >
237- < span fg = { theme . primary } >
238- < ShimmerText text = { formatWait ( session . estimatedWaitMs ) } />
239- </ span >
240- </ text >
241- ) }
195+ < text style = { { fg : theme . foreground , alignSelf : 'flex-start' } } >
196+ < span fg = { theme . muted } > Position </ span >
197+ < span fg = { theme . primary } attributes = { TextAttributes . BOLD } >
198+ { session . position }
199+ </ span >
200+ < span fg = { theme . muted } > / { session . queueDepth } </ span >
201+ </ text >
202+ < text style = { { fg : theme . foreground , alignSelf : 'flex-start' } } >
203+ < span fg = { theme . muted } > Wait </ span >
204+ < span fg = { theme . primary } >
205+ < ShimmerText
206+ text = {
207+ session . position === 1
208+ ? 'any moment now'
209+ : formatWait ( session . estimatedWaitMs )
210+ }
211+ />
212+ </ span >
213+ </ text >
242214 < text style = { { fg : theme . muted , alignSelf : 'flex-start' } } >
243215 < span > Elapsed </ span >
244216 { formatElapsed ( elapsedMs ) }
0 commit comments