Merge branch 'master' of github.com:ajayyy/SponsorBlock

This commit is contained in:
mmble
2020-09-07 17:36:42 +02:00
12 changed files with 10681 additions and 70 deletions

View File

@@ -77,6 +77,18 @@ The result is in `dist`. This can be loaded as an unpacked extension
Run `npm run dev` to run the extension using a clean browser profile with hot reloading. Use `npm run dev:firefox` for Firefox. This uses [`web-ext run`](https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#commands). Run `npm run dev` to run the extension using a clean browser profile with hot reloading. Use `npm run dev:firefox` for Firefox. This uses [`web-ext run`](https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#commands).
Known chromium bug: Extension is not loaded properly on first start. Visit `chrome://extensions/` and reload the extension. Known chromium bug: Extension is not loaded properly on first start. Visit `chrome://extensions/` and reload the extension.
### Attribution Generation
If you contribute and add a dependency, update the attribution file using the following steps:
Make sure the attribution generator is installed: `npm i -g oss-attribution-generator`
```bash
generate-attribution
mv ./oss-attribution/attribution.txt ./public/oss-attribution/attribution.txt
```
# Credit # Credit
The awesome [Invidious API](https://github.com/omarroth/invidious/wiki/API) was previously used. The awesome [Invidious API](https://github.com/omarroth/invidious/wiki/API) was previously used.
@@ -86,4 +98,4 @@ Originally forked from [YTSponsorSkip](https://github.com/NDevTK/YTSponsorSkip),
Icons made by: Icons made by:
* <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a> * <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
* <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a> * <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
* <a href="https://iconmonstr.com/about/#creator">Alexander Kahlkopf</a> from <a href="https://iconmonstr.com/">iconmonstr.com</a> and are licensed by <a href="https://iconmonstr.com/license/">iconmonstr License</a> * <a href="https://iconmonstr.com/about/#creator">Alexander Kahlkopf</a> from <a href="https://iconmonstr.com/">iconmonstr.com</a> and are licensed by <a href="https://iconmonstr.com/license/">iconmonstr License</a>

File diff suppressed because one or more lines are too long

View File

@@ -143,7 +143,7 @@
"message": "here" "message": "here"
}, },
"recordTimesDescription": { "recordTimesDescription": {
"message": "Click the button below when the segment starts and ends to record and submit it to the database." "message": "Submit"
}, },
"popupHint": { "popupHint": {
"message": "Hint: Press the semicolon key while focused on a video to report the start/end of a segment and quote to submit. (This can be changed in the options)" "message": "Hint: Press the semicolon key while focused on a video to report the start/end of a segment and quote to submit. (This can be changed in the options)"

View File

@@ -19,15 +19,11 @@
<p class="createdBy">Created By <a href="https://ajay.app">Ajay Ramachandran</a> <img src="https://ajay.app/newprofilepic.jpg" height="30" class="profilepiccircle"/></p> <p class="createdBy">Created By <a href="https://ajay.app">Ajay Ramachandran</a> <img src="https://ajay.app/newprofilepic.jpg" height="30" class="profilepiccircle"/></p>
<p> <p>
Thanks for installing SponsorBlock. Here are some quick tips for getting started. Feel free to contact me if you have any questions. Thanks for installing SponsorBlock. Here are some quick tips for getting started. Feel free to contact me if you have any questions. By using this extension, you agree to the <a href="https://gist.github.com/ajayyy/aa9f8ded2b573d4f73a3ffa0ef74f796">Privacy Policy</a>.
</p> </p>
<p class="projectPreview"> <p class="projectPreview">
<span class="projectPreviewImage"> Come contribute, make some suggestions and help out in the Discord: <a href="https://discord.gg/QnmVMpU">https://discord.gg/QnmVMpU</a>
<a href="https://discord.gg/QnmVMpU"><img width="80" src="https://www.logolynx.com/images/logolynx/1b/1bcc0f0aefe71b2c8ce66ffe8645d365.png"/></a>
</span>
Come contribute, make some suggestions and help out in the Discord: <a href="https://discord.gg/QnmVMpU">https://discord.gg/QnmVMpU</a>
</p> </p>
<p style="margin-bottom: 0" class="bigText center">Please review the options below</p> <p style="margin-bottom: 0" class="bigText center">Please review the options below</p>
@@ -125,12 +121,22 @@
<h1>Credits</h1> <h1>Credits</h1>
<p>
Thanks to all <a href="https://github.com/ajayyy/SponsorBlock/graphs/contributors">SponsorBlock contributors</a>,
<a href="https://github.com/ajayyy/SponsorBlockServer/graphs/contributors">SponsorBlockServer contributors</a> and
<a href="https://github.com/ajayyy/SponsorBlockSite/graphs/contributors">SponsorBlockSite contributors</a> such
as <a href="https://github.com/NDevTK">NDev</a>, <a href="https://github.com/Joe-Dowd">Joe Dowd</a>,
<a href="https://github.com/bershanskiy">Anton Bershanskiy</a> and more.
</p>
<p>The awesome <a href="https://github.com/omarroth/invidious/wiki/API">Invidious API</a> is used to grab the time the video was published.</p> <p>The awesome <a href="https://github.com/omarroth/invidious/wiki/API">Invidious API</a> is used to grab the time the video was published.</p>
<p>Some icons made by <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></p> <p>Some icons made by <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></p>
<p>Some icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></p> <p>Some icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></p>
<p style="text-align: center;"><a href="/oss-attribution/attribution.txt">Open Source Licenses</a></p>
</div> </div>
</body> </body>

View File

@@ -350,4 +350,7 @@ svg {
.categoryColorTextBox { .categoryColorTextBox {
width: 60px; width: 60px;
background: none;
border: none;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -35,7 +35,7 @@ div.logoText {
color: var(--sb-main-fg-color); color: var(--sb-main-fg-color);
} }
div.logoText>p, .recordingSubtitle { div.logoText>p, .sbHeader {
font-size: 32px; font-size: 32px;
margin: -4px 0 -2px; margin: -4px 0 -2px;
font-weight: bold; font-weight: bold;
@@ -138,7 +138,7 @@ div.logoText>p, .recordingSubtitle {
margin-bottom: 2px !important; margin-bottom: 2px !important;
} }
.recordingSubtitle { .sbHeader {
margin-bottom: 5px !important; margin-bottom: 5px !important;
} }

View File

@@ -20,24 +20,6 @@
<p id="videoFound"></p> <p id="videoFound"></p>
</div> </div>
<p id="downloadedSponsorMessageTimes"></p> <p id="downloadedSponsorMessageTimes"></p>
<div id="mainControls" style="display: none">
<p class="popupElement">
__MSG_recordTimesDescription__
</p>
<div>
<button id="sponsorStart" class="greenButton popupElement">__MSG_sponsorStart__</button>
</div>
<sub class="popupElement">__MSG_popupHint__</sub>
<div id="submissionSection" class="popupElement" style="display: none">
<b>Sponsor Editing has been moved and will appear after you click submit</b>
<div id="submitTimesContainer" class="popupElement" style="display: none">
<button id="submitTimes" class="smallButton popupElement">__MSG_submitTimesButton__</button>
</div>
</div>
</div>
</div>
<div class="sidebyside"> <div class="sidebyside">
<div id="disableExtension"> <div id="disableExtension">
<!--github: mbledkowski/toggle-switch--> <!--github: mbledkowski/toggle-switch-->
@@ -69,7 +51,23 @@
</button> </button>
</div> </div>
</div> </div>
<h1 class="recordingSubtitle">__MSG_yourWork__</h1> <div id="mainControls" style="display: none">
<p class="popupElement" class="sbHeader">
__MSG_recordTimesDescription__
</p>
<sub class="popupElement">__MSG_popupHint__</sub>
<div>
<button id="sponsorStart" class="greenButton popupElement">__MSG_sponsorStart__</button>
</div>
<div id="submissionSection" class="popupElement" style="display: none">
<b>Sponsor Editing has been moved and will appear after you click submit</b>
<div id="submitTimesContainer" class="popupElement" style="display: none">
<button id="submitTimes" class="smallButton popupElement">__MSG_submitTimesButton__</button>
</div>
</div>
</div>
</div>
<h1 class="recordingSubtitle sbHeader">__MSG_yourWork__</h1>
<div class="sidebyside"> <div class="sidebyside">
<div id="usernameElement"> <div id="usernameElement">
<div> <div>

View File

@@ -71,7 +71,7 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
<td id={this.props.category + "ColorOption"}> <td id={this.props.category + "ColorOption"}>
<input <input
className="categoryColorTextBox option-text-box" className="categoryColorTextBox option-text-box"
type="text" type="color"
onChange={(event) => this.setColorState(event, false)} onChange={(event) => this.setColorState(event, false)}
value={this.state.color} /> value={this.state.color} />
</td> </td>
@@ -79,20 +79,11 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
<td id={this.props.category + "PreviewColorOption"}> <td id={this.props.category + "PreviewColorOption"}>
<input <input
className="categoryColorTextBox option-text-box" className="categoryColorTextBox option-text-box"
type="text" type="color"
onChange={(event) => this.setColorState(event, true)} onChange={(event) => this.setColorState(event, true)}
value={this.state.previewColor} /> value={this.state.previewColor} />
</td> </td>
<td id={this.props.category + "SaveButton"}>
<div
className="option-button trigger-button"
onClick={() => this.save()}>
{chrome.i18n.getMessage("save")}
</div>
</td>
</tr> </tr>
<tr id={this.props.category + "DescriptionRow"} <tr id={this.props.category + "DescriptionRow"}
@@ -169,32 +160,22 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
return elements; return elements;
} }
setColorState(event: React.ChangeEvent<HTMLInputElement>, preview: boolean) { setColorState(event: React.FormEvent<HTMLInputElement>, preview: boolean) {
if (preview) { if (preview) {
this.setState({ this.setState({
previewColor: event.target.value previewColor: event.currentTarget.value
}); });
Config.config.barTypes["preview-" + this.props.category].color = event.currentTarget.value;
} else { } else {
this.setState({ this.setState({
color: event.target.value color: event.currentTarget.value
}); });
}
}
// Save text box data Config.config.barTypes[this.props.category].color = event.currentTarget.value;
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 // Make listener get called
Config.config.barTypes = Config.config.barTypes; Config.config.barTypes = Config.config.barTypes;
} }

View File

@@ -324,7 +324,7 @@ async function videoIDChange(id) {
if (previousVideoID != null) { if (previousVideoID != null) {
//get the sponsor times from storage //get the sponsor times from storage
let sponsorTimes = Config.config.segmentTimes.get(previousVideoID); let sponsorTimes = Config.config.segmentTimes.get(previousVideoID);
if (sponsorTimes != undefined && sponsorTimes.length > 0) { if (sponsorTimes != undefined && sponsorTimes.length > 0 && new URL(document.URL).host !== "music.youtube.com") {
//warn them that they have unsubmitted sponsor times //warn them that they have unsubmitted sponsor times
chrome.runtime.sendMessage({ chrome.runtime.sendMessage({
message: "alertPrevious", message: "alertPrevious",
@@ -760,7 +760,7 @@ function getYouTubeVideoID(url: string) {
onInvidious = true; onInvidious = true;
} else if (urlObject.host === "m.youtube.com") { } else if (urlObject.host === "m.youtube.com") {
onMobileYouTube = true; onMobileYouTube = true;
} else if (!["m.youtube.com", "www.youtube.com", "www.youtube-nocookie.com"].includes(urlObject.host)) { } else if (!["m.youtube.com", "www.youtube.com", "www.youtube-nocookie.com", "music.youtube.com"].includes(urlObject.host)) {
if (!Config.config) { if (!Config.config) {
// Call this later, in case this is an Invidious tab // Call this later, in case this is an Invidious tab
utils.wait(() => Config.config !== null).then(() => videoIDChange(getYouTubeVideoID(url))); utils.wait(() => Config.config !== null).then(() => videoIDChange(getYouTubeVideoID(url)));
@@ -1087,7 +1087,7 @@ async function createButtons(): Promise<boolean> {
let createdButton = false; let createdButton = false;
// Add button if does not already exist in html // Add button if does not already exist in html
createdButton = createButton("startSponsor", "sponsorStart", startSponsorClicked, "PlayerStartIconSponsorBlocker256px.png") || createdButton; createdButton = createButton("startSponsor", "sponsorStart", startSponsorClicked, "PlayerStartIconSponsorBlocker256px.png") || createdButton;
createdButton = createButton("info", "openPopup", openInfoMenu, "PlayerInfoIconSponsorBlocker256px.png") || createdButton; createdButton = createButton("info", "openPopup", openInfoMenu, "PlayerInfoIconSponsorBlocker256px.png") || createdButton;
createdButton = createButton("delete", "clearTimes", clearSponsorTimes, "PlayerDeleteIconSponsorBlocker256px.png") || createdButton; createdButton = createButton("delete", "clearTimes", clearSponsorTimes, "PlayerDeleteIconSponsorBlocker256px.png") || createdButton;
createdButton = createButton("submit", "SubmitTimes", submitSponsorTimes, "PlayerUploadIconSponsorBlocker256px.png") || createdButton; createdButton = createButton("submit", "SubmitTimes", submitSponsorTimes, "PlayerUploadIconSponsorBlocker256px.png") || createdButton;
@@ -1330,7 +1330,7 @@ function clearSponsorTimes() {
function vote(type: number, UUID: string, category?: string, skipNotice?: SkipNoticeComponent) { function vote(type: number, UUID: string, category?: string, skipNotice?: SkipNoticeComponent) {
if (skipNotice !== null && skipNotice !== undefined) { if (skipNotice !== null && skipNotice !== undefined) {
//add loading info //add loading info
skipNotice.addVoteButtonInfo.bind(skipNotice)("Loading...") skipNotice.addVoteButtonInfo.bind(skipNotice)(chrome.i18n.getMessage("Loading"))
skipNotice.setNoticeInfoMessage.bind(skipNotice)(); skipNotice.setNoticeInfoMessage.bind(skipNotice)();
} }

View File

@@ -105,7 +105,7 @@ async function runThePopup(messageListener?: MessageListener) {
].forEach(id => PageElements[id] = document.getElementById(id)); ].forEach(id => PageElements[id] = document.getElementById(id));
//setup click listeners //setup click listeners
//PageElements.sponsorStart.addEventListener("click", sendSponsorStartMessage); PageElements.sponsorStart.addEventListener("click", sendSponsorStartMessage);
PageElements.whitelistToggle.addEventListener("change", function() { PageElements.whitelistToggle.addEventListener("change", function() {
if (this.checked) { if (this.checked) {
whitelistChannel(); whitelistChannel();
@@ -114,8 +114,8 @@ async function runThePopup(messageListener?: MessageListener) {
} }
}); });
//PageElements.whitelistChannel.addEventListener("click", whitelistChannel); //PageElements.whitelistChannel.addEventListener("click", whitelistChannel);
//PageElements.whitelistForceCheck.addEventListener("click", openOptions); PageElements.whitelistForceCheck.addEventListener("click", openOptions);
//ageElements.unwhitelistChannel.addEventListener("click", unwhitelistChannel); //PageElements.unwhitelistChannel.addEventListener("click", unwhitelistChannel);
PageElements.toggleSwitch.addEventListener("change", function() { PageElements.toggleSwitch.addEventListener("change", function() {
if (this.checked) { if (this.checked) {
toggleSkipping(false); toggleSkipping(false);
@@ -125,7 +125,7 @@ async function runThePopup(messageListener?: MessageListener) {
}); });
//PageElements.disableSkipping.addEventListener("click", () => toggleSkipping(true)); //PageElements.disableSkipping.addEventListener("click", () => toggleSkipping(true));
//PageElements.enableSkipping.addEventListener("click", () => toggleSkipping(false)); //PageElements.enableSkipping.addEventListener("click", () => toggleSkipping(false));
//PageElements.submitTimes.addEventListener("click", submitTimes); PageElements.submitTimes.addEventListener("click", submitTimes);
//PageElements.showNoticeAgain.addEventListener("click", showNoticeAgain); //PageElements.showNoticeAgain.addEventListener("click", showNoticeAgain);
PageElements.setUsernameButton.addEventListener("click", setUsernameButton); PageElements.setUsernameButton.addEventListener("click", setUsernameButton);
PageElements.submitUsername.addEventListener("click", submitUsername); PageElements.submitUsername.addEventListener("click", submitUsername);
@@ -855,7 +855,7 @@ async function runThePopup(messageListener?: MessageListener) {
function submitUsername() { function submitUsername() {
//add loading indicator //add loading indicator
PageElements.setUsernameStatusContainer.style.display = "unset"; PageElements.setUsernameStatusContainer.style.display = "unset";
PageElements.setUsernameStatus.innerText = "Loading..."; PageElements.setUsernameStatus.innerText = chrome.i18n.getMessage("Loading");
//get the userID //get the userID
utils.sendRequestToServer("POST", "/api/setUsername?userID=" + Config.config.userID + "&username=" + PageElements.usernameInput.value, function (response) { utils.sendRequestToServer("POST", "/api/setUsername?userID=" + Config.config.userID + "&username=" + PageElements.usernameInput.value, function (response) {
@@ -902,7 +902,7 @@ async function runThePopup(messageListener?: MessageListener) {
function vote(type, UUID) { function vote(type, UUID) {
//add loading info //add loading info
addVoteMessage("Loading...", UUID) addVoteMessage(chrome.i18n.getMessage("Loading"), UUID)
//send the vote message to the tab //send the vote message to the tab
chrome.runtime.sendMessage({ chrome.runtime.sendMessage({

View File

@@ -2,19 +2,19 @@ import * as React from "react";
import * as ReactDOM from "react-dom"; import * as ReactDOM from "react-dom";
import SkipNoticeComponent from "../components/SkipNoticeComponent"; import SkipNoticeComponent from "../components/SkipNoticeComponent";
import { SponsorTime } from "../types"; import { SponsorTime, ContentContainer } from "../types";
class SkipNotice { class SkipNotice {
segments: SponsorTime[]; segments: SponsorTime[];
autoSkip: boolean; autoSkip: boolean;
// Contains functions and variables from the content script needed by the skip notice // Contains functions and variables from the content script needed by the skip notice
contentContainer: () => any; contentContainer: ContentContainer;
noticeElement: HTMLDivElement; noticeElement: HTMLDivElement;
skipNoticeRef: React.MutableRefObject<SkipNoticeComponent>; skipNoticeRef: React.MutableRefObject<SkipNoticeComponent>;
constructor(segments: SponsorTime[], autoSkip: boolean = false, contentContainer) { constructor(segments: SponsorTime[], autoSkip: boolean = false, contentContainer: ContentContainer) {
this.segments = segments; this.segments = segments;
this.autoSkip = autoSkip; this.autoSkip = autoSkip;
this.contentContainer = contentContainer; this.contentContainer = contentContainer;
@@ -35,6 +35,10 @@ class SkipNotice {
index++; index++;
} }
} }
// YouTube Music
if (new URL(document.URL).host === "music.youtube.com") {
referenceNode = document.querySelector("#main-panel.ytmusic-player-page");
}
let amountOfPreviousNotices = document.getElementsByClassName("sponsorSkipNotice").length; let amountOfPreviousNotices = document.getElementsByClassName("sponsorSkipNotice").length;
//this is the suffix added at the end of every id //this is the suffix added at the end of every id