Compare commits

..

26 Commits

Author SHA1 Message Date
Ajay Ramachandran
88350e3421 Merge pull request #308 from ajayyy/experimental
Skipping Fixes
2020-03-30 20:11:33 -04:00
Ajay Ramachandran
36d79313de Increase version number 2020-03-30 20:10:32 -04:00
Ajay Ramachandran
a9993d5d80 Added check for videoID change not being called 2020-03-30 20:08:00 -04:00
Ajay Ramachandran
4a6ddf6774 Remove mobile support announcement 2020-03-30 19:15:25 -04:00
Ajay Ramachandran
b6172c6d9b Fixed sponsor skipping after quickly playing and pausing. 2020-03-30 19:07:59 -04:00
Ajay Ramachandran
b21a59f4e5 Fixed looping sometimes not skipping beginning sponsors.
Resolves https://github.com/ajayyy/SponsorBlock/issues/306
2020-03-30 15:33:03 -04:00
Ajay Ramachandran
78dd44c502 Fixed missing name in release workflow 2020-03-30 14:44:26 -04:00
Ajay Ramachandran
f4a129b346 Merge pull request #307 from ajayyy/experimental
Skipping fixes
2020-03-30 14:34:31 -04:00
Ajay Ramachandran
6d60a90533 Increased version number. 2020-03-30 14:18:11 -04:00
Ajay Ramachandran
0d33794636 Fixed almost zero second sponsors skipping a little too late. 2020-03-30 14:11:46 -04:00
Ajay Ramachandran
e62d46f2dd Improved zero second skipping for directly loaded videos 2020-03-30 14:07:35 -04:00
Ajay Ramachandran
7f36c7eec3 Merge pull request #302 from Joe-Dowd/restrict-keybindings
Restrict keybindings
2020-03-26 12:35:28 -04:00
Ajay Ramachandran
08d28798c6 Localised key errors 2020-03-26 12:30:06 -04:00
Ajay Ramachandran
fe33277d8f Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into restrict-keybindings 2020-03-26 12:27:06 -04:00
Ajay Ramachandran
feec5b4e22 Added spacing and separated code into a function 2020-03-26 12:26:47 -04:00
Ajay Ramachandran
62b5e90d87 Merge pull request #300 from Joe-Dowd/debug-output
Added copy debug information to clipboard options element.
2020-03-26 12:19:07 -04:00
Ajay Ramachandran
2c980a269d Fixed sponsorTimes data on export and import 2020-03-26 12:18:52 -04:00
Ajay Ramachandran
1da60e38a1 Merge pull request #304 from ajayyy/experimental
Scheduling fixes
2020-03-25 19:01:43 -04:00
Ajay Ramachandran
ed67cc52fe Fixed mobile YouTube starting sponsor detection that are not exactly 0 seconds. 2020-03-21 20:59:08 -04:00
Joe-Dowd
b614dce91a Added more restricted characters 2020-03-20 19:55:29 +00:00
Joe-Dowd
c013c7ef0f added N and i to the list of restricted characters 2020-03-20 19:50:38 +00:00
Joe-Dowd
c78e2cd214 Fixed mod keys when setting keybinding 2020-03-20 19:39:37 +00:00
Joe-Dowd
da5a3841bd Added restrictions to keybindings. 2020-03-20 15:35:23 +00:00
Joe Dowd
e73d79071c Added copy debug information to clipboard options element. 2020-03-18 00:15:04 +00:00
Ajay Ramachandran
0467dd5d21 Made sure no skips are scheduled while paused 2020-03-11 19:39:08 -04:00
Ajay Ramachandran
5f879bceab Fixed where repo-token was inputted in release workflow 2020-03-10 23:30:53 -04:00
8 changed files with 215 additions and 61 deletions

View File

