From 8582199c6702187a5b041f3aa69c12600c078026 Mon Sep 17 00:00:00 2001 From: silentfun Date: Mon, 18 Nov 2024 21:05:00 +0800 Subject: [PATCH 01/11] Feature: Advance skip notice --- public/_locales/en/en.messages.json | 4 +- public/_locales/en/messages.json | 4 +- public/_locales/zh_CN/messages.json | 4 +- public/_locales/zh_TW/messages.json | 4 +- src/components/SkipNoticeComponent.tsx | 9 +- src/content.ts | 109 ++++++++++++++----------- src/render/SkipNotice.tsx | 4 +- src/types.ts | 2 +- 8 files changed, 81 insertions(+), 59 deletions(-) diff --git a/public/_locales/en/en.messages.json b/public/_locales/en/en.messages.json index 3433cf21..3d9195d7 100644 --- a/public/_locales/en/en.messages.json +++ b/public/_locales/en/en.messages.json @@ -371,11 +371,11 @@ "description": "Used for skipping to things (Skip to Highlight)" }, "skipped": { - "message": "{0} Skipped", + "message": "{0} Ready Skipped", "description": "Example: Sponsor Skipped" }, "muted": { - "message": "{0} Muted", + "message": "{0} Ready Muted", "description": "Example: Sponsor Muted" }, "skipped_to_category": { diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 13236447..bdb4e6bb 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -368,11 +368,11 @@ "description": "Used for skipping to things (Skip to Highlight)" }, "skipped": { - "message": "{0} 已跳过", + "message": "{0} 准备跳过", "description": "Example: Sponsor Skipped" }, "muted": { - "message": "{0} 已静音", + "message": "{0} 准备静音", "description": "Example: Sponsor Muted" }, "skipped_to_category": { diff --git a/public/_locales/zh_CN/messages.json b/public/_locales/zh_CN/messages.json index 13236447..bdb4e6bb 100644 --- a/public/_locales/zh_CN/messages.json +++ b/public/_locales/zh_CN/messages.json @@ -368,11 +368,11 @@ "description": "Used for skipping to things (Skip to Highlight)" }, "skipped": { - "message": "{0} 已跳过", + "message": "{0} 准备跳过", "description": "Example: Sponsor Skipped" }, "muted": { - "message": "{0} 已静音", + "message": "{0} 准备静音", "description": "Example: Sponsor Muted" }, "skipped_to_category": { diff --git a/public/_locales/zh_TW/messages.json b/public/_locales/zh_TW/messages.json index 80a12de8..ae1e8b8b 100644 --- a/public/_locales/zh_TW/messages.json +++ b/public/_locales/zh_TW/messages.json @@ -368,11 +368,11 @@ "description": "Used for skipping to things (Skip to Highlight)" }, "skipped": { - "message": "{0} 已跳過", + "message": "{0} 準備跳過", "description": "Example: Sponsor Skipped" }, "muted": { - "message": "{0} 已靜音", + "message": "{0} 準備靜音", "description": "Example: Sponsor Muted" }, "skipped_to_category": { diff --git a/src/components/SkipNoticeComponent.tsx b/src/components/SkipNoticeComponent.tsx index 41bd7630..f2e5952f 100644 --- a/src/components/SkipNoticeComponent.tsx +++ b/src/components/SkipNoticeComponent.tsx @@ -44,6 +44,7 @@ export interface SkipNoticeProps { smaller: boolean; unskipTime?: number; + readySkip: NodeJS.Timeout } export interface SkipNoticeState { @@ -72,6 +73,8 @@ export interface SkipNoticeState { voted?: SkipNoticeAction[]; copied?: SkipNoticeAction[]; + + readySkip: NodeJS.Timeout; } class SkipNoticeComponent extends React.Component { @@ -173,6 +176,8 @@ class SkipNoticeComponent extends React.Component Config.config.skipNoticeDuration, countdownTime: Config.config.skipNoticeDuration, + readySkip: null }; //reset countdown diff --git a/src/content.ts b/src/content.ts index aa5d7549..46c42a8f 100644 --- a/src/content.ts +++ b/src/content.ts @@ -92,6 +92,7 @@ let retryFetchTimeout: NodeJS.Timeout = null; let shownSegmentFailedToFetchWarning = false; let selectedSegment: SegmentUUID | null = null; let previewedSegment = false; +let readySkip: NodeJS.Timeout // JSON video info let videoInfo: VideoInfo = null; @@ -307,6 +308,7 @@ function messageListener( unskipSponsorTime( sponsorTimes.find((segment) => segment.UUID === request.UUID), null, + null, true ); break; @@ -651,7 +653,7 @@ async function startSponsorSchedule( shouldSkip(currentSkip) || sponsorTimesSubmitting?.some((segment) => segment.segment === currentSkip.segment) ) { - if (forceVideoTime >= skipTime[0] - skipBuffer && forceVideoTime < skipTime[1]) { + if (forceVideoTime >= skipTime[0] - skipBuffer - Config.config.skipNoticeDuration * 1000 && forceVideoTime < skipTime[1]) { skipToTime({ v: getVideo(), skipTime, @@ -757,7 +759,7 @@ async function startSponsorSchedule( const offset = isFirefoxOrSafari() && !isSafari() ? 600 : 150; // Schedule for right before to be more precise than normal timeout - currentSkipSchedule = setTimeout(skippingFunction, Math.max(0, delayTime - offset)); + currentSkipSchedule = setTimeout(skippingFunction, Math.max(0, delayTime - offset - Config.config.skipNoticeDuration * 1000)); } } } @@ -1850,50 +1852,54 @@ function skipToTime({ v, skipTime, skippingSegments, openNotice, forceAutoSkip, const autoSkip: boolean = forceAutoSkip || shouldAutoSkip(skippingSegments[0]); const isSubmittingSegment = sponsorTimesSubmitting.some((time) => time.segment === skippingSegments[0].segment); - if ((autoSkip || isSubmittingSegment) && v.currentTime !== skipTime[1]) { - switch (skippingSegments[0].actionType) { - case ActionType.Poi: - case ActionType.Skip: { - // Fix for looped videos not working when skipping to the end #426 - // for some reason you also can't skip to 1 second before the end - if (v.loop && v.duration > 1 && skipTime[1] >= v.duration - 1) { - v.currentTime = 0; - } else if ( - v.duration > 1 && - skipTime[1] >= v.duration && - (navigator.vendor === "Apple Computer, Inc." || isPlayingPlaylist()) - ) { - // MacOS will loop otherwise #1027 - // Sometimes playlists loop too #1804 - v.currentTime = v.duration - 0.001; - } else if ( - v.duration > 1 && - Math.abs(skipTime[1] - v.duration) < endTimeSkipBuffer && - isFirefoxOrSafari() && - !isSafari() - ) { - v.currentTime = v.duration; - } else { - if (inMuteSegment(skipTime[1], true)) { - // Make sure not to mute if skipping into a mute segment - v.muted = true; - videoMuted = true; + //防止重复调用导致反复横跳 + clearTimeout(readySkip) + readySkip = setTimeout(function () { + if ((autoSkip || isSubmittingSegment) && v.currentTime !== skipTime[1]) { + switch (skippingSegments[0].actionType) { + case ActionType.Poi: + case ActionType.Skip: { + // Fix for looped videos not working when skipping to the end #426 + // for some reason you also can't skip to 1 second before the end + if (v.loop && v.duration > 1 && skipTime[1] >= v.duration - 1) { + v.currentTime = 0; + } else if ( + v.duration > 1 && + skipTime[1] >= v.duration && + (navigator.vendor === "Apple Computer, Inc." || isPlayingPlaylist()) + ) { + // MacOS will loop otherwise #1027 + // Sometimes playlists loop too #1804 + v.currentTime = v.duration - 0.001; + } else if ( + v.duration > 1 && + Math.abs(skipTime[1] - v.duration) < endTimeSkipBuffer && + isFirefoxOrSafari() && + !isSafari() + ) { + v.currentTime = v.duration; + } else { + if (inMuteSegment(skipTime[1], true)) { + // Make sure not to mute if skipping into a mute segment + v.muted = true; + videoMuted = true; + } + + v.currentTime = skipTime[1]; } - v.currentTime = skipTime[1]; + break; } - - break; - } - case ActionType.Mute: { - if (!v.muted) { - v.muted = true; - videoMuted = true; + case ActionType.Mute: { + if (!v.muted) { + v.muted = true; + videoMuted = true; + } + break; } - break; } } - } + }, Math.min(Config.config.skipNoticeDuration * 1000 / getVideo().playbackRate, (skipTime[0] - getVideo().currentTime) * 1000 / getVideo().playbackRate)); if (autoSkip && Config.config.audioNotificationOnSkip && !isSubmittingSegment && !getVideo()?.muted) { const beep = new Audio(chrome.runtime.getURL("icons/beep.ogg")); @@ -1919,15 +1925,15 @@ function skipToTime({ v, skipTime, skippingSegments, openNotice, forceAutoSkip, if (openNotice) { //send out the message saying that a sponsor message was skipped if (!Config.config.dontShowNotice || !autoSkip) { - createSkipNotice(skippingSegments, autoSkip, unskipTime, false); + createSkipNotice(skippingSegments, autoSkip, unskipTime, false, readySkip); } else if (autoSkip) { activeSkipKeybindElement?.setShowKeybindHint(false); activeSkipKeybindElement = { - setShowKeybindHint: () => {}, //eslint-disable-line @typescript-eslint/no-empty-function + setShowKeybindHint: () => {}, toggleSkip: () => { - unskipSponsorTime(skippingSegments[0], unskipTime); + createSkipNotice(skippingSegments, autoSkip, unskipTime, true, readySkip); - createSkipNotice(skippingSegments, autoSkip, unskipTime, true); + readySkip = unskipSponsorTime(skippingSegments[0], unskipTime, readySkip); }, }; } @@ -1942,7 +1948,8 @@ function createSkipNotice( skippingSegments: SponsorTime[], autoSkip: boolean, unskipTime: number, - startReskip: boolean + startReskip: boolean, + readySkip: NodeJS.Timeout ) { for (const skipNotice of skipNotices) { if ( @@ -1959,7 +1966,8 @@ function createSkipNotice( autoSkip, skipNoticeContentContainer, unskipTime, - startReskip + startReskip, + readySkip ); if (Config.config.skipKeybind == null) newSkipNotice.setShowKeybindHint(false); skipNotices.push(newSkipNotice); @@ -1968,7 +1976,7 @@ function createSkipNotice( activeSkipKeybindElement = newSkipNotice; } -function unskipSponsorTime(segment: SponsorTime, unskipTime: number = null, forceSeek = false) { +function unskipSponsorTime(segment: SponsorTime, unskipTime: number, readySkip: NodeJS.Timeout, forceSeek = false) { if (segment.actionType === ActionType.Mute) { getVideo().muted = false; videoMuted = false; @@ -1976,7 +1984,12 @@ function unskipSponsorTime(segment: SponsorTime, unskipTime: number = null, forc if (forceSeek || segment.actionType === ActionType.Skip) { //add a tiny bit of time to make sure it is not skipped again - getVideo().currentTime = unskipTime ?? segment.segment[0] + 0.001; + if(readySkip){ + clearTimeout(readySkip) + return null + }else{ + getVideo().currentTime = unskipTime ?? segment.segment[0] + 0.001; + } } } diff --git a/src/render/SkipNotice.tsx b/src/render/SkipNotice.tsx index b5a3c1e3..e1b6c3e8 100644 --- a/src/render/SkipNotice.tsx +++ b/src/render/SkipNotice.tsx @@ -25,7 +25,8 @@ class SkipNotice { autoSkip = false, contentContainer: ContentContainer, unskipTime: number = null, - startReskip = false + startReskip = false, + readySkip: NodeJS.Timeout ) { this.skipNoticeRef = React.createRef(); @@ -63,6 +64,7 @@ class SkipNotice { (Config.config.noticeVisibilityMode >= NoticeVisbilityMode.MiniForAutoSkip && autoSkip) } unskipTime={unskipTime} + readySkip={readySkip} /> ); } diff --git a/src/types.ts b/src/types.ts index 4538312c..b1a983c8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -21,7 +21,7 @@ export interface ContentContainer { (): { vote: (type: number, UUID: SegmentUUID, category?: Category, skipNotice?: SkipNoticeComponent) => void; dontShowNoticeAgain: () => void; - unskipSponsorTime: (segment: SponsorTime, unskipTime: number, forceSeek?: boolean) => void; + unskipSponsorTime: (segment: SponsorTime, unskipTime: number, readySkip: NodeJS.Timeout, forceSeek?: boolean) => void; sponsorTimes: SponsorTime[]; sponsorTimesSubmitting: SponsorTime[]; skipNotices: SkipNotice[]; From f41d830b8f697c88b153458d5eb522106054b27c Mon Sep 17 00:00:00 2001 From: etherfun <124044584+etherfun@users.noreply.github.com> Date: Tue, 19 Nov 2024 12:33:47 +0800 Subject: [PATCH 02/11] Support all category --- src/content.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/content.ts b/src/content.ts index 46c42a8f..31a4823e 100644 --- a/src/content.ts +++ b/src/content.ts @@ -1899,7 +1899,7 @@ function skipToTime({ v, skipTime, skippingSegments, openNotice, forceAutoSkip, } } } - }, Math.min(Config.config.skipNoticeDuration * 1000 / getVideo().playbackRate, (skipTime[0] - getVideo().currentTime) * 1000 / getVideo().playbackRate)); + }, howLongToSkip(skippingSegments, skipTime)); if (autoSkip && Config.config.audioNotificationOnSkip && !isSubmittingSegment && !getVideo()?.muted) { const beep = new Audio(chrome.runtime.getURL("icons/beep.ogg")); @@ -1993,6 +1993,17 @@ function unskipSponsorTime(segment: SponsorTime, unskipTime: number, readySkip: } } +//适配不同的片段 +function howLongToSkip(skippingSegments: SponsorTime[], skipTime: number[]){ + if (skippingSegments[0].category === "sponsor" || skippingSegments[0].category === "selfpromo" || skippingSegments[0].category === "filler" || skippingSegments[0].category === "music_offtopic") { + return Math.min(Config.config.skipNoticeDuration * 1000 / getVideo().playbackRate, (skipTime[0] - getVideo().currentTime) * 1000 / getVideo().playbackRate) + } else if (skippingSegments[0].category === "poi_highlight" || skippingSegments[0].category === "preview" || skippingSegments[0].category === "interaction" || skippingSegments[0].category === "intro" || skippingSegments[0].category === "outro") { + return 0 + } else {//防止未来加入新的片段类型导致不可用 + return Math.min(Config.config.skipNoticeDuration * 1000 / getVideo().playbackRate, (skipTime[0] - getVideo().currentTime) * 1000 / getVideo().playbackRate) + } +} + function reskipSponsorTime(segment: SponsorTime, forceSeek = false) { if (segment.actionType === ActionType.Mute && !forceSeek) { getVideo().muted = true; From 72988adcf0611e20d21ddfae172e52b903c03435 Mon Sep 17 00:00:00 2001 From: etherfun <124044584+etherfun@users.noreply.github.com> Date: Wed, 20 Nov 2024 18:10:13 +0800 Subject: [PATCH 03/11] Fix bug and change massage Fix unskip bug and skip when paused bug --- public/_locales/en/en.messages.json | 4 +- public/_locales/zh_CN/messages.json | 4 +- public/_locales/zh_TW/messages.json | 2 +- src/components/SkipNoticeComponent.tsx | 2 +- src/content.ts | 52 +++++++++++++++++++++----- 5 files changed, 49 insertions(+), 15 deletions(-) diff --git a/public/_locales/en/en.messages.json b/public/_locales/en/en.messages.json index 3d9195d7..3433cf21 100644 --- a/public/_locales/en/en.messages.json +++ b/public/_locales/en/en.messages.json @@ -371,11 +371,11 @@ "description": "Used for skipping to things (Skip to Highlight)" }, "skipped": { - "message": "{0} Ready Skipped", + "message": "{0} Skipped", "description": "Example: Sponsor Skipped" }, "muted": { - "message": "{0} Ready Muted", + "message": "{0} Muted", "description": "Example: Sponsor Muted" }, "skipped_to_category": { diff --git a/public/_locales/zh_CN/messages.json b/public/_locales/zh_CN/messages.json index bdb4e6bb..3b45d61f 100644 --- a/public/_locales/zh_CN/messages.json +++ b/public/_locales/zh_CN/messages.json @@ -472,7 +472,7 @@ "message": "“空降提醒弹窗”显示持续时间(秒):" }, "skipNoticeDurationDescription": { - "message": "提醒您跳过片段的弹窗的显示时长。手动跳过片段的提醒弹窗可能会显示更久。" + "message": "提醒您跳过片段的弹窗的显示时长。手动跳过片段的提醒弹窗可能会显示更久。(请注意: 设置过久可能会在某些片段密集区域堆叠大量弹窗!)" }, "shortCheck": { "message": "以下的提交短于您的最小持续时间选项。这代表它们可能已经被提交,只是由于该选项被忽略了。您确定要提交吗?" @@ -1172,7 +1172,7 @@ "description": "This is used on the popup to show how much time left. It will look like \"5s\". The word {seconds} will be replaced, so keep it here. Translations should only change the \"s\"" }, "FillerWarning": { - "message": "Warning: This is an incredibly aggressive category. You most likely will have to unskip stuff, or disable it sometimes. Be warned that many videos have over 50% or more of the video skipped! However, remember that there are still specific guidelines to follow when submitting.", + "message": "警告:这是一个非常激进的分类。 您很可能会需要取消跳过某些内容,或者有时候需要禁用它。 请注意,许多视频的跳过率超过50%甚至更多! 但是请记住,在提交时仍需遵守特定的指导原则。", "description": "Warning that appears when enabling the filler tangent category" }, "cleanPopup": { diff --git a/public/_locales/zh_TW/messages.json b/public/_locales/zh_TW/messages.json index ae1e8b8b..d4b65b3f 100644 --- a/public/_locales/zh_TW/messages.json +++ b/public/_locales/zh_TW/messages.json @@ -472,7 +472,7 @@ "message": "跳過提醒跳出視窗持續時間(秒):" }, "skipNoticeDurationDescription": { - "message": "跳過提醒跳出視窗的顯示時常。手動跳過的提醒可能會顯示更久。" + "message": "跳過提醒跳出視窗的顯示時常。手動跳過的提醒可能會顯示更久。(請注意:設置過久可能會在某些片段密集區域堆疊大量彈窗!)" }, "shortCheck": { "message": "以下的提交短於您的最小持續時間選項。這代表它們可能已經被提交,只是由於該選項被忽略了。您確定要提交嗎?" diff --git a/src/components/SkipNoticeComponent.tsx b/src/components/SkipNoticeComponent.tsx index f2e5952f..e3ca4c61 100644 --- a/src/components/SkipNoticeComponent.tsx +++ b/src/components/SkipNoticeComponent.tsx @@ -44,7 +44,7 @@ export interface SkipNoticeProps { smaller: boolean; unskipTime?: number; - readySkip: NodeJS.Timeout + readySkip: NodeJS.Timeout; } export interface SkipNoticeState { diff --git a/src/content.ts b/src/content.ts index 31a4823e..7d48cf16 100644 --- a/src/content.ts +++ b/src/content.ts @@ -92,7 +92,8 @@ let retryFetchTimeout: NodeJS.Timeout = null; let shownSegmentFailedToFetchWarning = false; let selectedSegment: SegmentUUID | null = null; let previewedSegment = false; -let readySkip: NodeJS.Timeout +let readySkip: NodeJS.Timeout; +let readySkipCheck: number; // JSON video info let videoInfo: VideoInfo = null; @@ -1853,8 +1854,13 @@ function skipToTime({ v, skipTime, skippingSegments, openNotice, forceAutoSkip, const isSubmittingSegment = sponsorTimesSubmitting.some((time) => time.segment === skippingSegments[0].segment); //防止重复调用导致反复横跳 - clearTimeout(readySkip) - readySkip = setTimeout(function () { + let Check = readySkipCheck != skipTime[0]; + readySkipCheck = skipTime[0]; + if(!Check) return; + clearTimeout(readySkip); + const handleSkip = () => { + cleanListeners(); + if ((autoSkip || isSubmittingSegment) && v.currentTime !== skipTime[1]) { switch (skippingSegments[0].actionType) { case ActionType.Poi: @@ -1899,7 +1905,31 @@ function skipToTime({ v, skipTime, skippingSegments, openNotice, forceAutoSkip, } } } - }, howLongToSkip(skippingSegments, skipTime)); + } + + //防止在片段前暂停等 + const cleanListeners = () => { + v.removeEventListener("seeked", handleSeeked); + v.removeEventListener("pause", handlePause); + v.removeEventListener("play", handlePlay); + }; + const handlePause = () => { + clearTimeout(readySkip); + }; + const handlePlay = () => { + const text = document.querySelector('.sponsorSkipObject.sponsorSkipNoticeButton') as HTMLButtonElement; + if (text.textContent.slice(0, 4) === chrome.i18n.getMessage('unskip')) { + readySkip = setTimeout(handleSkip, howLongToSkip(skippingSegments, skipTime)); + }; + }; + const handleSeeked = () => { + readySkipCheck = null; + clearTimeout(readySkip); + }; + v.addEventListener("pause", handlePause); + v.addEventListener("play", handlePlay); + v.addEventListener("seeked", handleSeeked); + readySkip = setTimeout(handleSkip, howLongToSkip(skippingSegments, skipTime)); if (autoSkip && Config.config.audioNotificationOnSkip && !isSubmittingSegment && !getVideo()?.muted) { const beep = new Audio(chrome.runtime.getURL("icons/beep.ogg")); @@ -1983,11 +2013,15 @@ function unskipSponsorTime(segment: SponsorTime, unskipTime: number, readySkip: } if (forceSeek || segment.actionType === ActionType.Skip) { - //add a tiny bit of time to make sure it is not skipped again - if(readySkip){ - clearTimeout(readySkip) - return null - }else{ + if (readySkip && getVideo().currentTime > segment.segment[0]) { + clearTimeout(readySkip); + getVideo().currentTime = unskipTime ?? segment.segment[0] + 0.001; + return null; + } else if (readySkip) { + clearTimeout(readySkip); + return null; + } else { + //add a tiny bit of time to make sure it is not skipped again getVideo().currentTime = unskipTime ?? segment.segment[0] + 0.001; } } From d8cadc5d19616ceaff4da428611f1d081a4b60b2 Mon Sep 17 00:00:00 2001 From: etherfun <124044584+etherfun@users.noreply.github.com> Date: Thu, 21 Nov 2024 21:00:42 +0800 Subject: [PATCH 04/11] Support manually skip --- public/_locales/en/messages.json | 2 +- public/_locales/zh_CN/messages.json | 2 +- public/_locales/zh_TW/messages.json | 2 +- public/shared.css | 2 +- src/components/SkipNoticeComponent.tsx | 9 +-- src/content.ts | 100 +++++++++++++++---------- src/render/SkipNotice.tsx | 2 - src/types.ts | 2 +- 8 files changed, 65 insertions(+), 56 deletions(-) diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index bdb4e6bb..13bda0ae 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -258,7 +258,7 @@ "message": "重新显示空降提醒" }, "showSkipNotice": { - "message": "在跳过片段后显示提醒弹窗" + "message": "在跳过片段前显示提醒弹窗" }, "showCategoryGuidelines": { "message": "显示类别说明" diff --git a/public/_locales/zh_CN/messages.json b/public/_locales/zh_CN/messages.json index 3b45d61f..0de5177c 100644 --- a/public/_locales/zh_CN/messages.json +++ b/public/_locales/zh_CN/messages.json @@ -258,7 +258,7 @@ "message": "重新显示空降提醒" }, "showSkipNotice": { - "message": "在跳过片段后显示提醒弹窗" + "message": "在跳过片段前显示提醒弹窗" }, "showCategoryGuidelines": { "message": "显示类别说明" diff --git a/public/_locales/zh_TW/messages.json b/public/_locales/zh_TW/messages.json index d4b65b3f..026cacae 100644 --- a/public/_locales/zh_TW/messages.json +++ b/public/_locales/zh_TW/messages.json @@ -258,7 +258,7 @@ "message": "重新顯示跳過提醒" }, "showSkipNotice": { - "message": "在跳過片段後顯示提醒跳出視窗" + "message": "在跳過片段前顯示提醒跳出視窗" }, "showCategoryGuidelines": { "message": "顯示類別說明" diff --git a/public/shared.css b/public/shared.css index de327083..e4d1aab3 100644 --- a/public/shared.css +++ b/public/shared.css @@ -15,7 +15,7 @@ } .sponsorSkipNoticeParent { - min-width: 390px; + min-width: 410px; max-width: 50%; } diff --git a/src/components/SkipNoticeComponent.tsx b/src/components/SkipNoticeComponent.tsx index e3ca4c61..98445cc4 100644 --- a/src/components/SkipNoticeComponent.tsx +++ b/src/components/SkipNoticeComponent.tsx @@ -44,7 +44,6 @@ export interface SkipNoticeProps { smaller: boolean; unskipTime?: number; - readySkip: NodeJS.Timeout; } export interface SkipNoticeState { @@ -73,8 +72,6 @@ export interface SkipNoticeState { voted?: SkipNoticeAction[]; copied?: SkipNoticeAction[]; - - readySkip: NodeJS.Timeout; } class SkipNoticeComponent extends React.Component { @@ -176,8 +173,6 @@ class SkipNoticeComponent extends React.Component Config.config.skipNoticeDuration, countdownTime: Config.config.skipNoticeDuration, - readySkip: null }; //reset countdown diff --git a/src/content.ts b/src/content.ts index 7d48cf16..43d12db8 100644 --- a/src/content.ts +++ b/src/content.ts @@ -92,8 +92,11 @@ let retryFetchTimeout: NodeJS.Timeout = null; let shownSegmentFailedToFetchWarning = false; let selectedSegment: SegmentUUID | null = null; let previewedSegment = false; -let readySkip: NodeJS.Timeout; -let readySkipCheck: number; +const readySkip = { + readySkip: null as NodeJS.Timeout, + readySkipCheck: null as number, + ManualSkipSetTimeOut: null as NodeJS.Timeout, +}; // JSON video info let videoInfo: VideoInfo = null; @@ -309,7 +312,6 @@ function messageListener( unskipSponsorTime( sponsorTimes.find((segment) => segment.UUID === request.UUID), null, - null, true ); break; @@ -1854,12 +1856,14 @@ function skipToTime({ v, skipTime, skippingSegments, openNotice, forceAutoSkip, const isSubmittingSegment = sponsorTimesSubmitting.some((time) => time.segment === skippingSegments[0].segment); //防止重复调用导致反复横跳 - let Check = readySkipCheck != skipTime[0]; - readySkipCheck = skipTime[0]; - if(!Check) return; - clearTimeout(readySkip); + const Check = readySkip.readySkipCheck != skipTime[0]; + readySkip.readySkipCheck = skipTime[0]; + if (!Check) return; + clearTimeout(readySkip.readySkip); + const handleSkip = () => { cleanListeners(); + readySkip.readySkipCheck = null; if ((autoSkip || isSubmittingSegment) && v.currentTime !== skipTime[1]) { switch (skippingSegments[0].actionType) { @@ -1912,24 +1916,25 @@ function skipToTime({ v, skipTime, skippingSegments, openNotice, forceAutoSkip, v.removeEventListener("seeked", handleSeeked); v.removeEventListener("pause", handlePause); v.removeEventListener("play", handlePlay); - }; + } const handlePause = () => { - clearTimeout(readySkip); - }; + clearTimeout(readySkip.readySkip); + } const handlePlay = () => { const text = document.querySelector('.sponsorSkipObject.sponsorSkipNoticeButton') as HTMLButtonElement; - if (text.textContent.slice(0, 4) === chrome.i18n.getMessage('unskip')) { - readySkip = setTimeout(handleSkip, howLongToSkip(skippingSegments, skipTime)); - }; - }; + if (text && text.textContent.slice(0, 4) === chrome.i18n.getMessage('unskip')) { + readySkip.readySkip = setTimeout(handleSkip, howLongToSkip(skipTime)); + } + } const handleSeeked = () => { - readySkipCheck = null; - clearTimeout(readySkip); - }; + cleanListeners(); + readySkip.readySkipCheck = null; + clearTimeout(readySkip.readySkip); + } v.addEventListener("pause", handlePause); v.addEventListener("play", handlePlay); v.addEventListener("seeked", handleSeeked); - readySkip = setTimeout(handleSkip, howLongToSkip(skippingSegments, skipTime)); + readySkip.readySkip = setTimeout(handleSkip, howLongToSkip(skipTime)); if (autoSkip && Config.config.audioNotificationOnSkip && !isSubmittingSegment && !getVideo()?.muted) { const beep = new Audio(chrome.runtime.getURL("icons/beep.ogg")); @@ -1955,15 +1960,15 @@ function skipToTime({ v, skipTime, skippingSegments, openNotice, forceAutoSkip, if (openNotice) { //send out the message saying that a sponsor message was skipped if (!Config.config.dontShowNotice || !autoSkip) { - createSkipNotice(skippingSegments, autoSkip, unskipTime, false, readySkip); + createSkipNotice(skippingSegments, autoSkip, unskipTime, false); } else if (autoSkip) { activeSkipKeybindElement?.setShowKeybindHint(false); activeSkipKeybindElement = { setShowKeybindHint: () => {}, toggleSkip: () => { - createSkipNotice(skippingSegments, autoSkip, unskipTime, true, readySkip); + createSkipNotice(skippingSegments, autoSkip, unskipTime, true); - readySkip = unskipSponsorTime(skippingSegments[0], unskipTime, readySkip); + unskipSponsorTime(skippingSegments[0], unskipTime); }, }; } @@ -1979,7 +1984,6 @@ function createSkipNotice( autoSkip: boolean, unskipTime: number, startReskip: boolean, - readySkip: NodeJS.Timeout ) { for (const skipNotice of skipNotices) { if ( @@ -1997,7 +2001,6 @@ function createSkipNotice( skipNoticeContentContainer, unskipTime, startReskip, - readySkip ); if (Config.config.skipKeybind == null) newSkipNotice.setShowKeybindHint(false); skipNotices.push(newSkipNotice); @@ -2006,20 +2009,21 @@ function createSkipNotice( activeSkipKeybindElement = newSkipNotice; } -function unskipSponsorTime(segment: SponsorTime, unskipTime: number, readySkip: NodeJS.Timeout, forceSeek = false) { +function unskipSponsorTime(segment: SponsorTime, unskipTime: number, forceSeek = false) { if (segment.actionType === ActionType.Mute) { getVideo().muted = false; videoMuted = false; } if (forceSeek || segment.actionType === ActionType.Skip) { - if (readySkip && getVideo().currentTime > segment.segment[0]) { - clearTimeout(readySkip); + if (readySkip.readySkip && getVideo().currentTime > segment.segment[0]) { + clearTimeout(readySkip.readySkip); getVideo().currentTime = unskipTime ?? segment.segment[0] + 0.001; - return null; - } else if (readySkip) { - clearTimeout(readySkip); - return null; + } else if (readySkip.readySkip) { + clearTimeout(readySkip.readySkip); + clearTimeout(readySkip.ManualSkipSetTimeOut); + } else if (readySkip.ManualSkipSetTimeOut){ + clearTimeout(readySkip.ManualSkipSetTimeOut); } else { //add a tiny bit of time to make sure it is not skipped again getVideo().currentTime = unskipTime ?? segment.segment[0] + 0.001; @@ -2027,22 +2031,31 @@ function unskipSponsorTime(segment: SponsorTime, unskipTime: number, readySkip: } } -//适配不同的片段 -function howLongToSkip(skippingSegments: SponsorTime[], skipTime: number[]){ - if (skippingSegments[0].category === "sponsor" || skippingSegments[0].category === "selfpromo" || skippingSegments[0].category === "filler" || skippingSegments[0].category === "music_offtopic") { - return Math.min(Config.config.skipNoticeDuration * 1000 / getVideo().playbackRate, (skipTime[0] - getVideo().currentTime) * 1000 / getVideo().playbackRate) - } else if (skippingSegments[0].category === "poi_highlight" || skippingSegments[0].category === "preview" || skippingSegments[0].category === "interaction" || skippingSegments[0].category === "intro" || skippingSegments[0].category === "outro") { - return 0 - } else {//防止未来加入新的片段类型导致不可用 - return Math.min(Config.config.skipNoticeDuration * 1000 / getVideo().playbackRate, (skipTime[0] - getVideo().currentTime) * 1000 / getVideo().playbackRate) - } -} - function reskipSponsorTime(segment: SponsorTime, forceSeek = false) { if (segment.actionType === ActionType.Mute && !forceSeek) { getVideo().muted = true; videoMuted = true; } else { + if (utils.getCategorySelection(segment.category)?.option === CategorySkipOption.ManualSkip) { + readySkip.ManualSkipSetTimeOut = setTimeout(() => { + const skippedTime = Math.max(segment.segment[1] - getVideo().currentTime, 0); + const segmentDuration = segment.segment[1] - segment.segment[0]; + const fullSkip = skippedTime / segmentDuration > manualSkipPercentCount; + + getVideo().currentTime = segment.segment[1]; + sendTelemetryAndCount([segment], skippedTime, fullSkip); + startSponsorSchedule(true, segment.segment[1], false); + }, howLongToSkip(segment.segment)); + } else if (getVideo().currentTime < segment.segment[0]) { + readySkip.readySkipCheck = null; + const skipInfo = getNextSkipIndex(getVideo().currentTime, false, true); + skipToTime({ + v: getVideo(), + skipTime: segment.segment, + skippingSegments: [segment], + openNotice: skipInfo.openNotice, + }); + } else { const skippedTime = Math.max(segment.segment[1] - getVideo().currentTime, 0); const segmentDuration = segment.segment[1] - segment.segment[0]; const fullSkip = skippedTime / segmentDuration > manualSkipPercentCount; @@ -2050,9 +2063,14 @@ function reskipSponsorTime(segment: SponsorTime, forceSeek = false) { getVideo().currentTime = segment.segment[1]; sendTelemetryAndCount([segment], skippedTime, fullSkip); startSponsorSchedule(true, segment.segment[1], false); + } } } +function howLongToSkip(skipTime: number[]) { + return Math.min(Config.config.skipNoticeDuration * 1000 / getVideo().playbackRate, (skipTime[0] - getVideo().currentTime) * 1000 / getVideo().playbackRate) +} + function shouldAutoSkip(segment: SponsorTime): boolean { // danmaku segments are controlled by config if (segment.source === SponsorSourceType.Danmaku) { diff --git a/src/render/SkipNotice.tsx b/src/render/SkipNotice.tsx index e1b6c3e8..81052fe2 100644 --- a/src/render/SkipNotice.tsx +++ b/src/render/SkipNotice.tsx @@ -26,7 +26,6 @@ class SkipNotice { contentContainer: ContentContainer, unskipTime: number = null, startReskip = false, - readySkip: NodeJS.Timeout ) { this.skipNoticeRef = React.createRef(); @@ -64,7 +63,6 @@ class SkipNotice { (Config.config.noticeVisibilityMode >= NoticeVisbilityMode.MiniForAutoSkip && autoSkip) } unskipTime={unskipTime} - readySkip={readySkip} /> ); } diff --git a/src/types.ts b/src/types.ts index b1a983c8..4538312c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -21,7 +21,7 @@ export interface ContentContainer { (): { vote: (type: number, UUID: SegmentUUID, category?: Category, skipNotice?: SkipNoticeComponent) => void; dontShowNoticeAgain: () => void; - unskipSponsorTime: (segment: SponsorTime, unskipTime: number, readySkip: NodeJS.Timeout, forceSeek?: boolean) => void; + unskipSponsorTime: (segment: SponsorTime, unskipTime: number, forceSeek?: boolean) => void; sponsorTimes: SponsorTime[]; sponsorTimesSubmitting: SponsorTime[]; skipNotices: SkipNotice[]; From b46212d0a9fd999d19948116e5f444bfdd4fbbee Mon Sep 17 00:00:00 2001 From: etherfun <124044584+etherfun@users.noreply.github.com> Date: Fri, 22 Nov 2024 22:12:47 +0800 Subject: [PATCH 05/11] Fix bug Fix rare error skips. e.g.Notice appears earlier than the set time or error skip occurs --- src/content.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/content.ts b/src/content.ts index 43d12db8..e8424d24 100644 --- a/src/content.ts +++ b/src/content.ts @@ -1858,7 +1858,7 @@ function skipToTime({ v, skipTime, skippingSegments, openNotice, forceAutoSkip, //防止重复调用导致反复横跳 const Check = readySkip.readySkipCheck != skipTime[0]; readySkip.readySkipCheck = skipTime[0]; - if (!Check) return; + if (!Check || !(getVideo().currentTime < 5 || getVideo().currentTime + howLongToSkip(skipTime) >= skipTime[0])) return; clearTimeout(readySkip.readySkip); const handleSkip = () => { @@ -2056,13 +2056,13 @@ function reskipSponsorTime(segment: SponsorTime, forceSeek = false) { openNotice: skipInfo.openNotice, }); } else { - const skippedTime = Math.max(segment.segment[1] - getVideo().currentTime, 0); - const segmentDuration = segment.segment[1] - segment.segment[0]; - const fullSkip = skippedTime / segmentDuration > manualSkipPercentCount; + const skippedTime = Math.max(segment.segment[1] - getVideo().currentTime, 0); + const segmentDuration = segment.segment[1] - segment.segment[0]; + const fullSkip = skippedTime / segmentDuration > manualSkipPercentCount; - getVideo().currentTime = segment.segment[1]; - sendTelemetryAndCount([segment], skippedTime, fullSkip); - startSponsorSchedule(true, segment.segment[1], false); + getVideo().currentTime = segment.segment[1]; + sendTelemetryAndCount([segment], skippedTime, fullSkip); + startSponsorSchedule(true, segment.segment[1], false); } } } From b3cb1d95847f3e66e4df2ba49d0baaa7bd1b73da Mon Sep 17 00:00:00 2001 From: etherfun <124044584+etherfun@users.noreply.github.com> Date: Sun, 24 Nov 2024 00:02:48 +0800 Subject: [PATCH 06/11] Add advance skip notice switch --- public/_locales/en/messages.json | 25 +++++++++++++++++++---- public/_locales/zh_CN/messages.json | 25 +++++++++++++++++++---- public/_locales/zh_TW/messages.json | 25 +++++++++++++++++++---- public/options/options.html | 25 ++++++++++++++++++++++- src/components/SkipNoticeComponent.tsx | 28 ++++++++++++++++++++++---- src/config.ts | 4 ++++ src/content.ts | 18 ++++++++++++++--- src/utils/categoryUtils.ts | 13 ++++++++++-- 8 files changed, 141 insertions(+), 22 deletions(-) diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 13bda0ae..63c83dca 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -367,12 +367,20 @@ "message": "要跳到 {0} 吗?", "description": "Used for skipping to things (Skip to Highlight)" }, - "skipped": { + "autoSkipped": { "message": "{0} 准备跳过", + "description": "Example: Ready Sponsor Skipped" + }, + "autoMuted": { + "message": "{0} 准备静音", + "description": "Example: Ready Sponsor Muted" + }, + "skipped": { + "message": "{0} 已跳过", "description": "Example: Sponsor Skipped" }, "muted": { - "message": "{0} 准备静音", + "message": "{0} 已静音", "description": "Example: Sponsor Muted" }, "skipped_to_category": { @@ -468,11 +476,20 @@ "optionSectionExtensionRelated": { "message": "插件相关选项" }, + "advanceSkipNotice": { + "message": "提前显示“空降提醒弹窗”" + }, + "skipNoticeDurationBefore": { + "message": "“空降提醒弹窗”提前显示时间(秒):" + }, + "skipNoticeDurationBeforeDescription": { + "message": "提前提醒您跳过片段的弹窗的提前时间。" + }, "skipNoticeDuration": { - "message": "“空降提醒弹窗”显示持续时间(秒):" + "message": "“空降提醒弹窗”跳过后或跳过提醒显示时间(秒):" }, "skipNoticeDurationDescription": { - "message": "提醒您跳过片段的弹窗的显示时长。手动跳过片段的提醒弹窗可能会显示更久。" + "message": "您跳过片段或者提醒您跳过片段的弹窗的显示时长。用于您对片段投票或跳过/取消跳过。\n手动跳过片段的提醒弹窗可能会显示更久。" }, "shortCheck": { "message": "以下的提交短于您的最小持续时间选项。这代表它们可能已经被提交,只是由于该选项被忽略了。您确定要提交吗?" diff --git a/public/_locales/zh_CN/messages.json b/public/_locales/zh_CN/messages.json index 0de5177c..61c7fc16 100644 --- a/public/_locales/zh_CN/messages.json +++ b/public/_locales/zh_CN/messages.json @@ -367,12 +367,20 @@ "message": "要跳到 {0} 吗?", "description": "Used for skipping to things (Skip to Highlight)" }, - "skipped": { + "autoSkipped": { "message": "{0} 准备跳过", + "description": "Example: Ready Sponsor Skipped" + }, + "autoMuted": { + "message": "{0} 准备静音", + "description": "Example: Ready Sponsor Muted" + }, + "skipped": { + "message": "{0} 已跳过", "description": "Example: Sponsor Skipped" }, "muted": { - "message": "{0} 准备静音", + "message": "{0} 已静音", "description": "Example: Sponsor Muted" }, "skipped_to_category": { @@ -468,11 +476,20 @@ "optionSectionExtensionRelated": { "message": "插件相关选项" }, + "advanceSkipNotice": { + "message": "提前显示“空降提醒弹窗”" + }, + "skipNoticeDurationBefore": { + "message": "“空降提醒弹窗”提前显示时间(秒):" + }, + "skipNoticeDurationBeforeDescription": { + "message": "提前提醒您跳过片段的弹窗的提前时间。" + }, "skipNoticeDuration": { - "message": "“空降提醒弹窗”显示持续时间(秒):" + "message": "“空降提醒弹窗”跳过后或跳过提醒显示时间(秒):" }, "skipNoticeDurationDescription": { - "message": "提醒您跳过片段的弹窗的显示时长。手动跳过片段的提醒弹窗可能会显示更久。(请注意: 设置过久可能会在某些片段密集区域堆叠大量弹窗!)" + "message": "您跳过片段或者提醒您跳过片段的弹窗的显示时长。用于您对片段投票或跳过/取消跳过。\n手动跳过片段的提醒弹窗可能会显示更久。" }, "shortCheck": { "message": "以下的提交短于您的最小持续时间选项。这代表它们可能已经被提交,只是由于该选项被忽略了。您确定要提交吗?" diff --git a/public/_locales/zh_TW/messages.json b/public/_locales/zh_TW/messages.json index 026cacae..190f3b66 100644 --- a/public/_locales/zh_TW/messages.json +++ b/public/_locales/zh_TW/messages.json @@ -367,12 +367,20 @@ "message": "要跳到 {0} 嗎?", "description": "Used for skipping to things (Skip to Highlight)" }, - "skipped": { + "autoSkipped": { "message": "{0} 準備跳過", + "description": "Example: Ready Sponsor Skipped" + }, + "autoMuted": { + "message": "{0} 準備靜音", + "description": "Example: Ready Sponsor Muted" + }, + "skipped": { + "message": "{0} 已跳過", "description": "Example: Sponsor Skipped" }, "muted": { - "message": "{0} 準備靜音", + "message": "{0} 已靜音", "description": "Example: Sponsor Muted" }, "skipped_to_category": { @@ -468,11 +476,20 @@ "optionSectionExtensionRelated": { "message": "插件相關選項" }, + "advanceSkipNotice": { + "message": "提前顯示跳過提醒視窗" + }, + "skipNoticeDurationBefore": { + "message": "跳過提醒提前跳出視窗時間(秒):" + }, + "skipNoticeDurationBeforeDescription": { + "message": "跳過提醒提前跳出視窗的提前時常。" + }, "skipNoticeDuration": { - "message": "跳過提醒跳出視窗持續時間(秒):" + "message": "跳過后或跳過提醒顯示時間(秒):" }, "skipNoticeDurationDescription": { - "message": "跳過提醒跳出視窗的顯示時常。手動跳過的提醒可能會顯示更久。(請注意:設置過久可能會在某些片段密集區域堆疊大量彈窗!)" + "message": "您跳過片段或者跳過提醒跳出視窗的顯示時常。用於您對片段進行投票或者跳過/取消跳過。\n手動跳過的提醒可能會顯示更久。" }, "shortCheck": { "message": "以下的提交短於您的最小持續時間選項。這代表它們可能已經被提交,只是由於該選項被忽略了。您確定要提交嗎?" diff --git a/public/options/options.html b/public/options/options.html index 264cbe8e..13a6fa27 100644 --- a/public/options/options.html +++ b/public/options/options.html @@ -195,10 +195,33 @@

__MSG_optionSectionSkipNotice__

__MSG_skipNoticeDuration__ - +
__MSG_skipNoticeDurationDescription__
+
+
+ + +
+ +
+
+ + + +
__MSG_skipNoticeDurationBeforeDescription__
+
+
+
+ + 1
__MSG_skipNoticeDurationBeforeDescription__
diff --git a/src/components/NoticeComponent.tsx b/src/components/NoticeComponent.tsx index 7dbce02a..d1c05d2a 100644 --- a/src/components/NoticeComponent.tsx +++ b/src/components/NoticeComponent.tsx @@ -19,6 +19,8 @@ export interface NoticeProps { idSuffix?: string; fadeIn?: boolean; + fadeOut?: boolean; + startFaded?: boolean; firstColumn?: React.ReactElement[] | React.ReactElement; firstRow?: React.ReactElement; @@ -39,6 +41,8 @@ export interface NoticeProps { style?: React.CSSProperties; biggerCloseButton?: boolean; children?: React.ReactNode; + + advanceSkipNoticeShow: boolean; } interface MouseDownInfo { @@ -84,6 +88,7 @@ class NoticeComponent extends React.Component { this.parentRef = React.createRef(); const maxCountdownTime = () => { + if (this.props.advanceSkipNoticeShow) return Number(Config.config.skipNoticeDurationBefore) + 1; if (this.props.maxCountdownTime) return this.props.maxCountdownTime(); else return Config.config.skipNoticeDuration; }; @@ -310,7 +315,7 @@ class NoticeComponent extends React.Component { }); } - toggleManualPause(): void { + toggleManualPause = (): void => { this.setState( { countdownMode: @@ -342,7 +347,7 @@ class NoticeComponent extends React.Component { return; } - if (countdownTime == 3) { + if (countdownTime == 3 && !this.props.fadeOut) { //start fade out animation const notice = document.getElementById("sponsorSkipNotice" + this.idSuffix); notice?.style.removeProperty("animation"); diff --git a/src/components/SkipNoticeComponent.tsx b/src/components/SkipNoticeComponent.tsx index 52f84be9..a9861e49 100644 --- a/src/components/SkipNoticeComponent.tsx +++ b/src/components/SkipNoticeComponent.tsx @@ -11,7 +11,7 @@ import { SponsorTime, } from "../types"; import Utils from "../utils"; -import { getSkippingText } from "../utils/categoryUtils"; +import { getSkippingText, getAdvanceSkipText } from "../utils/categoryUtils"; import NoticeComponent from "./NoticeComponent"; import NoticeTextSelectionComponent from "./NoticeTextSectionComponent"; const utils = new Utils(); @@ -36,14 +36,21 @@ export interface SkipNoticeProps { autoSkip: boolean; startReskip?: boolean; + advanceSkipNotice?: boolean; // Contains functions and variables from the content script needed by the skip notice contentContainer: ContentContainer; closeListener: () => void; showKeybindHint?: boolean; smaller: boolean; + fadeIn: boolean; + fadeOut: boolean; + + componentDidMount?: () => void; unskipTime?: number; + + advanceSkipNoticeShow: boolean; } export interface SkipNoticeState { @@ -79,6 +86,7 @@ class SkipNoticeComponent extends React.Component { - if (Config.config.advanceSkipNotice && Config.config.skipNoticeDurationBefore > 0) { - return Config.config.skipNoticeDurationBefore + Config.config.skipNoticeDuration; - } else { - return Config.config.skipNoticeDuration; - } - }; const isMuteSegment = this.segments[0].actionType === ActionType.Mute; - const maxCountdownTime = isMuteSegment ? this.getFullDurationCountdown(0) : calculateCountDown; + const maxCountdownTime = isMuteSegment + ? this.getFullDurationCountdown(0) + : () => Config.config.skipNoticeDuration; const defaultSkipButtonState = this.props.startReskip ? SkipButtonState.Redo : SkipButtonState.Undo; const skipButtonStates = [ @@ -200,7 +205,8 @@ class SkipNoticeComponent extends React.Component= NoticeVisbilityMode.FadedForAll || (Config.config.noticeVisibilityMode >= NoticeVisbilityMode.FadedForAutoSkip && this.autoSkip) @@ -215,12 +221,20 @@ class SkipNoticeComponent extends React.Component this.onMouseEnter()} + advanceSkipNoticeShow={this.advanceSkipNoticeShow} > ); } + componentDidMount(): void { + if (this.props.componentDidMount) { + this.props.componentDidMount(); + } + } + getBottomRow(): JSX.Element[] { return [ /* Bottom Row */ @@ -420,8 +434,10 @@ class SkipNoticeComponent extends React.Component +