@@ -69,6 +69,9 @@ type ACTION_SUSPENSE_PLAY_PAUSE = {
6969 type : 'SUSPENSE_PLAY_PAUSE' ,
7070 payload : 'toggle' | 'play' | 'pause' ,
7171} ;
72+ type ACTION_SUSPENSE_PLAY_TICK = {
73+ type : 'SUSPENSE_PLAY_TICK' ,
74+ } ;
7275
7376export type SuspenseTreeAction =
7477 | ACTION_SUSPENSE_TREE_MUTATION
@@ -77,7 +80,8 @@ export type SuspenseTreeAction =
7780 | ACTION_SET_SUSPENSE_TIMELINE
7881 | ACTION_SUSPENSE_SET_TIMELINE_INDEX
7982 | ACTION_SUSPENSE_SKIP_TIMELINE_INDEX
80- | ACTION_SUSPENSE_PLAY_PAUSE ;
83+ | ACTION_SUSPENSE_PLAY_PAUSE
84+ | ACTION_SUSPENSE_PLAY_TICK ;
8185export type SuspenseTreeDispatch = ( action : SuspenseTreeAction ) => void ;
8286
8387const SuspenseTreeStateContext : ReactContext < SuspenseTreeState > =
@@ -369,6 +373,30 @@ function SuspenseTreeContextController({children}: Props): React.Node {
369373 playing : mode === 'toggle' ? ! state . playing : mode === 'play' ,
370374 } ;
371375 }
376+ case 'SUSPENSE_PLAY_TICK' : {
377+ if ( ! state . playing ) {
378+ // We stopped but haven't yet cleaned up the callback. Noop.
379+ return state ;
380+ }
381+ // Advance time
382+ const nextTimelineIndex = state . timelineIndex + 1 ;
383+ if ( nextTimelineIndex > state . timeline . length - 1 ) {
384+ return state ;
385+ }
386+ const nextSelectedSuspenseID = state . timeline [ nextTimelineIndex ] ;
387+ const nextLineage = store . getSuspenseLineage (
388+ nextSelectedSuspenseID ,
389+ ) ;
390+ // Stop once we reach the end.
391+ const nextPlaying = nextTimelineIndex < state . timeline . length - 1 ;
392+ return {
393+ ...state ,
394+ lineage : nextLineage ,
395+ selectedSuspenseID : nextSelectedSuspenseID ,
396+ timelineIndex : nextTimelineIndex ,
397+ playing : nextPlaying ,
398+ } ;
399+ }
372400 default :
373401 throw new Error ( `Unrecognized action "${ action . type } "` ) ;
374402 }
0 commit comments