mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-10 21:47:06 +03:00
Merge branch 'master' of https://github.com/ajayyy/SponsorBlock
This commit is contained in:
@@ -28,8 +28,8 @@ enum SegmentListTab {
|
|||||||
Chapter
|
Chapter
|
||||||
}
|
}
|
||||||
|
|
||||||
interface segmentWithNesting extends SponsorTime {
|
interface SegmentWithNesting extends SponsorTime {
|
||||||
innerChapters?: (segmentWithNesting|SponsorTime)[];
|
innerChapters?: (SegmentWithNesting|SponsorTime)[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SegmentListComponent = (props: SegmentListComponentProps) => {
|
export const SegmentListComponent = (props: SegmentListComponentProps) => {
|
||||||
@@ -58,37 +58,43 @@ export const SegmentListComponent = (props: SegmentListComponentProps) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const segmentsWithNesting: segmentWithNesting[] = [];
|
const segmentsWithNesting = React.useMemo(() => {
|
||||||
let nbTrailingNonChapters = 0;
|
const result: SegmentWithNesting[] = [];
|
||||||
function nestChapters(segments: segmentWithNesting[], seg: SponsorTime, topLevel?: boolean) {
|
const chapterStack: SegmentWithNesting[] = [];
|
||||||
if (seg.actionType === ActionType.Chapter && segments.length) {
|
for (let seg of props.segments) {
|
||||||
// trailing non-chapters can only exist at top level
|
seg = {...seg};
|
||||||
const lastElement = segments[segments.length - (topLevel ? nbTrailingNonChapters + 1 : 1)]
|
// non-chapter, do not nest
|
||||||
|
|
||||||
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) {
|
if (seg.actionType !== ActionType.Chapter) {
|
||||||
nbTrailingNonChapters++;
|
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);
|
||||||
|
|
||||||
segments.push(seg);
|
|
||||||
}
|
}
|
||||||
}
|
return result;
|
||||||
props.segments.forEach((seg) => nestChapters(segmentsWithNesting, {...seg}, true));
|
}, [props.segments])
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="issueReporterContainer">
|
<div id="issueReporterContainer">
|
||||||
@@ -136,7 +142,7 @@ export const SegmentListComponent = (props: SegmentListComponentProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function SegmentListItem({ segment, videoID, currentTime, isVip, loopedChapter, tabFilter, sendMessage }: {
|
function SegmentListItem({ segment, videoID, currentTime, isVip, loopedChapter, tabFilter, sendMessage }: {
|
||||||
segment: segmentWithNesting;
|
segment: SegmentWithNesting;
|
||||||
videoID: VideoID;
|
videoID: VideoID;
|
||||||
currentTime: number;
|
currentTime: number;
|
||||||
isVip: boolean;
|
isVip: boolean;
|
||||||
@@ -146,18 +152,32 @@ function SegmentListItem({ segment, videoID, currentTime, isVip, loopedChapter,
|
|||||||
sendMessage: (request: Message) => Promise<MessageResponse>;
|
sendMessage: (request: Message) => Promise<MessageResponse>;
|
||||||
}) {
|
}) {
|
||||||
const [voteMessage, setVoteMessage] = React.useState<string | null>(null);
|
const [voteMessage, setVoteMessage] = React.useState<string | null>(null);
|
||||||
const [hidden, setHidden] = React.useState(segment.hidden || SponsorHideType.Visible);
|
const [hidden, setHidden] = React.useState(segment.hidden ?? SponsorHideType.Visible); // undefined ?? undefined lol
|
||||||
const [isLooped, setIsLooped] = React.useState(loopedChapter === segment.UUID);
|
const [isLooped, setIsLooped] = React.useState(loopedChapter === segment.UUID);
|
||||||
|
|
||||||
let extraInfo = "";
|
// Update internal state if the hidden property of the segment changes
|
||||||
if (segment.hidden === SponsorHideType.Downvoted) {
|
React.useEffect(() => {
|
||||||
// This one is downvoted
|
setHidden(segment.hidden ?? SponsorHideType.Visible);
|
||||||
|
}, [segment.hidden])
|
||||||
|
|
||||||
|
let extraInfo: string;
|
||||||
|
switch (hidden) {
|
||||||
|
case SponsorHideType.Visible:
|
||||||
|
extraInfo = "";
|
||||||
|
break;
|
||||||
|
case SponsorHideType.Downvoted:
|
||||||
extraInfo = " (" + chrome.i18n.getMessage("hiddenDueToDownvote") + ")";
|
extraInfo = " (" + chrome.i18n.getMessage("hiddenDueToDownvote") + ")";
|
||||||
} else if (segment.hidden === SponsorHideType.MinimumDuration) {
|
break;
|
||||||
// This one is too short
|
case SponsorHideType.MinimumDuration:
|
||||||
extraInfo = " (" + chrome.i18n.getMessage("hiddenDueToDuration") + ")";
|
extraInfo = " (" + chrome.i18n.getMessage("hiddenDueToDuration") + ")";
|
||||||
} else if (segment.hidden === SponsorHideType.Hidden) {
|
break;
|
||||||
|
case SponsorHideType.Hidden:
|
||||||
extraInfo = " (" + chrome.i18n.getMessage("manuallyHidden") + ")";
|
extraInfo = " (" + chrome.i18n.getMessage("manuallyHidden") + ")";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// hidden satisfies never; // need to upgrade TS
|
||||||
|
console.warn(`[SB] Unhandled variant of SponsorHideType in SegmentListItem: ${hidden}`);
|
||||||
|
extraInfo = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -279,7 +299,7 @@ function SegmentListItem({ segment, videoID, currentTime, isVip, loopedChapter,
|
|||||||
{
|
{
|
||||||
(segment.actionType === ActionType.Skip || segment.actionType === ActionType.Mute
|
(segment.actionType === ActionType.Skip || segment.actionType === ActionType.Mute
|
||||||
|| segment.actionType === ActionType.Poi
|
|| segment.actionType === ActionType.Poi
|
||||||
&& [SponsorHideType.Visible, SponsorHideType.Hidden].includes(segment.hidden)) &&
|
&& [SponsorHideType.Visible, SponsorHideType.Hidden].includes(hidden)) &&
|
||||||
<img
|
<img
|
||||||
className="voteButton"
|
className="voteButton"
|
||||||
title={chrome.i18n.getMessage("hideSegment")}
|
title={chrome.i18n.getMessage("hideSegment")}
|
||||||
@@ -288,17 +308,11 @@ function SegmentListItem({ segment, videoID, currentTime, isVip, loopedChapter,
|
|||||||
const stopAnimation = AnimationUtils.applyLoadingAnimation(e.currentTarget, 0.4);
|
const stopAnimation = AnimationUtils.applyLoadingAnimation(e.currentTarget, 0.4);
|
||||||
stopAnimation();
|
stopAnimation();
|
||||||
|
|
||||||
if (segment.hidden === SponsorHideType.Hidden) {
|
const newState = hidden === SponsorHideType.Hidden ? SponsorHideType.Visible : SponsorHideType.Hidden;
|
||||||
segment.hidden = SponsorHideType.Visible;
|
setHidden(newState);
|
||||||
setHidden(SponsorHideType.Visible);
|
|
||||||
} else {
|
|
||||||
segment.hidden = SponsorHideType.Hidden;
|
|
||||||
setHidden(SponsorHideType.Hidden);
|
|
||||||
}
|
|
||||||
|
|
||||||
sendMessage({
|
sendMessage({
|
||||||
message: "hideSegment",
|
message: "hideSegment",
|
||||||
type: segment.hidden,
|
type: newState,
|
||||||
UUID: segment.UUID
|
UUID: segment.UUID
|
||||||
});
|
});
|
||||||
}}/>
|
}}/>
|
||||||
@@ -343,7 +357,7 @@ function SegmentListItem({ segment, videoID, currentTime, isVip, loopedChapter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
function InnerChapterList({ chapters, videoID, currentTime, isVip, loopedChapter, tabFilter, sendMessage }: {
|
function InnerChapterList({ chapters, videoID, currentTime, isVip, loopedChapter, tabFilter, sendMessage }: {
|
||||||
chapters: (segmentWithNesting)[];
|
chapters: (SegmentWithNesting)[];
|
||||||
videoID: VideoID;
|
videoID: VideoID;
|
||||||
currentTime: number;
|
currentTime: number;
|
||||||
isVip: boolean;
|
isVip: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user