aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/content.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/content.ts')
-rw-r--r--src/content.ts254
1 files changed, 192 insertions, 62 deletions
diff --git a/src/content.ts b/src/content.ts
index e0af1f34..a1f22fbc 100644
--- a/src/content.ts
+++ b/src/content.ts
@@ -12,12 +12,14 @@ import SubmissionNotice from "./render/SubmissionNotice";
import { Message, MessageResponse, VoteResponse } from "./messageTypes";
import { SkipButtonControlBar } from "./js-components/skipButtonControlBar";
import { getStartTimeFromUrl } from "./utils/urlParser";
-import { findValidElement, getControls, getHashParams, isVisible } from "./utils/pageUtils";
+import { findValidElement, getControls, getExistingChapters, 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";
import { logDebug } from "./utils/logger";
+import { importTimes } from "./utils/exporter";
+import { ChapterVote } from "./render/ChapterVote";
import { openWarningDialog } from "./utils/warnings";
// Hack to get the CSS loaded on permission-based sites (Invidious)
@@ -26,7 +28,8 @@ utils.wait(() => Config.config !== null, 5000, 10).then(addCSS);
//was sponsor data found when doing SponsorsLookup
let sponsorDataFound = false;
//the actual sponsorTimes if loaded and UUIDs associated with them
-let sponsorTimes: SponsorTime[] = null;
+let sponsorTimes: SponsorTime[] = [];
+let existingChaptersImported = false;
//what video id are these sponsors for
let sponsorVideoID: VideoID = null;
// List of open skip notices
@@ -138,7 +141,8 @@ const skipNoticeContentContainer: ContentContainer = () => ({
previewTime,
videoInfo,
getRealCurrentTime: getRealCurrentTime,
- lockedCategories
+ lockedCategories,
+ channelIDInfo
});
// value determining when to count segment as skipped and send telemetry to server (percent based)
@@ -167,6 +171,7 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
found: sponsorDataFound,
status: lastResponseStatus,
sponsorTimes: sponsorTimes,
+ time: video.currentTime,
onMobileYouTube
});
@@ -212,10 +217,17 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
found: sponsorDataFound,
status: lastResponseStatus,
sponsorTimes: sponsorTimes,
+ time: video.currentTime,
onMobileYouTube
}));
return true;
+ case "unskip":
+ unskipSponsorTime(sponsorTimes.find((segment) => segment.UUID === request.UUID), null, true);
+ break;
+ case "reskip":
+ reskipSponsorTime(sponsorTimes.find((segment) => segment.UUID === request.UUID), true);
+ break;
case "submitVote":
vote(request.type, request.UUID).then((response) => sendResponse(response));
return true;
@@ -230,6 +242,31 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
case "copyToClipboard":
navigator.clipboard.writeText(request.text);
break;
+ case "importSegments": {
+ const importedSegments = importTimes(request.data, video.duration);
+ let addedSegments = false;
+ for (const segment of importedSegments) {
+ if (!sponsorTimesSubmitting.concat(sponsorTimes ?? []).some(
+ (s) => Math.abs(s.segment[0] - segment.segment[0]) < 1
+ && Math.abs(s.segment[1] - segment.segment[1]) < 1)) {
+ sponsorTimesSubmitting.push(segment);
+ addedSegments = true;
+ }
+ }
+
+ if (addedSegments) {
+ Config.config.unsubmittedSegments[sponsorVideoID] = sponsorTimesSubmitting;
+ Config.forceSyncUpdate("unsubmittedSegments");
+
+ updateEditButtonsOnPlayer();
+ updateSponsorTimesSubmitting(false);
+ }
+
+ sendResponse({
+ importedSegments
+ });
+ break;
+ }
case "keydown":
document.dispatchEvent(new KeyboardEvent('keydown', {
key: request.key,
@@ -249,8 +286,6 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
/**
* Called when the config is updated
- *
- * @param {String} changes
*/
function contentConfigUpdateListener(changes: StorageChangesObject) {
for (const key in changes) {
@@ -276,8 +311,8 @@ function resetValues() {
lastCheckVideoTime = -1;
retryCount = 0;
- //reset sponsor times
- sponsorTimes = null;
+ sponsorTimes = [];
+ existingChaptersImported = false;
sponsorSkipped = [];
videoInfo = null;
@@ -423,7 +458,7 @@ function createPreviewBar(): void {
isVisibleCheck: true
}, {
// For Desktop YouTube
- selector: ".ytp-progress-bar-container",
+ selector: ".ytp-progress-bar",
isVisibleCheck: true
}, {
// For Desktop YouTube
@@ -441,7 +476,8 @@ function createPreviewBar(): void {
const el = option.isVisibleCheck ? findValidElement(allElements) : allElements[0];
if (el) {
- previewBar = new PreviewBar(el, onMobileYouTube, onInvidious);
+ const chapterVote = new ChapterVote(voteAsync);
+ previewBar = new PreviewBar(el, onMobileYouTube, onInvidious, chapterVote);
updatePreviewBar();
@@ -507,13 +543,15 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
}
logDebug(`Considering to start skipping: ${!video}, ${video?.paused}`);
-
- if (!video || video.paused) return;
+ if (!video) return;
if (currentTime === undefined || currentTime === null) {
currentTime = getVirtualTime();
}
lastTimeFromWaitingEvent = null;
+ updateActiveSegment(currentTime);
+
+ if (video.paused) return;
const skipInfo = getNextSkipIndex(currentTime, includeIntersectingSegments, includeNonIntersectingSegments);
const currentSkip = skipInfo.array[skipInfo.index];
@@ -568,35 +606,41 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
if (incorrectVideoCheck(videoID, currentSkip)) return;
forceVideoTime ||= Math.max(video.currentTime, getVirtualTime());
- if (forceVideoTime >= skipTime[0] - skipBuffer && forceVideoTime < skipTime[1]) {
- skipToTime({
- v: video,
- skipTime,
- skippingSegments,
- openNotice: skipInfo.openNotice
- });
+ if ((shouldSkip(currentSkip) || sponsorTimesSubmitting?.some((segment) => segment.segment === currentSkip.segment))) {
+ if (forceVideoTime >= skipTime[0] - skipBuffer && forceVideoTime < skipTime[1]) {
+ skipToTime({
+ v: video,
+ skipTime,
+ skippingSegments,
+ openNotice: skipInfo.openNotice
+ });
- // These are segments that start at the exact same time but need seperate notices
- for (const extra of skipInfo.extraIndexes) {
- const extraSkip = skipInfo.array[extra];
- if (shouldSkip(extraSkip)) {
- skipToTime({
- v: video,
- skipTime: [extraSkip.scheduledTime, extraSkip.segment[1]],
- skippingSegments: [extraSkip],
- openNotice: skipInfo.openNotice
- });
+ // These are segments that start at the exact same time but need seperate notices
+ for (const extra of skipInfo.extraIndexes) {
+ const extraSkip = skipInfo.array[extra];
+ if (shouldSkip(extraSkip)) {
+ skipToTime({
+ v: video,
+ skipTime: [extraSkip.scheduledTime, extraSkip.segment[1]],
+ skippingSegments: [extraSkip],
+ openNotice: skipInfo.openNotice
+ });
+ }
+ }
+
+ if (utils.getCategorySelection(currentSkip.category)?.option === CategorySkipOption.ManualSkip
+ || currentSkip.actionType === ActionType.Mute) {
+ forcedSkipTime = skipTime[0] + 0.001;
+ } else {
+ forcedSkipTime = skipTime[1];
+ forcedIncludeIntersectingSegments = true;
+ forcedIncludeNonIntersectingSegments = false;
}
- }
-
- if (utils.getCategorySelection(currentSkip.category)?.option === CategorySkipOption.ManualSkip
- || currentSkip.actionType === ActionType.Mute) {
- forcedSkipTime = skipTime[0] + 0.001;
} else {
- forcedSkipTime = skipTime[1];
- forcedIncludeIntersectingSegments = true;
- forcedIncludeNonIntersectingSegments = false;
+ forcedSkipTime = forceVideoTime + 0.001;
}
+ } else {
+ forcedSkipTime = forceVideoTime + 0.001;
}
startSponsorSchedule(forcedIncludeIntersectingSegments, forcedSkipTime, forcedIncludeNonIntersectingSegments);
@@ -793,8 +837,12 @@ function setupVideoListeners() {
lastTimeFromWaitingEvent = null;
startSponsorSchedule();
- } else if (video.currentTime === 0) {
- lastPausedAtZero = true;
+ } else {
+ updateActiveSegment(video.currentTime);
+
+ if (video.currentTime === 0) {
+ lastPausedAtZero = true;
+ }
}
});
video.addEventListener('ratechange', () => startSponsorSchedule());
@@ -888,7 +936,12 @@ async function sponsorsLookup(keepOldSubmissions = true) {
if (response?.ok) {
const recievedSegments: SponsorTime[] = JSON.parse(response.responseText)
?.filter((video) => video.videoID === sponsorVideoID)
- ?.map((video) => video.segments)[0];
+ ?.map((video) => video.segments)?.[0]
+ ?.map((segment) => ({
+ ...segment,
+ source: SponsorSourceType.Server
+ }))
+ ?.sort((a, b) => a.segment[0] - b.segment[0]);
if (!recievedSegments || !recievedSegments.length) {
// return if no video found
retryFetch(404);
@@ -909,6 +962,7 @@ async function sponsorsLookup(keepOldSubmissions = true) {
const oldSegments = sponsorTimes || [];
sponsorTimes = recievedSegments;
+ existingChaptersImported = false;
// Hide all submissions smaller than the minimum duration
if (Config.config.minDuration !== 0) {
@@ -956,13 +1010,28 @@ async function sponsorsLookup(keepOldSubmissions = true) {
retryFetch(lastResponseStatus);
}
+ importExistingChapters(true);
+
if (Config.config.isVip) {
lockedCategoriesLookup();
}
}
+function importExistingChapters(wait: boolean) {
+ if (!existingChaptersImported) {
+ GenericUtils.wait(() => video && getExistingChapters(sponsorVideoID, video.duration),
+ wait ? 5000 : 0, 100, (c) => c?.length > 0).then((chapters) => {
+ if (!existingChaptersImported && chapters?.length > 0) {
+ sponsorTimes = (sponsorTimes ?? []).concat(...chapters).sort((a, b) => a.segment[0] - b.segment[0]);
+ existingChaptersImported = true;
+ updatePreviewBar();
+ }
+ }).catch(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function
+ }
+}
+
function getEnabledActionTypes(): ActionType[] {
- const actionTypes = [ActionType.Skip, ActionType.Poi];
+ const actionTypes = [ActionType.Skip, ActionType.Poi, ActionType.Chapter];
if (Config.config.muteSegments) {
actionTypes.push(ActionType.Mute);
}
@@ -1000,7 +1069,8 @@ function retryFetch(errorCode: number): void {
const delay = errorCode === 404 ? (10000 + Math.random() * 30000) : (2000 + Math.random() * 10000);
setTimeout(() => {
- if (sponsorVideoID && sponsorTimes?.length === 0) {
+ if (sponsorVideoID && sponsorTimes?.length === 0
+ || sponsorTimes.every((segment) => segment.source !== SponsorSourceType.Server)) {
sponsorsLookup();
}
}, delay);
@@ -1164,9 +1234,11 @@ function updatePreviewBar(): void {
previewBarSegments.push({
segment: segment.segment as [number, number],
category: segment.category,
- unsubmitted: false,
actionType: segment.actionType,
- showLarger: segment.actionType === ActionType.Poi
+ unsubmitted: false,
+ showLarger: segment.actionType === ActionType.Poi,
+ description: segment.description,
+ source: segment.source,
});
});
}
@@ -1175,16 +1247,21 @@ function updatePreviewBar(): void {
previewBarSegments.push({
segment: segment.segment as [number, number],
category: segment.category,
- unsubmitted: true,
actionType: segment.actionType,
- showLarger: segment.actionType === ActionType.Poi
+ unsubmitted: true,
+ showLarger: segment.actionType === ActionType.Poi,
+ description: segment.description,
+ source: segment.source
});
});
previewBar.set(previewBarSegments.filter((segment) => segment.actionType !== ActionType.Full), video?.duration)
+ updateActiveSegment(video.currentTime);
if (Config.config.showTimeWithSkips) {
- const skippedDuration = utils.getTimestampsDuration(previewBarSegments.map(({segment}) => segment));
+ const skippedDuration = utils.getTimestampsDuration(previewBarSegments
+ .filter(({actionType}) => actionType !== ActionType.Chapter)
+ .map(({segment}) => segment));
showTimeWithoutSkips(skippedDuration);
}
@@ -1248,7 +1325,7 @@ function getNextSkipIndex(currentTime: number, includeIntersectingSegments: bool
const { includedTimes: submittedArray, scheduledTimes: sponsorStartTimes } =
getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments);
- const { scheduledTimes: sponsorStartTimesAfterCurrentTime } = getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, true, true);
+ const { scheduledTimes: sponsorStartTimesAfterCurrentTime } = getStartTimes(sponsorTimes, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, true);
// This is an array in-case multiple segments have the exact same start time
const minSponsorTimeIndexes = GenericUtils.indexesOf(sponsorStartTimes, Math.min(...sponsorStartTimesAfterCurrentTime));
@@ -1263,7 +1340,7 @@ function getNextSkipIndex(currentTime: number, includeIntersectingSegments: bool
const { includedTimes: unsubmittedArray, scheduledTimes: unsubmittedSponsorStartTimes } =
getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, includeNonIntersectingSegments);
- const { scheduledTimes: unsubmittedSponsorStartTimesAfterCurrentTime } = getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, false, false);
+ const { scheduledTimes: unsubmittedSponsorStartTimesAfterCurrentTime } = getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, includeNonIntersectingSegments, currentTime, false);
const minUnsubmittedSponsorTimeIndex = unsubmittedSponsorStartTimes.indexOf(Math.min(...unsubmittedSponsorStartTimesAfterCurrentTime));
const previewEndTimeIndex = getLatestEndTimeIndex(unsubmittedArray, minUnsubmittedSponsorTimeIndex);
@@ -1344,7 +1421,7 @@ function getLatestEndTimeIndex(sponsorTimes: SponsorTime[], index: number, hideH
* the current time, but end after
*/
function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments: boolean, includeNonIntersectingSegments: boolean,
- minimum?: number, onlySkippableSponsors = false, hideHiddenSponsors = false): {includedTimes: ScheduledTime[], scheduledTimes: number[]} {
+ minimum?: number, hideHiddenSponsors = false): {includedTimes: ScheduledTime[], scheduledTimes: number[]} {
if (!sponsorTimes) return {includedTimes: [], scheduledTimes: []};
const includedTimes: ScheduledTime[] = [];
@@ -1355,9 +1432,8 @@ function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments:
scheduledTime: sponsorTime.segment[0]
}));
- // Schedule at the end time to know when to unmute
- sponsorTimes.filter(sponsorTime => sponsorTime.actionType === ActionType.Mute)
- .forEach(sponsorTime => {
+ // Schedule at the end time to know when to unmute and remove title from seek bar
+ sponsorTimes.forEach(sponsorTime => {
if (!possibleTimes.some((time) => sponsorTime.segment[1] === time.scheduledTime)) {
possibleTimes.push({
...sponsorTime,
@@ -1369,9 +1445,9 @@ function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments:
for (let i = 0; i < possibleTimes.length; i++) {
if ((minimum === undefined
|| ((includeNonIntersectingSegments && possibleTimes[i].scheduledTime >= minimum)
- || (includeIntersectingSegments && possibleTimes[i].scheduledTime < minimum && possibleTimes[i].segment[1] > minimum)))
- && (!onlySkippableSponsors || shouldSkip(possibleTimes[i]))
+ || (includeIntersectingSegments && possibleTimes[i].scheduledTime < minimum && possibleTimes[i].segment[1] > minimum)))
&& (!hideHiddenSponsors || possibleTimes[i].hidden === SponsorHideType.Visible)
+ && possibleTimes[i].segment.length === 2
&& possibleTimes[i].actionType !== ActionType.Poi) {
scheduledTimes.push(possibleTimes[i].scheduledTime);
@@ -1535,7 +1611,7 @@ function reskipSponsorTime(segment: SponsorTime, forceSeek = false) {
const fullSkip = skippedTime / segmentDuration > manualSkipPercentCount;
video.currentTime = segment.segment[1];
- sendTelemetryAndCount([segment], skippedTime, fullSkip);
+ sendTelemetryAndCount([segment], segment.actionType !== ActionType.Chapter ? skippedTime : 0, fullSkip);
startSponsorSchedule(true, segment.segment[1], false);
}
}
@@ -1586,6 +1662,7 @@ function shouldAutoSkip(segment: SponsorTime): boolean {
function shouldSkip(segment: SponsorTime): boolean {
return (segment.actionType !== ActionType.Full
+ && segment.source !== SponsorSourceType.YouTube
&& utils.getCategorySelection(segment.category)?.option !== CategorySkipOption.ShowOverlay)
|| (Config.config.autoSkipOnMusicVideos && sponsorTimes?.some((s) => s.category === "music_offtopic"));
}
@@ -1692,7 +1769,7 @@ function startOrEndTimingNewSegment() {
if (!isSegmentCreationInProgress()) {
sponsorTimesSubmitting.push({
segment: [roundedTime],
- UUID: utils.generateUserID() as SegmentUUID,
+ UUID: GenericUtils.generateUserID() as SegmentUUID,
category: Config.config.defaultCategory,
actionType: ActionType.Skip,
source: SponsorSourceType.Local
@@ -1716,6 +1793,8 @@ function startOrEndTimingNewSegment() {
updateEditButtonsOnPlayer();
updateSponsorTimesSubmitting(false);
+
+ importExistingChapters(false);
}
function getIncompleteSegment(): SponsorTime {
@@ -1754,9 +1833,14 @@ function updateSponsorTimesSubmitting(getFromConfig = true) {
UUID: segmentTime.UUID,
category: segmentTime.category,
actionType: segmentTime.actionType,
+ description: segmentTime.description,
source: segmentTime.source
});
}
+
+ if (sponsorTimesSubmitting.length > 0) {
+ importExistingChapters(true);
+ }
}
updatePreviewBar();
@@ -1878,7 +1962,7 @@ async function voteAsync(type: number, UUID: SegmentUUID, category?: Category):
const sponsorIndex = utils.getSponsorIndexFromUUID(sponsorTimes, UUID);
// Don't vote for preview sponsors
- if (sponsorIndex == -1 || sponsorTimes[sponsorIndex].source === SponsorSourceType.Local) return;
+ if (sponsorIndex == -1 || sponsorTimes[sponsorIndex].source !== SponsorSourceType.Server) return;
// See if the local time saved count and skip count should be saved
if (type === 0 && sponsorSkipped[sponsorIndex] || type === 1 && !sponsorSkipped[sponsorIndex]) {
@@ -2025,7 +2109,7 @@ async function sendSubmitMessage() {
} catch(e) {} // eslint-disable-line no-empty
// Add submissions to current sponsors list
- sponsorTimes = (sponsorTimes || []).concat(newSegments);
+ sponsorTimes = (sponsorTimes || []).concat(newSegments).sort((a, b) => a.segment[0] - b.segment[0]);
// Increase contribution count
Config.config.sponsorTimesContributed = Config.config.sponsorTimesContributed + sponsorTimesSubmitting.length;
@@ -2062,7 +2146,7 @@ function getSegmentsMessage(sponsorTimes: SponsorTime[]): string {
for (let i = 0; i < sponsorTimes.length; i++) {
for (let s = 0; s < sponsorTimes[i].segment.length; s++) {
- let timeMessage = utils.getFormattedTime(sponsorTimes[i].segment[s]);
+ let timeMessage = GenericUtils.getFormattedTime(sponsorTimes[i].segment[s]);
//if this is an end time
if (s == 1) {
timeMessage = " " + chrome.i18n.getMessage("to") + " " + timeMessage;
@@ -2078,6 +2162,44 @@ function getSegmentsMessage(sponsorTimes: SponsorTime[]): string {
return sponsorTimesMessage;
}
+function updateActiveSegment(currentTime: number): void {
+ previewBar?.updateChapterText(sponsorTimes, sponsorTimesSubmitting, currentTime);
+ chrome.runtime.sendMessage({
+ message: "time",
+ time: currentTime
+ });
+}
+
+function nextChapter(): void {
+ const chapters = sponsorTimes.filter((time) => time.actionType === ActionType.Chapter)
+ .sort((a, b) => a.segment[1] - b.segment[1]);
+ if (chapters.length <= 0) return;
+
+ const nextChapter = chapters.findIndex((time) => time.actionType === ActionType.Chapter
+ && time.segment[1] > video.currentTime);
+ if (nextChapter !== -1) {
+ reskipSponsorTime(chapters[nextChapter], true);
+ } else {
+ video.currentTime = video.duration;
+ }
+}
+
+function previousChapter(): void {
+ const chapters = sponsorTimes.filter((time) => time.actionType === ActionType.Chapter);
+ if (chapters.length <= 0) return;
+
+ // subtract 5 seconds to allow skipping back to the previous chapter if close to start of
+ // the current one
+ const nextChapter = chapters.findIndex((time) => time.actionType === ActionType.Chapter
+ && time.segment[0] > video.currentTime - Math.min(5, time.segment[1] - time.segment[0]));
+ const previousChapter = nextChapter !== -1 ? (nextChapter - 1) : (chapters.length - 1);
+ if (previousChapter !== -1) {
+ unskipSponsorTime(chapters[previousChapter], null, true);
+ } else {
+ video.currentTime = 0;
+ }
+}
+
function addPageListeners(): void {
const refreshListners = () => {
if (!isVisible(video)) {
@@ -2107,6 +2229,8 @@ function hotkeyListener(e: KeyboardEvent): void {
const skipKey = Config.config.skipKeybind;
const startSponsorKey = Config.config.startSponsorKeybind;
const submitKey = Config.config.submitKeybind;
+ const nextChapterKey = Config.config.nextChapterKeybind;
+ const previousChapterKey = Config.config.previousChapterKeybind;
if (keybindEquals(key, skipKey)) {
if (activeSkipKeybindElement)
@@ -2118,6 +2242,12 @@ function hotkeyListener(e: KeyboardEvent): void {
} else if (keybindEquals(key, submitKey)) {
submitSponsorTimes();
return;
+ } else if (keybindEquals(key, nextChapterKey)) {
+ nextChapter();
+ return;
+ } else if (keybindEquals(key, previousChapterKey)) {
+ previousChapter();
+ 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)
@@ -2187,8 +2317,8 @@ function showTimeWithoutSkips(skippedDuration: number): void {
display.appendChild(duration);
}
-
- const durationAfterSkips = utils.getFormattedTime(video?.duration - skippedDuration)
+
+ const durationAfterSkips = GenericUtils.getFormattedTime(video?.duration - skippedDuration);
duration.innerText = (durationAfterSkips == null || skippedDuration <= 0) ? "" : " (" + durationAfterSkips + ")";
}
@@ -2207,7 +2337,7 @@ function checkForPreloadedSegment() {
if (!sponsorTimesSubmitting.some((s) => s.segment[0] === segment.segment[0] && s.segment[1] === s.segment[1])) {
sponsorTimesSubmitting.push({
segment: segment.segment,
- UUID: utils.generateUserID() as SegmentUUID,
+ UUID: GenericUtils.generateUserID() as SegmentUUID,
category: segment.category ? segment.category : Config.config.defaultCategory,
actionType: segment.actionType ? segment.actionType : ActionType.Skip,
source: SponsorSourceType.Local