mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-06 11:37:02 +03:00
Merge pull request #2339 from mini-bomba/fix/chapter-nesting-crash
Rewrite chapter nesting code
This commit is contained in:
@@ -60,36 +60,38 @@ export const SegmentListComponent = (props: SegmentListComponentProps) => {
|
||||
|
||||
const segmentsWithNesting = React.useMemo(() => {
|
||||
const result: SegmentWithNesting[] = [];
|
||||
let nbTrailingNonChapters = 0;
|
||||
function nestChapters(segments: SegmentWithNesting[], seg: SponsorTime, topLevel?: boolean) {
|
||||
if (seg.actionType === ActionType.Chapter && segments.length) {
|
||||
// trailing non-chapters can only exist at top level
|
||||
const lastElement = segments[segments.length - (topLevel ? nbTrailingNonChapters + 1 : 1)]
|
||||
|
||||
if (lastElement.actionType === ActionType.Chapter
|
||||
&& lastElement.segment[0] <= seg.segment[0]
|
||||
&& lastElement.segment[1] >= seg.segment[1]) {
|
||||
if (lastElement.innerChapters){
|
||||
nestChapters(lastElement.innerChapters, seg);
|
||||
} else {
|
||||
lastElement.innerChapters = [seg];
|
||||
}
|
||||
} else {
|
||||
if (topLevel) {
|
||||
nbTrailingNonChapters = 0;
|
||||
}
|
||||
|
||||
segments.push(seg);
|
||||
}
|
||||
} else {
|
||||
if (seg.actionType !== ActionType.Chapter) {
|
||||
nbTrailingNonChapters++;
|
||||
}
|
||||
|
||||
segments.push(seg);
|
||||
const chapterStack: SegmentWithNesting[] = [];
|
||||
for (let seg of props.segments) {
|
||||
seg = {...seg};
|
||||
// non-chapter, do not nest
|
||||
if (seg.actionType !== ActionType.Chapter) {
|
||||
result.push(seg);
|
||||
continue;
|
||||
}
|
||||
// traverse the stack
|
||||
while (chapterStack.length !== 0) {
|
||||
// where's Array.prototype.at() :sob:
|
||||
const lastChapter = chapterStack[chapterStack.length - 1];
|
||||
// we know lastChapter.startTime <= seg.startTime, as content.ts sorts these
|
||||
// so only compare endTime - if new ends before last, new is nested inside last
|
||||
if (lastChapter.segment[1] >= seg.segment[1]) {
|
||||
lastChapter.innerChapters ??= [];
|
||||
lastChapter.innerChapters.push(seg);
|
||||
chapterStack.push(seg);
|
||||
break;
|
||||
}
|
||||
// last did not match, pop it off the stack
|
||||
chapterStack.pop();
|
||||
}
|
||||
// chapter stack not empty = we found a place for the chapter
|
||||
if (chapterStack.length !== 0) {
|
||||
continue;
|
||||
}
|
||||
// push the chapter to the top-level list and to the stack
|
||||
result.push(seg);
|
||||
chapterStack.push(seg);
|
||||
|
||||
}
|
||||
props.segments.forEach((seg) => nestChapters(result, {...seg}, true));
|
||||
return result;
|
||||
}, [props.segments])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user