From 1a855a6993c1b6ccbacedeccfc56993dfb6ad124 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 29 Jul 2021 18:16:44 -0400 Subject: [PATCH 1/4] Add basic chat box when getting a warning --- public/_locales/en/messages.json | 3 +++ public/content.css | 10 ++++++++++ src/background.ts | 6 +----- src/content.ts | 8 ++++++-- src/js-components/chat.ts | 30 ++++++++++++++++++++++++++++++ src/utils.ts | 13 +++++++++++++ 6 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 src/js-components/chat.ts diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 8a5a2b30..4a462055 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -675,5 +675,8 @@ }, "hideForever": { "message": "Hide forever" + }, + "warningChatInfo": { + "message": "You got a warning and cannot submit segments temporarily. This means that we noticed you were making some common mistakes that are not malicious, and we just want to clarify the rules. You can also join this chat using discord.gg/SponsorBlock or matrix.to/#/+sponsor:ajay.app" } } diff --git a/public/content.css b/public/content.css index 70b74766..2238a2bd 100644 --- a/public/content.css +++ b/public/content.css @@ -121,6 +121,16 @@ margin-left: 5px; } +.chatNotice { + min-width: 350px; + height: 70%; + + position: absolute; + right: 5px; + bottom: 100px; + right: 10px; +} + .sponsorSkipNotice { min-width: 350px; background-color: rgba(28, 28, 28, 0.9); diff --git a/src/background.ts b/src/background.ts index e44dd28a..53f9d415 100644 --- a/src/background.ts +++ b/src/background.ts @@ -164,11 +164,7 @@ async function asyncRequestToServer(type: string, address: string, data = {}) { async function sendRequestToCustomServer(type: string, url: string, data = {}) { // If GET, convert JSON to parameters if (type.toLowerCase() === "get") { - for (const key in data) { - const seperator = url.includes("?") ? "&" : "?"; - const value = (typeof(data[key]) === "string") ? data[key]: JSON.stringify(data[key]); - url += seperator + key + "=" + value; - } + url = utils.objectToURI(url, data, true); data = null; } diff --git a/src/content.ts b/src/content.ts index e0f0572e..dc7a3427 100644 --- a/src/content.ts +++ b/src/content.ts @@ -13,7 +13,7 @@ import SkipNotice from "./render/SkipNotice"; import SkipNoticeComponent from "./components/SkipNoticeComponent"; import SubmissionNotice from "./render/SubmissionNotice"; import { Message, MessageResponse } from "./messageTypes"; -import GenericNotice from "./render/GenericNotice"; +import * as Chat from "./js-components/chat"; // Hack to get the CSS loaded on permission-based sites (Invidious) utils.wait(() => Config.config !== null, 5000, 10).then(addCSS); @@ -1567,7 +1567,11 @@ async function sendSubmitMessage() { playerButtons.submit.button.style.animation = "unset"; playerButtons.submit.image.src = chrome.extension.getURL("icons/PlayerUploadFailedIconSponsorBlocker.svg"); - alert(utils.getErrorMessage(response.status, response.responseText)); + if (response.status === 403 && response.responseText.startsWith("Submission rejected due to a warning from a moderator.")) { + Chat.openWarningChat(response.responseText); + } else { + alert(utils.getErrorMessage(response.status, response.responseText)); + } } } diff --git a/src/js-components/chat.ts b/src/js-components/chat.ts new file mode 100644 index 00000000..41725775 --- /dev/null +++ b/src/js-components/chat.ts @@ -0,0 +1,30 @@ +import Config from "../config"; +import Utils from "../utils"; +const utils = new Utils(); + +export interface ChatConfig { + displayName: string, + composerInitialValue?: string, + customDescription?: string +} + +export function openChat(config: ChatConfig): void { + const chat = document.createElement("iframe"); + chat.src = "https://chat.sponsor.ajay.app/#" + utils.objectToURI("", config, false); + chat.classList.add("chatNotice"); + chat.style.zIndex = "2000"; + + console.log(utils.objectToURI("", config, false)) + + const referenceNode = utils.findReferenceNode(); + referenceNode.prepend(chat); +} + +export async function openWarningChat(warningMessage: string): Promise { + openChat({ + displayName: await utils.getHash(Config.config.userID), + composerInitialValue: `I got a warning and want to know what I need to do to improve. ` + + `Warning reason: ${warningMessage.match(/Warning reason: '(.+)'/)[1]}`, + customDescription: chrome.i18n.getMessage("warningChatInfo") + }); +} \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index e93782cd..ed83857b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -415,6 +415,19 @@ export default class Utils { return referenceNode; } + objectToURI(url: string, data: T, includeQuestionMark: boolean): string { + let counter = 0; + for (const key in data) { + const seperator = (url.includes("?") || counter > 0) ? "&" : (includeQuestionMark ? "?" : ""); + const value = (typeof(data[key]) === "string") ? data[key] as unknown as string : JSON.stringify(data[key]); + url += seperator + encodeURIComponent(key) + "=" + encodeURIComponent(value); + + counter++; + } + + return url; + } + getFormattedTime(seconds: number, precise?: boolean): string { const hours = Math.floor(seconds / 60 / 60); const minutes = Math.floor(seconds / 60) % 60; From d0949452dac82214f493eca9045ad82b70a064b3 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 29 Jul 2021 18:34:31 -0400 Subject: [PATCH 2/4] Add close button --- public/content.css | 13 ++++++++++++- src/js-components/chat.ts | 18 +++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/public/content.css b/public/content.css index 2238a2bd..c4c528ae 100644 --- a/public/content.css +++ b/public/content.css @@ -121,7 +121,7 @@ margin-left: 5px; } -.chatNotice { +.sbChatNotice { min-width: 350px; height: 70%; @@ -455,4 +455,15 @@ input::-webkit-inner-spin-button { } .helpButton:hover { filter: brightness(80%); +} + +.sbChatNotice iframe { + height: 32px; + cursor: pointer; + height: 100%; +} + +.sbChatClose { + height: 14px; + cursor: pointer; } \ No newline at end of file diff --git a/src/js-components/chat.ts b/src/js-components/chat.ts index 41725775..ee3e800d 100644 --- a/src/js-components/chat.ts +++ b/src/js-components/chat.ts @@ -9,11 +9,23 @@ export interface ChatConfig { } export function openChat(config: ChatConfig): void { - const chat = document.createElement("iframe"); - chat.src = "https://chat.sponsor.ajay.app/#" + utils.objectToURI("", config, false); - chat.classList.add("chatNotice"); + const chat = document.createElement("div"); + chat.classList.add("sbChatNotice"); chat.style.zIndex = "2000"; + const iframe= document.createElement("iframe"); + iframe.src = "https://chat.sponsor.ajay.app/#" + utils.objectToURI("", config, false); + chat.appendChild(iframe); + + const closeButton = document.createElement("img"); + closeButton.classList.add("sbChatClose"); + closeButton.src = chrome.extension.getURL("icons/close.png"); + closeButton.addEventListener("click", () => { + chat.remove(); + closeButton.remove(); + }); + chat.appendChild(closeButton); + console.log(utils.objectToURI("", config, false)) const referenceNode = utils.findReferenceNode(); From c84a951accfe8bf5bbf632f4cef8a168037359d0 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 29 Jul 2021 19:16:18 -0400 Subject: [PATCH 3/4] Add chat for warnings after voting --- public/_locales/en/messages.json | 3 +++ public/content.css | 1 + src/components/SkipNoticeComponent.tsx | 14 +++++++++----- src/content.ts | 10 +++++++++- src/js-components/chat.ts | 2 -- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 4a462055..3105f7ed 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -678,5 +678,8 @@ }, "warningChatInfo": { "message": "You got a warning and cannot submit segments temporarily. This means that we noticed you were making some common mistakes that are not malicious, and we just want to clarify the rules. You can also join this chat using discord.gg/SponsorBlock or matrix.to/#/+sponsor:ajay.app" + }, + "voteRejectedWarning": { + "message": "Vote rejected due to a warning. Click to open a chat to resolve it, or come back later when you have time." } } diff --git a/public/content.css b/public/content.css index c4c528ae..ba0d7016 100644 --- a/public/content.css +++ b/public/content.css @@ -133,6 +133,7 @@ .sponsorSkipNotice { min-width: 350px; + max-width: 50%; background-color: rgba(28, 28, 28, 0.9); position: absolute; right: 5px; diff --git a/src/components/SkipNoticeComponent.tsx b/src/components/SkipNoticeComponent.tsx index 1582c2c9..f8269e88 100644 --- a/src/components/SkipNoticeComponent.tsx +++ b/src/components/SkipNoticeComponent.tsx @@ -313,11 +313,15 @@ class SkipNoticeComponent extends React.Component - + + + + + + ) } diff --git a/src/content.ts b/src/content.ts index dc7a3427..6320249a 100644 --- a/src/content.ts +++ b/src/content.ts @@ -1458,7 +1458,15 @@ function vote(type: number, UUID: string, category?: string, skipNotice?: SkipNo //success (treat rate limits as a success) skipNotice.afterVote.bind(skipNotice)(utils.getSponsorTimeFromUUID(sponsorTimes, UUID), type, category); } else if (response.successType == -1) { - skipNotice.setNoticeInfoMessage.bind(skipNotice)(utils.getErrorMessage(response.statusCode, response.responseText)) + if (response.statusCode === 403 && response.responseText.startsWith("Vote rejected due to a warning from a moderator.")) { + skipNotice.setNoticeInfoMessageWithOnClick.bind(skipNotice)(() => { + Chat.openWarningChat(response.responseText); + skipNotice.closeListener.call(skipNotice); + }, chrome.i18n.getMessage("voteRejectedWarning")); + } else { + skipNotice.setNoticeInfoMessage.bind(skipNotice)(utils.getErrorMessage(response.statusCode, response.responseText)) + } + skipNotice.resetVoteButtonInfo.bind(skipNotice)(); } } diff --git a/src/js-components/chat.ts b/src/js-components/chat.ts index ee3e800d..513d8fe4 100644 --- a/src/js-components/chat.ts +++ b/src/js-components/chat.ts @@ -26,8 +26,6 @@ export function openChat(config: ChatConfig): void { }); chat.appendChild(closeButton); - console.log(utils.objectToURI("", config, false)) - const referenceNode = utils.findReferenceNode(); referenceNode.prepend(chat); } From 839dd4613c44f16455121f8a1b7d8f24dd35a6ff Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 29 Jul 2021 19:29:34 -0400 Subject: [PATCH 4/4] Get username for warning chat --- src/js-components/chat.ts | 6 +++++- src/utils.ts | 11 +++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/js-components/chat.ts b/src/js-components/chat.ts index 513d8fe4..4bbb4a2b 100644 --- a/src/js-components/chat.ts +++ b/src/js-components/chat.ts @@ -31,8 +31,12 @@ export function openChat(config: ChatConfig): void { } export async function openWarningChat(warningMessage: string): Promise { + const userNameData = await utils.asyncRequestToServer("GET", "/api/getUsername?userID=" + Config.config.userID); + const userName = userNameData.ok ? JSON.parse(userNameData.responseText).userName : ""; + const publicUserID = await utils.getHash(Config.config.userID); + openChat({ - displayName: await utils.getHash(Config.config.userID), + displayName: `${userName ? `${userName} | `: ``}${userName !== publicUserID ? publicUserID : ``}`, composerInitialValue: `I got a warning and want to know what I need to do to improve. ` + `Warning reason: ${warningMessage.match(/Warning reason: '(.+)'/)[1]}`, customDescription: chrome.i18n.getMessage("warningChatInfo") diff --git a/src/utils.ts b/src/utils.ts index ed83857b..0ea27238 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -492,14 +492,13 @@ export default class Utils { async getHash(value: string, times = 5000): Promise { if (times <= 0) return ""; - let hashBuffer = new TextEncoder().encode(value).buffer; - + let hashHex = value; for (let i = 0; i < times; i++) { - hashBuffer = await crypto.subtle.digest('SHA-256', hashBuffer); - } + const hashBuffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(hashHex).buffer); - const hashArray = Array.from(new Uint8Array(hashBuffer)); - const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); + const hashArray = Array.from(new Uint8Array(hashBuffer)); + hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); + } return hashHex; }