Files
return-youtube-dislike/Extensions/combined/ryd.background.js
T

443 lines
13 KiB
JavaScript
Raw Normal View History

const apiUrl = "https://returnyoutubedislikeapi.com";
const voteDisabledIconName = "icon_hold128.png";
const defaultIconName = "icon128.png";
let api;
2021-12-15 21:53:43 +05:30
/** stores extension's global config */
let extConfig = {
disableVoteSubmission: false,
disableLogging: true,
coloredThumbs: false,
coloredBar: false,
colorTheme: "classic", // classic, accessible, neon
numberDisplayFormat: "compactShort", // compactShort, compactLong, standard
2022-04-19 00:57:28 -05:00
numberDisplayReformatLikes: false, // use existing (native) likes number
2022-01-11 17:48:24 -05:00
};
2021-12-15 21:53:43 +05:30
if (isChrome()) api = chrome;
else if (isFirefox()) api = browser;
initExtConfig();
api.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.message === "get_auth_token") {
chrome.identity.getAuthToken({ interactive: true }, function (token) {
console.log(token);
chrome.identity.getProfileUserInfo(function (userInfo) {
console.log(JSON.stringify(userInfo));
});
});
} else if (request.message === "log_off") {
// chrome.identity.clearAllCachedAuthTokens(() => console.log("logged off"));
} else if (request.message == "set_state") {
// chrome.identity.getAuthToken({ interactive: true }, function (token) {
let token = "";
fetch(`${apiUrl}/votes?videoId=${request.videoId}&likeCount=${request.likeCount || ""}`, {
method: "GET",
headers: {
Accept: "application/json",
},
})
.then((response) => response.json())
.then((response) => {
sendResponse(response);
})
.catch();
return true;
} else if (request.message == "send_links") {
toSend = toSend.concat(request.videoIds.filter((x) => !sentIds.has(x)));
if (toSend.length >= 20) {
fetch(`${apiUrl}/votes`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(toSend),
});
for (const toSendUrl of toSend) {
sentIds.add(toSendUrl);
}
toSend = [];
}
} else if (request.message == "register") {
register();
return true;
} else if (request.message == "send_vote") {
sendVote(request.videoId, request.vote);
return true;
}
});
2022-04-20 23:06:06 +03:00
api.runtime.onInstalled.addListener((details) => {
if (
// No need to show changelog if its was a browser update (and not extension update)
details.reason === "browser_update" ||
2022-06-16 23:00:22 +03:00
// Chromium (e.g., Google Chrome Cannary) uses this name instead of the one above for some reason
details.reason === "chrome_update" ||
2022-04-20 23:06:06 +03:00
// No need to show changelog if developer just reloaded the extension
2022-04-27 00:56:05 +02:00
details.reason === "update"
2022-07-28 22:56:32 +02:00
) {
2022-04-20 23:06:06 +03:00
return;
2022-07-28 22:56:32 +02:00
} else if (details.reason == "install") {
api.tabs.create({
url: api.runtime.getURL("/changelog/3/changelog_3.0.html"),
});
}
2022-04-27 00:56:05 +02:00
});
2022-03-27 01:25:10 +03:00
2022-04-26 23:05:26 +02:00
// api.storage.sync.get(['lastShowChangelogVersion'], (details) => {
// if (extConfig.showUpdatePopup === true &&
// details.lastShowChangelogVersion !== chrome.runtime.getManifest().version
// ) {
// // keep it inside get to avoid race condition
// api.storage.sync.set({'lastShowChangelogVersion ': chrome.runtime.getManifest().version});
// // wait until async get runs & don't steal tab focus
// api.tabs.create({url: api.runtime.getURL("/changelog/3/changelog_3.0.html"), active: false});
// }
// });
2022-03-27 01:25:10 +03:00
2025-07-13 13:29:34 +02:00
async function sendVote(videoId, vote, depth = 1) {
api.storage.sync.get(null, async (storageResult) => {
if (!storageResult.userId || !storageResult.registrationConfirmed) {
await register();
}
2022-04-27 00:56:05 +02:00
let voteResponse = await fetch(`${apiUrl}/interact/vote`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userId: storageResult.userId,
videoId,
value: vote,
}),
2022-04-27 00:56:05 +02:00
});
2025-07-13 13:29:34 +02:00
if (voteResponse.status == 401 && depth > 0) {
2022-04-27 00:56:05 +02:00
await register();
2025-07-13 13:29:34 +02:00
await sendVote(videoId, vote, depth-1);
return;
} else if (voteResponse.status == 401) { // We have already tried registering
2022-04-27 00:56:05 +02:00
return;
}
2025-07-13 13:29:34 +02:00
2022-04-27 00:56:05 +02:00
const voteResponseJson = await voteResponse.json();
const solvedPuzzle = await solvePuzzle(voteResponseJson);
if (!solvedPuzzle.solution) {
await sendVote(videoId, vote);
return;
}
await fetch(`${apiUrl}/interact/confirmVote`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...solvedPuzzle,
userId: storageResult.userId,
videoId,
}),
});
});
}
2022-04-27 00:56:05 +02:00
async function register() {
const userId = generateUserID();
api.storage.sync.set({ userId });
const registrationResponse = await fetch(`${apiUrl}/puzzle/registration?userId=${userId}`, {
method: "GET",
headers: {
Accept: "application/json",
},
}).then((response) => response.json());
2022-04-27 00:56:05 +02:00
const solvedPuzzle = await solvePuzzle(registrationResponse);
if (!solvedPuzzle.solution) {
await register();
return;
}
const result = await fetch(`${apiUrl}/puzzle/registration?userId=${userId}`, {
method: "POST",
headers: {
2022-04-27 00:56:05 +02:00
"Content-Type": "application/json",
},
2022-04-27 00:56:05 +02:00
body: JSON.stringify(solvedPuzzle),
}).then((response) => response.json());
if (result === true) {
return api.storage.sync.set({ registrationConfirmed: true });
}
}
2022-04-27 00:56:05 +02:00
api.storage.sync.get(null, async (res) => {
if (!res || !res.userId || !res.registrationConfirmed) {
2022-04-27 00:56:05 +02:00
await register();
}
});
const sentIds = new Set();
let toSend = [];
function countLeadingZeroes(uInt8View, limit) {
let zeroes = 0;
let value = 0;
for (let i = 0; i < uInt8View.length; i++) {
value = uInt8View[i];
if (value === 0) {
zeroes += 8;
} else {
let count = 1;
if (value >>> 4 === 0) {
count += 4;
value <<= 4;
}
if (value >>> 6 === 0) {
count += 2;
value <<= 2;
}
zeroes += count - (value >>> 7);
break;
}
if (zeroes >= limit) {
break;
}
}
return zeroes;
}
async function solvePuzzle(puzzle) {
let challenge = Uint8Array.from(atob(puzzle.challenge), (c) => c.charCodeAt(0));
let buffer = new ArrayBuffer(20);
let uInt8View = new Uint8Array(buffer);
let uInt32View = new Uint32Array(buffer);
2022-04-27 00:56:05 +02:00
let maxCount = Math.pow(2, puzzle.difficulty) * 3;
for (let i = 4; i < 20; i++) {
uInt8View[i] = challenge[i - 4];
}
for (let i = 0; i < maxCount; i++) {
uInt32View[0] = i;
let hash = await crypto.subtle.digest("SHA-512", buffer);
let hashUint8 = new Uint8Array(hash);
if (countLeadingZeroes(hashUint8) >= puzzle.difficulty) {
return {
solution: btoa(String.fromCharCode.apply(null, uInt8View.slice(0, 4))),
};
}
}
2022-04-27 00:56:05 +02:00
return {};
}
function generateUserID(length = 36) {
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = "";
if (crypto && crypto.getRandomValues) {
const values = new Uint32Array(length);
crypto.getRandomValues(values);
for (let i = 0; i < length; i++) {
result += charset[values[i] % charset.length];
}
return result;
} else {
for (let i = 0; i < length; i++) {
result += charset[Math.floor(Math.random() * charset.length)];
}
return result;
}
}
2021-12-15 21:53:43 +05:30
function storageChangeHandler(changes, area) {
if (changes.disableVoteSubmission !== undefined) {
handleDisableVoteSubmissionChangeEvent(changes.disableVoteSubmission.newValue);
2021-12-15 21:53:43 +05:30
}
if (changes.coloredThumbs !== undefined) {
handleColoredThumbsChangeEvent(changes.coloredThumbs.newValue);
}
if (changes.coloredBar !== undefined) {
handleColoredBarChangeEvent(changes.coloredBar.newValue);
}
if (changes.colorTheme !== undefined) {
handleColorThemeChangeEvent(changes.colorTheme.newValue);
}
2022-01-11 17:48:24 -05:00
if (changes.numberDisplayFormat !== undefined) {
handleNumberDisplayFormatChangeEvent(changes.numberDisplayFormat.newValue);
}
2022-04-19 00:57:28 -05:00
if (changes.numberDisplayReformatLikes !== undefined) {
handleNumberDisplayReformatLikesChangeEvent(changes.numberDisplayReformatLikes.newValue);
2022-04-19 00:57:28 -05:00
}
if (changes.disableLogging !== undefined) {
handleDisableLoggingChangeEvent(changes.disableLogging.newValue);
}
if (changes.showTooltipPercentage !== undefined) {
handleShowTooltipPercentageChangeEvent(changes.showTooltipPercentage.newValue);
}
if (changes.numberDisplayReformatLikes !== undefined) {
handleNumberDisplayReformatLikesChangeEvent(changes.numberDisplayReformatLikes.newValue);
}
2021-12-15 21:53:43 +05:30
}
function handleDisableVoteSubmissionChangeEvent(value) {
extConfig.disableVoteSubmission = value;
if (value === true) {
changeIcon(voteDisabledIconName);
} else {
changeIcon(defaultIconName);
}
}
function handleDisableLoggingChangeEvent(value) {
extConfig.disableLogging = value;
}
2022-01-11 17:48:24 -05:00
function handleNumberDisplayFormatChangeEvent(value) {
extConfig.numberDisplayFormat = value;
}
function handleShowTooltipPercentageChangeEvent(value) {
extConfig.showTooltipPercentage = value;
}
function handleTooltipPercentageModeChangeEvent(value) {
if (!value) {
value = "dash_like";
}
extConfig.tooltipPercentageMode = value;
}
2021-12-15 21:53:43 +05:30
function changeIcon(iconName) {
if (api.action !== undefined) api.action.setIcon({ path: "/icons/" + iconName });
else if (api.browserAction !== undefined) api.browserAction.setIcon({ path: "/icons/" + iconName });
else console.log("changing icon is not supported");
2021-12-15 21:53:43 +05:30
}
function handleColoredThumbsChangeEvent(value) {
extConfig.coloredThumbs = value;
}
function handleColoredBarChangeEvent(value) {
extConfig.coloredBar = value;
}
function handleColorThemeChangeEvent(value) {
2022-03-21 01:26:42 +03:00
if (!value) {
value = "classic";
}
extConfig.colorTheme = value;
}
2022-04-19 00:57:28 -05:00
function handleNumberDisplayReformatLikesChangeEvent(value) {
extConfig.numberDisplayReformatLikes = value;
}
2021-12-15 21:53:43 +05:30
api.storage.onChanged.addListener(storageChangeHandler);
function initExtConfig() {
initializeDisableVoteSubmission();
initializeDisableLogging();
initializeColoredThumbs();
initializeColoredBar();
initializeColorTheme();
2022-01-11 17:48:24 -05:00
initializeNumberDisplayFormat();
2022-04-19 00:57:28 -05:00
initializeNumberDisplayReformatLikes();
initializeTooltipPercentage();
initializeTooltipPercentageMode();
2021-12-15 21:53:43 +05:30
}
function initializeDisableVoteSubmission() {
api.storage.sync.get(["disableVoteSubmission"], (res) => {
2021-12-15 21:53:43 +05:30
if (res.disableVoteSubmission === undefined) {
api.storage.sync.set({ disableVoteSubmission: false });
} else {
2021-12-15 21:53:43 +05:30
extConfig.disableVoteSubmission = res.disableVoteSubmission;
if (res.disableVoteSubmission) changeIcon(voteDisabledIconName);
}
});
}
function initializeDisableLogging() {
api.storage.sync.get(["disableLogging"], (res) => {
if (res.disableLogging === undefined) {
api.storage.sync.set({ disableLogging: true });
} else {
extConfig.disableLogging = res.disableLogging;
}
});
}
function initializeColoredThumbs() {
api.storage.sync.get(["coloredThumbs"], (res) => {
if (res.coloredThumbs === undefined) {
api.storage.sync.set({ coloredThumbs: false });
} else {
extConfig.coloredThumbs = res.coloredThumbs;
}
});
}
function initializeColoredBar() {
api.storage.sync.get(["coloredBar"], (res) => {
if (res.coloredBar === undefined) {
api.storage.sync.set({ coloredBar: false });
} else {
extConfig.coloredBar = res.coloredBar;
}
});
}
function initializeColorTheme() {
api.storage.sync.get(["colorTheme"], (res) => {
if (res.colorTheme === undefined) {
api.storage.sync.set({ colorTheme: false });
} else {
extConfig.colorTheme = res.colorTheme;
}
});
}
2022-03-27 01:25:10 +03:00
2022-01-11 17:48:24 -05:00
function initializeNumberDisplayFormat() {
api.storage.sync.get(["numberDisplayFormat"], (res) => {
2022-01-11 17:48:24 -05:00
if (res.numberDisplayFormat === undefined) {
api.storage.sync.set({ numberDisplayFormat: "compactShort" });
2022-01-11 17:48:24 -05:00
} else {
extConfig.numberDisplayFormat = res.numberDisplayFormat;
}
});
}
function initializeTooltipPercentage() {
api.storage.sync.get(["showTooltipPercentage"], (res) => {
if (res.showTooltipPercentage === undefined) {
api.storage.sync.set({ showTooltipPercentage: false });
} else {
extConfig.showTooltipPercentage = res.showTooltipPercentage;
}
});
}
function initializeTooltipPercentageMode() {
api.storage.sync.get(["tooltipPercentageMode"], (res) => {
if (res.tooltipPercentageMode === undefined) {
api.storage.sync.set({ tooltipPercentageMode: "dash_like" });
} else {
extConfig.tooltipPercentageMode = res.tooltipPercentageMode;
}
});
}
2022-04-19 00:57:28 -05:00
function initializeNumberDisplayReformatLikes() {
api.storage.sync.get(["numberDisplayReformatLikes"], (res) => {
if (res.numberDisplayReformatLikes === undefined) {
api.storage.sync.set({ numberDisplayReformatLikes: false });
} else {
extConfig.numberDisplayReformatLikes = res.numberDisplayReformatLikes;
}
});
}
2021-12-15 21:53:43 +05:30
function isChrome() {
return typeof chrome !== "undefined" && typeof chrome.runtime !== "undefined";
}
function isFirefox() {
return typeof browser !== "undefined" && typeof browser.runtime !== "undefined";
2022-01-08 23:22:29 +03:00
}