diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/background.ts | 14 | ||||
-rw-r--r-- | src/components/CategoryChooserComponent.tsx | 21 | ||||
-rw-r--r-- | src/components/CategorySkipOptionsComponent.tsx | 115 | ||||
-rw-r--r-- | src/components/NoticeTextSectionComponent.tsx | 11 | ||||
-rw-r--r-- | src/components/SkipNoticeComponent.tsx | 20 | ||||
-rw-r--r-- | src/components/SponsorTimeEditComponent.tsx | 25 | ||||
-rw-r--r-- | src/components/SubmissionNoticeComponent.tsx | 9 | ||||
-rw-r--r-- | src/config.ts | 89 | ||||
-rw-r--r-- | src/content.ts | 6 | ||||
-rw-r--r-- | src/js-components/previewBar.ts | 59 | ||||
-rw-r--r-- | src/options.ts | 7 | ||||
-rw-r--r-- | src/render/SkipNotice.tsx | 3 | ||||
-rw-r--r-- | src/types.ts | 8 | ||||
-rw-r--r-- | src/utils.ts | 4 |
14 files changed, 289 insertions, 102 deletions
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) */ |