Improve close popup button

This commit is contained in:
Alec Rust 2022-03-13 11:42:16 +00:00
parent 24fc5e4370
commit f7510eea88
No known key found for this signature in database
GPG key ID: EB374231DBCA5067
2 changed files with 132 additions and 107 deletions

View file

@ -7,14 +7,26 @@
} }
/* /*
* IDs on container element (when inserted in page), <html> element, * Container when popup displayed in-page
* <body> element and main container
*/ */
#sponsorBlockPopupContainer { #sponsorBlockPopupContainer {
position: relative;
margin-bottom: 16px; margin-bottom: 16px;
} }
/*
* Disable fixed popup width when displayed in-page
*/
#sponsorBlockPopupContainer #sponsorBlockPopupBody {
width: auto;
}
/*
* Main containers
*/
#sponsorBlockPopupHTML { #sponsorBlockPopupHTML {
color-scheme: dark; color-scheme: dark;
} }
@ -33,14 +45,6 @@
text-align: center; text-align: center;
} }
/*
* Disable fixed popup width when displayed inline
*/
#sponsorBlockPopupContainer #sponsorBlockPopupBody {
width: auto;
}
/* /*
* Disable transition on all elements until the extension has loaded * Disable transition on all elements until the extension has loaded
*/ */
@ -49,6 +53,25 @@
transition: none !important; transition: none !important;
} }
/*
* Close popup button when displayed in-page
*/
.sbCloseButton {
background: transparent;
border: 0;
padding: 8px;
cursor: pointer;
position: absolute;
top: 5px;
right: 5px;
opacity: 0.5;
}
.sbCloseButton:hover {
opacity: 1;
}
/* /*
* Header logo * Header logo
*/ */

View file

