diff options
-rw-r--r-- | public/_locales/en/messages.json | 6 | ||||
-rw-r--r-- | public/help/index_en.html | 9 | ||||
-rw-r--r-- | public/help/styles.css | 4 | ||||
-rw-r--r-- | public/options/options.css | 4 | ||||
-rw-r--r-- | public/options/options.html | 25 | ||||
-rw-r--r-- | src/config.ts | 2 | ||||
-rw-r--r-- | src/help.ts | 9 | ||||
-rw-r--r-- | src/options.ts | 5 | ||||
-rw-r--r-- | src/popup.ts | 156 | ||||
-rw-r--r-- | src/utils/configUtils.ts | 5 | ||||
-rw-r--r-- | webpack/webpack.common.js | 1 |
11 files changed, 147 insertions, 79 deletions
diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 0ba715fe..726c35bd 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -724,5 +724,11 @@ "voteRejectedWarning": { "message": "Vote rejected due to a warning. Click to open a chat to resolve it, or come back later when you have time.", "description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser." + }, + "Donate": { + "message": "Donate" + }, + "hideDonationLink": { + "message": "Hide Donation Link" } } diff --git a/public/help/index_en.html b/public/help/index_en.html index d6d8d762..9606649f 100644 --- a/public/help/index_en.html +++ b/public/help/index_en.html @@ -5,6 +5,9 @@ <meta charset="utf-8"> <link href="styles.css" rel="stylesheet"/> + + <script src="../js/vendor.js"></script> + <script src="../js/help.js"></script> </head> <body> @@ -16,7 +19,11 @@ <div class="container"> - <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"> + <img src="https://ajay.app/newprofilepic.jpg" height="30" class="profilepiccircle"/> + Created By <a href="https://ajay.app">Ajay Ramachandran</a> + <a href="https://sponsor.ajay.app/donate" target="_blank" rel="noopener" id="sbDonate">(Donate)</a> + </p> <p> Thanks for installing SponsorBlock. By using this extension, you agree to the <a href="https://gist.github.com/ajayyy/aa9f8ded2b573d4f73a3ffa0ef74f796">Privacy Policy</a> and <a href="https://gist.github.com/ajayyy/9e8100f069348e0bc062641f34d6af12">Terms of Use</a>. diff --git a/public/help/styles.css b/public/help/styles.css index a7b8b9fd..2e392c2e 100644 --- a/public/help/styles.css +++ b/public/help/styles.css @@ -183,4 +183,8 @@ h1,h2,h3,h4,h5,h6 { svg { text-decoration: none; +} + +#sbDonate { + font-size: 10px; }
\ No newline at end of file diff --git a/public/options/options.css b/public/options/options.css index e6dd3a01..708139ab 100644 --- a/public/options/options.css +++ b/public/options/options.css @@ -364,4 +364,8 @@ svg { background: none; border: none; +} + +#sbDonate { + font-size: 10px; }
\ No newline at end of file diff --git a/public/options/options.html b/public/options/options.html index 90a2e51f..540b5122 100644 --- a/public/options/options.html +++ b/public/options/options.html @@ -19,7 +19,12 @@ </div> <div class="center"> - <p class="createdBy titleBar">__MSG_createdBy__ <a href="https://ajay.app">Ajay Ramachandran</a> <img src="../icons/newprofilepic.jpg" height="30" class="profilepiccircle"/></p> + <p class="createdBy titleBar"> + <img src="../icons/newprofilepic.jpg" height="30" class="profilepiccircle"/> + __MSG_createdBy__ + <a href="https://ajay.app">Ajay Ramachandran</a> + <a href="https://sponsor.ajay.app/donate" target="_blank" rel="noopener" id="sbDonate">(__MSG_Donate__)</a> + </p> <h1>__MSG_Options__</h1> @@ -451,6 +456,24 @@ <br/> <br/> + + <div option-type="toggle" toggle-type="reverse" sync-option="showDonationLink" no-safari="true"> + <label class="switch-container"> + <label class="switch"> + <input type="checkbox" checked> + <span class="slider round"></span> + </label> + <div class="switch-label"> + __MSG_hideDonationLink__ + </div> + </label> + + </div> + + <br/> + <br/> + <br/> + <br/> <div option-type="private-text-change" sync-option="userID" confirm-message="userIDChangeWarning"> <div class="option-button trigger-button"> diff --git a/src/config.ts b/src/config.ts index f6153a5e..25b3a11b 100644 --- a/src/config.ts +++ b/src/config.ts @@ -38,6 +38,7 @@ interface SBConfig { refetchWhenNotFound: boolean, ytInfoPermissionGranted: boolean, allowExpirements: boolean, + showDonationLink: boolean, autoHideInfoButton: boolean, autoSkipOnMusicVideos: boolean, @@ -181,6 +182,7 @@ const Config: SBObject = { refetchWhenNotFound: true, ytInfoPermissionGranted: false, allowExpirements: true, + showDonationLink: true, autoHideInfoButton: true, autoSkipOnMusicVideos: false, diff --git a/src/help.ts b/src/help.ts new file mode 100644 index 00000000..97f9c444 --- /dev/null +++ b/src/help.ts @@ -0,0 +1,9 @@ +import { showDonationLink } from "./utils/configUtils"; + +window.addEventListener('DOMContentLoaded', init); + +async function init() { + if (!showDonationLink()) { + document.getElementById("sbDonate").style.display = "none"; + } +}
\ No newline at end of file diff --git a/src/options.ts b/src/options.ts index dad0a52d..8c5c3bca 100644 --- a/src/options.ts +++ b/src/options.ts @@ -6,6 +6,7 @@ window.SB = Config; import Utils from "./utils"; import CategoryChooser from "./render/CategoryChooser"; +import { showDonationLink } from "./utils/configUtils"; const utils = new Utils(); window.addEventListener('DOMContentLoaded', init); @@ -28,6 +29,10 @@ async function init() { await utils.wait(() => Config.config !== null); + if (!showDonationLink()) { + document.getElementById("sbDonate").style.visibility = "hidden"; + } + // Set all of the toggle options to the correct option const optionsContainer = document.getElementById("options"); const optionsElements = optionsContainer.querySelectorAll("*"); diff --git a/src/popup.ts b/src/popup.ts index 092b7db2..0b0664c0 100644 --- a/src/popup.ts +++ b/src/popup.ts @@ -3,6 +3,7 @@ import Config from "./config"; import Utils from "./utils"; import { SponsorTime, SponsorHideType } from "./types"; import { Message, MessageResponse } from "./messageTypes"; +import { showDonationLink } from "./utils/configUtils"; const utils = new Utils(); interface MessageListener { @@ -12,7 +13,7 @@ interface MessageListener { class MessageHandler { messageListener: MessageListener; - constructor (messageListener?: MessageListener) { + constructor(messageListener?: MessageListener) { this.messageListener = messageListener; } @@ -107,14 +108,14 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { "sbDonate" ].forEach(id => PageElements[id] = document.getElementById(id)); - // Hide donate button on safari - if (navigator.vendor === "Apple Computer, Inc.") { + // Hide donate button if wanted (Safari, or user choice) + if (!showDonationLink()) { PageElements.sbDonate.style.display = "none"; } //setup click listeners PageElements.sponsorStart.addEventListener("click", sendSponsorStartMessage); - PageElements.whitelistToggle.addEventListener("change", function() { + PageElements.whitelistToggle.addEventListener("change", function () { if (this.checked) { whitelistChannel(); } else { @@ -122,7 +123,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { } }); PageElements.whitelistForceCheck.addEventListener("click", openOptions); - PageElements.toggleSwitch.addEventListener("change", function() { + PageElements.toggleSwitch.addEventListener("change", function () { toggleSkipping(!this.checked); }); PageElements.submitTimes.addEventListener("click", submitTimes); @@ -174,7 +175,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { if (userID != undefined) { //there are probably some views on these submissions then //get the amount of views from the sponsors submitted - utils.sendRequestToServer("GET", "/api/getViewsForUser?userID=" + userID, function(response) { + utils.sendRequestToServer("GET", "/api/getViewsForUser?userID=" + userID, function (response) { if (response.status == 200) { const viewCount = JSON.parse(response.responseText).viewCount; if (viewCount != 0) { @@ -191,7 +192,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { }); //get this time in minutes - utils.sendRequestToServer("GET", "/api/getSavedTimeForUser?userID=" + userID, function(response) { + utils.sendRequestToServer("GET", "/api/getSavedTimeForUser?userID=" + userID, function (response) { if (response.status == 200) { const minutesSaved = JSON.parse(response.responseText).timeSaved; if (minutesSaved != 0) { @@ -237,7 +238,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { getSegmentsFromContentScript(false); function onTabs(tabs, updating: boolean): void { - messageHandler.sendMessage(tabs[0].id, {message: 'getVideoID'}, function(result) { + messageHandler.sendMessage(tabs[0].id, { message: 'getVideoID' }, function (result) { if (result !== undefined && result.videoID) { currentVideoID = result.videoID; creatingSegment = result.creatingSegment; @@ -262,7 +263,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { messageHandler.sendMessage( tabs[0].id, - {message: 'isInfoFound', updating}, + { message: 'isInfoFound', updating }, infoFound ); } @@ -274,8 +275,8 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { }, (tabs) => onTabs(tabs, updating)); } - function infoFound(request: {found: boolean, sponsorTimes: SponsorTime[]}) { - if(chrome.runtime.lastError) { + function infoFound(request: { found: boolean, sponsorTimes: SponsorTime[] }) { + if (chrome.runtime.lastError) { //This page doesn't have the injected content script, or at least not yet displayNoVideo(); return; @@ -306,8 +307,8 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { }, tabs => { messageHandler.sendMessage( tabs[0].id, - {message: 'isChannelWhitelisted'}, - function(response) { + { message: 'isChannelWhitelisted' }, + function (response) { if (response.value) { PageElements.whitelistChannel.style.display = "none"; PageElements.unwhitelistChannel.style.display = "unset"; @@ -315,7 +316,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { document.querySelectorAll('.SBWhitelistIcon')[0].classList.add("rotated"); } }); - } + } ); } @@ -327,7 +328,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { }, (tabs) => { messageHandler.sendMessage( tabs[0].id, - {from: 'popup', message: 'sponsorStart'}, + { from: 'popup', message: 'sponsorStart' }, async (response) => { startSponsorCallback(response); @@ -351,7 +352,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { }); } - function startSponsorCallback(response: {creatingSegment: boolean}) { + function startSponsorCallback(response: { creatingSegment: boolean }) { creatingSegment = response.creatingSegment; // Only update the segments after a segment was created @@ -364,12 +365,12 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { } //display the video times from the array at the top, in a different section - function displayDownloadedSponsorTimes(request: {found: boolean, sponsorTimes: SponsorTime[]}) { + function displayDownloadedSponsorTimes(request: { found: boolean, sponsorTimes: SponsorTime[] }) { if (request.sponsorTimes != undefined) { // Sort list by start time const segmentTimes = request.sponsorTimes - .sort((a, b) => a.segment[1] - b.segment[1]) - .sort((a, b) => a.segment[0] - b.segment[0]); + .sort((a, b) => a.segment[1] - b.segment[1]) + .sort((a, b) => a.segment[0] - b.segment[0]); //add them as buttons to the issue reporting container const container = document.getElementById("issueReporterTimeButtons"); @@ -388,7 +389,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { categoryColorCircle.style.backgroundColor = Config.config.barTypes[segmentTimes[i].category]?.color; categoryColorCircle.classList.add("dot"); categoryColorCircle.classList.add("sponsorTimesCategoryColorCircle"); - + let extraInfo = ""; if (segmentTimes[i].hidden === SponsorHideType.Downvoted) { //this one is downvoted @@ -397,7 +398,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { //this one is too short extraInfo = " (" + chrome.i18n.getMessage("hiddenDueToDuration") + ")"; } - + const textNode = document.createTextNode(utils.shortCategoryName(segmentTimes[i].category) + extraInfo); const segmentTimeFromToNode = document.createElement("div"); segmentTimeFromToNode.innerText = utils.getFormattedTime(segmentTimes[i].segment[0], true) + " " + chrome.i18n.getMessage("to") + " " + utils.getFormattedTime(segmentTimes[i].segment[1], true); @@ -446,7 +447,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { voteButtonsContainer.appendChild(uuidButton); //add click listener to open up vote panel - sponsorTimeButton.addEventListener("click", function() { + sponsorTimeButton.addEventListener("click", function () { voteButtonsContainer.classList.toggle("voteButtonsContainer--hide"); }); @@ -478,15 +479,15 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { }, tabs => { messageHandler.sendMessage( tabs[0].id, - {message: 'submitTimes'}, + { message: 'submitTimes' }, ); }); } } - + function showNoticeAgain() { Config.config.dontShowNotice = false; - + PageElements.showNoticeAgain.style.display = "none"; } @@ -499,11 +500,11 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { //make the options div visible function openOptions() { - chrome.runtime.sendMessage({"message": "openConfig"}); + chrome.runtime.sendMessage({ "message": "openConfig" }); } function openHelp() { - chrome.runtime.sendMessage({"message": "openHelp"}); + chrome.runtime.sendMessage({ "message": "openHelp" }); } //make the options username setting option visible @@ -516,7 +517,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { PageElements.setUsernameContainer.style.display = "none"; PageElements.setUsername.style.display = "flex"; PageElements.setUsername.classList.add("SBExpanded"); - + PageElements.setUsernameStatusContainer.style.display = "none"; PageElements.sponsorTimesContributionsContainer.classList.add("hidden"); @@ -555,18 +556,18 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { function displayNoVideo() { document.getElementById("loadingIndicator").innerText = chrome.i18n.getMessage("noVideoID"); } - + function addVoteMessage(message, UUID) { const voteButtonsContainer = document.getElementById("sponsorTimesVoteButtonsContainer" + UUID); voteButtonsContainer.style.display = "none"; const voteStatusContainer = document.getElementById("sponsorTimesVoteStatusContainer" + UUID); voteStatusContainer.style.removeProperty("display"); - + const thanksForVotingText = document.getElementById("sponsorTimesThanksForVotingText" + UUID); thanksForVotingText.innerText = message; } - + function vote(type, UUID) { //add loading info addVoteMessage(chrome.i18n.getMessage("Loading"), UUID); @@ -597,8 +598,8 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { }, tabs => { messageHandler.sendMessage( tabs[0].id, - {message: 'getChannelID'}, - function(response) { + { message: 'getChannelID' }, + function (response) { if (!response.channelID) { alert(chrome.i18n.getMessage("channelDataNotFound") + " https://github.com/ajayyy/SponsorBlock/issues/753"); return; @@ -630,10 +631,10 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { }, tabs => { messageHandler.sendMessage( tabs[0].id, { - message: 'whitelistChange', - value: true - }); - } + message: 'whitelistChange', + value: true + }); + } ); } ); @@ -648,38 +649,38 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { }, tabs => { messageHandler.sendMessage( tabs[0].id, - {message: 'getChannelID'}, - function(response) { + { message: 'getChannelID' }, + function (response) { //get whitelisted channels - let whitelistedChannels = Config.config.whitelistedChannels; - if (whitelistedChannels == undefined) { - whitelistedChannels = []; - } + let whitelistedChannels = Config.config.whitelistedChannels; + if (whitelistedChannels == undefined) { + whitelistedChannels = []; + } + + //remove this channel + const index = whitelistedChannels.indexOf(response.channelID); + whitelistedChannels.splice(index, 1); - //remove this channel - const index = whitelistedChannels.indexOf(response.channelID); - whitelistedChannels.splice(index, 1); - - //change button - PageElements.whitelistChannel.style.display = "unset"; - PageElements.unwhitelistChannel.style.display = "none"; - document.querySelectorAll('.SBWhitelistIcon')[0].classList.remove("rotated"); - - //save this - Config.config.whitelistedChannels = whitelistedChannels; - - //send a message to the client - messageHandler.query({ - active: true, - currentWindow: true - }, tabs => { - messageHandler.sendMessage( - tabs[0].id, { - message: 'whitelistChange', - value: false - }); - } - ); + //change button + PageElements.whitelistChannel.style.display = "unset"; + PageElements.unwhitelistChannel.style.display = "none"; + document.querySelectorAll('.SBWhitelistIcon')[0].classList.remove("rotated"); + + //save this + Config.config.whitelistedChannels = whitelistedChannels; + + //send a message to the client + messageHandler.query({ + active: true, + currentWindow: true + }, tabs => { + messageHandler.sendMessage( + tabs[0].id, { + message: 'whitelistChange', + value: false + }); + } + ); } ); }); @@ -694,12 +695,13 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { }, tabs => { messageHandler.sendMessage( tabs[0].id, - {message: 'refreshSegments'}, + { message: 'refreshSegments' }, (response) => { infoFound(response); stopAnimation(); } - )} + ) + } ); } @@ -707,7 +709,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { * Should skipping be disabled (visuals stay) */ function toggleSkipping(disabled) { - Config.config.disableSkipping = disabled; + Config.config.disableSkipping = disabled; let hiddenButton = PageElements.disableSkipping; let shownButton = PageElements.enableSkipping; @@ -728,13 +730,13 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { * @param {float} seconds * @returns {string} */ - function getFormattedHours(minutes) { - minutes = Math.round(minutes * 10) / 10 - const hours = Math.floor(minutes / 60); - return (hours > 0 ? hours + "h " : "") + (minutes % 60).toFixed(1); - } - -//end of function + function getFormattedHours(minutes) { + minutes = Math.round(minutes * 10) / 10 + const hours = Math.floor(minutes / 60); + return (hours > 0 ? hours + "h " : "") + (minutes % 60).toFixed(1); + } + + //end of function } if (chrome.tabs != undefined) { diff --git a/src/utils/configUtils.ts b/src/utils/configUtils.ts new file mode 100644 index 00000000..8aec5208 --- /dev/null +++ b/src/utils/configUtils.ts @@ -0,0 +1,5 @@ +import Config from "../config"; + +export function showDonationLink(): boolean { + return navigator.vendor !== "Apple Computer, Inc." && Config.config.showDonationLink; +}
\ No newline at end of file diff --git a/webpack/webpack.common.js b/webpack/webpack.common.js index 1d130af0..ccc1c82c 100644 --- a/webpack/webpack.common.js +++ b/webpack/webpack.common.js @@ -10,6 +10,7 @@ module.exports = env => ({ background: path.join(__dirname, srcDir + 'background.ts'), content: path.join(__dirname, srcDir + 'content.ts'), options: path.join(__dirname, srcDir + 'options.ts'), + help: path.join(__dirname, srcDir + 'help.ts'), permissions: path.join(__dirname, srcDir + 'permissions.ts') }, output: { |