@@ -80,7 +80,14 @@ const findActionByTime = (steps: ListTreeItemType<Step>[], startTime: number, ti
8080 return null ;
8181} ;
8282
83- export function SnapshotsPlayer ( ) : ReactNode {
83+ const SnapshotsPlayerError = ( { text} : { text : string } ) : ReactNode => (
84+ < div className = { styles . snapshotMissingContainer } >
85+ < img src = { BrokenSnapshotIcon } alt = "icon" width = { 44 } height = { 44 } />
86+ < span > { text } </ span >
87+ </ div >
88+ ) ;
89+
90+ export function SnapshotsPlayer ( { isSnapshotBroken = false } : { isSnapshotBroken ?: boolean } ) : ReactNode {
8491 const currentResult = useSelector ( getCurrentResult ) ;
8592
8693 const [ playerElement , setPlayerElement ] = useState < HTMLDivElement | null > ( null ) ;
@@ -313,7 +320,7 @@ export function SnapshotsPlayer(): ReactNode {
313320 } ;
314321
315322 useEffect ( ( ) => {
316- if ( ! currentResult || ! playerElement ) {
323+ if ( ! currentResult || ! playerElement || isSnapshotBroken ) {
317324 return ;
318325 }
319326
@@ -375,7 +382,7 @@ export function SnapshotsPlayer(): ReactNode {
375382 abortControllerRef . current = null ;
376383 destroyPlayer ( ) ;
377384 } ;
378- } , [ currentResult , playerElement , startStreaming , initializePlayer , destroyPlayer , handleCustomEvent ] ) ;
385+ } , [ currentResult , playerElement , startStreaming , initializePlayer , destroyPlayer , handleCustomEvent , isSnapshotBroken ] ) ;
379386 const playerElementRef = useCallback ( ( node : HTMLDivElement | null ) => {
380387 if ( node !== null ) {
381388 setPlayerElement ( node ) ;
@@ -563,10 +570,11 @@ export function SnapshotsPlayer(): ReactNode {
563570 </ div >
564571
565572 { isSnapshotMissing && (
566- < div className = { styles . snapshotMissingContainer } >
567- < img src = { BrokenSnapshotIcon } alt = "icon" width = { 44 } height = { 44 } />
568- < span > Snapshot file is missing</ span >
569- </ div >
573+ < SnapshotsPlayerError text = "Snapshot file is missing" />
574+ ) }
575+
576+ { isSnapshotBroken && (
577+ < SnapshotsPlayerError text = "Snapshot file is broken" />
570578 ) }
571579
572580 { /* This container is for the player itself and matches size of the outer container */ }
@@ -576,51 +584,53 @@ export function SnapshotsPlayer(): ReactNode {
576584 </ div >
577585 </ div >
578586 </ div >
579- < div className = { styles . buttonsContainer } >
580- < Tooltip content = { < > { isPlaying ? 'Pause' : 'Play' } ⋅ < Hotkey value = "k" view = "light" /> </ > } placement = "top" openDelay = { 1000 } >
581- < Button
582- onClick = { onPlayClick }
583- view = { 'flat' }
584- className = { classNames ( styles . playPauseButton , styles . controlButton ) }
587+ { ! isSnapshotBroken && (
588+ < div className = { styles . buttonsContainer } >
589+ < Tooltip content = { < > { isPlaying ? 'Pause' : 'Play' } ⋅ < Hotkey value = "k" view = "light" /> </ > } placement = "top" openDelay = { 1000 } >
590+ < Button
591+ onClick = { onPlayClick }
592+ view = { 'flat' }
593+ className = { classNames ( styles . playPauseButton , styles . controlButton ) }
594+ disabled = { isSnapshotMissing }
595+ >
596+ < div
597+ className = { classNames ( styles . playPauseIcon , { [ styles . playPauseIconVisible ] : isPlaying } ) } >
598+ < Icon data = { PauseFill } size = { 14 } /> </ div >
599+ < div
600+ className = { classNames ( styles . playPauseIcon , { [ styles . playPauseIconVisible ] : ! isPlaying } ) } >
601+ < PlayIcon />
602+ </ div >
603+ </ Button >
604+ </ Tooltip >
605+ < Timeline
606+ currentTime = { currentPlayerTime }
607+ totalTime = { totalTime }
608+ onScrubStart = { onScrubStart }
609+ onScrub = { onScrub }
610+ onScrubEnd = { onScrubEnd }
611+ onHover = { onTimelineHover }
612+ onMouseLeave = { onTimelineMouseLeave }
613+ isLive = { isLive }
614+ isLoading = { isSnapshotZipLoading }
615+ downloadProgress = { snapshotZipDownloadProgress }
616+ isPlaying = { isPlaying }
617+ playerStartTimestamp = { playerStartTimestamp }
618+ highlightState = { currentPlayerHighlightState }
619+ isSnapshotMissing = { isSnapshotMissing }
620+ />
621+ < Select
622+ value = { [ playbackSpeed . toString ( ) ] }
585623 disabled = { isSnapshotMissing }
624+ renderControl = { renderSettingsControl }
625+ renderOptionGroup = { renderSettingsOptionGroup }
626+ popupPlacement = "top-end"
627+ popupWidth = { 100 }
628+ multiple = { true }
629+ onUpdate = { onSpeedChange }
630+ options = { SETTINGS_OPTIONS }
586631 >
587- < div
588- className = { classNames ( styles . playPauseIcon , { [ styles . playPauseIconVisible ] : isPlaying } ) } >
589- < Icon data = { PauseFill } size = { 14 } /> </ div >
590- < div
591- className = { classNames ( styles . playPauseIcon , { [ styles . playPauseIconVisible ] : ! isPlaying } ) } >
592- < PlayIcon />
593- </ div >
594- </ Button >
595- </ Tooltip >
596- < Timeline
597- currentTime = { currentPlayerTime }
598- totalTime = { totalTime }
599- onScrubStart = { onScrubStart }
600- onScrub = { onScrub }
601- onScrubEnd = { onScrubEnd }
602- onHover = { onTimelineHover }
603- onMouseLeave = { onTimelineMouseLeave }
604- isLive = { isLive }
605- isLoading = { isSnapshotZipLoading }
606- downloadProgress = { snapshotZipDownloadProgress }
607- isPlaying = { isPlaying }
608- playerStartTimestamp = { playerStartTimestamp }
609- highlightState = { currentPlayerHighlightState }
610- isSnapshotMissing = { isSnapshotMissing }
611- />
612- < Select
613- value = { [ playbackSpeed . toString ( ) ] }
614- disabled = { isSnapshotMissing }
615- renderControl = { renderSettingsControl }
616- renderOptionGroup = { renderSettingsOptionGroup }
617- popupPlacement = "top-end"
618- popupWidth = { 100 }
619- multiple = { true }
620- onUpdate = { onSpeedChange }
621- options = { SETTINGS_OPTIONS }
622- >
623- </ Select >
624- </ div >
632+ </ Select >
633+ </ div >
634+ ) }
625635 </ div > ;
626636}
0 commit comments