@ -34,7 +34,7 @@ let sponsorVideoID: VideoID = null;
const skipNotices: SkipNotice[] = []; const skipNotices: SkipNotice[] = [];
let activeSkipKeybindElement: ToggleSkippable = null; let activeSkipKeybindElement: ToggleSkippable = null;
// JSON video info // JSON video info
let videoInfo: VideoInfo = null; let videoInfo: VideoInfo = null;
// The channel this video is about // The channel this video is about
let channelIDInfo: ChannelIDInfo; let channelIDInfo: ChannelIDInfo;
@ -221,8 +221,8 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
/** /**
* Called when the config is updated * Called when the config is updated
* *
* @param {String} changes * @param {String} changes
*/ */
function contentConfigUpdateListener(changes: StorageChangesObject) { function contentConfigUpdateListener(changes: StorageChangesObject) {
for (const key in changes) { for (const key in changes) {
@ -301,7 +301,7 @@ async function videoIDChange(id) {
// If enabled, it will check if this video is private or unlisted and double check with the user if the sponsors should be looked up // If enabled, it will check if this video is private or unlisted and double check with the user if the sponsors should be looked up
if (Config.config.checkForUnlistedVideos) { if (Config.config.checkForUnlistedVideos) {
const shouldContinue = confirm("SponsorBlock: You have the setting 'Ignore Unlisted/Private Videos' enabled." const shouldContinue = confirm("SponsorBlock: You have the setting 'Ignore Unlisted/Private Videos' enabled."
+ " Due to a change in how segment fetching works, this setting is not needed anymore as it cannot leak your video ID to the server." + " Due to a change in how segment fetching works, this setting is not needed anymore as it cannot leak your video ID to the server."
+ " It instead sends just the first 4 characters of a longer hash of the videoID to the server, and filters through a subset of the database." + " It instead sends just the first 4 characters of a longer hash of the videoID to the server, and filters through a subset of the database."
+ " More info about this implementation can be found here: https://github.com/ajayyy/SponsorBlockServer/issues/25" + " More info about this implementation can be found here: https://github.com/ajayyy/SponsorBlockServer/issues/25"
@ -327,13 +327,13 @@ async function videoIDChange(id) {
let controlsContainer = null; let controlsContainer = null;
utils.wait(() => { utils.wait(() => {
controlsContainer = document.getElementById("player-control-container") controlsContainer = document.getElementById("player-control-container")
return controlsContainer !== null return controlsContainer !== null
}).then(() => { }).then(() => {
observer.observe(document.getElementById("player-control-container"), { observer.observe(document.getElementById("player-control-container"), {
attributes: true, attributes: true,
childList: true, childList: true,
subtree: true subtree: true
}); });
}).catch(); }).catch();
} else { } else {
@ -456,7 +456,7 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
if (!video || video.paused) return; if (!video || video.paused) return;
if (currentTime === undefined || currentTime === null) { if (currentTime === undefined || currentTime === null) {
const virtualTime = lastKnownVideoTime.videoTime ? const virtualTime = lastKnownVideoTime.videoTime ?
(performance.now() - lastKnownVideoTime.preciseTime) / 1000 + lastKnownVideoTime.videoTime : null; (performance.now() - lastKnownVideoTime.preciseTime) / 1000 + lastKnownVideoTime.videoTime : null;
if (!isSafari() && virtualTime && Math.abs(virtualTime - video.currentTime) < 0.6){ if (!isSafari() && virtualTime && Math.abs(virtualTime - video.currentTime) < 0.6){
currentTime = virtualTime; currentTime = virtualTime;
@ -516,13 +516,13 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
if (forceVideoTime >= skipTime[0] && forceVideoTime < skipTime[1]) { if (forceVideoTime >= skipTime[0] && forceVideoTime < skipTime[1]) {
skipToTime({ skipToTime({
v: video, v: video,
skipTime, skipTime,
skippingSegments, skippingSegments,
openNotice: skipInfo.openNotice openNotice: skipInfo.openNotice
}); });
if (utils.getCategorySelection(currentSkip.category)?.option === CategorySkipOption.ManualSkip if (utils.getCategorySelection(currentSkip.category)?.option === CategorySkipOption.ManualSkip
|| currentSkip.actionType === ActionType.Mute) { || currentSkip.actionType === ActionType.Mute) {
forcedSkipTime = skipTime[0] + 0.001; forcedSkipTime = skipTime[0] + 0.001;
} else { } else {
@ -573,8 +573,8 @@ function inMuteSegment(currentTime: number): boolean {
*/ */
function incorrectVideoCheck(videoID?: string, sponsorTime?: SponsorTime): boolean { function incorrectVideoCheck(videoID?: string, sponsorTime?: SponsorTime): boolean {
const currentVideoID = getYouTubeVideoID(document); const currentVideoID = getYouTubeVideoID(document);
if (currentVideoID !== (videoID || sponsorVideoID) || (sponsorTime if (currentVideoID !== (videoID || sponsorVideoID) || (sponsorTime
&& (!sponsorTimes || !sponsorTimes?.some((time) => time.segment === sponsorTime.segment)) && (!sponsorTimes || !sponsorTimes?.some((time) => time.segment === sponsorTime.segment))
&& !sponsorTimesSubmitting.some((time) => time.segment === sponsorTime.segment))) { && !sponsorTimesSubmitting.some((time) => time.segment === sponsorTime.segment))) {
// Something has really gone wrong // Something has really gone wrong
console.error("[SponsorBlock] The videoID recorded when trying to skip is different than what it should be."); console.error("[SponsorBlock] The videoID recorded when trying to skip is different than what it should be.");
@ -592,13 +592,13 @@ function incorrectVideoCheck(videoID?: string, sponsorTime?: SponsorTime): boole
function setupVideoMutationListener() { function setupVideoMutationListener() {
const videoContainer = document.querySelector(".html5-video-container"); const videoContainer = document.querySelector(".html5-video-container");
if (!videoContainer || videoMutationObserver !== null || onInvidious) return; if (!videoContainer || videoMutationObserver !== null || onInvidious) return;
videoMutationObserver = new MutationObserver(refreshVideoAttachments); videoMutationObserver = new MutationObserver(refreshVideoAttachments);
videoMutationObserver.observe(videoContainer, { videoMutationObserver.observe(videoContainer, {
attributes: true, attributes: true,
childList: true, childList: true,
subtree: true subtree: true
}); });
} }
@ -647,19 +647,19 @@ function setupVideoListeners() {
// If already segments loaded before video, retry to skip starting segments // If already segments loaded before video, retry to skip starting segments
if (sponsorTimes) startSkipScheduleCheckingForStartSponsors(); if (sponsorTimes) startSkipScheduleCheckingForStartSponsors();
} }
// Check if an ad is playing // Check if an ad is playing
updateAdFlag(); updateAdFlag();
// Make sure it doesn't get double called with the playing event // Make sure it doesn't get double called with the playing event
if (Math.abs(lastCheckVideoTime - video.currentTime) > 0.3 if (Math.abs(lastCheckVideoTime - video.currentTime) > 0.3
|| (lastCheckVideoTime !== video.currentTime && Date.now() - lastCheckTime > 2000)) { || (lastCheckVideoTime !== video.currentTime && Date.now() - lastCheckTime > 2000)) {
lastCheckTime = Date.now(); lastCheckTime = Date.now();
lastCheckVideoTime = video.currentTime; lastCheckVideoTime = video.currentTime;
startSponsorSchedule(); startSponsorSchedule();
} }
}); });
video.addEventListener('playing', () => { video.addEventListener('playing', () => {
updateVirtualTime(); updateVirtualTime();
@ -669,7 +669,7 @@ function setupVideoListeners() {
|| (lastCheckVideoTime !== video.currentTime && Date.now() - lastCheckTime > 2000)) { || (lastCheckVideoTime !== video.currentTime && Date.now() - lastCheckTime > 2000)) {
lastCheckTime = Date.now(); lastCheckTime = Date.now();
lastCheckVideoTime = video.currentTime; lastCheckVideoTime = video.currentTime;
startSponsorSchedule(); startSponsorSchedule();
} }
}); });
@ -680,7 +680,7 @@ function setupVideoListeners() {
lastCheckVideoTime = video.currentTime; lastCheckVideoTime = video.currentTime;
updateVirtualTime(); updateVirtualTime();
startSponsorSchedule(); startSponsorSchedule();
} }
}); });
@ -696,12 +696,12 @@ function setupVideoListeners() {
videoTime: null, videoTime: null,
preciseTime: null preciseTime: null
} }
cancelSponsorSchedule(); cancelSponsorSchedule();
}; };
video.addEventListener('pause', paused); video.addEventListener('pause', paused);
video.addEventListener('waiting', paused); video.addEventListener('waiting', paused);
startSponsorSchedule(); startSponsorSchedule();
} }
} }
@ -717,10 +717,10 @@ function setupSkipButtonControlBar() {
if (!skipButtonControlBar) { if (!skipButtonControlBar) {
skipButtonControlBar = new SkipButtonControlBar({ skipButtonControlBar = new SkipButtonControlBar({
skip: (segment) => skipToTime({ skip: (segment) => skipToTime({
v: video, v: video,
skipTime: segment.segment, skipTime: segment.segment,
skippingSegments: [segment], skippingSegments: [segment],
openNotice: true, openNotice: true,
forceAutoSkip: true forceAutoSkip: true
}), }),
onMobileYouTube onMobileYouTube
@ -759,7 +759,7 @@ async function sponsorsLookup(id: string, keepOldSubmissions = true) {
const hashPrefix = (await utils.getHash(id, 1)).slice(0, 4) as VideoID & HashedValue; const hashPrefix = (await utils.getHash(id, 1)).slice(0, 4) as VideoID & HashedValue;
const response = await utils.asyncRequestToServer('GET', "/api/skipSegments/" + hashPrefix, { const response = await utils.asyncRequestToServer('GET', "/api/skipSegments/" + hashPrefix, {
categories, categories,
actionTypes: getEnabledActionTypes(), actionTypes: getEnabledActionTypes(),
userAgent: `${chrome.runtime.id}`, userAgent: `${chrome.runtime.id}`,
...extraRequestData ...extraRequestData
}); });
@ -768,7 +768,7 @@ async function sponsorsLookup(id: string, keepOldSubmissions = true) {
const recievedSegments: SponsorTime[] = JSON.parse(response.responseText) const recievedSegments: SponsorTime[] = JSON.parse(response.responseText)
?.filter((video) => video.videoID === id) ?.filter((video) => video.videoID === id)
?.map((video) => video.segments)[0]; ?.map((video) => video.segments)[0];
if (!recievedSegments || !recievedSegments.length) { if (!recievedSegments || !recievedSegments.length) {
// return if no video found // return if no video found
retryFetch(); retryFetch();
return; return;
@ -834,7 +834,7 @@ async function sponsorsLookup(id: string, keepOldSubmissions = true) {
} else if (response?.status === 404) { } else if (response?.status === 404) {
retryFetch(); retryFetch();
} }
lookupVipInformation(id); lookupVipInformation(id);
} }
@ -910,8 +910,8 @@ function retryFetch(): void {
} }
/** /**
* Only should be used when it is okay to skip a sponsor when in the middle of it * Only should be used when it is okay to skip a sponsor when in the middle of it
* *
* Ex. When segments are first loaded * Ex. When segments are first loaded
*/ */
function startSkipScheduleCheckingForStartSponsors() { function startSkipScheduleCheckingForStartSponsors() {
@ -922,7 +922,7 @@ function startSkipScheduleCheckingForStartSponsors() {
let found = false; let found = false;
let startingSegment: SponsorTime = null; let startingSegment: SponsorTime = null;
for (const time of sponsorTimes) { for (const time of sponsorTimes) {
if (time.segment[0] <= video.currentTime && time.segment[0] > startingSegmentTime && time.segment[1] > video.currentTime if (time.segment[0] <= video.currentTime && time.segment[0] > startingSegmentTime && time.segment[1] > video.currentTime
&& time.actionType !== ActionType.Poi) { && time.actionType !== ActionType.Poi) {
startingSegmentTime = time.segment[0]; startingSegmentTime = time.segment[0];
startingSegment = time; startingSegment = time;
@ -932,7 +932,7 @@ function startSkipScheduleCheckingForStartSponsors() {
} }
if (!found) { if (!found) {
for (const time of sponsorTimesSubmitting) { for (const time of sponsorTimesSubmitting) {
if (time.segment[0] <= video.currentTime && time.segment[0] > startingSegmentTime && time.segment[1] > video.currentTime if (time.segment[0] <= video.currentTime && time.segment[0] > startingSegmentTime && time.segment[1] > video.currentTime
&& time.actionType !== ActionType.Poi) { && time.actionType !== ActionType.Poi) {
startingSegmentTime = time.segment[0]; startingSegmentTime = time.segment[0];
startingSegment = time; startingSegment = time;
@ -951,8 +951,8 @@ function startSkipScheduleCheckingForStartSponsors() {
if (skipOption !== CategorySkipOption.ShowOverlay) { if (skipOption !== CategorySkipOption.ShowOverlay) {
skipToTime({ skipToTime({
v: video, v: video,
skipTime: time.segment, skipTime: time.segment,
skippingSegments: [time], skippingSegments: [time],
openNotice: true, openNotice: true,
unskipTime: video.currentTime unskipTime: video.currentTime
}); });
@ -975,7 +975,7 @@ function startSkipScheduleCheckingForStartSponsors() {
/** /**
* Get the video info for the current tab from YouTube * Get the video info for the current tab from YouTube
* *
* TODO: Replace * TODO: Replace
*/ */
async function getVideoInfo(): Promise<void> { async function getVideoInfo(): Promise<void> {
@ -1023,9 +1023,9 @@ function getYouTubeVideoIDFromURL(url: string): string | boolean {
//Attempt to parse url //Attempt to parse url
let urlObject: URL = null; let urlObject: URL = null;
try { try {
urlObject = new URL(url); urlObject = new URL(url);
} catch (e) { } catch (e) {
console.error("[SB] Unable to parse URL: " + url); console.error("[SB] Unable to parse URL: " + url);
return false; return false;
} }
@ -1143,7 +1143,7 @@ async function whitelistCheck() {
} }
//see if this is a whitelisted channel //see if this is a whitelisted channel
if (whitelistedChannels != undefined && if (whitelistedChannels != undefined &&
channelIDInfo.status === ChannelIDStatus.Found && whitelistedChannels.includes(channelIDInfo.id)) { channelIDInfo.status === ChannelIDStatus.Found && whitelistedChannels.includes(channelIDInfo.id)) {
channelWhitelisted = true; channelWhitelisted = true;
} }
@ -1155,24 +1155,24 @@ async function whitelistCheck() {
/** /**
* Returns info about the next upcoming sponsor skip * Returns info about the next upcoming sponsor skip
*/ */
function getNextSkipIndex(currentTime: number, includeIntersectingSegments: boolean, includeNonIntersectingSegments: boolean): function getNextSkipIndex(currentTime: number, includeIntersectingSegments: boolean, includeNonIntersectingSegments: boolean):
{array: ScheduledTime[], index: number, endIndex: number, openNotice: boolean} { {array: ScheduledTime[], index: number, endIndex: number, openNotice: boolean} {
const { includedTimes: submittedArray, scheduledTimes: sponsorStartTimes } = const { includedTimes: submittedArray, scheduledTimes: sponsorStartTimes } =
getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments); getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments);
const { scheduledTimes: sponsorStartTimesAfterCurrentTime } = getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, true, true); const { scheduledTimes: sponsorStartTimesAfterCurrentTime } = getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, true, true);
const minSponsorTimeIndex = sponsorStartTimes.indexOf(Math.min(...sponsorStartTimesAfterCurrentTime)); const minSponsorTimeIndex = sponsorStartTimes.indexOf(Math.min(...sponsorStartTimesAfterCurrentTime));
const endTimeIndex = getLatestEndTimeIndex(submittedArray, minSponsorTimeIndex); const endTimeIndex = getLatestEndTimeIndex(submittedArray, minSponsorTimeIndex);
const { includedTimes: unsubmittedArray, scheduledTimes: unsubmittedSponsorStartTimes } = const { includedTimes: unsubmittedArray, scheduledTimes: unsubmittedSponsorStartTimes } =
getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, includeNonIntersectingSegments); getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, includeNonIntersectingSegments);
const { scheduledTimes: unsubmittedSponsorStartTimesAfterCurrentTime } = getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, false, false); const { scheduledTimes: unsubmittedSponsorStartTimesAfterCurrentTime } = getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, false, false);
const minUnsubmittedSponsorTimeIndex = unsubmittedSponsorStartTimes.indexOf(Math.min(...unsubmittedSponsorStartTimesAfterCurrentTime)); const minUnsubmittedSponsorTimeIndex = unsubmittedSponsorStartTimes.indexOf(Math.min(...unsubmittedSponsorStartTimesAfterCurrentTime));
const previewEndTimeIndex = getLatestEndTimeIndex(unsubmittedArray, minUnsubmittedSponsorTimeIndex); const previewEndTimeIndex = getLatestEndTimeIndex(unsubmittedArray, minUnsubmittedSponsorTimeIndex);
if ((minUnsubmittedSponsorTimeIndex === -1 && minSponsorTimeIndex !== -1) || if ((minUnsubmittedSponsorTimeIndex === -1 && minSponsorTimeIndex !== -1) ||
sponsorStartTimes[minSponsorTimeIndex] < unsubmittedSponsorStartTimes[minUnsubmittedSponsorTimeIndex]) { sponsorStartTimes[minSponsorTimeIndex] < unsubmittedSponsorStartTimes[minUnsubmittedSponsorTimeIndex]) {
return { return {
array: submittedArray, array: submittedArray,
@ -1192,20 +1192,20 @@ function getNextSkipIndex(currentTime: number, includeIntersectingSegments: bool
/** /**
* This returns index if the skip option is not AutoSkip * This returns index if the skip option is not AutoSkip
* *
* Finds the last endTime that occurs in a segment that the given * Finds the last endTime that occurs in a segment that the given
* segment skips into that is part of an AutoSkip category. * segment skips into that is part of an AutoSkip category.
* *
* Used to find where a segment should truely skip to if there are intersecting submissions due to * Used to find where a segment should truely skip to if there are intersecting submissions due to
* them having different categories. * them having different categories.
* *
* @param sponsorTimes * @param sponsorTimes
* @param index Index of the given sponsor * @param index Index of the given sponsor
* @param hideHiddenSponsors * @param hideHiddenSponsors
*/ */
function getLatestEndTimeIndex(sponsorTimes: SponsorTime[], index: number, hideHiddenSponsors = true): number { function getLatestEndTimeIndex(sponsorTimes: SponsorTime[], index: number, hideHiddenSponsors = true): number {
// Only combine segments for AutoSkip // Only combine segments for AutoSkip
if (index == -1 || if (index == -1 ||
!shouldAutoSkip(sponsorTimes[index]) !shouldAutoSkip(sponsorTimes[index])
|| sponsorTimes[index].actionType !== ActionType.Skip) { || sponsorTimes[index].actionType !== ActionType.Skip) {
return index; return index;
@ -1218,7 +1218,7 @@ function getLatestEndTimeIndex(sponsorTimes: SponsorTime[], index: number, hideH
const currentSegment = sponsorTimes[i].segment; const currentSegment = sponsorTimes[i].segment;
const latestEndTime = sponsorTimes[latestEndTimeIndex].segment[1]; const latestEndTime = sponsorTimes[latestEndTimeIndex].segment[1];
if (currentSegment[0] <= latestEndTime && currentSegment[1] > latestEndTime if (currentSegment[0] <= latestEndTime && currentSegment[1] > latestEndTime
&& (!hideHiddenSponsors || sponsorTimes[i].hidden === SponsorHideType.Visible) && (!hideHiddenSponsors || sponsorTimes[i].hidden === SponsorHideType.Visible)
&& shouldAutoSkip(sponsorTimes[i]) && shouldAutoSkip(sponsorTimes[i])
&& sponsorTimes[i].actionType === ActionType.Skip) { && sponsorTimes[i].actionType === ActionType.Skip) {
@ -1238,11 +1238,11 @@ function getLatestEndTimeIndex(sponsorTimes: SponsorTime[], index: number, hideH
/** /**
* Gets just the start times from a sponsor times array. * Gets just the start times from a sponsor times array.
* Optionally specify a minimum * Optionally specify a minimum
* *
* @param sponsorTimes * @param sponsorTimes
* @param minimum * @param minimum
* @param hideHiddenSponsors * @param hideHiddenSponsors
* @param includeIntersectingSegments If true, it will include segments that start before * @param includeIntersectingSegments If true, it will include segments that start before
* the current time, but end after * the current time, but end after
*/ */
function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments: boolean, includeNonIntersectingSegments: boolean, function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments: boolean, includeNonIntersectingSegments: boolean,
@ -1271,14 +1271,14 @@ function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments:
for (let i = 0; i < possibleTimes.length; i++) { for (let i = 0; i < possibleTimes.length; i++) {
if ((minimum === undefined if ((minimum === undefined
|| ((includeNonIntersectingSegments && possibleTimes[i].scheduledTime >= minimum) || ((includeNonIntersectingSegments && possibleTimes[i].scheduledTime >= minimum)
|| (includeIntersectingSegments && possibleTimes[i].scheduledTime < minimum && possibleTimes[i].segment[1] > minimum))) || (includeIntersectingSegments && possibleTimes[i].scheduledTime < minimum && possibleTimes[i].segment[1] > minimum)))
&& (!onlySkippableSponsors || shouldSkip(possibleTimes[i])) && (!onlySkippableSponsors || shouldSkip(possibleTimes[i]))
&& (!hideHiddenSponsors || possibleTimes[i].hidden === SponsorHideType.Visible) && (!hideHiddenSponsors || possibleTimes[i].hidden === SponsorHideType.Visible)
&& possibleTimes[i].actionType !== ActionType.Poi) { && possibleTimes[i].actionType !== ActionType.Poi) {
scheduledTimes.push(possibleTimes[i].scheduledTime); scheduledTimes.push(possibleTimes[i].scheduledTime);
includedTimes.push(possibleTimes[i]); includedTimes.push(possibleTimes[i]);
} }
} }
return { includedTimes, scheduledTimes }; return { includedTimes, scheduledTimes };
@ -1286,8 +1286,8 @@ function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments:
/** /**
* Skip to exact time in a video and autoskips * Skip to exact time in a video and autoskips
* *
* @param time * @param time
*/ */
function previewTime(time: number, unpause = true) { function previewTime(time: number, unpause = true) {
video.currentTime = time; video.currentTime = time;
@ -1312,7 +1312,7 @@ function sendTelemetryAndCount(skippingSegments: SponsorTime[], secondsSkipped:
Config.config.skipCount = Config.config.skipCount + 1; Config.config.skipCount = Config.config.skipCount + 1;
counted = true; counted = true;
} }
if (fullSkip) utils.asyncRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + segment.UUID); if (fullSkip) utils.asyncRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + segment.UUID);
} }
} }
@ -1325,7 +1325,7 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
// There will only be one submission if it is manual skip // There will only be one submission if it is manual skip
const autoSkip: boolean = forceAutoSkip || shouldAutoSkip(skippingSegments[0]); const autoSkip: boolean = forceAutoSkip || shouldAutoSkip(skippingSegments[0]);
if ((autoSkip || sponsorTimesSubmitting.some((time) => time.segment === skippingSegments[0].segment)) if ((autoSkip || sponsorTimesSubmitting.some((time) => time.segment === skippingSegments[0].segment))
&& v.currentTime !== skipTime[1]) { && v.currentTime !== skipTime[1]) {
switch(skippingSegments[0].actionType) { switch(skippingSegments[0].actionType) {
case ActionType.Poi: case ActionType.Poi:
@ -1366,8 +1366,8 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
}) })
} }
if (!autoSkip if (!autoSkip
&& skippingSegments.length === 1 && skippingSegments.length === 1
&& skippingSegments[0].actionType === ActionType.Poi) { && skippingSegments[0].actionType === ActionType.Poi) {
skipButtonControlBar.enable(skippingSegments[0]); skipButtonControlBar.enable(skippingSegments[0]);
if (onMobileYouTube || Config.config.skipKeybind == null) skipButtonControlBar.setShowKeybindHint(false); if (onMobileYouTube || Config.config.skipKeybind == null) skipButtonControlBar.setShowKeybindHint(false);
@ -1400,7 +1400,7 @@ function unskipSponsorTime(segment: SponsorTime, unskipTime: number = null) {
//add a tiny bit of time to make sure it is not skipped again //add a tiny bit of time to make sure it is not skipped again
video.currentTime = unskipTime ?? segment.segment[0] + 0.001; video.currentTime = unskipTime ?? segment.segment[0] + 0.001;
} }
} }
function reskipSponsorTime(segment: SponsorTime) { function reskipSponsorTime(segment: SponsorTime) {
@ -1411,7 +1411,7 @@ function reskipSponsorTime(segment: SponsorTime) {
const skippedTime = Math.max(segment.segment[1] - video.currentTime, 0); const skippedTime = Math.max(segment.segment[1] - video.currentTime, 0);
const segmentDuration = segment.segment[1] - segment.segment[0]; const segmentDuration = segment.segment[1] - segment.segment[0];
const fullSkip = skippedTime / segmentDuration > manualSkipPercentCount; const fullSkip = skippedTime / segmentDuration > manualSkipPercentCount;
video.currentTime = segment.segment[1]; video.currentTime = segment.segment[1];
sendTelemetryAndCount([segment], skippedTime, fullSkip); sendTelemetryAndCount([segment], skippedTime, fullSkip);
startSponsorSchedule(true, segment.segment[1], false); startSponsorSchedule(true, segment.segment[1], false);
@ -1463,8 +1463,8 @@ function shouldAutoSkip(segment: SponsorTime): boolean {
} }
function shouldSkip(segment: SponsorTime): boolean { function shouldSkip(segment: SponsorTime): boolean {
return (segment.actionType !== ActionType.Full return (segment.actionType !== ActionType.Full
&& utils.getCategorySelection(segment.category)?.option !== CategorySkipOption.ShowOverlay) && utils.getCategorySelection(segment.category)?.option !== CategorySkipOption.ShowOverlay)
|| (Config.config.autoSkipOnMusicVideos && sponsorTimes?.some((s) => s.category === "music_offtopic")); || (Config.config.autoSkipOnMusicVideos && sponsorTimes?.some((s) => s.category === "music_offtopic"));
} }
@ -1482,10 +1482,10 @@ async function createButtons(): Promise<void> {
createButton("info", "openPopup", openInfoMenu, "PlayerInfoIconSponsorBlocker.svg"); createButton("info", "openPopup", openInfoMenu, "PlayerInfoIconSponsorBlocker.svg");
const controlsContainer = getControls(); const controlsContainer = getControls();
if (Config.config.autoHideInfoButton && !onInvidious && controlsContainer if (Config.config.autoHideInfoButton && !onInvidious && controlsContainer
&& playerButtons["info"]?.button && !controlsWithEventListeners.includes(controlsContainer)) { && playerButtons["info"]?.button && !controlsWithEventListeners.includes(controlsContainer)) {
controlsWithEventListeners.push(controlsContainer); controlsWithEventListeners.push(controlsContainer);
AnimationUtils.setupAutoHideAnimation(playerButtons["info"].button, controlsContainer); AnimationUtils.setupAutoHideAnimation(playerButtons["info"].button, controlsContainer);
} }
} }
@ -1580,7 +1580,7 @@ function startOrEndTimingNewSegment() {
const existingSegment = getIncompleteSegment(); const existingSegment = getIncompleteSegment();
const existingTime = existingSegment.segment[0]; const existingTime = existingSegment.segment[0];
const currentTime = roundedTime; const currentTime = roundedTime;
// Swap timestamps if the user put the segment end before the start // Swap timestamps if the user put the segment end before the start
existingSegment.segment = [Math.min(existingTime, currentTime), Math.max(existingTime, currentTime)]; existingSegment.segment = [Math.min(existingTime, currentTime), Math.max(existingTime, currentTime)];
} }
@ -1677,17 +1677,19 @@ function openInfoMenu() {
popup.innerHTML = htmlData; popup.innerHTML = htmlData;
//close button //close button
const closeButton = document.createElement("div"); const closeButton = document.createElement("button");
closeButton.innerText = chrome.i18n.getMessage("closePopup"); const closeButtonIcon = document.createElement("img");
closeButton.classList.add("smallLink"); closeButtonIcon.src = chrome.extension.getURL("icons/close.png");
closeButton.setAttribute("align", "center"); closeButtonIcon.width = 16;
closeButtonIcon.height = 16;
closeButton.appendChild(closeButtonIcon);
closeButton.setAttribute("title", chrome.i18n.getMessage("closePopup"));
closeButton.classList.add("sbCloseButton");
closeButton.addEventListener("click", closeInfoMenu); closeButton.addEventListener("click", closeInfoMenu);
// Theme based color
closeButton.style.color = "var(--yt-spec-text-primary)";
//add the close button //add the close button
popup.prepend(closeButton); popup.prepend(closeButton);
const parentNodes = document.querySelectorAll("#secondary"); const parentNodes = document.querySelectorAll("#secondary");
let parentNode = null; let parentNode = null;
for (let i = 0; i < parentNodes.length; i++) { for (let i = 0; i < parentNodes.length; i++) {
@ -1798,7 +1800,7 @@ async function vote(type: number, UUID: SegmentUUID, category?: Category, skipNo
} else { } else {
skipNotice.setNoticeInfoMessage.bind(skipNotice)(GenericUtils.getErrorMessage(response.statusCode, response.responseText)) skipNotice.setNoticeInfoMessage.bind(skipNotice)(GenericUtils.getErrorMessage(response.statusCode, response.responseText))
} }
skipNotice.resetVoteButtonInfo.bind(skipNotice)(); skipNotice.resetVoteButtonInfo.bind(skipNotice)();
} }
} }
@ -1824,7 +1826,7 @@ async function voteAsync(type: number, UUID: SegmentUUID, category?: Category):
// Count this as a skip // Count this as a skip
Config.config.minutesSaved = Config.config.minutesSaved + factor * (sponsorTimes[sponsorIndex].segment[1] - sponsorTimes[sponsorIndex].segment[0]) / 60; Config.config.minutesSaved = Config.config.minutesSaved + factor * (sponsorTimes[sponsorIndex].segment[1] - sponsorTimes[sponsorIndex].segment[0]) / 60;
Config.config.skipCount = Config.config.skipCount + factor; Config.config.skipCount = Config.config.skipCount + factor;
} }
@ -1886,8 +1888,8 @@ function submitSponsorTimes() {
submissionNotice.close(); submissionNotice.close();
submissionNotice = null; submissionNotice = null;
return; return;
} }
if (sponsorTimesSubmitting !== undefined && sponsorTimesSubmitting.length > 0) { if (sponsorTimesSubmitting !== undefined && sponsorTimesSubmitting.length > 0) {
submissionNotice = new SubmissionNotice(skipNoticeContentContainer, sendSubmitMessage); submissionNotice = new SubmissionNotice(skipNoticeContentContainer, sendSubmitMessage);
} }
@ -1923,9 +1925,9 @@ async function sendSubmitMessage() {
for (let i = 0; i < sponsorTimesSubmitting.length; i++) { for (let i = 0; i < sponsorTimesSubmitting.length; i++) {
const duration = sponsorTimesSubmitting[i].segment[1] - sponsorTimesSubmitting[i].segment[0]; const duration = sponsorTimesSubmitting[i].segment[1] - sponsorTimesSubmitting[i].segment[0];
if (duration > 0 && duration < Config.config.minDuration) { if (duration > 0 && duration < Config.config.minDuration) {
const confirmShort = chrome.i18n.getMessage("shortCheck") + "\n\n" + const confirmShort = chrome.i18n.getMessage("shortCheck") + "\n\n" +
getSegmentsMessage(sponsorTimesSubmitting); getSegmentsMessage(sponsorTimesSubmitting);
if(!confirm(confirmShort)) return; if(!confirm(confirmShort)) return;
} }
} }
@ -2030,10 +2032,10 @@ function hotkeyListener(e: KeyboardEvent): void {
|| document.activeElement?.id?.toLowerCase()?.includes("editable")) return; || document.activeElement?.id?.toLowerCase()?.includes("editable")) return;
const key: Keybind = { const key: Keybind = {
key: e.key, key: e.key,
code: e.code, code: e.code,
alt: e.altKey, alt: e.altKey,
ctrl: e.ctrlKey, ctrl: e.ctrlKey,
shift: e.shiftKey shift: e.shiftKey
}; };
@ -2094,7 +2096,7 @@ function sendRequestToCustomServer(type, fullAddress, callback) {
xmlhttp.onreadystatechange = function () { xmlhttp.onreadystatechange = function () {
callback(xmlhttp, false); callback(xmlhttp, false);
}; };
xmlhttp.onerror = function() { xmlhttp.onerror = function() {
callback(xmlhttp, true); callback(xmlhttp, true);
}; };
@ -2138,7 +2140,7 @@ function showTimeWithoutSkips(skippedDuration: number): void {
display.appendChild(duration); display.appendChild(duration);
} }
const durationAfterSkips = utils.getFormattedTime(video?.duration - skippedDuration) const durationAfterSkips = utils.getFormattedTime(video?.duration - skippedDuration)
duration.innerText = (durationAfterSkips == null || skippedDuration <= 0) ? "" : " (" + durationAfterSkips + ")"; duration.innerText = (durationAfterSkips == null || skippedDuration <= 0) ? "" : " (" + durationAfterSkips + ")";
@ -2146,7 +2148,7 @@ function showTimeWithoutSkips(skippedDuration: number): void {
function checkForPreloadedSegment() { function checkForPreloadedSegment() {
if (loadedPreloadedSegment) return; if (loadedPreloadedSegment) return;
loadedPreloadedSegment = true; loadedPreloadedSegment = true;
const hashParams = getHashParams(); const hashParams = getHashParams();
@ -2174,4 +2176,4 @@ function checkForPreloadedSegment() {
Config.config.unsubmittedSegments[sponsorVideoID] = sponsorTimesSubmitting; Config.config.unsubmittedSegments[sponsorVideoID] = sponsorTimesSubmitting;
Config.forceSyncUpdate("unsubmittedSegments"); Config.forceSyncUpdate("unsubmittedSegments");
} }
} }