mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-14 23:47:04 +03:00
Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into chapters
This commit is contained in:
201
src/content.ts
201
src/content.ts
@@ -1,7 +1,7 @@
|
||||
import Config from "./config";
|
||||
import { SponsorTime, CategorySkipOption, VideoID, SponsorHideType, VideoInfo, StorageChangesObject, ChannelIDInfo, ChannelIDStatus, SponsorSourceType, SegmentUUID, Category, SkipToTimeParams, ToggleSkippable, ActionType, ScheduledTime } from "./types";
|
||||
import { SponsorTime, CategorySkipOption, VideoID, SponsorHideType, VideoInfo, StorageChangesObject, ChannelIDInfo, ChannelIDStatus, SponsorSourceType, SegmentUUID, Category, SkipToTimeParams, ToggleSkippable, ActionType, ScheduledTime, HashedValue } from "./types";
|
||||
|
||||
import { ContentContainer } from "./types";
|
||||
import { ContentContainer, Keybind } from "./types";
|
||||
import Utils from "./utils";
|
||||
const utils = new Utils();
|
||||
|
||||
@@ -16,6 +16,7 @@ import * as Chat from "./js-components/chat";
|
||||
import { SkipButtonControlBar } from "./js-components/skipButtonControlBar";
|
||||
import { getStartTimeFromUrl } from "./utils/urlParser";
|
||||
import { findValidElement, getControls, getHashParams, isVisible } from "./utils/pageUtils";
|
||||
import { isSafari, keybindEquals } from "./utils/configUtils";
|
||||
import { CategoryPill } from "./render/CategoryPill";
|
||||
import { AnimationUtils } from "./utils/animationUtils";
|
||||
import { GenericUtils } from "./utils/genericUtils";
|
||||
@@ -44,6 +45,7 @@ let lockedCategories: Category[] = [];
|
||||
// Skips are rescheduled every seeking event.
|
||||
// Skips are canceled every seeking event
|
||||
let currentSkipSchedule: NodeJS.Timeout = null;
|
||||
let currentSkipInterval: NodeJS.Timeout = null;
|
||||
|
||||
/** Has the sponsor been skipped */
|
||||
let sponsorSkipped: boolean[] = [];
|
||||
@@ -97,6 +99,7 @@ addHotkeyListener();
|
||||
|
||||
/** Segments created by the user which have not yet been submitted. */
|
||||
let sponsorTimesSubmitting: SponsorTime[] = [];
|
||||
let loadedPreloadedSegment = false;
|
||||
|
||||
//becomes true when isInfoFound is called
|
||||
//this is used to close the popup on YouTube when the other popup opens
|
||||
@@ -135,6 +138,9 @@ const manualSkipPercentCount = 0.5;
|
||||
|
||||
//get messages from the background script and the popup
|
||||
chrome.runtime.onMessage.addListener(messageListener);
|
||||
|
||||
//store pressed modifier keys
|
||||
const pressedKeys = new Set();
|
||||
|
||||
function messageListener(request: Message, sender: unknown, sendResponse: (response: MessageResponse) => void): void | boolean {
|
||||
//messages from popup script
|
||||
@@ -206,6 +212,14 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
|
||||
case "reskip":
|
||||
reskipSponsorTime(sponsorTimes.find((segment) => segment.UUID === request.UUID));
|
||||
break;
|
||||
case "submitVote":
|
||||
vote(request.type, request.UUID).then((response) => sendResponse(response));
|
||||
return true;
|
||||
case "hideSegment":
|
||||
utils.getSponsorTimeFromUUID(sponsorTimes, request.UUID).hidden = request.type;
|
||||
utils.addHiddenSegment(sponsorVideoID, request.UUID, request.type);
|
||||
updatePreviewBar();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,8 +238,8 @@ function contentConfigUpdateListener(changes: StorageChangesObject) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!Config.configListeners.includes(contentConfigUpdateListener)) {
|
||||
Config.configListeners.push(contentConfigUpdateListener);
|
||||
if (!Config.configSyncListeners.includes(contentConfigUpdateListener)) {
|
||||
Config.configSyncListeners.push(contentConfigUpdateListener);
|
||||
}
|
||||
|
||||
function resetValues() {
|
||||
@@ -418,9 +432,13 @@ function videoOnReadyListener(): void {
|
||||
function cancelSponsorSchedule(): void {
|
||||
if (currentSkipSchedule !== null) {
|
||||
clearTimeout(currentSkipSchedule);
|
||||
|
||||
currentSkipSchedule = null;
|
||||
}
|
||||
|
||||
if (currentSkipInterval !== null) {
|
||||
clearInterval(currentSkipInterval);
|
||||
currentSkipInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -482,15 +500,16 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
|
||||
}
|
||||
}
|
||||
|
||||
const skippingFunction = () => {
|
||||
const skippingFunction = (forceVideoTime?: number) => {
|
||||
let forcedSkipTime: number = null;
|
||||
let forcedIncludeIntersectingSegments = false;
|
||||
let forcedIncludeNonIntersectingSegments = true;
|
||||
|
||||
if (incorrectVideoCheck(videoID, currentSkip)) return;
|
||||
forceVideoTime ||= video.currentTime;
|
||||
|
||||
if ((shouldSkip(currentSkip) || sponsorTimesSubmitting?.some((segment) => segment.segment === currentSkip.segment))
|
||||
&& video.currentTime >= skipTime[0] && video.currentTime < skipTime[1]) {
|
||||
&& forceVideoTime >= skipTime[0] && forceVideoTime < skipTime[1]) {
|
||||
skipToTime({
|
||||
v: video,
|
||||
skipTime,
|
||||
@@ -514,7 +533,22 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
|
||||
if (timeUntilSponsor <= 0) {
|
||||
skippingFunction();
|
||||
} else {
|
||||
currentSkipSchedule = setTimeout(skippingFunction, timeUntilSponsor * 1000 * (1 / video.playbackRate));
|
||||
const delayTime = timeUntilSponsor * 1000 * (1 / video.playbackRate);
|
||||
if (delayTime < 300 && utils.isFirefox() && !isSafari()) {
|
||||
// For Firefox, use interval instead of timeout near the end to combat imprecise video time
|
||||
const startIntervalTime = performance.now();
|
||||
const startVideoTime = video.currentTime;
|
||||
currentSkipInterval = setInterval(() => {
|
||||
const intervalDuration = performance.now() - startIntervalTime;
|
||||
if (intervalDuration >= delayTime || video.currentTime >= skipTime[0]) {
|
||||
clearInterval(currentSkipInterval);
|
||||
skippingFunction(Math.max(video.currentTime, startVideoTime + intervalDuration / 1000));
|
||||
}
|
||||
}, 5);
|
||||
} else {
|
||||
// Schedule for right before to be more precise than normal timeout
|
||||
currentSkipSchedule = setTimeout(skippingFunction, Math.max(0, delayTime - 30));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -686,17 +720,14 @@ async function sponsorsLookup(id: string, keepOldSubmissions = true) {
|
||||
setupVideoMutationListener();
|
||||
|
||||
// Create categories list
|
||||
const categories: string[] = [];
|
||||
for (const categorySelection of Config.config.categorySelections) {
|
||||
categories.push(categorySelection.name);
|
||||
}
|
||||
const categories: string[] = Config.config.categorySelections.map((category) => category.name);
|
||||
|
||||
const extraRequestData: Record<string, unknown> = {};
|
||||
const hashParams = getHashParams();
|
||||
if (hashParams.requiredSegment) extraRequestData.requiredSegment = hashParams.requiredSegment;
|
||||
|
||||
// Check for hashPrefix setting
|
||||
const hashPrefix = (await utils.getHash(id, 1)).substr(0, 4);
|
||||
const hashPrefix = (await utils.getHash(id, 1)).slice(0, 4) as VideoID & HashedValue;
|
||||
const response = await utils.asyncRequestToServer('GET', "/api/skipSegments/" + hashPrefix, {
|
||||
categories,
|
||||
actionTypes: getEnabledActionTypes(),
|
||||
@@ -735,10 +766,10 @@ async function sponsorsLookup(id: string, keepOldSubmissions = true) {
|
||||
|
||||
// Hide all submissions smaller than the minimum duration
|
||||
if (Config.config.minDuration !== 0) {
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
if (sponsorTimes[i].segment[1] - sponsorTimes[i].segment[0] < Config.config.minDuration
|
||||
&& sponsorTimes[i].actionType !== ActionType.Poi) {
|
||||
sponsorTimes[i].hidden = SponsorHideType.MinimumDuration;
|
||||
for (const segment of sponsorTimes) {
|
||||
const duration = segment[1] - segment[0];
|
||||
if (duration > 0 && duration < Config.config.minDuration) {
|
||||
segment.hidden = SponsorHideType.MinimumDuration;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -754,6 +785,18 @@ async function sponsorsLookup(id: string, keepOldSubmissions = true) {
|
||||
}
|
||||
}
|
||||
|
||||
// See if some segments should be hidden
|
||||
const downvotedData = Config.local.downvotedSegments[hashPrefix];
|
||||
if (downvotedData) {
|
||||
for (const segment of sponsorTimes) {
|
||||
const hashedUUID = await utils.getHash(segment.UUID, 1);
|
||||
const segmentDownvoteData = downvotedData.segments.find((downvote) => downvote.uuid === hashedUUID);
|
||||
if (segmentDownvoteData) {
|
||||
segment.hidden = segmentDownvoteData.hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
startSkipScheduleCheckingForStartSponsors();
|
||||
|
||||
//update the preview bar
|
||||
@@ -816,7 +859,7 @@ async function updateVipInfo(): Promise<boolean> {
|
||||
}
|
||||
|
||||
async function lockedCategoriesLookup(id: string): Promise<void> {
|
||||
const hashPrefix = (await utils.getHash(id, 1)).substr(0, 4);
|
||||
const hashPrefix = (await utils.getHash(id, 1)).slice(0, 4);
|
||||
const response = await utils.asyncRequestToServer("GET", "/api/lockCategories/" + hashPrefix);
|
||||
|
||||
if (response.ok) {
|
||||
@@ -926,6 +969,8 @@ async function getVideoInfo(): Promise<void> {
|
||||
|
||||
function getYouTubeVideoID(document: Document): string | boolean {
|
||||
const url = document.URL;
|
||||
// clips should never skip, going from clip to full video has no indications.
|
||||
if (url.includes("youtube.com/clip/")) return false;
|
||||
// skip to URL if matches youtube watch or invidious or matches youtube pattern
|
||||
if ((!url.includes("youtube.com")) || url.includes("/watch") || url.includes("/shorts/") || url.includes("playlist")) return getYouTubeVideoIDFromURL(url);
|
||||
// skip to document and don't hide if on /embed/
|
||||
@@ -979,8 +1024,8 @@ function getYouTubeVideoIDFromURL(url: string): string | boolean {
|
||||
return id.length == 11 ? id : false;
|
||||
} else if (urlObject.pathname.startsWith("/embed/") || urlObject.pathname.startsWith("/shorts/")) {
|
||||
try {
|
||||
const id = urlObject.pathname.split("/")[2];
|
||||
if (id && id.length >= 11) return id.substr(0, 11);
|
||||
const id = urlObject.pathname.split("/")[2]
|
||||
if (id?.length >=11 ) return id.slice(0, 11);
|
||||
} catch (e) {
|
||||
console.error("[SB] Video ID not valid for " + url);
|
||||
return false;
|
||||
@@ -1054,7 +1099,8 @@ async function whitelistCheck() {
|
||||
const getChannelID = () => videoInfo?.videoDetails?.channelId
|
||||
?? document.querySelector(".ytd-channel-name a")?.getAttribute("href")?.replace(/\/.+\//, "") // YouTube
|
||||
?? document.querySelector(".ytp-title-channel-logo")?.getAttribute("href")?.replace(/https:\/.+\//, "") // YouTube Embed
|
||||
?? document.querySelector("a > .channel-profile")?.parentElement?.getAttribute("href")?.replace(/\/.+\//, ""); // Invidious
|
||||
?? document.querySelector("a > .channel-profile")?.parentElement?.getAttribute("href")?.replace(/\/.+\//, "") // Invidious
|
||||
?? document.querySelector("a.slim-owner-icon-and-title")?.getAttribute("href")?.replace(/\/.+\//, ""); // Mobile YouTube
|
||||
|
||||
try {
|
||||
await utils.wait(() => !!getChannelID(), 6000, 20);
|
||||
@@ -1285,14 +1331,21 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
|
||||
if (autoSkip && Config.config.audioNotificationOnSkip) {
|
||||
const beep = new Audio(chrome.runtime.getURL("icons/beep.ogg"));
|
||||
beep.volume = video.volume * 0.1;
|
||||
const oldMetadata = navigator.mediaSession.metadata
|
||||
beep.play();
|
||||
beep.addEventListener("ended", () => {
|
||||
navigator.mediaSession.metadata = null;
|
||||
setTimeout(() =>
|
||||
navigator.mediaSession.metadata = oldMetadata
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
if (!autoSkip
|
||||
&& skippingSegments.length === 1
|
||||
&& skippingSegments[0].actionType === ActionType.Poi) {
|
||||
skipButtonControlBar.enable(skippingSegments[0]);
|
||||
if (onMobileYouTube) skipButtonControlBar.setShowKeybindHint(false);
|
||||
if (onMobileYouTube || Config.config.skipKeybind == null) skipButtonControlBar.setShowKeybindHint(false);
|
||||
|
||||
activeSkipKeybindElement?.setShowKeybindHint(false);
|
||||
activeSkipKeybindElement = skipButtonControlBar;
|
||||
@@ -1301,7 +1354,7 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
|
||||
//send out the message saying that a sponsor message was skipped
|
||||
if (!Config.config.dontShowNotice || !autoSkip) {
|
||||
const newSkipNotice = new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer, unskipTime);
|
||||
if (onMobileYouTube) newSkipNotice.setShowKeybindHint(false);
|
||||
if (onMobileYouTube || Config.config.skipKeybind == null) newSkipNotice.setShowKeybindHint(false);
|
||||
skipNotices.push(newSkipNotice);
|
||||
|
||||
activeSkipKeybindElement?.setShowKeybindHint(false);
|
||||
@@ -1508,7 +1561,8 @@ function startOrEndTimingNewSegment() {
|
||||
}
|
||||
|
||||
// Save the newly created segment
|
||||
Config.config.segmentTimes.set(sponsorVideoID, sponsorTimesSubmitting);
|
||||
Config.config.unsubmittedSegments[sponsorVideoID] = sponsorTimesSubmitting;
|
||||
Config.forceSyncUpdate("unsubmittedSegments");
|
||||
|
||||
// Make sure they know if someone has already submitted something it while they were watching
|
||||
sponsorsLookup(sponsorVideoID);
|
||||
@@ -1530,7 +1584,8 @@ function isSegmentCreationInProgress(): boolean {
|
||||
function cancelCreatingSegment() {
|
||||
if (isSegmentCreationInProgress()) {
|
||||
sponsorTimesSubmitting.splice(sponsorTimesSubmitting.length - 1, 1);
|
||||
Config.config.segmentTimes.set(sponsorVideoID, sponsorTimesSubmitting);
|
||||
Config.config.unsubmittedSegments[sponsorVideoID] = sponsorTimesSubmitting;
|
||||
Config.forceSyncUpdate("unsubmittedSegments");
|
||||
|
||||
if (sponsorTimesSubmitting.length <= 0) resetSponsorSubmissionNotice();
|
||||
}
|
||||
@@ -1540,7 +1595,7 @@ function cancelCreatingSegment() {
|
||||
}
|
||||
|
||||
function updateSponsorTimesSubmitting(getFromConfig = true) {
|
||||
const segmentTimes = Config.config.segmentTimes.get(sponsorVideoID);
|
||||
const segmentTimes = Config.config.unsubmittedSegments[sponsorVideoID];
|
||||
|
||||
//see if this data should be saved in the sponsorTimesSubmitting variable
|
||||
if (getFromConfig && segmentTimes != undefined) {
|
||||
@@ -1629,11 +1684,15 @@ function openInfoMenu() {
|
||||
const copy = <HTMLImageElement> popup.querySelector("#sbPopupIconCopyUserID");
|
||||
const check = <HTMLImageElement> popup.querySelector("#sbPopupIconCheck");
|
||||
const refreshSegments = <HTMLImageElement> popup.querySelector("#refreshSegments");
|
||||
const heart = <HTMLImageElement> popup.querySelector(".sbHeart");
|
||||
const close = <HTMLImageElement> popup.querySelector("#sbCloseDonate");
|
||||
logo.src = chrome.extension.getURL("icons/IconSponsorBlocker256px.png");
|
||||
settings.src = chrome.extension.getURL("icons/settings.svg");
|
||||
edit.src = chrome.extension.getURL("icons/pencil.svg");
|
||||
copy.src = chrome.extension.getURL("icons/clipboard.svg");
|
||||
check.src = chrome.extension.getURL("icons/check.svg");
|
||||
heart.src = chrome.extension.getURL("icons/heart.svg");
|
||||
close.src = chrome.extension.getURL("icons/close.png");
|
||||
refreshSegments.src = chrome.extension.getURL("icons/refresh.svg");
|
||||
|
||||
parentNode.insertBefore(popup, parentNode.firstChild);
|
||||
@@ -1670,7 +1729,7 @@ function closeInfoMenuAnd<T>(func: () => T): T {
|
||||
function clearSponsorTimes() {
|
||||
const currentVideoID = sponsorVideoID;
|
||||
|
||||
const sponsorTimes = Config.config.segmentTimes.get(currentVideoID);
|
||||
const sponsorTimes = Config.config.unsubmittedSegments[currentVideoID];
|
||||
|
||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
||||
const confirmMessage = chrome.i18n.getMessage("clearThis") + getSegmentsMessage(sponsorTimes)
|
||||
@@ -1680,7 +1739,8 @@ function clearSponsorTimes() {
|
||||
resetSponsorSubmissionNotice();
|
||||
|
||||
//clear the sponsor times
|
||||
Config.config.segmentTimes.delete(currentVideoID);
|
||||
delete Config.config.unsubmittedSegments[currentVideoID];
|
||||
Config.forceSyncUpdate("unsubmittedSegments");
|
||||
|
||||
//clear sponsor times submitting
|
||||
sponsorTimesSubmitting = [];
|
||||
@@ -1691,7 +1751,7 @@ function clearSponsorTimes() {
|
||||
}
|
||||
|
||||
//if skipNotice is null, it will not affect the UI
|
||||
async function vote(type: number, UUID: SegmentUUID, category?: Category, skipNotice?: SkipNoticeComponent): Promise<void> {
|
||||
async function vote(type: number, UUID: SegmentUUID, category?: Category, skipNotice?: SkipNoticeComponent): Promise<VoteResponse> {
|
||||
if (skipNotice !== null && skipNotice !== undefined) {
|
||||
//add loading info
|
||||
skipNotice.addVoteButtonInfo.bind(skipNotice)(chrome.i18n.getMessage("Loading"))
|
||||
@@ -1719,6 +1779,8 @@ async function vote(type: number, UUID: SegmentUUID, category?: Category, skipNo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
async function voteAsync(type: number, UUID: SegmentUUID, category?: Category): Promise<VoteResponse> {
|
||||
@@ -1748,7 +1810,29 @@ async function voteAsync(type: number, UUID: SegmentUUID, category?: Category):
|
||||
type: type,
|
||||
UUID: UUID,
|
||||
category: category
|
||||
}, resolve);
|
||||
}, (response) => {
|
||||
if (response.successType === 1) {
|
||||
// Change the sponsor locally
|
||||
const segment = utils.getSponsorTimeFromUUID(sponsorTimes, UUID);
|
||||
if (segment) {
|
||||
if (type === 0) {
|
||||
segment.hidden = SponsorHideType.Downvoted;
|
||||
} else if (category) {
|
||||
segment.category = category;
|
||||
} else if (type === 1) {
|
||||
segment.hidden = SponsorHideType.Visible;
|
||||
}
|
||||
|
||||
if (!category && !Config.config.isVip) {
|
||||
utils.addHiddenSegment(sponsorVideoID, segment.UUID, segment.hidden);
|
||||
}
|
||||
|
||||
updatePreviewBar();
|
||||
}
|
||||
}
|
||||
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1807,7 +1891,8 @@ async function sendSubmitMessage() {
|
||||
}
|
||||
|
||||
//update sponsorTimes
|
||||
Config.config.segmentTimes.set(sponsorVideoID, sponsorTimesSubmitting);
|
||||
Config.config.unsubmittedSegments[sponsorVideoID] = sponsorTimesSubmitting;
|
||||
Config.forceSyncUpdate("unsubmittedSegments");
|
||||
|
||||
// Check to see if any of the submissions are below the minimum duration set
|
||||
if (Config.config.minDuration > 0) {
|
||||
@@ -1834,7 +1919,8 @@ async function sendSubmitMessage() {
|
||||
stopAnimation();
|
||||
|
||||
// Remove segments from storage since they've already been submitted
|
||||
Config.config.segmentTimes.delete(sponsorVideoID);
|
||||
delete Config.config.unsubmittedSegments[sponsorVideoID];
|
||||
Config.forceSyncUpdate("unsubmittedSegments");
|
||||
|
||||
const newSegments = sponsorTimesSubmitting;
|
||||
try {
|
||||
@@ -1883,7 +1969,7 @@ function getSegmentsMessage(sponsorTimes: SponsorTime[]): string {
|
||||
let timeMessage = utils.getFormattedTime(sponsorTimes[i].segment[s]);
|
||||
//if this is an end time
|
||||
if (s == 1) {
|
||||
timeMessage = " to " + timeMessage;
|
||||
timeMessage = " " + chrome.i18n.getMessage("to") + " " + timeMessage;
|
||||
} else if (i > 0) {
|
||||
//add commas if necessary
|
||||
timeMessage = ", " + timeMessage;
|
||||
@@ -1908,30 +1994,47 @@ function addPageListeners(): void {
|
||||
|
||||
function addHotkeyListener(): void {
|
||||
document.addEventListener("keydown", hotkeyListener);
|
||||
document.addEventListener("keyup", (e) => pressedKeys.delete(e.key));
|
||||
document.addEventListener("focus", (e) => pressedKeys.clear());
|
||||
}
|
||||
|
||||
function hotkeyListener(e: KeyboardEvent): void {
|
||||
if (["textarea", "input"].includes(document.activeElement?.tagName?.toLowerCase())
|
||||
|| document.activeElement?.id?.toLowerCase()?.includes("editable")) return;
|
||||
|
||||
const key = e.key;
|
||||
if (["Alt", "Control", "Shift", "AltGraph"].includes(e.key)) {
|
||||
pressedKeys.add(e.key);
|
||||
return;
|
||||
}
|
||||
|
||||
const key:Keybind = {key: e.key, code: e.code, alt: pressedKeys.has("Alt"), ctrl: pressedKeys.has("Control"), shift: pressedKeys.has("Shift")};
|
||||
|
||||
const skipKey = Config.config.skipKeybind;
|
||||
const startSponsorKey = Config.config.startSponsorKeybind;
|
||||
const submitKey = Config.config.submitKeybind;
|
||||
|
||||
switch (key) {
|
||||
case skipKey:
|
||||
if (activeSkipKeybindElement) {
|
||||
if (!pressedKeys.has("AltGraph")) {
|
||||
if (keybindEquals(key, skipKey)) {
|
||||
if (activeSkipKeybindElement)
|
||||
activeSkipKeybindElement.toggleSkip.call(activeSkipKeybindElement);
|
||||
}
|
||||
break;
|
||||
case startSponsorKey:
|
||||
return;
|
||||
} else if (keybindEquals(key, startSponsorKey)) {
|
||||
startOrEndTimingNewSegment();
|
||||
break;
|
||||
case submitKey:
|
||||
return;
|
||||
} else if (keybindEquals(key, submitKey)) {
|
||||
submitSponsorTimes();
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//legacy - to preserve keybinds for skipKey, startSponsorKey and submitKey for people who set it before the update. (shouldn't be changed for future keybind options)
|
||||
if (key.key == skipKey?.key && skipKey.code == null && !keybindEquals(Config.syncDefaults.skipKeybind, skipKey)) {
|
||||
if (activeSkipKeybindElement)
|
||||
activeSkipKeybindElement.toggleSkip.call(activeSkipKeybindElement);
|
||||
} else if (key.key == startSponsorKey?.key && startSponsorKey.code == null && !keybindEquals(Config.syncDefaults.startSponsorKeybind, startSponsorKey)) {
|
||||
startOrEndTimingNewSegment();
|
||||
} else if (key.key == submitKey?.key && submitKey.code == null && !keybindEquals(Config.syncDefaults.submitKeybind, submitKey)) {
|
||||
submitSponsorTimes();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1981,7 +2084,6 @@ function sendRequestToCustomServer(type, fullAddress, callback) {
|
||||
function updateAdFlag(): void {
|
||||
const wasAdPlaying = isAdPlaying;
|
||||
isAdPlaying = document.getElementsByClassName('ad-showing').length > 0;
|
||||
|
||||
if(wasAdPlaying != isAdPlaying) {
|
||||
updatePreviewBar();
|
||||
updateVisibilityOfPlayerControlsButton();
|
||||
@@ -2017,8 +2119,12 @@ function showTimeWithoutSkips(skippedDuration: number): void {
|
||||
}
|
||||
|
||||
function checkForPreloadedSegment() {
|
||||
if (loadedPreloadedSegment) return;
|
||||
|
||||
loadedPreloadedSegment = true;
|
||||
const hashParams = getHashParams();
|
||||
|
||||
let pushed = false;
|
||||
const segments = hashParams.segments;
|
||||
if (Array.isArray(segments)) {
|
||||
for (const segment of segments) {
|
||||
@@ -2031,8 +2137,15 @@ function checkForPreloadedSegment() {
|
||||
actionType: segment.actionType ? segment.actionType : ActionType.Skip,
|
||||
source: SponsorSourceType.Local
|
||||
});
|
||||
|
||||
pushed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pushed) {
|
||||
Config.config.unsubmittedSegments[sponsorVideoID] = sponsorTimesSubmitting;
|
||||
Config.forceSyncUpdate("unsubmittedSegments");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user