mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2024-11-10 01:01:55 +01:00
Added skip button in control bar instead of using skip notice
This commit is contained in:
parent
2a0e893dfc
commit
e126b59078
11 changed files with 237 additions and 50 deletions
|
@ -41,6 +41,7 @@
|
||||||
"icons/help.svg",
|
"icons/help.svg",
|
||||||
"icons/report.png",
|
"icons/report.png",
|
||||||
"icons/close.png",
|
"icons/close.png",
|
||||||
|
"icons/skipIcon.svg",
|
||||||
"icons/refresh.svg",
|
"icons/refresh.svg",
|
||||||
"icons/beep.ogg",
|
"icons/beep.ogg",
|
||||||
"icons/pause.svg",
|
"icons/pause.svg",
|
||||||
|
|
|
@ -502,3 +502,16 @@ input::-webkit-inner-spin-button {
|
||||||
height: 14px;
|
height: 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.skipButtonControlBarContainer {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sbSkipIconControlBarImage {
|
||||||
|
height: 60%;
|
||||||
|
top: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
}
|
|
@ -41,12 +41,13 @@
|
||||||
id="namedview18"
|
id="namedview18"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:zoom="0.83098592"
|
inkscape:zoom="0.83098592"
|
||||||
inkscape:cx="-238.41697"
|
inkscape:cx="220.07455"
|
||||||
inkscape:cy="258.22009"
|
inkscape:cy="308.76246"
|
||||||
inkscape:window-x="477"
|
inkscape:window-x="477"
|
||||||
inkscape:window-y="961"
|
inkscape:window-y="961"
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="1"
|
||||||
inkscape:current-layer="svg16" />
|
inkscape:current-layer="svg16"
|
||||||
|
inkscape:pagecheckerboard="true" />
|
||||||
<defs
|
<defs
|
||||||
id="defs4">
|
id="defs4">
|
||||||
<style
|
<style
|
||||||
|
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 3.1 KiB |
71
public/icons/skipIcon.svg
Normal file
71
public/icons/skipIcon.svg
Normal file
|
@ -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>
|
After Width: | Height: | Size: 3.1 KiB |
|
@ -4,6 +4,7 @@ import Config from "../config"
|
||||||
import { Category, CategorySkipOption } from "../types";
|
import { Category, CategorySkipOption } from "../types";
|
||||||
|
|
||||||
import Utils from "../utils";
|
import Utils from "../utils";
|
||||||
|
import { getCategoryActionType } from "../utils/categoryUtils";
|
||||||
const utils = new Utils();
|
const utils = new Utils();
|
||||||
|
|
||||||
export interface CategorySkipOptionsProps {
|
export interface CategorySkipOptionsProps {
|
||||||
|
@ -152,12 +153,12 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
|
||||||
|
|
||||||
const optionNames = ["disable", "showOverlay", "manualSkip", "autoSkip"];
|
const optionNames = ["disable", "showOverlay", "manualSkip", "autoSkip"];
|
||||||
|
|
||||||
console.log(utils.getCategoryActionType(this.props.category))
|
console.log(getCategoryActionType(this.props.category))
|
||||||
|
|
||||||
for (const optionName of optionNames) {
|
for (const optionName of optionNames) {
|
||||||
elements.push(
|
elements.push(
|
||||||
<option key={optionName} value={optionName}>
|
<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)}
|
: optionName)}
|
||||||
</option>
|
</option>
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,8 +5,7 @@ import { Category, ContentContainer, CategoryActionType, SponsorHideType, Sponso
|
||||||
import NoticeComponent from "./NoticeComponent";
|
import NoticeComponent from "./NoticeComponent";
|
||||||
import NoticeTextSelectionComponent from "./NoticeTextSectionComponent";
|
import NoticeTextSelectionComponent from "./NoticeTextSectionComponent";
|
||||||
|
|
||||||
import Utils from "../utils";
|
import { getCategoryActionType, getSkippingText } from "../utils/categoryUtils";
|
||||||
const utils = new Utils();
|
|
||||||
|
|
||||||
export enum SkipNoticeAction {
|
export enum SkipNoticeAction {
|
||||||
None,
|
None,
|
||||||
|
@ -82,18 +81,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
||||||
this.contentContainer = props.contentContainer;
|
this.contentContainer = props.contentContainer;
|
||||||
this.audio = null;
|
this.audio = null;
|
||||||
|
|
||||||
const categoryName = chrome.i18n.getMessage(this.segments.length > 1 ? "multipleSegments"
|
const noticeTitle = getSkippingText(this.segments, this.props.autoSkip);
|
||||||
: "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 previousSkipNotices = document.getElementsByClassName("sponsorSkipNoticeParent");
|
const previousSkipNotices = document.getElementsByClassName("sponsorSkipNoticeParent");
|
||||||
this.amountOfPreviousNotices = previousSkipNotices.length;
|
this.amountOfPreviousNotices = previousSkipNotices.length;
|
||||||
|
@ -308,7 +296,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
||||||
|
|
||||||
getSkipButton(): JSX.Element {
|
getSkipButton(): JSX.Element {
|
||||||
if (this.segments.length > 1
|
if (this.segments.length > 1
|
||||||
|| utils.getCategoryActionType(this.segments[0].category) !== CategoryActionType.POI
|
|| getCategoryActionType(this.segments[0].category) !== CategoryActionType.POI
|
||||||
|| this.props.unskipTime) {
|
|| this.props.unskipTime) {
|
||||||
return (
|
return (
|
||||||
<span className="sponsorSkipNoticeUnskipSection">
|
<span className="sponsorSkipNoticeUnskipSection">
|
||||||
|
@ -451,7 +439,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
||||||
getCategoryOptions(): React.ReactElement[] {
|
getCategoryOptions(): React.ReactElement[] {
|
||||||
const elements = [];
|
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) {
|
for (const category of categories) {
|
||||||
elements.push(
|
elements.push(
|
||||||
<option value={category}
|
<option value={category}
|
||||||
|
@ -479,7 +467,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
||||||
}
|
}
|
||||||
|
|
||||||
getUnskippedModeInfo(index: number, buttonText: string): SkipNoticeState {
|
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 maxCountdownTime = changeCountdown ? () => {
|
||||||
const sponsorTime = this.segments[index];
|
const sponsorTime = this.segments[index];
|
||||||
|
|
|
@ -6,6 +6,7 @@ import * as CompileConfig from "../../config.json";
|
||||||
import Utils from "../utils";
|
import Utils from "../utils";
|
||||||
import { Category, CategoryActionType, ContentContainer, SponsorTime } from "../types";
|
import { Category, CategoryActionType, ContentContainer, SponsorTime } from "../types";
|
||||||
import SubmissionNoticeComponent from "./SubmissionNoticeComponent";
|
import SubmissionNoticeComponent from "./SubmissionNoticeComponent";
|
||||||
|
import { getCategoryActionType } from "../utils/categoryUtils";
|
||||||
const utils = new Utils();
|
const utils = new Utils();
|
||||||
|
|
||||||
export interface SponsorTimeEditProps {
|
export interface SponsorTimeEditProps {
|
||||||
|
@ -107,14 +108,14 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const sponsorTimeEdits = this.state.sponsorTimeEdits;
|
const sponsorTimeEdits = this.state.sponsorTimeEdits;
|
||||||
sponsorTimeEdits[0] = e.target.value;
|
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.setState({sponsorTimeEdits});
|
||||||
this.saveEditTimes();
|
this.saveEditTimes();
|
||||||
}}>
|
}}>
|
||||||
</input>
|
</input>
|
||||||
|
|
||||||
{utils.getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable ? (
|
{getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable ? (
|
||||||
<span>
|
<span>
|
||||||
<span>
|
<span>
|
||||||
{" " + chrome.i18n.getMessage("to") + " "}
|
{" " + chrome.i18n.getMessage("to") + " "}
|
||||||
|
@ -156,7 +157,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||||
className="sponsorTimeDisplay"
|
className="sponsorTimeDisplay"
|
||||||
onClick={this.toggleEditTime.bind(this)}>
|
onClick={this.toggleEditTime.bind(this)}>
|
||||||
{utils.getFormattedTime(segment[0], true) +
|
{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) : "")}
|
? " " + chrome.i18n.getMessage("to") + " " + utils.getFormattedTime(segment[1], true) : "")}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -197,7 +198,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||||
{chrome.i18n.getMessage("delete")}
|
{chrome.i18n.getMessage("delete")}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{(!isNaN(segment[1]) && utils.getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable) ? (
|
{(!isNaN(segment[1]) && getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable) ? (
|
||||||
<span id={"sponsorTimePreviewButton" + this.idSuffix}
|
<span id={"sponsorTimePreviewButton" + this.idSuffix}
|
||||||
className="sponsorTimeEditButton"
|
className="sponsorTimeEditButton"
|
||||||
onClick={this.previewTime.bind(this)}>
|
onClick={this.previewTime.bind(this)}>
|
||||||
|
@ -260,7 +261,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||||
return;
|
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.setTimeTo(1, null);
|
||||||
this.props.contentContainer().updateEditButtonsOnPlayer();
|
this.props.contentContainer().updateEditButtonsOnPlayer();
|
||||||
}
|
}
|
||||||
|
@ -285,7 +286,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||||
if (time === null) time = sponsorTime.segment[0];
|
if (time === null) time = sponsorTime.segment[0];
|
||||||
|
|
||||||
sponsorTime.segment[index] = time;
|
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({
|
this.setState({
|
||||||
sponsorTimeEdits: this.getFormattedSponsorTimesEdits(sponsorTime)
|
sponsorTimeEdits: this.getFormattedSponsorTimesEdits(sponsorTime)
|
||||||
|
|
|
@ -13,6 +13,8 @@ import SkipNoticeComponent from "./components/SkipNoticeComponent";
|
||||||
import SubmissionNotice from "./render/SubmissionNotice";
|
import SubmissionNotice from "./render/SubmissionNotice";
|
||||||
import { Message, MessageResponse } from "./messageTypes";
|
import { Message, MessageResponse } from "./messageTypes";
|
||||||
import * as Chat from "./js-components/chat";
|
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)
|
// Hack to get the CSS loaded on permission-based sites (Invidious)
|
||||||
utils.wait(() => Config.config !== null, 5000, 10).then(addCSS);
|
utils.wait(() => Config.config !== null, 5000, 10).then(addCSS);
|
||||||
|
@ -68,6 +70,7 @@ let channelWhitelisted = false;
|
||||||
|
|
||||||
// create preview bar
|
// create preview bar
|
||||||
let previewBar: PreviewBar = null;
|
let previewBar: PreviewBar = null;
|
||||||
|
let skipButtonControlBar: SkipButtonControlBar = null;
|
||||||
|
|
||||||
/** Element containing the player controls on the YouTube player. */
|
/** Element containing the player controls on the YouTube player. */
|
||||||
let controls: HTMLElement | null = null;
|
let controls: HTMLElement | null = null;
|
||||||
|
@ -515,6 +518,7 @@ function refreshVideoAttachments() {
|
||||||
videosWithEventListeners.push(video);
|
videosWithEventListeners.push(video);
|
||||||
|
|
||||||
setupVideoListeners();
|
setupVideoListeners();
|
||||||
|
setupSkipButtonControlBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -569,7 +573,7 @@ function setupVideoListeners() {
|
||||||
|
|
||||||
if (!Config.config.dontShowNotice) {
|
if (!Config.config.dontShowNotice) {
|
||||||
const currentPoiSegment = sponsorTimes.find((segment) =>
|
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] > 0 &&
|
||||||
video.currentTime - segment.segment[0] < video.duration * 0.006); // Approximate size on preview bar
|
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))) {
|
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) {
|
async function sponsorsLookup(id: string, keepOldSubmissions = true) {
|
||||||
if (!video) refreshVideoAttachments();
|
if (!video) refreshVideoAttachments();
|
||||||
//there is still no video here
|
//there is still no video here
|
||||||
|
@ -731,7 +751,7 @@ function startSkipScheduleCheckingForStartSponsors() {
|
||||||
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
|
||||||
&& utils.getCategoryActionType(time.category) === CategoryActionType.Skippable) {
|
&& getCategoryActionType(time.category) === CategoryActionType.Skippable) {
|
||||||
startingSegmentTime = time.segment[0];
|
startingSegmentTime = time.segment[0];
|
||||||
startingSegment = time;
|
startingSegment = time;
|
||||||
break;
|
break;
|
||||||
|
@ -740,7 +760,7 @@ function startSkipScheduleCheckingForStartSponsors() {
|
||||||
if (startingSegmentTime === -1) {
|
if (startingSegmentTime === -1) {
|
||||||
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
|
||||||
&& utils.getCategoryActionType(time.category) === CategoryActionType.Skippable) {
|
&& getCategoryActionType(time.category) === CategoryActionType.Skippable) {
|
||||||
startingSegmentTime = time.segment[0];
|
startingSegmentTime = time.segment[0];
|
||||||
startingSegment = time;
|
startingSegment = time;
|
||||||
break;
|
break;
|
||||||
|
@ -750,7 +770,7 @@ function startSkipScheduleCheckingForStartSponsors() {
|
||||||
|
|
||||||
// For highlight category
|
// For highlight category
|
||||||
const poiSegments = sponsorTimes
|
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]);
|
.sort((a, b) => b.segment[0] - a.segment[0]);
|
||||||
for (const time of poiSegments) {
|
for (const time of poiSegments) {
|
||||||
const skipOption = utils.getCategorySelection(time.category)?.option;
|
const skipOption = utils.getCategorySelection(time.category)?.option;
|
||||||
|
@ -862,7 +882,7 @@ function updatePreviewBar(): void {
|
||||||
segment: segment.segment as [number, number],
|
segment: segment.segment as [number, number],
|
||||||
category: segment.category,
|
category: segment.category,
|
||||||
unsubmitted: false,
|
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],
|
segment: segment.segment as [number, number],
|
||||||
category: segment.category,
|
category: segment.category,
|
||||||
unsubmitted: true,
|
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)))
|
|| (includeIntersectingSegments && sponsorTimes[i].segment[0] < minimum && sponsorTimes[i].segment[1] > minimum)))
|
||||||
&& (!onlySkippableSponsors || utils.getCategorySelection(sponsorTimes[i].category).option !== CategorySkipOption.ShowOverlay)
|
&& (!onlySkippableSponsors || utils.getCategorySelection(sponsorTimes[i].category).option !== CategorySkipOption.ShowOverlay)
|
||||||
&& (!hideHiddenSponsors || sponsorTimes[i].hidden === SponsorHideType.Visible)
|
&& (!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]);
|
startTimes.push(sponsorTimes[i].segment[0]);
|
||||||
}
|
}
|
||||||
|
@ -1080,6 +1100,11 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!autoSkip
|
||||||
|
&& skippingSegments.length === 1
|
||||||
|
&& getCategoryActionType(skippingSegments[0].category) === CategoryActionType.POI) {
|
||||||
|
skipButtonControlBar.enable(skippingSegments[0]);
|
||||||
|
} else {
|
||||||
if (openNotice) {
|
if (openNotice) {
|
||||||
//send out the message saying that a sponsor message was skipped
|
//send out the message saying that a sponsor message was skipped
|
||||||
if (!Config.config.dontShowNotice || !autoSkip) {
|
if (!Config.config.dontShowNotice || !autoSkip) {
|
||||||
|
@ -1087,6 +1112,7 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
|
||||||
skipNotices.push(new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer, unskipTime));
|
skipNotices.push(new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer, unskipTime));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//send telemetry that a this sponsor was skipped
|
//send telemetry that a this sponsor was skipped
|
||||||
if (autoSkip) sendTelemetryAndCount(skippingSegments, skipTime[1] - skipTime[0], true);
|
if (autoSkip) sendTelemetryAndCount(skippingSegments, skipTime[1] - skipTime[0], true);
|
||||||
|
|
70
src/js-components/skipButtonControlBar.ts
Normal file
70
src/js-components/skipButtonControlBar.ts
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
12
src/utils.ts
12
src/utils.ts
|
@ -1,5 +1,5 @@
|
||||||
import Config from "./config";
|
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";
|
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> {
|
containsPermission(permissions: chrome.permissions.Permissions): Promise<boolean> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
chrome.permissions.contains(permissions, resolve)
|
chrome.permissions.contains(permissions, resolve)
|
||||||
|
@ -364,7 +356,7 @@ export default class Utils {
|
||||||
}, (response) => {
|
}, (response) => {
|
||||||
resolve(response);
|
resolve(response);
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
23
src/utils/categoryUtils.ts
Normal file
23
src/utils/categoryUtils.ts
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue