|
+
+ {chrome.i18n.getMessage("exportSegments")}
+
+ {" "}
@@ -55,10 +62,20 @@ class UnsubmittedVideoListItem extends React.Component {
+ alert(chrome.i18n.getMessage("CopiedExclamation"));
+ })
+ .catch(() => {
+ alert(chrome.i18n.getMessage("copyDebugInformationFailed"));
+ });
+ }
}
export default UnsubmittedVideoListItem;
diff --git a/src/components/UnsubmittedVideosComponent.tsx b/src/components/UnsubmittedVideosComponent.tsx
index 04542adc..ee1f70f2 100644
--- a/src/components/UnsubmittedVideosComponent.tsx
+++ b/src/components/UnsubmittedVideosComponent.tsx
@@ -38,7 +38,7 @@ class UnsubmittedVideosComponent extends React.Component 0 && this.setState({tableVisible: !this.state.tableVisible})}>
{chrome.i18n.getMessage(this.state.tableVisible ? "hideUnsubmittedSegments" : "showUnsubmittedSegments")}
}
-
+ {" "}
{chrome.i18n.getMessage("clearUnsubmittedSegments")}
From 59093cdf212d06cc2c56fea384923f5553be864c Mon Sep 17 00:00:00 2001
From: mini-bomba <55105495+mini-bomba@users.noreply.github.com>
Date: Thu, 1 Sep 2022 21:46:21 +0200
Subject: [PATCH 5/8] Move new react components to components/options/,
following latest changes
---
.../{ => options}/UnsubmittedVideoListComponent.tsx | 2 +-
src/components/{ => options}/UnsubmittedVideoListItem.tsx | 4 ++--
src/components/{ => options}/UnsubmittedVideosComponent.tsx | 2 +-
src/render/UnsubmittedVideos.tsx | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
rename src/components/{ => options}/UnsubmittedVideoListComponent.tsx (98%)
rename src/components/{ => options}/UnsubmittedVideoListItem.tsx (96%)
rename src/components/{ => options}/UnsubmittedVideosComponent.tsx (98%)
diff --git a/src/components/UnsubmittedVideoListComponent.tsx b/src/components/options/UnsubmittedVideoListComponent.tsx
similarity index 98%
rename from src/components/UnsubmittedVideoListComponent.tsx
rename to src/components/options/UnsubmittedVideoListComponent.tsx
index d726b5f2..2f3aa75a 100644
--- a/src/components/UnsubmittedVideoListComponent.tsx
+++ b/src/components/options/UnsubmittedVideoListComponent.tsx
@@ -1,6 +1,6 @@
import * as React from "react";
-import Config from "../config";
+import Config from "../../config";
import UnsubmittedVideoListItem from "./UnsubmittedVideoListItem";
export interface UnsubmittedVideoListProps {
diff --git a/src/components/UnsubmittedVideoListItem.tsx b/src/components/options/UnsubmittedVideoListItem.tsx
similarity index 96%
rename from src/components/UnsubmittedVideoListItem.tsx
rename to src/components/options/UnsubmittedVideoListItem.tsx
index fec08dc9..c203f533 100644
--- a/src/components/UnsubmittedVideoListItem.tsx
+++ b/src/components/options/UnsubmittedVideoListItem.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
-import Config from "../config";
-import { exportTimes } from "../utils/exporter";
+import Config from "../../config";
+import { exportTimes } from "../../utils/exporter";
export interface UnsubmittedVideosListItemProps {
videoID: string;
diff --git a/src/components/UnsubmittedVideosComponent.tsx b/src/components/options/UnsubmittedVideosComponent.tsx
similarity index 98%
rename from src/components/UnsubmittedVideosComponent.tsx
rename to src/components/options/UnsubmittedVideosComponent.tsx
index ee1f70f2..d01c8294 100644
--- a/src/components/UnsubmittedVideosComponent.tsx
+++ b/src/components/options/UnsubmittedVideosComponent.tsx
@@ -1,5 +1,5 @@
import * as React from "react";
-import Config from "../config";
+import Config from "../../config";
import UnsubmittedVideoListComponent from "./UnsubmittedVideoListComponent";
export interface UnsubmittedVideosProps {
diff --git a/src/render/UnsubmittedVideos.tsx b/src/render/UnsubmittedVideos.tsx
index 0b90fd27..1ae119e3 100644
--- a/src/render/UnsubmittedVideos.tsx
+++ b/src/render/UnsubmittedVideos.tsx
@@ -1,6 +1,6 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
-import UnsubmittedVideosComponent from "../components/UnsubmittedVideosComponent";
+import UnsubmittedVideosComponent from "../components/options/UnsubmittedVideosComponent";
class UnsubmittedVideos {
From df2586e76dd668ebdd82b3c0486f18eb3074c1e2 Mon Sep 17 00:00:00 2001
From: mini-bomba <55105495+mini-bomba@users.noreply.github.com>
Date: Thu, 1 Sep 2022 23:10:03 +0200
Subject: [PATCH 6/8] Load segment description from hashparams
---
src/content.ts | 76 +++++++++++++++++++++++++++++++-------------------
1 file changed, 47 insertions(+), 29 deletions(-)
diff --git a/src/content.ts b/src/content.ts
index 0842e521..cb2d3964 100644
--- a/src/content.ts
+++ b/src/content.ts
@@ -1,11 +1,26 @@
import Config from "./config";
-import { SponsorTime, CategorySkipOption, VideoID, SponsorHideType, VideoInfo, StorageChangesObject, ChannelIDInfo, ChannelIDStatus, SponsorSourceType, SegmentUUID, Category, SkipToTimeParams, ToggleSkippable, ActionType, ScheduledTime, HashedValue } from "./types";
-
-import { ContentContainer, Keybind } from "./types";
+import {
+ ActionType,
+ Category,
+ CategorySkipOption,
+ ChannelIDInfo,
+ ChannelIDStatus,
+ ContentContainer,
+ HashedValue,
+ Keybind,
+ ScheduledTime,
+ SegmentUUID,
+ SkipToTimeParams,
+ SponsorHideType,
+ SponsorSourceType,
+ SponsorTime,
+ StorageChangesObject,
+ ToggleSkippable,
+ VideoID,
+ VideoInfo,
+} from "./types";
import Utils from "./utils";
-const utils = new Utils();
-
-import PreviewBar, {PreviewBarSegment} from "./js-components/previewBar";
+import PreviewBar, { PreviewBarSegment } from "./js-components/previewBar";
import SkipNotice from "./render/SkipNotice";
import SkipNoticeComponent from "./components/SkipNoticeComponent";
import SubmissionNotice from "./render/SubmissionNotice";
@@ -22,6 +37,8 @@ import { importTimes } from "./utils/exporter";
import { ChapterVote } from "./render/ChapterVote";
import { openWarningDialog } from "./utils/warnings";
+const utils = new Utils();
+
// Hack to get the CSS loaded on permission-based sites (Invidious)
utils.wait(() => Config.config !== null, 5000, 10).then(addCSS);
@@ -247,7 +264,7 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
let addedSegments = false;
for (const segment of importedSegments) {
if (!sponsorTimesSubmitting.concat(sponsorTimes ?? []).some(
- (s) => Math.abs(s.segment[0] - segment.segment[0]) < 1
+ (s) => Math.abs(s.segment[0] - segment.segment[0]) < 1
&& Math.abs(s.segment[1] - segment.segment[1]) < 1)
&& (segment.category !== "chapter" || utils.getCategorySelection("chapter"))) {
sponsorTimesSubmitting.push(segment);
@@ -561,7 +578,7 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
const videoID = sponsorVideoID;
const skipBuffer = 0.003;
- if (videoMuted && !inMuteSegment(currentTime, skipInfo.index !== -1
+ if (videoMuted && !inMuteSegment(currentTime, skipInfo.index !== -1
&& timeUntilSponsor < skipBuffer && shouldAutoSkip(currentSkip))) {
video.muted = false;
videoMuted = false;
@@ -628,8 +645,8 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
});
}
}
-
- if (utils.getCategorySelection(currentSkip.category)?.option === CategorySkipOption.ManualSkip
+
+ if (utils.getCategorySelection(currentSkip.category)?.option === CategorySkipOption.ManualSkip
|| currentSkip.actionType === ActionType.Mute) {
forcedSkipTime = skipTime[0] + 0.001;
} else {
@@ -672,7 +689,7 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
}, 1);
} else {
logDebug(`Starting timeout to skip ${video.currentTime} to skip at ${skipTime[0]}`);
-
+
// Schedule for right before to be more precise than normal timeout
currentSkipSchedule = setTimeout(skippingFunction, Math.max(0, delayTime - 150));
}
@@ -692,8 +709,8 @@ function getVirtualTime(): number {
}
function inMuteSegment(currentTime: number, includeOverlap: boolean): boolean {
- const checkFunction = (segment) => segment.actionType === ActionType.Mute
- && segment.segment[0] <= currentTime
+ const checkFunction = (segment) => segment.actionType === ActionType.Mute
+ && segment.segment[0] <= currentTime
&& (segment.segment[1] > currentTime || (includeOverlap && segment.segment[1] + 0.02 > currentTime));
return sponsorTimes?.some(checkFunction) || sponsorTimesSubmitting.some(checkFunction);
}
@@ -773,7 +790,7 @@ function setupVideoListeners() {
// If it is not the first event, then the only way to get to 0 is if there is a seek event
// This check makes sure that changing the video resolution doesn't cause the extension to think it
// gone back to the begining
- if (video.readyState <= HTMLMediaElement.HAVE_CURRENT_DATA
+ if (video.readyState <= HTMLMediaElement.HAVE_CURRENT_DATA
&& video.currentTime === 0) return;
updateVirtualTime();
@@ -804,7 +821,7 @@ function setupVideoListeners() {
video.addEventListener('playing', () => {
updateVirtualTime();
lastPausedAtZero = false;
-
+
if (startedWaiting) {
startedWaiting = false;
logDebug(`[SB] Playing event after buffering: ${Math.abs(lastCheckVideoTime - video.currentTime) > 0.3
@@ -1062,7 +1079,7 @@ function retryFetch(errorCode: number): void {
sponsorDataFound = false;
if (errorCode !== 404 && retryCount > 1) {
- // Too many errors (50x), give up
+ // Too many errors (50x), give up
return;
}
@@ -1070,7 +1087,7 @@ 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();
}
@@ -1334,7 +1351,7 @@ function getNextSkipIndex(currentTime: number, includeIntersectingSegments: bool
const minSponsorTimeIndexes = GenericUtils.indexesOf(sponsorStartTimes, Math.min(...sponsorStartTimesAfterCurrentTime));
// Find auto skipping segments if possible, sort by duration otherwise
const minSponsorTimeIndex = minSponsorTimeIndexes.sort(
- (a, b) => ((autoSkipSorter(submittedArray[a]) - autoSkipSorter(submittedArray[b]))
+ (a, b) => ((autoSkipSorter(submittedArray[a]) - autoSkipSorter(submittedArray[b]))
|| (submittedArray[a].segment[1] - submittedArray[a].segment[0]) - (submittedArray[b].segment[1] - submittedArray[b].segment[0])))[0] ?? -1;
// Store extra indexes for the non-auto skipping segments if others occur at the exact same start time
const extraIndexes = minSponsorTimeIndexes.filter((i) => i !== minSponsorTimeIndex && autoSkipSorter(submittedArray[i]) !== 0);
@@ -1448,7 +1465,7 @@ 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)))
+ || (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) {
@@ -1576,13 +1593,13 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
function createSkipNotice(skippingSegments: SponsorTime[], autoSkip: boolean, unskipTime: number, startReskip: boolean) {
for (const skipNotice of skipNotices) {
- if (skippingSegments.length === skipNotice.segments.length
+ if (skippingSegments.length === skipNotice.segments.length
&& skippingSegments.every((segment) => skipNotice.segments.some((s) => s.UUID === segment.UUID))) {
// Skip notice already exists
return;
}
}
-
+
const newSkipNotice = new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer, unskipTime, startReskip);
if (onMobileYouTube || Config.config.skipKeybind == null) newSkipNotice.setShowKeybindHint(false);
skipNotices.push(newSkipNotice);
@@ -1596,7 +1613,7 @@ function unskipSponsorTime(segment: SponsorTime, unskipTime: number = null, forc
video.muted = false;
videoMuted = false;
}
-
+
if (forceSeek || segment.actionType === ActionType.Skip) {
//add a tiny bit of time to make sure it is not skipped again
video.currentTime = unskipTime ?? segment.segment[0] + 0.001;
@@ -1869,10 +1886,10 @@ function openInfoMenu() {
//hide info button
if (playerButtons.info) playerButtons.info.button.style.display = "none";
-
+
const popup = document.createElement("div");
popup.id = "sponsorBlockPopupContainer";
-
+
const frame = document.createElement("iframe");
frame.width = "374";
frame.height = "500";
@@ -1891,7 +1908,7 @@ function openInfoMenu() {
//old youtube theme
parentNode = document.getElementById("watch7-sidebar-contents");
}
-
+
parentNode.insertBefore(popup, parentNode.firstChild);
}
@@ -2178,7 +2195,7 @@ function nextChapter(): void {
.sort((a, b) => a.segment[1] - b.segment[1]);
if (chapters.length <= 0) return;
- const nextChapter = chapters.findIndex((time) => time.actionType === ActionType.Chapter
+ const nextChapter = chapters.findIndex((time) => time.actionType === ActionType.Chapter
&& time.segment[1] > video.currentTime);
if (nextChapter !== -1) {
reskipSponsorTime(chapters[nextChapter], true);
@@ -2193,7 +2210,7 @@ function previousChapter(): void {
// 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
+ 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) {
@@ -2320,7 +2337,7 @@ function showTimeWithoutSkips(skippedDuration: number): void {
display.appendChild(duration);
}
-
+
const durationAfterSkips = GenericUtils.getFormattedTime(video?.duration - skippedDuration);
duration.innerText = (durationAfterSkips == null || skippedDuration <= 0) ? "" : " (" + durationAfterSkips + ")";
@@ -2343,6 +2360,7 @@ function checkForPreloadedSegment() {
UUID: GenericUtils.generateUserID() as SegmentUUID,
category: segment.category ? segment.category : Config.config.defaultCategory,
actionType: segment.actionType ? segment.actionType : ActionType.Skip,
+ description: segment.description ?? "",
source: SponsorSourceType.Local
});
@@ -2362,7 +2380,7 @@ function checkForPreloadedSegment() {
const navigationApiAvailable = "navigation" in window;
if (navigationApiAvailable) {
// TODO: Remove type cast once type declarations are updated
- (window as unknown as { navigation: EventTarget }).navigation.addEventListener("navigate", (e) =>
+ (window as unknown as { navigation: EventTarget }).navigation.addEventListener("navigate", (e) =>
videoIDChange(getYouTubeVideoID(document, (e as unknown as Record>).destination.url)));
}
From bbea534781cc1b07d6c5a3ba6ffd6f60bbd8aee6 Mon Sep 17 00:00:00 2001
From: mini-bomba <55105495+mini-bomba@users.noreply.github.com>
Date: Thu, 1 Sep 2022 23:31:16 +0200
Subject: [PATCH 7/8] Add "Export segments as URL" option the unsubmitted
videos section
---
public/_locales/en/messages.json | 3 +++
.../options/UnsubmittedVideoListItem.tsx | 18 ++++++++++++++++--
src/utils/exporter.ts | 13 ++++++++++++-
3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json
index df50b436..e7cbfaa0 100644
--- a/public/_locales/en/messages.json
+++ b/public/_locales/en/messages.json
@@ -1205,5 +1205,8 @@
"actions": {
"message": "Actions",
"description": "Header of the unsubmitted segments list"
+ },
+ "exportSegmentsAsURL": {
+ "message": "Export segments as URL"
}
}
diff --git a/src/components/options/UnsubmittedVideoListItem.tsx b/src/components/options/UnsubmittedVideoListItem.tsx
index c203f533..d670461d 100644
--- a/src/components/options/UnsubmittedVideoListItem.tsx
+++ b/src/components/options/UnsubmittedVideoListItem.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import Config from "../../config";
-import { exportTimes } from "../../utils/exporter";
+import { exportTimes, exportTimesAsHashParam } from "../../utils/exporter";
export interface UnsubmittedVideosListItemProps {
videoID: string;
@@ -47,6 +47,12 @@ class UnsubmittedVideoListItem extends React.Component
{" "}
+
+ {chrome.i18n.getMessage("exportSegmentsAsURL")}
+
+ {" "}
@@ -68,7 +74,15 @@ class UnsubmittedVideoListItem extends React.Component {
alert(chrome.i18n.getMessage("CopiedExclamation"));
})
diff --git a/src/utils/exporter.ts b/src/utils/exporter.ts
index 089ef782..fe2b4f88 100644
--- a/src/utils/exporter.ts
+++ b/src/utils/exporter.ts
@@ -73,4 +73,15 @@ export function importTimes(data: string, videoDuration: number): SponsorTime[]
}
return result;
-}
\ No newline at end of file
+}
+
+export function exportTimesAsHashParam(segments: SponsorTime[]): string {
+ const hashparamSegments = segments.map(segment => ({
+ actionType: segment.actionType,
+ category: segment.category,
+ segment: segment.segment,
+ ...(segment.description ? {description: segment.description} : {}) // don't include the description param if empty
+ }));
+
+ return `#segments=${JSON.stringify(hashparamSegments)}`;
+}
From 9c7d153f150f890281b2566079e8487c264a9d5e Mon Sep 17 00:00:00 2001
From: Ajay
Date: Fri, 2 Sep 2022 00:15:05 -0400
Subject: [PATCH 8/8] Move segment export to backup page and improve margins
---
public/_locales/en/messages.json | 2 +-
public/options/options.html | 6 ++----
src/components/options/UnsubmittedVideoListComponent.tsx | 3 ++-
src/components/options/UnsubmittedVideosComponent.tsx | 5 ++---
4 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json
index e7cbfaa0..20381761 100644
--- a/public/_locales/en/messages.json
+++ b/public/_locales/en/messages.json
@@ -1207,6 +1207,6 @@
"description": "Header of the unsubmitted segments list"
},
"exportSegmentsAsURL": {
- "message": "Export segments as URL"
+ "message": "Share as URL"
}
}
diff --git a/public/options/options.html b/public/options/options.html
index dbf9473f..fa23687a 100644
--- a/public/options/options.html
+++ b/public/options/options.html
@@ -362,6 +362,8 @@
+
+
__MSG_exportOptions__
@@ -491,10 +493,6 @@
__MSG_copyDebugInformationOptions__
-
-
-
-
|