@@ -27,6 +27,7 @@ import { BoardController } from 'src/components/Board/BoardController'
27
27
import { PromotionOverlay } from 'src/components/Board/PromotionOverlay'
28
28
import { GameInfo } from 'src/components/Common/GameInfo'
29
29
import { AnalysisSidebar } from 'src/components/Analysis'
30
+ import { ConfigurableScreens } from 'src/components/Analysis/ConfigurableScreens'
30
31
import { MAIA_MODELS } from 'src/constants/common'
31
32
32
33
interface Props {
@@ -179,56 +180,6 @@ export const StreamAnalysis: React.FC<Props> = ({
179
180
// Check if we're using dummy game data (waiting for real game data)
180
181
const isWaitingForGameData = game . id === ''
181
182
182
- // Stream status component
183
- const StreamStatus = ( ) => (
184
- < div className = "mb-2 flex items-center justify-between rounded bg-background-1 px-4 py-2" >
185
- < div className = "flex items-center gap-2" >
186
- < div
187
- className = { `h-2 w-2 rounded-full ${
188
- streamState . isLive
189
- ? 'animate-pulse bg-red-500'
190
- : streamState . isConnected
191
- ? 'bg-green-500'
192
- : 'bg-gray-500'
193
- } `}
194
- />
195
- < span className = "text-sm font-medium" >
196
- { isWaitingForGameData && streamState . isConnected
197
- ? 'Waiting for game data...'
198
- : streamState . isLive
199
- ? 'LIVE'
200
- : streamState . isConnected
201
- ? 'Connected'
202
- : streamState . error
203
- ? 'Disconnected'
204
- : 'Connecting...' }
205
- </ span >
206
- { streamState . error && (
207
- < span className = "text-xs text-red-400" > ({ streamState . error } )</ span >
208
- ) }
209
- </ div >
210
- < div className = "flex items-center gap-2" >
211
- { streamState . error && (
212
- < button
213
- onClick = { onReconnect }
214
- className = "rounded bg-human-4 px-2 py-1 text-xs text-white transition hover:bg-human-4/80"
215
- >
216
- Reconnect
217
- </ button >
218
- ) }
219
- < button
220
- onClick = { ( ) => {
221
- onStopStream ( )
222
- router . push ( '/analysis' )
223
- } }
224
- className = "rounded bg-background-2 px-2 py-1 text-xs text-secondary transition hover:bg-background-3"
225
- >
226
- Exit Stream
227
- </ button >
228
- </ div >
229
- </ div >
230
- )
231
-
232
183
const NestedGameInfo = ( ) => (
233
184
< div className = "flex w-full flex-col" >
234
185
< div className = "hidden md:block" >
@@ -336,123 +287,137 @@ export const StreamAnalysis: React.FC<Props> = ({
336
287
exit = "exit"
337
288
style = { { willChange : 'transform, opacity' } }
338
289
>
339
- < div className = "flex h-full w-[90%] flex-col gap-2" >
340
- < StreamStatus />
341
- < div className = "flex h-full flex-row gap-2" >
342
- < motion . div
343
- id = "navigation"
344
- className = "desktop-left-column-container flex flex-col gap-2 overflow-hidden"
345
- variants = { itemVariants }
346
- style = { { willChange : 'transform, opacity' } }
290
+ < div className = "flex h-full w-[90%] flex-row gap-2" >
291
+ < motion . div
292
+ id = "navigation"
293
+ className = "desktop-left-column-container flex flex-col gap-2 overflow-hidden"
294
+ variants = { itemVariants }
295
+ style = { { willChange : 'transform, opacity' } }
296
+ >
297
+ < GameInfo
298
+ title = "Live Analysis"
299
+ icon = "live_tv"
300
+ type = "analysis"
301
+ streamState = { {
302
+ isLive : streamState . isLive ,
303
+ isConnected : streamState . isConnected ,
304
+ error : streamState . error ,
305
+ } }
347
306
>
348
- < GameInfo title = "Live Analysis" icon = "live_tv" type = "analysis" >
349
- < NestedGameInfo />
350
- </ GameInfo >
351
- < div className = "flex h-1/2 w-full flex-1 flex-col gap-2" >
352
- < div className = "flex h-full flex-col overflow-y-scroll" >
353
- < MovesContainer
354
- game = { game }
355
- termination = { game . termination }
356
- type = "analysis"
357
- showAnnotations = { true }
358
- disableKeyboardNavigation = { false }
359
- disableMoveClicking = { false }
360
- />
361
- < BoardController
362
- gameTree = { analysisController . gameTree }
363
- orientation = { analysisController . orientation }
364
- setOrientation = { analysisController . setOrientation }
365
- currentNode = { analysisController . currentNode }
366
- plyCount = { analysisController . plyCount }
367
- goToNode = { analysisController . goToNode }
368
- goToNextNode = { analysisController . goToNextNode }
369
- goToPreviousNode = { analysisController . goToPreviousNode }
370
- goToRootNode = { analysisController . goToRootNode }
371
- disableKeyboardNavigation = { false }
372
- disableNavigation = { false }
373
- />
374
- </ div >
307
+ < NestedGameInfo />
308
+ </ GameInfo >
309
+ < div className = "flex h-1/2 w-full flex-1 flex-col gap-2" >
310
+ < div className = "flex h-full flex-col overflow-y-scroll" >
311
+ < MovesContainer
312
+ game = { game }
313
+ termination = { game . termination }
314
+ type = "analysis"
315
+ showAnnotations = { true }
316
+ disableKeyboardNavigation = { false }
317
+ disableMoveClicking = { false }
318
+ />
319
+ < BoardController
320
+ gameTree = { analysisController . gameTree }
321
+ orientation = { analysisController . orientation }
322
+ setOrientation = { analysisController . setOrientation }
323
+ currentNode = { analysisController . currentNode }
324
+ plyCount = { analysisController . plyCount }
325
+ goToNode = { analysisController . goToNode }
326
+ goToNextNode = { analysisController . goToNextNode }
327
+ goToPreviousNode = { analysisController . goToPreviousNode }
328
+ goToRootNode = { analysisController . goToRootNode }
329
+ disableKeyboardNavigation = { false }
330
+ disableNavigation = { false }
331
+ />
375
332
</ div >
376
- </ motion . div >
377
- < motion . div
378
- className = "desktop-middle-column-container flex flex-col gap-2"
379
- variants = { itemVariants }
380
- style = { { willChange : 'transform, opacity' } }
381
- >
382
- < div className = "flex w-full flex-col overflow-hidden rounded" >
383
- < PlayerInfo
384
- name = {
385
- analysisController . orientation === 'white'
386
- ? game . blackPlayer . name
387
- : game . whitePlayer . name
388
- }
389
- rating = {
390
- analysisController . orientation === 'white'
391
- ? game . blackPlayer . rating
392
- : game . whitePlayer . rating
393
- }
394
- color = {
395
- analysisController . orientation === 'white' ? 'black' : 'white'
396
- }
397
- termination = { game . termination . winner }
333
+ </ div >
334
+ </ motion . div >
335
+ < motion . div
336
+ className = "desktop-middle-column-container flex flex-col gap-2"
337
+ variants = { itemVariants }
338
+ style = { { willChange : 'transform, opacity' } }
339
+ >
340
+ < div className = "flex w-full flex-col overflow-hidden rounded" >
341
+ < PlayerInfo
342
+ name = {
343
+ analysisController . orientation === 'white'
344
+ ? game . blackPlayer . name
345
+ : game . whitePlayer . name
346
+ }
347
+ rating = {
348
+ analysisController . orientation === 'white'
349
+ ? game . blackPlayer . rating
350
+ : game . whitePlayer . rating
351
+ }
352
+ color = {
353
+ analysisController . orientation === 'white' ? 'black' : 'white'
354
+ }
355
+ termination = { game . termination . winner }
356
+ />
357
+ < div className = "desktop-board-container relative flex aspect-square" >
358
+ < GameBoard
359
+ game = { game }
360
+ availableMoves = { analysisController . availableMoves }
361
+ setCurrentSquare = { setCurrentSquare }
362
+ shapes = { ( ( ) => {
363
+ const baseShapes = [ ...analysisController . arrows ]
364
+ if ( hoverArrow ) {
365
+ baseShapes . push ( hoverArrow )
366
+ }
367
+ return baseShapes
368
+ } ) ( ) }
369
+ currentNode = { analysisController . currentNode as GameNode }
370
+ orientation = { analysisController . orientation }
371
+ onPlayerMakeMove = { onPlayerMakeMove }
372
+ goToNode = { analysisController . goToNode }
373
+ gameTree = { game . tree }
398
374
/>
399
- < div className = "desktop-board-container relative flex aspect-square" >
400
- < GameBoard
401
- game = { game }
402
- availableMoves = { analysisController . availableMoves }
403
- setCurrentSquare = { setCurrentSquare }
404
- shapes = { ( ( ) => {
405
- const baseShapes = [ ...analysisController . arrows ]
406
- if ( hoverArrow ) {
407
- baseShapes . push ( hoverArrow )
408
- }
409
- return baseShapes
410
- } ) ( ) }
411
- currentNode = { analysisController . currentNode as GameNode }
412
- orientation = { analysisController . orientation }
413
- onPlayerMakeMove = { onPlayerMakeMove }
414
- goToNode = { analysisController . goToNode }
415
- gameTree = { game . tree }
375
+ { promotionFromTo ? (
376
+ < PromotionOverlay
377
+ player = { currentPlayer }
378
+ file = { promotionFromTo [ 1 ] . slice ( 0 , 1 ) }
379
+ onPlayerSelectPromotion = { onPlayerSelectPromotion }
416
380
/>
417
- { promotionFromTo ? (
418
- < PromotionOverlay
419
- player = { currentPlayer }
420
- file = { promotionFromTo [ 1 ] . slice ( 0 , 1 ) }
421
- onPlayerSelectPromotion = { onPlayerSelectPromotion }
422
- />
423
- ) : null }
424
- </ div >
425
- < PlayerInfo
426
- name = {
427
- analysisController . orientation === 'white'
428
- ? game . whitePlayer . name
429
- : game . blackPlayer . name
430
- }
431
- rating = {
432
- analysisController . orientation === 'white'
433
- ? game . whitePlayer . rating
434
- : game . blackPlayer . rating
435
- }
436
- color = {
437
- analysisController . orientation === 'white' ? 'white' : 'black'
438
- }
439
- termination = { game . termination . winner }
440
- showArrowLegend = { true }
441
- />
381
+ ) : null }
442
382
</ div >
443
- </ motion . div >
444
- < AnalysisSidebar
445
- hover = { hover }
446
- makeMove = { makeMove }
447
- controller = { analysisController }
448
- setHoverArrow = { setHoverArrow }
449
- analysisEnabled = { true }
450
- handleToggleAnalysis = { ( ) => {
451
- // Analysis toggle not needed for stream - always enabled
452
- } }
453
- itemVariants = { itemVariants }
383
+ < PlayerInfo
384
+ name = {
385
+ analysisController . orientation === 'white'
386
+ ? game . whitePlayer . name
387
+ : game . blackPlayer . name
388
+ }
389
+ rating = {
390
+ analysisController . orientation === 'white'
391
+ ? game . whitePlayer . rating
392
+ : game . blackPlayer . rating
393
+ }
394
+ color = {
395
+ analysisController . orientation === 'white' ? 'white' : 'black'
396
+ }
397
+ termination = { game . termination . winner }
398
+ showArrowLegend = { true }
399
+ />
400
+ </ div >
401
+ < ConfigurableScreens
402
+ currentMaiaModel = { analysisController . currentMaiaModel }
403
+ setCurrentMaiaModel = { analysisController . setCurrentMaiaModel }
404
+ launchContinue = { launchContinue }
405
+ MAIA_MODELS = { MAIA_MODELS }
406
+ game = { game }
407
+ currentNode = { analysisController . currentNode as GameNode }
454
408
/>
455
- </ div >
409
+ </ motion . div >
410
+ < AnalysisSidebar
411
+ hover = { hover }
412
+ makeMove = { makeMove }
413
+ controller = { analysisController }
414
+ setHoverArrow = { setHoverArrow }
415
+ analysisEnabled = { true }
416
+ handleToggleAnalysis = { ( ) => {
417
+ // Analysis toggle not needed for stream - always enabled
418
+ } }
419
+ itemVariants = { itemVariants }
420
+ />
456
421
</ div >
457
422
</ motion . div >
458
423
)
@@ -466,7 +431,6 @@ export const StreamAnalysis: React.FC<Props> = ({
466
431
style = { { willChange : 'transform, opacity' } }
467
432
>
468
433
< div className = "flex h-full flex-1 flex-col justify-center gap-1" >
469
- < StreamStatus />
470
434
< motion . div
471
435
className = "flex w-full flex-col items-start justify-start gap-1"
472
436
variants = { itemVariants }
@@ -479,6 +443,11 @@ export const StreamAnalysis: React.FC<Props> = ({
479
443
currentMaiaModel = { analysisController . currentMaiaModel }
480
444
setCurrentMaiaModel = { analysisController . setCurrentMaiaModel }
481
445
MAIA_MODELS = { MAIA_MODELS }
446
+ streamState = { {
447
+ isLive : streamState . isLive ,
448
+ isConnected : streamState . isConnected ,
449
+ error : streamState . error ,
450
+ } }
482
451
>
483
452
< NestedGameInfo />
484
453
</ GameInfo >
@@ -535,6 +504,14 @@ export const StreamAnalysis: React.FC<Props> = ({
535
504
/>
536
505
</ div >
537
506
</ div >
507
+ < ConfigurableScreens
508
+ currentMaiaModel = { analysisController . currentMaiaModel }
509
+ setCurrentMaiaModel = { analysisController . setCurrentMaiaModel }
510
+ launchContinue = { launchContinue }
511
+ MAIA_MODELS = { MAIA_MODELS }
512
+ game = { game }
513
+ currentNode = { analysisController . currentNode as GameNode }
514
+ />
538
515
</ motion . div >
539
516
</ div >
540
517
</ motion . div >
0 commit comments