@@ -67,12 +67,12 @@ jobs:
uses: Shopify/upload-to-release@master uses: Shopify/upload-to-release@master
with: with:
args: builds/ChromeExtension.zip args: builds/ChromeExtension.zip
env: name: ChromeExtension.zip
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload to release - name: Upload to release
uses: Shopify/upload-to-release@master uses: Shopify/upload-to-release@master
with: with:
args: builds/FirefoxExtension.zip args: builds/FirefoxExtension.zip
env: name: FirefoxExtension.zip
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,7 +1,7 @@
{ {
"name": "__MSG_fullName__", "name": "__MSG_fullName__",
"short_name": "__MSG_Name__", "short_name": "__MSG_Name__",
"version": "1.2.22", "version": "1.2.24",
"default_locale": "en", "default_locale": "en",
"description": "__MSG_Description__", "description": "__MSG_Description__",
"content_scripts": [{ "content_scripts": [{

View File

@@ -440,5 +440,26 @@
}, },
"incorrectlyFormattedOptions": { "incorrectlyFormattedOptions": {
"message": "This JSON is not formatted correctly. Your options have not been changed." "message": "This JSON is not formatted correctly. Your options have not been changed."
},
"copyDebugInformation": {
"message": "Copy Debug Information To Clipboard"
},
"copyDebugInformationFailed": {
"message": "Failed to write to clipboard"
},
"copyDebugInformationOptions": {
"message": "Copies information to the clipboard to be provided to a developer when raising a bug / when a developer requests it. Sensitive information such as your user ID, whitelisted channels, and custom server address have been removed. However it does contain information such as your useragent, browser, operating system, and extension version number. "
},
"copyDebugInformationComplete": {
"message": "The debug information has been copied to the clip board. Feel free to remove any information you would rather not share. Save this in a text file or paste into the bug report."
},
"theKey": {
"message": "The key"
},
"keyAlreadyUsedByYouTube": {
"message": "is already used by youtube. Please select another key."
},
"keyAlreadyUsed": {
"message": "is bound to another action. Please select another key."
} }
} }

View File

@@ -334,6 +334,20 @@
<br/> <br/>
<br/> <br/>
<div option-type="button-press" sync-option="copyDebugInformation" confirm-message="copyDebugInformation">
<div class="option-button trigger-button">
__MSG_copyDebugInformation__
</div>
<br/>
<div class="small-description">__MSG_copyDebugInformationOptions__</div>
</div>
<br/>
<br/>
<div option-type="text-change" sync-option="serverAddress"> <div option-type="text-change" sync-option="serverAddress">
<label class="text-label-container"> <label class="text-label-container">
<div>__MSG_customServerAddress__</div> <div>__MSG_customServerAddress__</div>

View File

@@ -88,10 +88,6 @@ chrome.runtime.onInstalled.addListener(function (object) {
const newUserID = utils.generateUserID(); const newUserID = utils.generateUserID();
//save this UUID //save this UUID
Config.config.userID = newUserID; Config.config.userID = newUserID;
//TODO: Remove when mobile support is old
// Don't show this to new users
// Config.config.mobileUpdateShowCount = 1;
} }
}, 1500); }, 1500);
}); });

View File

