aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAjay Ramachandran <[email protected]>2021-08-18 02:07:24 -0400
committerAjay Ramachandran <[email protected]>2021-08-18 02:07:24 -0400
commite126b59078b18624915dcf8213fa4132fc0e0580 (patch)
treecb31d07cdc01bddefc5b7c1f9cfe1ff194cb3e66
parent2a0e893dfc7381b18a103426bc760675e8916eff (diff)
downloadSponsorBlock-e126b59078b18624915dcf8213fa4132fc0e0580.tar.gz
SponsorBlock-e126b59078b18624915dcf8213fa4132fc0e0580.zip
Added skip button in control bar instead of using skip notice
-rw-r--r--manifest/manifest.json1
-rw-r--r--public/content.css13
-rw-r--r--public/icons/PlayerCancelSegmentIconSponsorBlocker.svg7
-rw-r--r--public/icons/skipIcon.svg71
-rw-r--r--src/components/CategorySkipOptionsComponent.tsx5
-rw-r--r--src/components/SkipNoticeComponent.tsx22
-rw-r--r--src/components/SponsorTimeEditComponent.tsx13
-rw-r--r--src/content.ts50
-rw-r--r--src/js-components/skipButtonControlBar.ts70
-rw-r--r--src/utils.ts12
-rw-r--r--src/utils/categoryUtils.ts23
11 files changed, 237 insertions, 50 deletions
diff --git a/manifest/manifest.json b/manifest/manifest.json
index e0565a39..3ac8ee6f 100644
--- a/manifest/manifest.json
+++ b/manifest/manifest.json
@@ -41,6 +41,7 @@
"icons/help.svg",
"icons/report.png",
"icons/close.png",
+ "icons/skipIcon.svg",
"icons/refresh.svg",
"icons/beep.ogg",
"icons/pause.svg",
diff --git a/public/content.css b/public/content.css
index 55e4b63e..7494d7fb 100644
--- a/public/content.css
+++ b/public/content.css
@@ -501,4 +501,17 @@ input::-webkit-inner-spin-button {
.sbChatClose {
height: 14px;
cursor: pointer;
+}
+
+.skipButtonControlBarContainer {
+ cursor: pointer;
+ display: flex;
+}
+
+#sbSkipIconControlBarImage {
+ height: 60%;
+ top: 0px;
+ bottom: 0px;
+ display: block;
+ margin: auto;
} \ No newline at end of file
diff --git a/public/icons/PlayerCancelSegmentIconSponsorBlocker.svg b/public/icons/PlayerCancelSegmentIconSponsorBlocker.svg
index 6b48b6d0..619b4b04 100644
--- a/public/icons/PlayerCancelSegmentIconSponsorBlocker.svg
+++ b/public/icons/PlayerCancelSegmentIconSponsorBlocker.svg
@@ -41,12 +41,13 @@
id="namedview18"
showgrid="false"
inkscape:zoom="0.83098592"
- inkscape:cx="-238.41697"
- inkscape:cy="258.22009"
+ inkscape:cx="220.07455"
+ inkscape:cy="308.76246"
inkscape:window-x="477"
inkscape:window-y="961"
inkscape:window-maximized="1"
- inkscape:current-layer="svg16" />
+ inkscape:current-layer="svg16"
+ inkscape:pagecheckerboard="true" />
<defs
id="defs4">
<style
diff --git a/public/icons/skipIcon.svg b/public/icons/skipIcon.svg
new file mode 100644
index 00000000..84bf7f5b
--- /dev/null
+++ b/public/icons/skipIcon.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ viewBox="0 0 565.15 568"
+ version="1.1"
+ id="svg16"
+ sodipodi:docname="skipIcon.svg"
+ inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+ inkscape:export-filename="D:\Dell Data\_Projects\_____SponsorSkip\ignored\svg\SponsorBlocker4.png"
+ inkscape:export-xdpi="43.436523"
+ inkscape:export-ydpi="43.436523">
+ <metadata
+ id="metadata20">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>LogoSponsorBlocker2</dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1001"
+ id="namedview18"
+ showgrid="false"
+ inkscape:zoom="1.6619718"
+ inkscape:cx="316.31071"
+ inkscape:cy="330.01409"
+ inkscape:window-x="477"
+ inkscape:window-y="961"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg16"
+ inkscape:pagecheckerboard="true" />
+ <defs
+ id="defs4">
+ <style
+ id="style2">.cls-1{fill:red;}.cls-2{fill:#fff;}</style>
+ </defs>
+ <title
+ id="title6">LogoSponsorBlocker2</title>
+ <path
+ class="cls-1"
+ d="m 282.58,568 a 65,65 0 0 1 -34.14,-9.66 C 95.41,463.94 2.54,300.46 0,121 a 64.91,64.91 0 0 1 34,-58.09 522.56,522.56 0 0 1 497.16,0 64.91,64.91 0 0 1 34,58.12 c -2.53,179.43 -95.4,342.91 -248.42,437.3 A 65,65 0 0 1 282.58,568 Z m 0,-548.31 A 502.24,502.24 0 0 0 43.4,80.22 45.27,45.27 0 0 0 19.7,120.75 c 2.44,172.67 91.81,330 239.07,420.83 a 46.19,46.19 0 0 0 47.61,0 C 453.64,450.73 543,293.42 545.45,120.75 A 45.26,45.26 0 0 0 521.75,80.21 502.26,502.26 0 0 0 282.58,19.69 Z"
+ id="path8"
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff" />
+ <path
+ style="fill:#ffffff"
+ d="M 284.70508 42.693359 A 479.9 479.9 0 0 0 54.369141 100.41992 A 22.53 22.53 0 0 0 42.669922 120.41992 C 45.069922 290.25992 135.67008 438.63977 270.83008 522.00977 A 22.48 22.48 0 0 0 294.32031 522.00977 C 429.48031 438.63977 520.08047 290.25992 522.48047 120.41992 A 22.53 22.53 0 0 0 510.7793 100.41992 A 479.9 479.9 0 0 0 284.70508 42.693359 z M 188.7168 140.07227 L 312.64844 264.00586 L 188.7168 387.9375 L 159.5918 358.8125 L 254.19336 264.00586 L 159.5918 169.19727 L 188.7168 140.07227 z M 305.625 140.07227 L 429.55859 264.00586 L 305.625 387.9375 L 276.50195 358.8125 L 371.10352 264.00586 L 276.50195 169.19727 L 305.625 140.07227 z "
+ id="path10" />
+ <g
+ id="g825"
+ transform="translate(-3.86549,36.564644)" />
+</svg>
diff --git a/src/components/CategorySkipOptionsComponent.tsx b/src/components/CategorySkipOptionsComponent.tsx
index 9a134a5e..370e1bb0 100644
--- a/src/components/CategorySkipOptionsComponent.tsx
+++ b/src/components/CategorySkipOptionsComponent.tsx
@@ -4,6 +4,7 @@ import Config from "../config"
import { Category, CategorySkipOption } from "../types";
import Utils from "../utils";
+import { getCategoryActionType } from "../utils/categoryUtils";
const utils = new Utils();
export interface CategorySkipOptionsProps {
@@ -152,12 +153,12 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
const optionNames = ["disable", "showOverlay", "manualSkip", "autoSkip"];
- console.log(utils.getCategoryActionType(this.props.category))
+ console.log(getCategoryActionType(this.props.category))
for (const optionName of optionNames) {
elements.push(
<option key={optionName} value={optionName}>
- {chrome.i18n.getMessage(optionName !== "disable" ? optionName + utils.getCategoryActionType(this.props.category)
+ {chrome.i18n.getMessage(optionName !== "disable" ? optionName + getCategoryActionType(this.props.category)
: optionName)}
</option>
);
diff --git a/src/components/SkipNoticeComponent.tsx b/src/components/SkipNoticeComponent.tsx
index 63a53165..a98e2f4d 100644
--- a/src/components/SkipNoticeComponent.tsx
+++ b/src/components/SkipNoticeComponent.tsx
@@ -5,8 +5,7 @@ import { Category, ContentContainer, CategoryActionType, SponsorHideType, Sponso
import NoticeComponent from "./NoticeComponent";
import NoticeTextSelectionComponent from "./NoticeTextSectionComponent";
-import Utils from "../utils";
-const utils = new Utils();
+import { getCategoryActionType, getSkippingText } from "../utils/categoryUtils";
export enum SkipNoticeAction {
None,
@@ -82,18 +81,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
this.contentContainer = props.contentContainer;
this.audio = null;
- const categoryName = chrome.i18n.getMessage(this.segments.length > 1 ? "multipleSegments"
- : "category_" + this.segments[0].category + "_short") || chrome.i18n.getMessage("category_" + this.segments[0].category);
- let noticeTitle = "";
- if (this.autoSkip) {
- const messageId = utils.getCategoryActionType(this.segments[0].category) === CategoryActionType.Skippable
- ? "skipped" : "skipped_to_category";
- noticeTitle = chrome.i18n.getMessage(messageId).replace("{0}", categoryName);
- } else {
- const messageId = utils.getCategoryActionType(this.segments[0].category) === CategoryActionType.Skippable
- ? "skip_category" : "skip_to_category";
- noticeTitle = chrome.i18n.getMessage(messageId).replace("{0}", categoryName);
- }
+ const noticeTitle = getSkippingText(this.segments, this.props.autoSkip);
const previousSkipNotices = document.getElementsByClassName("sponsorSkipNoticeParent");
this.amountOfPreviousNotices = previousSkipNotices.length;
@@ -308,7 +296,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
getSkipButton(): JSX.Element {
if (this.segments.length > 1
- || utils.getCategoryActionType(this.segments[0].category) !== CategoryActionType.POI
+ || getCategoryActionType(this.segments[0].category) !== CategoryActionType.POI
|| this.props.unskipTime) {
return (
<span className="sponsorSkipNoticeUnskipSection">
@@ -451,7 +439,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
getCategoryOptions(): React.ReactElement[] {
const elements = [];
- const categories = CompileConfig.categoryList.filter((cat => utils.getCategoryActionType(cat as Category) === CategoryActionType.Skippable));
+ const categories = CompileConfig.categoryList.filter((cat => getCategoryActionType(cat as Category) === CategoryActionType.Skippable));
for (const category of categories) {
elements.push(
<option value={category}
@@ -479,7 +467,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
}
getUnskippedModeInfo(index: number, buttonText: string): SkipNoticeState {
- const changeCountdown = utils.getCategoryActionType(this.segments[index].category) === CategoryActionType.Skippable;
+ const changeCountdown = getCategoryActionType(this.segments[index].category) === CategoryActionType.Skippable;
const maxCountdownTime = changeCountdown ? () => {
const sponsorTime = this.segments[index];
diff --git a/src/components/SponsorTimeEditComponent.tsx b/src/components/SponsorTimeEditComponent.tsx
index c133883f..8d9f516e 100644
--- a/src/components/SponsorTimeEditComponent.tsx
+++ b/src/components/SponsorTimeEditComponent.tsx
@@ -6,6 +6,7 @@ import * as CompileConfig from "../../config.json";
import Utils from "../utils";
import { Category, CategoryActionType, ContentContainer, SponsorTime } from "../types";
import SubmissionNoticeComponent from "./SubmissionNoticeComponent";
+import { getCategoryActionType } from "../utils/categoryUtils";
const utils = new Utils();
export interface SponsorTimeEditProps {
@@ -107,14 +108,14 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
onChange={(e) => {
const sponsorTimeEdits = this.state.sponsorTimeEdits;
sponsorTimeEdits[0] = e.target.value;
- if (utils.getCategoryActionType(sponsorTime.category) === CategoryActionType.POI) sponsorTimeEdits[1] = e.target.value;
+ if (getCategoryActionType(sponsorTime.category) === CategoryActionType.POI) sponsorTimeEdits[1] = e.target.value;
this.setState({sponsorTimeEdits});
this.saveEditTimes();
}}>
</input>
- {utils.getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable ? (
+ {getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable ? (
<span>
<span>
{" " + chrome.i18n.getMessage("to") + " "}
@@ -156,7 +157,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
className="sponsorTimeDisplay"
onClick={this.toggleEditTime.bind(this)}>
{utils.getFormattedTime(segment[0], true) +
- ((!isNaN(segment[1]) && utils.getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable)
+ ((!isNaN(segment[1]) && getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable)
? " " + chrome.i18n.getMessage("to") + " " + utils.getFormattedTime(segment[1], true) : "")}
</div>
);
@@ -197,7 +198,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
{chrome.i18n.getMessage("delete")}
</span>
- {(!isNaN(segment[1]) && utils.getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable) ? (
+ {(!isNaN(segment[1]) && getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable) ? (
<span id={"sponsorTimePreviewButton" + this.idSuffix}
className="sponsorTimeEditButton"
onClick={this.previewTime.bind(this)}>
@@ -260,7 +261,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
return;
}
- if (utils.getCategoryActionType(event.target.value as Category) === CategoryActionType.POI) {
+ if (getCategoryActionType(event.target.value as Category) === CategoryActionType.POI) {
this.setTimeTo(1, null);
this.props.contentContainer().updateEditButtonsOnPlayer();
}
@@ -285,7 +286,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
if (time === null) time = sponsorTime.segment[0];
sponsorTime.segment[index] = time;
- if (utils.getCategoryActionType(sponsorTime.category) === CategoryActionType.POI) sponsorTime.segment[1] = time;
+ if (getCategoryActionType(sponsorTime.category) === CategoryActionType.POI) sponsorTime.segment[1] = time;
this.setState({
sponsorTimeEdits: this.getFormattedSponsorTimesEdits(sponsorTime)
diff --git a/src/content.ts b/src/content.ts
index c1f1a9c7..9e9e5ccf 100644
--- a/src/content.ts
+++ b/src/content.ts
@@ -13,6 +13,8 @@ import SkipNoticeComponent from "./components/SkipNoticeComponent";
import SubmissionNotice from "./render/SubmissionNotice";
import { Message, MessageResponse } from "./messageTypes";
import * as Chat from "./js-components/chat";
+import { getCategoryActionType } from "./utils/categoryUtils";
+import { SkipButtonControlBar } from "./js-components/skipButtonControlBar";
// Hack to get the CSS loaded on permission-based sites (Invidious)
utils.wait(() => Config.config !== null, 5000, 10).then(addCSS);
@@ -68,6 +70,7 @@ let channelWhitelisted = false;
// create preview bar
let previewBar: PreviewBar = null;
+let skipButtonControlBar: SkipButtonControlBar = null;
/** Element containing the player controls on the YouTube player. */
let controls: HTMLElement | null = null;
@@ -515,6 +518,7 @@ function refreshVideoAttachments() {
videosWithEventListeners.push(video);
setupVideoListeners();
+ setupSkipButtonControlBar();
}
}
}
@@ -569,7 +573,7 @@ function setupVideoListeners() {
if (!Config.config.dontShowNotice) {
const currentPoiSegment = sponsorTimes.find((segment) =>
- utils.getCategoryActionType(segment.category) === CategoryActionType.POI &&
+ getCategoryActionType(segment.category) === CategoryActionType.POI &&
video.currentTime - segment.segment[0] > 0 &&
video.currentTime - segment.segment[0] < video.duration * 0.006); // Approximate size on preview bar
if (currentPoiSegment && !skipNotices.some((notice) => notice.segments.some((s) => s.UUID === currentPoiSegment.UUID))) {
@@ -598,6 +602,22 @@ function setupVideoListeners() {
}
}
+function setupSkipButtonControlBar() {
+ if (!skipButtonControlBar) {
+ skipButtonControlBar = new SkipButtonControlBar({
+ skip: (segment) => skipToTime({
+ v: video,
+ skipTime: segment.segment,
+ skippingSegments: [segment],
+ openNotice: true,
+ forceAutoSkip: true
+ })
+ });
+ }
+
+ skipButtonControlBar.attachToPage();
+}
+
async function sponsorsLookup(id: string, keepOldSubmissions = true) {
if (!video) refreshVideoAttachments();
//there is still no video here
@@ -731,7 +751,7 @@ function startSkipScheduleCheckingForStartSponsors() {
let startingSegment: SponsorTime = null;
for (const time of sponsorTimes) {
if (time.segment[0] <= video.currentTime && time.segment[0] > startingSegmentTime && time.segment[1] > video.currentTime
- && utils.getCategoryActionType(time.category) === CategoryActionType.Skippable) {
+ && getCategoryActionType(time.category) === CategoryActionType.Skippable) {
startingSegmentTime = time.segment[0];
startingSegment = time;
break;
@@ -740,7 +760,7 @@ function startSkipScheduleCheckingForStartSponsors() {
if (startingSegmentTime === -1) {
for (const time of sponsorTimesSubmitting) {
if (time.segment[0] <= video.currentTime && time.segment[0] > startingSegmentTime && time.segment[1] > video.currentTime
- && utils.getCategoryActionType(time.category) === CategoryActionType.Skippable) {
+ && getCategoryActionType(time.category) === CategoryActionType.Skippable) {
startingSegmentTime = time.segment[0];
startingSegment = time;
break;
@@ -750,7 +770,7 @@ function startSkipScheduleCheckingForStartSponsors() {
// For highlight category
const poiSegments = sponsorTimes
- .filter((time) => time.segment[1] > video.currentTime && utils.getCategoryActionType(time.category) === CategoryActionType.POI)
+ .filter((time) => time.segment[1] > video.currentTime && getCategoryActionType(time.category) === CategoryActionType.POI)
.sort((a, b) => b.segment[0] - a.segment[0]);
for (const time of poiSegments) {
const skipOption = utils.getCategorySelection(time.category)?.option;
@@ -862,7 +882,7 @@ function updatePreviewBar(): void {
segment: segment.segment as [number, number],
category: segment.category,
unsubmitted: false,
- showLarger: utils.getCategoryActionType(segment.category) === CategoryActionType.POI
+ showLarger: getCategoryActionType(segment.category) === CategoryActionType.POI
});
});
}
@@ -872,7 +892,7 @@ function updatePreviewBar(): void {
segment: segment.segment as [number, number],
category: segment.category,
unsubmitted: true,
- showLarger: utils.getCategoryActionType(segment.category) === CategoryActionType.POI
+ showLarger: getCategoryActionType(segment.category) === CategoryActionType.POI
});
});
@@ -1022,7 +1042,7 @@ function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments:
|| (includeIntersectingSegments && sponsorTimes[i].segment[0] < minimum && sponsorTimes[i].segment[1] > minimum)))
&& (!onlySkippableSponsors || utils.getCategorySelection(sponsorTimes[i].category).option !== CategorySkipOption.ShowOverlay)
&& (!hideHiddenSponsors || sponsorTimes[i].hidden === SponsorHideType.Visible)
- && utils.getCategoryActionType(sponsorTimes[i].category) === CategoryActionType.Skippable) {
+ && getCategoryActionType(sponsorTimes[i].category) === CategoryActionType.Skippable) {
startTimes.push(sponsorTimes[i].segment[0]);
}
@@ -1080,11 +1100,17 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
}
}
- if (openNotice) {
- //send out the message saying that a sponsor message was skipped
- if (!Config.config.dontShowNotice || !autoSkip) {
- skipNotices.forEach((notice) => notice.setShowKeybindHint(false));
- skipNotices.push(new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer, unskipTime));
+ if (!autoSkip
+ && skippingSegments.length === 1
+ && getCategoryActionType(skippingSegments[0].category) === CategoryActionType.POI) {
+ skipButtonControlBar.enable(skippingSegments[0]);
+ } else {
+ if (openNotice) {
+ //send out the message saying that a sponsor message was skipped
+ if (!Config.config.dontShowNotice || !autoSkip) {
+ skipNotices.forEach((notice) => notice.setShowKeybindHint(false));
+ skipNotices.push(new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer, unskipTime));
+ }
}
}
diff --git a/src/js-components/skipButtonControlBar.ts b/src/js-components/skipButtonControlBar.ts
new file mode 100644
index 00000000..b46f9147
--- /dev/null
+++ b/src/js-components/skipButtonControlBar.ts
@@ -0,0 +1,70 @@
+import Config from "../config";
+import { SponsorTime } from "../types";
+import { getSkippingText } from "../utils/categoryUtils";
+
+
+export interface SkipButtonControlBarProps {
+ skip: (segment: SponsorTime) => void;
+}
+
+export class SkipButtonControlBar {
+
+ container: HTMLElement;
+ skipIcon: HTMLImageElement;
+ textContainer: HTMLElement;
+ chapterText: HTMLElement;
+ segment: SponsorTime;
+
+ timeout: NodeJS.Timeout;
+
+ skip: (segment: SponsorTime) => void;
+
+ constructor(props: SkipButtonControlBarProps) {
+ this.skip = props.skip;
+
+ this.container = document.createElement("div");
+ this.container.classList.add("skipButtonControlBarContainer");
+ this.container.classList.add("hidden");
+
+ this.skipIcon = document.createElement("img");
+ this.skipIcon.src = chrome.runtime.getURL("icons/skipIcon.svg");
+ this.skipIcon.classList.add("ytp-button");
+ this.skipIcon.id = "sbSkipIconControlBarImage";
+
+ this.textContainer = document.createElement("div");
+
+ this.container.appendChild(this.skipIcon);
+ this.container.appendChild(this.textContainer);
+ this.container.addEventListener("click", () => this.onClick());
+ }
+
+ attachToPage(): void {
+ const leftControlsContainer = document.querySelector(".ytp-left-controls");
+ this.chapterText = document.querySelector(".ytp-chapter-container");
+
+ if (!leftControlsContainer.contains(this.container)) {
+ leftControlsContainer.insertBefore(this.container, this.chapterText);
+ }
+ }
+
+ enable(segment: SponsorTime): void {
+ this.segment = segment;
+ this.chapterText?.classList?.add("hidden");
+ this.container.classList.remove("hidden");
+ this.textContainer.innerText = getSkippingText([segment], false);
+
+ if (this.timeout) clearTimeout(this.timeout);
+ this.timeout = setTimeout(() => this.disable(), Config.config.skipNoticeDuration * 1000);
+ }
+
+ disable(): void {
+ this.container.classList.add("hidden");
+ this.chapterText?.classList?.remove("hidden");
+ }
+
+ onClick(): void {
+ this.skip(this.segment);
+ this.disable();
+ }
+}
+
diff --git a/src/utils.ts b/src/utils.ts
index b2c75cd8..a40dd5f9 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -1,5 +1,5 @@
import Config from "./config";
-import { CategorySelection, SponsorTime, FetchResponse, BackgroundScriptContainer, Registration, Category, CategoryActionType } from "./types";
+import { CategorySelection, SponsorTime, FetchResponse, BackgroundScriptContainer, Registration } from "./types";
import * as CompileConfig from "../config.json";
@@ -43,14 +43,6 @@ export default class Utils {
});
}
- getCategoryActionType(category: Category): CategoryActionType {
- if (category.startsWith("poi_")) {
- return CategoryActionType.POI;
- } else {
- return CategoryActionType.Skippable;
- }
- }
-
containsPermission(permissions: chrome.permissions.Permissions): Promise<boolean> {
return new Promise((resolve) => {
chrome.permissions.contains(permissions, resolve)
@@ -364,7 +356,7 @@ export default class Utils {
}, (response) => {
resolve(response);
});
- })
+ });
}
/**
diff --git a/src/utils/categoryUtils.ts b/src/utils/categoryUtils.ts
new file mode 100644
index 00000000..b349aefe
--- /dev/null
+++ b/src/utils/categoryUtils.ts
@@ -0,0 +1,23 @@
+import { Category, CategoryActionType, SponsorTime } from "../types";
+
+export function getSkippingText(segments: SponsorTime[], autoSkip: boolean): string {
+ const categoryName = chrome.i18n.getMessage(segments.length > 1 ? "multipleSegments"
+ : "category_" + segments[0].category + "_short") || chrome.i18n.getMessage("category_" + segments[0].category);
+ if (autoSkip) {
+ const messageId = getCategoryActionType(segments[0].category) === CategoryActionType.Skippable
+ ? "skipped" : "skipped_to_category";
+ return chrome.i18n.getMessage(messageId).replace("{0}", categoryName);
+ } else {
+ const messageId = getCategoryActionType(segments[0].category) === CategoryActionType.Skippable
+ ? "skip_category" : "skip_to_category";
+ return chrome.i18n.getMessage(messageId).replace("{0}", categoryName);
+ }
+}
+
+export function getCategoryActionType(category: Category): CategoryActionType {
+ if (category.startsWith("poi_")) {
+ return CategoryActionType.POI;
+ } else {
+ return CategoryActionType.Skippable;
+ }
+} \ No newline at end of file