aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAjay Ramachandran <[email protected]>2020-06-07 11:30:33 -0400
committerGitHub <[email protected]>2020-06-07 11:30:33 -0400
commit9ad67c1a0315fbc25ca10838819149f85d7b16d5 (patch)
tree8eaf4b14ee2f517acd951964335f1ed8b202903e
parent53071a92914149a4348c656f912bb9221a167168 (diff)
parent56e40b791fcb6fd807d4d7f207c6e7f32dd531e5 (diff)
downloadSponsorBlock-9ad67c1a0315fbc25ca10838819149f85d7b16d5.tar.gz
SponsorBlock-9ad67c1a0315fbc25ca10838819149f85d7b16d5.zip
Merge pull request #363 from ajayyy/react1.2.31
Category Improvements
-rw-r--r--manifest/manifest.json3
-rw-r--r--public/_locales/en/messages.json66
-rw-r--r--public/content.css18
-rw-r--r--public/help/index_en.html8
-rw-r--r--public/icons/help.svg58
-rw-r--r--public/options/options.css4
-rw-r--r--src/background.ts14
-rw-r--r--src/components/CategoryChooserComponent.tsx21
-rw-r--r--src/components/CategorySkipOptionsComponent.tsx115
-rw-r--r--src/components/NoticeTextSectionComponent.tsx11
-rw-r--r--src/components/SkipNoticeComponent.tsx20
-rw-r--r--src/components/SponsorTimeEditComponent.tsx25
-rw-r--r--src/components/SubmissionNoticeComponent.tsx9
-rw-r--r--src/config.ts89
-rw-r--r--src/content.ts6
-rw-r--r--src/js-components/previewBar.ts59
-rw-r--r--src/options.ts7
-rw-r--r--src/render/SkipNotice.tsx3
-rw-r--r--src/types.ts8
-rw-r--r--src/utils.ts4
20 files changed, 441 insertions, 107 deletions
diff --git a/manifest/manifest.json b/manifest/manifest.json
index 59dc3272..f4d92bbe 100644
--- a/manifest/manifest.json
+++ b/manifest/manifest.json
@@ -1,7 +1,7 @@
{
"name": "__MSG_fullName__",
"short_name": "__MSG_Name__",
- "version": "1.2.30",
+ "version": "1.2.31",
"default_locale": "en",
"description": "__MSG_Description__",
"content_scripts": [{
@@ -32,6 +32,7 @@
"icons/downvote.png",
"icons/thumbs_down.svg",
"icons/thumbs_up.svg",
+ "icons/help.svg",
"icons/report.png",
"icons/close.png",
"icons/beep.ogg",
diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json
index 30e9be2e..43999660 100644
--- a/public/_locales/en/messages.json
+++ b/public/_locales/en/messages.json
@@ -483,24 +483,54 @@
"category_sponsor": {
"message": "Sponsor"
},
+ "category_sponsor_description": {
+ "message": "Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free shoutouts to causes/creators/websites/products they like."
+ },
"category_intro": {
"message": "Intro Animation"
},
+ "category_intro_description": {
+ "message": "Intro animations that are recurring in the series or provide no direct value. This should not be used on music videos."
+ },
+ "category_intro_short": {
+ "message": "Intro"
+ },
"category_outro": {
"message": "Endcards/Credits"
},
+ "category_outro_description": {
+ "message": "Credits or when the YouTube endcards appear. Not for spoken conclusions. This should not include useful content. This should not be used on music videos."
+ },
"category_interaction": {
"message": "Interaction Reminder (Subscribe)"
},
+ "category_interaction_description": {
+ "message": "When there is a short reminder to like, subscribe or follow them in the middle of content. If it is long or about something specific, it should be under self promotion instead."
+ },
+ "category_interaction_short": {
+ "message": "Interaction Reminder"
+ },
"category_selfpromo": {
"message": "Unpaid/Self Promotion"
},
+ "category_selfpromo_description": {
+ "message": "Similar to \"sponsor\" except for unpaid or self promotion. This includes sections about merchandise, donations, or information about who they collaborated with."
+ },
"category_music_offtopic": {
"message": "Music: Non-Music Section"
},
+ "category_music_offtopic_description": {
+ "message": "Only for use in music videos. This includes introductions or outros in music videos."
+ },
+ "category_music_offtopic_short": {
+ "message": "Non-Music"
+ },
"category_livestream_messages": {
"message": "Livestream: Donation/Message Readings"
},
+ "category_livestream_messages_short": {
+ "message": "Message Reading"
+ },
"disable": {
"message": "Disable"
},
@@ -510,6 +540,23 @@
"showOverlay": {
"message": "Show In Seek Bar"
},
+ "colorFormatIncorrect": {
+ "message": "Your color is formatted incorrectly. It should be a 3 or 6 digit hex code with a number sign at the beginning."
+ },
+ "previewColor": {
+ "message": "Preview Color",
+ "description": "Referring to submissions that have not been sent to the server yet."
+ },
+ "seekBarColor": {
+ "message": "Seek Bar Color"
+ },
+ "category": {
+ "message": "Category"
+ },
+ "skipOption": {
+ "message": "Skip Option",
+ "description": "Used on the options page to describe the ways to skip the segment (auto skip, manual, etc.)"
+ },
"enableTestingServer": {
"message": "Enable Beta Testing Server"
},
@@ -563,5 +610,24 @@
},
"multipleSegments": {
"message": "Multiple Segments"
+ },
+ "guidelines": {
+ "message": "Guidelines"
+ },
+ "readTheGuidelines": {
+ "message": "Read The Guidelines!!",
+ "description": "Show the first time they submit or if they are \"high risk\""
+ },
+ "categoryUpdate1": {
+ "message": "Categories are here!"
+ },
+ "categoryUpdate2": {
+ "message": "Open the options to skip intros, outros, merch, etc."
+ },
+ "unsubmittedWarning": {
+ "message": "Unsubmitted Segments Notification"
+ },
+ "unsubmittedWarningDescription": {
+ "message": "Send a notification when you leave a video with segments that are not uploaded"
}
}
diff --git a/public/content.css b/public/content.css
index 66838a9f..95009d26 100644
--- a/public/content.css
+++ b/public/content.css
@@ -394,4 +394,22 @@ input::-webkit-inner-spin-button {
color: white;
border-width: 3px;
padding: 3px;
+}
+
+.helpButton {
+
+}
+
+.helpButton {
+ height: 25px;
+ cursor: pointer;
+ padding: 5px;
+
+ margin: auto;
+ top: 0;
+ bottom: 0;
+ position: absolute;
+}
+.helpButton:hover {
+ filter: brightness(80%);
} \ No newline at end of file
diff --git a/public/help/index_en.html b/public/help/index_en.html
index 163e26e5..605ed501 100644
--- a/public/help/index_en.html
+++ b/public/help/index_en.html
@@ -30,15 +30,15 @@
Come contribute, make some suggestions and help out in the Discord: <a href="https://discord.gg/QnmVMpU">https://discord.gg/QnmVMpU</a>
</p>
- <div class="center">
- <a class="bigText" href="/options/options.html">Enable optional features</a>
- </div>
+ <p style="margin-bottom: 0" class="bigText center">Please review the options below</p>
<p>
- Some features, such as support for non third-party YouTube sites, are disabled by default and can be enabled in the options. These can be enabled or disabled at any time.
+ Many features are disabled by default. If you want to skip Intros, outros, use Invidious, please enable the specific options. These can be enabled or disabled at any time.
You can also hide/show all UI elements added to the YouTube page.
</p>
+ <iframe src="../options/options.html#embed" width="100%" height="500px" style="border: none"></iframe>
+
<h1>How skipping works</h1>
<p class="projectPreview">
diff --git a/public/icons/help.svg b/public/icons/help.svg
new file mode 100644
index 00000000..571216ba
--- /dev/null
+++ b/public/icons/help.svg
@@ -0,0 +1,58 @@
+<?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"
+ height="24"
+ viewBox="0 0 24 24"
+ width="24"
+ version="1.1"
+ id="svg6"
+ sodipodi:docname="help.svg"
+ inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
+ <metadata
+ id="metadata12">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs10" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="730"
+ inkscape:window-height="480"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="9.8333333"
+ inkscape:cx="12"
+ inkscape:cy="12"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg6" />
+ <path
+ d="M0 0h24v24H0z"
+ fill="none"
+ id="path2" />
+ <path
+ d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"
+ id="path4"
+ style="fill:#ffffff" />
+</svg>
diff --git a/public/options/options.css b/public/options/options.css
index 36db654e..8ad87e3d 100644
--- a/public/options/options.css
+++ b/public/options/options.css
@@ -346,4 +346,8 @@ svg {
font-size: 14px;
padding: 5px;
border-radius: 5px;
+}
+
+.categoryColorTextBox {
+ width: 60px;
} \ No newline at end of file
diff --git a/src/background.ts b/src/background.ts
index 0c11ab06..28a1051e 100644
--- a/src/background.ts
+++ b/src/background.ts
@@ -62,12 +62,14 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
//this allows the callback to be called later
return true;
case "alertPrevious":
- chrome.notifications.create("stillThere" + Math.random(), {
- type: "basic",
- title: chrome.i18n.getMessage("wantToSubmit") + " " + request.previousVideoID + "?",
- message: chrome.i18n.getMessage("leftTimes"),
- iconUrl: "./icons/LogoSponsorBlocker256px.png"
- });
+ if (Config.config.unsubmittedWarning) {
+ chrome.notifications.create("stillThere" + Math.random(), {
+ type: "basic",
+ title: chrome.i18n.getMessage("wantToSubmit") + " " + request.previousVideoID + "?",
+ message: chrome.i18n.getMessage("leftTimes"),
+ iconUrl: "./icons/LogoSponsorBlocker256px.png"
+ });
+ }
case "registerContentScript":
registerFirefoxContentScript(request);
return false;
diff --git a/src/components/CategoryChooserComponent.tsx b/src/components/CategoryChooserComponent.tsx
index 3ec272fa..1aa401c1 100644
--- a/src/components/CategoryChooserComponent.tsx
+++ b/src/components/CategoryChooserComponent.tsx
@@ -28,6 +28,26 @@ class CategoryChooserComponent extends React.Component<CategoryChooserProps, Cat
<table id="categoryChooserTable"
className="categoryChooserTable">
<tbody>
+ {/* Headers */}
+ <tr id={"CategoryOptionsRow"}
+ className="categoryTableElement categoryTableHeader">
+ <td id={"CategoryOptionName"}>
+ {chrome.i18n.getMessage("category")}
+ </td>
+
+ <td id={"CategorySkipOption"}>
+ {chrome.i18n.getMessage("skipOption")}
+ </td>
+
+ <td id={"CategoryColorOption"}>
+ {chrome.i18n.getMessage("seekBarColor")}
+ </td>
+
+ <td id={"CategoryPreviewColorOption"}>
+ {chrome.i18n.getMessage("previewColor")}
+ </td>
+ </tr>
+
{this.getCategorySkipOptions()}
</tbody>
</table>
@@ -40,7 +60,6 @@ class CategoryChooserComponent extends React.Component<CategoryChooserProps, Cat
for (const category of CompileConfig.categoryList) {
elements.push(
<CategorySkipOptionsComponent category={category}
- defaultColor={"00d400"}
key={category}>
</CategorySkipOptionsComponent>
);
diff --git a/src/components/CategorySkipOptionsComponent.tsx b/src/components/CategorySkipOptionsComponent.tsx
index 58301d7b..0a44b172 100644
--- a/src/components/CategorySkipOptionsComponent.tsx
+++ b/src/components/CategorySkipOptionsComponent.tsx
@@ -2,14 +2,19 @@ import * as React from "react";
import Config from "../config"
import { CategorySkipOption } from "../types";
+import Utils from "../utils";
+
+const utils = new Utils();
export interface CategorySkipOptionsProps {
category: string;
- defaultColor: string;
+ defaultColor?: string;
+ defaultPreviewColor?: string;
}
export interface CategorySkipOptionsState {
color: string;
+ previewColor: string;
}
class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsProps, CategorySkipOptionsState> {
@@ -19,7 +24,8 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
// Setup state
this.state = {
- color: props.defaultColor
+ color: props.defaultColor || Config.config.barTypes[this.props.category].color,
+ previewColor: props.defaultPreviewColor || Config.config.barTypes["preview-" + this.props.category].color,
}
}
@@ -39,28 +45,65 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
defaultOption = "autoSkip";
break;
}
+
+ break;
}
}
return (
- <tr id={this.props.category + "OptionsRow"}
- className="categoryTableElement">
- <td id={this.props.category + "OptionName"}
- className="categoryTableLabel">
- {chrome.i18n.getMessage("category_" + this.props.category)}
- </td>
-
- <td id={this.props.category + "SkipOption"}>
- <select
- className="categoryOptionsSelector"
- defaultValue={defaultOption}
- onChange={this.skipOptionSelected.bind(this)}>
- {this.getCategorySkipOptions()}
- </select>
- </td>
-
- {/* TODO: Add colour chooser */}
- </tr>
+ <>
+ <tr id={this.props.category + "OptionsRow"}
+ className="categoryTableElement">
+ <td id={this.props.category + "OptionName"}
+ className="categoryTableLabel">
+ {chrome.i18n.getMessage("category_" + this.props.category)}
+ </td>
+
+ <td id={this.props.category + "SkipOption"}>
+ <select
+ className="categoryOptionsSelector"
+ defaultValue={defaultOption}
+ onChange={this.skipOptionSelected.bind(this)}>
+ {this.getCategorySkipOptions()}
+ </select>
+ </td>
+
+ <td id={this.props.category + "ColorOption"}>
+ <input
+ className="categoryColorTextBox option-text-box"
+ type="text"
+ onChange={(event) => this.setColorState(event, false)}
+ value={this.state.color} />
+ </td>
+
+ <td id={this.props.category + "PreviewColorOption"}>
+ <input
+ className="categoryColorTextBox option-text-box"
+ type="text"
+ onChange={(event) => this.setColorState(event, true)}
+ value={this.state.previewColor} />
+ </td>
+
+ <td id={this.props.category + "SaveButton"}>
+ <div
+ className="option-button trigger-button"
+ onClick={() => this.save()}>
+ {chrome.i18n.getMessage("save")}
+ </div>
+ </td>
+
+
+ </tr>
+
+ <tr id={this.props.category + "DescriptionRow"}
+ className="small-description">
+ <td
+ colSpan={2}>
+ {chrome.i18n.getMessage("category_" + this.props.category + "_description")}
+ </td>
+ </tr>
+
+ </>
);
}
@@ -112,7 +155,7 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
getCategorySkipOptions(): JSX.Element[] {
let elements: JSX.Element[] = [];
-""
+
let optionNames = ["disable", "showOverlay", "manualSkip", "autoSkip"];
for (const optionName of optionNames) {
@@ -125,6 +168,36 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
return elements;
}
+
+ setColorState(event: React.ChangeEvent<HTMLInputElement>, preview: boolean) {
+ if (preview) {
+ this.setState({
+ previewColor: event.target.value
+ });
+ } else {
+ this.setState({
+ color: event.target.value
+ });
+ }
+ }
+
+ // Save text box data
+ save() {
+ // Validate colors
+ let checkVar = [this.state.color, this.state.previewColor]
+ for (const color of checkVar) {
+ if (color[0] !== "#" || (color.length !== 7 && color.length !== 4) || !utils.isHex(color.slice(1))) {
+ alert(chrome.i18n.getMessage("colorFormatIncorrect") + " " + color.slice(1) + " " + utils.isHex(color.slice(1)) + " " + utils.isHex("abcd123"));
+ return;
+ }
+ }
+
+ // Save colors
+ Config.config.barTypes[this.props.category].color = this.state.color;
+ Config.config.barTypes["preview-" + this.props.category].color = this.state.previewColor;
+ // Make listener get called
+ Config.config.barTypes = Config.config.barTypes;
+ }
}
export default CategorySkipOptionsComponent; \ No newline at end of file
diff --git a/src/components/NoticeTextSectionComponent.tsx b/src/components/NoticeTextSectionComponent.tsx
index 839d7448..faed5704 100644
--- a/src/components/NoticeTextSectionComponent.tsx
+++ b/src/components/NoticeTextSectionComponent.tsx
@@ -2,7 +2,8 @@ import * as React from "react";
export interface NoticeTextSelectionProps {
text: string,
- idSuffix: string
+ idSuffix: string,
+ onClick?: (event: React.MouseEvent) => any
}
export interface NoticeTextSelectionState {
@@ -16,8 +17,16 @@ class NoticeTextSelectionComponent extends React.Component<NoticeTextSelectionPr
}
render() {
+ let style: React.CSSProperties = {};
+ if (this.props.onClick) {
+ style.cursor = "pointer";
+ style.textDecoration = "underline"
+ }
+
return (
<p id={"sponsorTimesInfoMessage" + this.props.idSuffix}
+ onClick={this.props.onClick}
+ style={style}
className="sponsorTimesInfoMessage">
{this.props.text}
</p>
diff --git a/src/components/SkipNoticeComponent.tsx b/src/components/SkipNoticeComponent.tsx
index 7e6c4751..022490d0 100644
--- a/src/components/SkipNoticeComponent.tsx
+++ b/src/components/SkipNoticeComponent.tsx
@@ -31,6 +31,7 @@ export interface SkipNoticeState {
noticeTitle: string;
messages: string[];
+ messageOnClick: (event: React.MouseEvent) => any;
countdownTime: number;
maxCountdownTime: () => number;
@@ -73,7 +74,8 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
this.contentContainer = props.contentContainer;
this.audio = null;
- let categoryName = chrome.i18n.getMessage(this.segments.length > 1 ? "multipleSegments" : "category_" + this.segments[0].category);
+ let 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 = categoryName + " " + chrome.i18n.getMessage("skipped");
if (!this.autoSkip) {
noticeTitle = chrome.i18n.getMessage("skip") + " " + categoryName + "?";
@@ -104,6 +106,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
this.state = {
noticeTitle,
messages: [],
+ messageOnClick: null,
//the countdown until this notice closes
maxCountdownTime: () => 4,
@@ -131,6 +134,13 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
this.audio.volume = this.contentContainer().v.volume * 0.1;
this.audio.play();
}
+
+ if (Config.config.categoryUpdateShowCount < 3 && Config.config.categorySelections.length <= 1) {
+ this.setNoticeInfoMessageWithOnClick(() => chrome.runtime.sendMessage({"message": "openConfig"})
+ , chrome.i18n.getMessage("categoryUpdate1"), chrome.i18n.getMessage("categoryUpdate2"));
+
+ Config.config.categoryUpdateShowCount = Config.config.categoryUpdateShowCount + 1
+ }
}
render() {
@@ -324,6 +334,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
elements.push(
<NoticeTextSelectionComponent idSuffix={this.idSuffix}
text={this.state.messages[i]}
+ onClick={this.state.messageOnClick}
key={i}>
</NoticeTextSelectionComponent>
)
@@ -504,6 +515,13 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
}
}
+ setNoticeInfoMessageWithOnClick(onClick: (event: React.MouseEvent) => any, ...messages: string[]) {
+ this.setState({
+ messages,
+ messageOnClick: (event) => onClick(event)
+ });
+ }
+
setNoticeInfoMessage(...messages: string[]) {
this.setState({
messages
diff --git a/src/components/SponsorTimeEditComponent.tsx b/src/components/SponsorTimeEditComponent.tsx
index 73e9b422..52c1da0c 100644
--- a/src/components/SponsorTimeEditComponent.tsx
+++ b/src/components/SponsorTimeEditComponent.tsx
@@ -182,14 +182,23 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
{timeDisplay}
{/* Category */}
-
- <select id={"sponsorTimeCategories" + this.idSuffix}
- className="sponsorTimeCategories"
- defaultValue={sponsorTime.category}
- ref={this.categoryOptionRef}
- onChange={this.categorySelectionChange.bind(this)}>
- {this.getCategoryOptions()}
- </select>
+ <div style={{position: "relative"}}>
+ <select id={"sponsorTimeCategories" + this.idSuffix}
+ className="sponsorTimeCategories"
+ defaultValue={sponsorTime.category}
+ ref={this.categoryOptionRef}
+ onChange={this.categorySelectionChange.bind(this)}>
+ {this.getCategoryOptions()}
+ </select>
+
+ <img id={"sponsorTimeCategoriesHelpButton" + this.idSuffix}
+ className="helpButton"
+ src={chrome.extension.getURL("icons/help.svg")}
+ title={chrome.i18n.getMessage("categoryGuidelines")}
+ onClick={() => chrome.runtime.sendMessage({"message": "openConfig"})}>
+
+ </img>
+ </div>
<br/>
diff --git a/src/components/SubmissionNoticeComponent.tsx b/src/components/SubmissionNoticeComponent.tsx
index a380fd73..a545c340 100644
--- a/src/components/SubmissionNoticeComponent.tsx
+++ b/src/components/SubmissionNoticeComponent.tsx
@@ -86,13 +86,20 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
{this.getSponsorTimeMessages()}
</td>
</tr>
-
+
{/* Last Row */}
<tr id={"sponsorSkipNoticeSecondRow" + this.state.idSuffix}>
<td className="sponsorSkipNoticeRightSection"
style={{position: "relative"}}>
+ {/* Guidelines button */}
+ <button className="sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeRightButton"
+ onClick={() => window.open("https://github.com/ajayyy/SponsorBlock/wiki/Guidelines")}>
+
+ {chrome.i18n.getMessage(Config.config.submissionCountSinceCategories > 3 ? "guidelines" : "readTheGuidelines")}
+ </button>
+
{/* Submit Button */}
<button className="sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeRightButton"
onClick={this.submit.bind(this)}>
diff --git a/src/config.ts b/src/config.ts
index 1b0a56d1..634947a9 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,5 +1,5 @@
import * as CompileConfig from "../config.json";
-import { CategorySelection, CategorySkipOption } from "./types";
+import { CategorySelection, CategorySkipOption, PreviewBarOption } from "./types";
import Utils from "./utils";
const utils = new Utils();
@@ -14,6 +14,8 @@ interface SBConfig {
minutesSaved: number,
skipCount: number,
sponsorTimesContributed: number,
+ submissionCountSinceCategories: number, // New count used to show the "Read The Guidelines!!" message
+ unsubmittedWarning: boolean,
disableSkipping: boolean,
trackViewCount: boolean,
dontShowNotice: boolean,
@@ -29,11 +31,28 @@ interface SBConfig {
minDuration: number,
audioNotificationOnSkip,
checkForUnlistedVideos: boolean,
- mobileUpdateShowCount: number,
testingServer: boolean,
+ categoryUpdateShowCount: number,
+
// What categories should be skipped
- categorySelections: CategorySelection[]
+ categorySelections: CategorySelection[],
+
+ // Preview bar
+ barTypes: {
+ "sponsor": PreviewBarOption,
+ "preview-sponsor": PreviewBarOption,
+ "intro": PreviewBarOption,
+ "preview-intro": PreviewBarOption,
+ "outro": PreviewBarOption,
+ "preview-outro": PreviewBarOption,
+ "interaction": PreviewBarOption,
+ "preview-interaction": PreviewBarOption,
+ "selfpromo": PreviewBarOption,
+ "preview-selfpromo": PreviewBarOption,
+ "music_offtopic": PreviewBarOption,
+ "preview-music_offtopic": PreviewBarOption
+ }
}
interface SBObject {
@@ -113,6 +132,8 @@ var Config: SBObject = {
minutesSaved: 0,
skipCount: 0,
sponsorTimesContributed: 0,
+ submissionCountSinceCategories: 0,
+ unsubmittedWarning: true,
disableSkipping: false,
trackViewCount: true,
dontShowNotice: false,
@@ -128,13 +149,66 @@ var Config: SBObject = {
minDuration: 0,
audioNotificationOnSkip: false,
checkForUnlistedVideos: false,
- mobileUpdateShowCount: 0,
testingServer: false,
+ categoryUpdateShowCount: 0,
+
categorySelections: [{
name: "sponsor",
option: CategorySkipOption.AutoSkip
- }]
+ }],
+
+ // Preview bar
+ barTypes: {
+ "sponsor": {
+ color: "#00d400",
+ opacity: "0.7"
+ },
+ "preview-sponsor": {
+ color: "#007800",
+ opacity: "0.7"
+ },
+ "intro": {
+ color: "#00ffff",
+ opacity: "0.7"
+ },
+ "preview-intro": {
+ color: "#008080",
+ opacity: "0.7"
+ },
+ "outro": {
+ color: "#0202ed",
+ opacity: "0.7"
+ },
+ "preview-outro": {
+ color: "#000070",
+ opacity: "0.7"
+ },
+ "interaction": {
+ color: "#cc00ff",
+ opacity: "0.7"
+ },
+ "preview-interaction": {
+ color: "#6c0087",
+ opacity: "0.7"
+ },
+ "selfpromo": {
+ color: "#ffff00",
+ opacity: "0.7"
+ },
+ "preview-selfpromo": {
+ color: "#bfbf35",
+ opacity: "0.7"
+ },
+ "music_offtopic": {
+ color: "#ff9900",
+ opacity: "0.7"
+ },
+ "preview-music_offtopic": {
+ color: "#a6634a",
+ opacity: "0.7"
+ }
+ }
},
localConfig: null,
config: null,
@@ -255,6 +329,11 @@ async function migrateOldFormats() {
chrome.storage.sync.remove("autoUpvote");
}
+ // mobileUpdateShowCount removal
+ if (Config.config["mobileUpdateShowCount"] !== undefined) {
+ chrome.storage.sync.remove("mobileUpdateShowCount");
+ }
+
// Channel URLS
if (Config.config.whitelistedChannels.length > 0 &&
(Config.config.whitelistedChannels[0] == null || Config.config.whitelistedChannels[0].includes("/"))) {
diff --git a/src/content.ts b/src/content.ts
index f61705b7..86ae8342 100644
--- a/src/content.ts
+++ b/src/content.ts
@@ -973,7 +973,7 @@ function skipToTime(v: HTMLVideoElement, skipTime: number[], skippingSegments: S
if (openNotice) {
//send out the message saying that a sponsor message was skipped
if (!Config.config.dontShowNotice || !autoSkip) {
- let skipNotice = new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer);
+ new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer);
}
}
@@ -1494,6 +1494,10 @@ async function sendSubmitMessage(){
// Increase contribution count
Config.config.sponsorTimesContributed = Config.config.sponsorTimesContributed + sponsorTimesSubmitting.length;
+ // New count just used to see if a warning "Read The Guidelines!!" message needs to be shown
+ // One per time submitting
+ Config.config.submissionCountSinceCategories = Config.config.submissionCountSinceCategories + 1;
+
// Empty the submitting times
sponsorTimesSubmitting = [];
diff --git a/src/js-components/previewBar.ts b/src/js-components/previewBar.ts
index a7e5c8ec..e0931d91 100644
--- a/src/js-components/previewBar.ts
+++ b/src/js-components/previewBar.ts
@@ -5,60 +5,7 @@
'use strict';
-let barTypes = {
- "undefined": {
- color: "#00d400",
- opacity: "0.7"
- },
- "sponsor": {
- color: "#00d400",
- opacity: "0.7"
- },
- "preview-sponsor": {
- color: "#007800",
- opacity: "0.7"
- },
- "intro": {
- color: "#00ffff",
- opacity: "0.7"
- },
- "preview-intro": {
- color: "#008080",
- opacity: "0.7"
- },
- "outro": {
- color: "#0202ed",
- opacity: "0.7"
- },
- "preview-outro": {
- color: "#000070",
- opacity: "0.7"
- },
- "interaction": {
- color: "#cc00ff",
- opacity: "0.7"
- },
- "preview-interaction": {
- color: "#6c0087",
- opacity: "0.7"
- },
- "selfpromo": {
- color: "#ffff00",
- opacity: "0.7"
- },
- "preview-selfpromo": {
- color: "#bfbf35",
- opacity: "0.7"
- },
- "music_offtopic": {
- color: "#ff9900",
- opacity: "0.7"
- },
- "preview-music_offtopic": {
- color: "#a6634a",
- opacity: "0.7"
- }
-};
+import Config from "../config";
class PreviewBar {
container: HTMLUListElement;
@@ -208,8 +155,8 @@ class PreviewBar {
let bar = this.createBar();
bar.setAttribute('data-vs-segment-type', types[i]);
- bar.style.backgroundColor = barTypes[types[i]].color;
- if (!this.onMobileYouTube) bar.style.opacity = barTypes[types[i]].opacity;
+ bar.style.backgroundColor = Config.config.barTypes[types[i]].color;
+ if (!this.onMobileYouTube) bar.style.opacity = Config.config.barTypes[types[i]].opacity;
bar.style.width = width + '%';
bar.style.left = (timestamps[i][0] / duration * 100) + "%";
bar.style.position = "absolute"
diff --git a/src/options.ts b/src/options.ts
index e9a622a5..0a196a9a 100644
--- a/src/options.ts
+++ b/src/options.ts
@@ -13,6 +13,13 @@ window.addEventListener('DOMContentLoaded', init);
async function init() {
utils.localizeHtmlPage();
+ // Remove header if needed
+ if (window.location.hash === "#embed") {
+ for (const element of document.getElementsByClassName("titleBar")) {
+ element.classList.add("hidden");
+ }
+ }
+
if (!Config.configListeners.includes(optionsConfigUpdateListener)) {
Config.configListeners.push(optionsConfigUpdateListener);
}
diff --git a/src/render/SkipNotice.tsx b/src/render/SkipNotice.tsx
index 4b969098..81f4c026 100644
--- a/src/render/SkipNotice.tsx
+++ b/src/render/SkipNotice.tsx
@@ -12,6 +12,8 @@ class SkipNotice {
noticeElement: HTMLDivElement;
+ skipNoticeRef: React.MutableRefObject<SkipNoticeComponent>;
+
constructor(segments: SponsorTime[], autoSkip: boolean = false, contentContainer) {
this.segments = segments;
this.autoSkip = autoSkip;
@@ -51,6 +53,7 @@ class SkipNotice {
<SkipNoticeComponent segments={segments}
autoSkip={autoSkip}
contentContainer={contentContainer}
+ ref={this.skipNoticeRef}
closeListener={() => this.close()} />,
this.noticeElement
);
diff --git a/src/types.ts b/src/types.ts
index 3bef9248..3d0f783e 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -58,6 +58,11 @@ interface SponsorTime {
hidden?: SponsorHideType;
}
+interface PreviewBarOption {
+ color: string,
+ opacity: string
+}
+
type VideoID = string;
export {
@@ -68,5 +73,6 @@ export {
CategorySkipOption,
SponsorTime,
VideoID,
- SponsorHideType
+ SponsorHideType,
+ PreviewBarOption
}; \ No newline at end of file
diff --git a/src/utils.ts b/src/utils.ts
index f3501b5d..6e12a0e5 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -358,6 +358,10 @@ class Utils {
return window.location.protocol === "http:" || window.location.protocol === "https:";
}
+ isHex(num: string): boolean {
+ return Boolean(num.match(/^[0-9a-f]+$/i));
+ }
+
/**
* Is this Firefox (web-extensions)
*/