@@ -33,6 +33,10 @@ interface SBObject {
defaults: SBConfig; defaults: SBConfig;
localConfig: SBConfig; localConfig: SBConfig;
config: SBConfig; config: SBConfig;
// Functions
encodeStoredItem<T>(data: T): T | Array<any>;
convertJSON(): void;
} }
// Allows a SBMap to be conveted into json form // Allows a SBMap to be conveted into json form
@@ -119,7 +123,11 @@ var Config: SBObject = {
mobileUpdateShowCount: 0 mobileUpdateShowCount: 0
}, },
localConfig: null, localConfig: null,
config: null config: null,
// Functions
encodeStoredItem,
convertJSON
}; };
// Function setup // Function setup
@@ -130,7 +138,7 @@ var Config: SBObject = {
* *
* @param data * @param data
*/ */
function encodeStoredItem(data) { function encodeStoredItem<T>(data: T): T | Array<any> {
// if data is SBMap convert to json for storing // if data is SBMap convert to json for storing
if(!(data instanceof SBMap)) return data; if(!(data instanceof SBMap)) return data;
return Array.from(data.entries()); return Array.from(data.entries());
@@ -142,7 +150,7 @@ function encodeStoredItem(data) {
* *
* @param {*} data * @param {*} data
*/ */
function decodeStoredItem(id: string, data) { function decodeStoredItem<T>(id: string, data: T): T | SBMap<string, any> {
if (!Config.defaults[id]) return data; if (!Config.defaults[id]) return data;
if (Config.defaults[id] instanceof SBMap) { if (Config.defaults[id] instanceof SBMap) {
@@ -239,7 +247,7 @@ function resetConfig() {
Config.config = Config.defaults; Config.config = Config.defaults;
}; };
function convertJSON() { function convertJSON(): void {
Object.keys(Config.localConfig).forEach(key => { Object.keys(Config.localConfig).forEach(key => {
Config.localConfig[key] = decodeStoredItem(key, Config.localConfig[key]); Config.localConfig[key] = decodeStoredItem(key, Config.localConfig[key]);
}); });

View File

@@ -21,7 +21,7 @@ var UUIDs = [];
var sponsorVideoID = null; var sponsorVideoID = null;
// Skips are scheduled to ensure precision. // Skips are scheduled to ensure precision.
// Skips are rescheduled every seeked event. // Skips are rescheduled every seeking event.
// Skips are canceled every seeking event // Skips are canceled every seeking event
var currentSkipSchedule: NodeJS.Timeout = null; var currentSkipSchedule: NodeJS.Timeout = null;
var seekListenerSetUp = false var seekListenerSetUp = false
@@ -35,6 +35,9 @@ var sponsorSkipped = [];
//the video //the video
var video: HTMLVideoElement; var video: HTMLVideoElement;
/** The last time this video was seeking to */
var lastVideoTime: number = null;
var onInvidious; var onInvidious;
var onMobileYouTube; var onMobileYouTube;
@@ -259,7 +262,12 @@ function resetValues() {
//reset sponsor data found check //reset sponsor data found check
sponsorDataFound = false; sponsorDataFound = false;
if (switchingVideos === null) {
// When first loading a video, it is not switching videos
switchingVideos = false;
} else {
switchingVideos = true; switchingVideos = true;
}
} }
async function videoIDChange(id) { async function videoIDChange(id) {
@@ -452,6 +460,7 @@ function cancelSponsorSchedule(): void {
*/ */
function startSponsorSchedule(currentTime?: number): void { function startSponsorSchedule(currentTime?: number): void {
cancelSponsorSchedule(); cancelSponsorSchedule();
if (video.paused) return;
if (Config.config.disableSkipping || channelWhitelisted){ if (Config.config.disableSkipping || channelWhitelisted){
return; return;
@@ -470,6 +479,10 @@ function startSponsorSchedule(currentTime?: number): void {
let forcedSkipTime: number = null; let forcedSkipTime: number = null;
if (video.currentTime >= skipTime[0] && video.currentTime < skipTime[1]) { if (video.currentTime >= skipTime[0] && video.currentTime < skipTime[1]) {
// Double check that the videoID is correct
// TODO: Remove this bug catching if statement when the bug is found
let currentVideoID = getYouTubeVideoID(document.URL);
if (currentVideoID == sponsorVideoID) {
skipToTime(video, skipInfo.index, skipInfo.array, skipInfo.openNotice); skipToTime(video, skipInfo.index, skipInfo.array, skipInfo.openNotice);
if (Config.config.disableAutoSkip) { if (Config.config.disableAutoSkip) {
@@ -477,6 +490,14 @@ function startSponsorSchedule(currentTime?: number): void {
} else { } else {
forcedSkipTime = skipTime[1]; forcedSkipTime = skipTime[1];
} }
} else {
// Something has really gone wrong
console.error("[SponsorBlock] The videoID recorded when trying to skip is different than what it should be.");
console.error("[SponsorBlock] VideoID recorded: " + sponsorVideoID + ". Actual VideoID: " + currentVideoID);
// Video ID change occured
videoIDChange(currentVideoID);
}
} }
startSponsorSchedule(forcedSkipTime); startSponsorSchedule(forcedSkipTime);
@@ -527,12 +548,27 @@ function sponsorsLookup(id: string, channelIDPromise?) {
startSponsorSchedule(); startSponsorSchedule();
} }
}); });
video.addEventListener('seeked', () => { video.addEventListener('seeking', () => {
if (!video.paused) startSponsorSchedule(); // Reset lastCheckVideoTime
lastCheckVideoTime = -1
lastCheckTime = 0;
lastVideoTime = video.currentTime;
if (!video.paused){
startSponsorSchedule();
}
}); });
video.addEventListener('ratechange', () => startSponsorSchedule()); video.addEventListener('ratechange', () => startSponsorSchedule());
video.addEventListener('seeking', cancelSponsorSchedule); video.addEventListener('pause', () => {
video.addEventListener('pause', cancelSponsorSchedule); // Reset lastCheckVideoTime
lastCheckVideoTime = -1;
lastCheckTime = 0;
lastVideoTime = video.currentTime;
cancelSponsorSchedule();
});
startSponsorSchedule(); startSponsorSchedule();
} }
@@ -587,26 +623,26 @@ function sponsorsLookup(id: string, channelIDPromise?) {
UUIDs = smallUUIDs; UUIDs = smallUUIDs;
} }
// See if there are any zero second sponsors if (!switchingVideos) {
let zeroSecondSponsor = false; // See if there are any starting sponsors
let startingSponsor: number = -1;
for (const time of sponsorTimes) { for (const time of sponsorTimes) {
if (time[0] <= 0) { if (time[0] <= video.currentTime && time[0] > startingSponsor && time[1] > video.currentTime) {
zeroSecondSponsor = true; startingSponsor = time[0];
break; break;
} }
} }
if (!zeroSecondSponsor) { if (!startingSponsor) {
for (const time of sponsorTimesSubmitting) { for (const time of sponsorTimesSubmitting) {
if (time[0] <= 0) { if (time[0] <= video.currentTime && time[0] > startingSponsor && time[1] > video.currentTime) {
zeroSecondSponsor = true; startingSponsor = time[0];
break; break;
} }
} }
} }
if (!video.paused && !switchingVideos) { if (startingSponsor !== -1) {
if (zeroSecondSponsor) { startSponsorSchedule(startingSponsor);
startSponsorSchedule(0);
} else { } else {
startSponsorSchedule(); startSponsorSchedule();
} }
@@ -866,13 +902,6 @@ function skipToTime(v, index, sponsorTimes, openNotice) {
let skipNotice = new SkipNotice(this, currentUUID, Config.config.disableAutoSkip, skipNoticeContentContainer); let skipNotice = new SkipNotice(this, currentUUID, Config.config.disableAutoSkip, skipNoticeContentContainer);
//TODO: Remove this when Mobile support is old
if (Config.config.mobileUpdateShowCount < 1) {
skipNotice.addNoticeInfoMessage(chrome.i18n.getMessage("mobileUpdateInfo"));
Config.config.mobileUpdateShowCount += 1;
}
//auto-upvote this sponsor //auto-upvote this sponsor
if (Config.config.trackViewCount && !Config.config.disableAutoSkip && Config.config.autoUpvote) { if (Config.config.trackViewCount && !Config.config.disableAutoSkip && Config.config.autoUpvote) {
vote(1, currentUUID, null); vote(1, currentUUID, null);

View File

@@ -1,4 +1,6 @@
import Config from "./config"; import Config from "./config";
import * as CompileConfig from "../config.json";
// Make the config public for debugging purposes // Make the config public for debugging purposes
(<any> window).SB = Config; (<any> window).SB = Config;
@@ -126,6 +128,16 @@ async function init() {
invidiousInstanceAddInit(<HTMLElement> optionsElements[i], privateTextChangeOption); invidiousInstanceAddInit(<HTMLElement> optionsElements[i], privateTextChangeOption);
} }
break;
case "button-press":
let actionButton = optionsElements[i].querySelector(".trigger-button");
switch(optionsElements[i].getAttribute("sync-option")) {
case "copyDebugInformation":
actionButton.addEventListener("click", copyDebugOutputToClipboard);
break;
}
break; break;
case "keybind-change": case "keybind-change":
let keybindButton = optionsElements[i].querySelector(".trigger-button"); let keybindButton = optionsElements[i].querySelector(".trigger-button");
@@ -319,16 +331,39 @@ function activateKeybindChange(element: HTMLElement) {
function keybindKeyPressed(element: HTMLElement, e: KeyboardEvent) { function keybindKeyPressed(element: HTMLElement, e: KeyboardEvent) {
var key = e.key; var key = e.key;
let button = element.querySelector(".trigger-button"); if (["Shift", "Control", "Meta", "Alt", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Tab"].indexOf(key) !== -1) {
// cancel setting a keybind // Wait for more
if (key === "Escape") { document.addEventListener("keydown", (e) => keybindKeyPressed(element, e), {once: true});
element.querySelector(".option-hidden-section").classList.add("hidden"); } else {
button.classList.remove("disabled"); let button: HTMLElement = element.querySelector(".trigger-button");
let option = element.getAttribute("sync-option");
// Don't allow keys which are already listened for by youtube
let restrictedKeys = "1234567890,.jklftcibmJKLFTCIBMNP/<> -+";
if (restrictedKeys.indexOf(key) !== -1 ) {
closeKeybindOption(element, button);
alert(chrome.i18n.getMessage("theKey") + " " + key + " " + chrome.i18n.getMessage("keyAlreadyUsedByYouTube"));
return; return;
} }
let option = element.getAttribute("sync-option"); // Make sure keybind isn't used by the other listener
// TODO: If other keybindings are going to be added, we need a better way to find the other keys used.
let otherKeybind = (option === "startSponsorKeybind") ? Config.config['submitKeybind'] : Config.config['startSponsorKeybind'];
if (key === otherKeybind) {
closeKeybindOption(element, button);
alert(chrome.i18n.getMessage("theKey") + " " + key + " " + chrome.i18n.getMessage("keyAlreadyUsed"));
return;
}
// cancel setting a keybind
if (key === "Escape") {
closeKeybindOption(element, button);
return;
}
Config.config[option] = key; Config.config[option] = key;
@@ -338,6 +373,18 @@ function keybindKeyPressed(element: HTMLElement, e: KeyboardEvent) {
let statusKey = <HTMLElement> element.querySelector(".option-hidden-section > .keybind-status-key"); let statusKey = <HTMLElement> element.querySelector(".option-hidden-section > .keybind-status-key");
statusKey.innerText = key; statusKey.innerText = key;
button.classList.remove("disabled");
}
}
/**
* Closes the menu for editing the keybind
*
* @param element
* @param button
*/
function closeKeybindOption(element: HTMLElement, button: HTMLElement) {
element.querySelector(".option-hidden-section").classList.add("hidden");
button.classList.remove("disabled"); button.classList.remove("disabled");
} }
@@ -367,7 +414,12 @@ function activatePrivateTextChange(element: HTMLElement) {
// See if anything extra must be done // See if anything extra must be done
switch (option) { switch (option) {
case "*": case "*":
result = JSON.stringify(Config.localConfig); let jsonData = JSON.parse(JSON.stringify(Config.localConfig));
// Fix sponsorTimes data as it is destroyed from the JSON stringify
jsonData.sponsorTimes = Config.encodeStoredItem(Config.localConfig.sponsorTimes);
result = JSON.stringify(jsonData);
break; break;
} }
@@ -387,7 +439,9 @@ function activatePrivateTextChange(element: HTMLElement) {
for (const key in newConfig) { for (const key in newConfig) {
Config.config[key] = newConfig[key]; Config.config[key] = newConfig[key];
} }
Config.convertJSON();
// Reload options on page
init(); init();
if (newConfig.supportInvidious) { if (newConfig.supportInvidious) {
@@ -433,3 +487,35 @@ function validateServerAddress(input: string): string {
return input; return input;
} }
function copyDebugOutputToClipboard() {
// Build output debug information object
let output = {
debug: {
userAgent: navigator.userAgent,
platform: navigator.platform,
language: navigator.language,
extensionVersion: chrome.runtime.getManifest().version
},
config: JSON.parse(JSON.stringify(Config.localConfig)) // Deep clone config object
};
// Fix sponsorTimes data as it is destroyed from the JSON stringify
output.config.sponsorTimes = Config.encodeStoredItem(Config.localConfig.sponsorTimes);
// Sanitise sensitive user config values
delete output.config.userID;
output.config.serverAddress = (output.config.serverAddress === CompileConfig.serverAddress)
? "Default server address" : "Custom server address";
output.config.invidiousInstances = output.config.invidiousInstances.length;
output.config.whitelistedChannels = output.config.whitelistedChannels.length;
// Copy object to clipboard
navigator.clipboard.writeText(JSON.stringify(output, null, 4))
.then(() => {
alert(chrome.i18n.getMessage("copyDebugInformationComplete"));
})
.catch(err => {
alert(chrome.i18n.getMessage("copyDebugInformationFailed"));
});;
}