@@ -60,36 +60,38 @@ export const SegmentListComponent = (props: SegmentListComponentProps) => {
6060
6161 const segmentsWithNesting = React . useMemo ( ( ) => {
6262 const result : SegmentWithNesting [ ] = [ ] ;
63- let nbTrailingNonChapters = 0 ;
64- function nestChapters ( segments : SegmentWithNesting [ ] , seg : SponsorTime , topLevel ?: boolean ) {
65- if ( seg . actionType === ActionType . Chapter && segments . length ) {
66- // trailing non-chapters can only exist at top level
67- const lastElement = segments [ segments . length - ( topLevel ? nbTrailingNonChapters + 1 : 1 ) ]
68-
69- if ( lastElement . actionType === ActionType . Chapter
70- && lastElement . segment [ 0 ] <= seg . segment [ 0 ]
71- && lastElement . segment [ 1 ] >= seg . segment [ 1 ] ) {
72- if ( lastElement . innerChapters ) {
73- nestChapters ( lastElement . innerChapters , seg ) ;
74- } else {
75- lastElement . innerChapters = [ seg ] ;
76- }
77- } else {
78- if ( topLevel ) {
79- nbTrailingNonChapters = 0 ;
80- }
81-
82- segments . push ( seg ) ;
83- }
84- } else {
85- if ( seg . actionType !== ActionType . Chapter ) {
86- nbTrailingNonChapters ++ ;
63+ const chapterStack : SegmentWithNesting [ ] = [ ] ;
64+ for ( let seg of props . segments ) {
65+ seg = { ...seg } ;
66+ // non-chapter, do not nest
67+ if ( seg . actionType !== ActionType . Chapter ) {
68+ result . push ( seg ) ;
69+ continue ;
70+ }
71+ // traverse the stack
72+ while ( chapterStack . length !== 0 ) {
73+ // where's Array.prototype.at() :sob:
74+ const lastChapter = chapterStack [ chapterStack . length - 1 ] ;
75+ // we know lastChapter.startTime <= seg.startTime, as content.ts sorts these
76+ // so only compare endTime - if new ends before last, new is nested inside last
77+ if ( lastChapter . segment [ 1 ] >= seg . segment [ 1 ] ) {
78+ lastChapter . innerChapters ??= [ ] ;
79+ lastChapter . innerChapters . push ( seg ) ;
80+ chapterStack . push ( seg ) ;
81+ break ;
8782 }
88-
89- segments . push ( seg ) ;
83+ // last did not match, pop it off the stack
84+ chapterStack . pop ( ) ;
9085 }
86+ // chapter stack not empty = we found a place for the chapter
87+ if ( chapterStack . length !== 0 ) {
88+ continue ;
89+ }
90+ // push the chapter to the top-level list and to the stack
91+ result . push ( seg ) ;
92+ chapterStack . push ( seg ) ;
93+
9194 }
92- props . segments . forEach ( ( seg ) => nestChapters ( result , { ...seg } , true ) ) ;
9395 return result ;
9496 } , [ props . segments ] )
9597
0 commit comments