Files
return-youtube-dislike/Extensions/combined/popup.js
T
Dmitrii Selivanov 40fda6dd32 Advanced stats for patreon supporters (#1222)
* auth works

* Works after review.

* switched to auth flow

* all works well in chrome

* all works well in chrome and firefox

* translations harmonized

* translations harmonized

* website translations

* Translations harmonized.

* Everything kinda works

* Almost works

* all works

* all works

* all works #2

* Streamline premium analytics range handling

* Restore premium analytics selection flow

* Fix analytics zoom interactions

* Add per-section expansion controls to premium analytics

* Adjust map legend visibility for premium analytics

* Add missing country synonyms for premium map

* Remove legacy premium badge overlay

* Polish premium analytics controls for light theme

* Refresh map legend when toggling sections

* Improve light-mode styling for range selectors

* Fix map mode switching regression

* Fix for panel expand

* Typo fix

* webpack fix

* before next steps.

* split, zero-buckets

* bucket size indicated on UI

* all works

* first/last toggle

* breadcrumbs

* release
2025-10-20 18:43:06 +02:00

674 lines
24 KiB
JavaScript

import { config as appConfig, getApiUrl, getApiEndpoint } from "./src/config.js";
/* Config */
const config = {
advanced: false,
disableVoteSubmission: false,
disableLogging: true,
coloredThumbs: false,
coloredBar: false,
colorTheme: "classic",
numberDisplayFormat: "compactShort",
showTooltipPercentage: false,
tooltipPercentageMode: "dash_like",
numberDisplayReformatLikes: false,
hidePremiumTeaser: false,
showAdvancedMessage:
'<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor"><rect fill="none" height="24" width="24"/><path d="M19.5,12c0-0.23-0.01-0.45-0.03-0.68l1.86-1.41c0.4-0.3,0.51-0.86,0.26-1.3l-1.87-3.23c-0.25-0.44-0.79-0.62-1.25-0.42 l-2.15,0.91c-0.37-0.26-0.76-0.49-1.17-0.68l-0.29-2.31C14.8,2.38,14.37,2,13.87,2h-3.73C9.63,2,9.2,2.38,9.14,2.88L8.85,5.19 c-0.41,0.19-0.8,0.42-1.17,0.68L5.53,4.96c-0.46-0.2-1-0.02-1.25,0.42L2.41,8.62c-0.25,0.44-0.14,0.99,0.26,1.3l1.86,1.41 C4.51,11.55,4.5,11.77,4.5,12s0.01,0.45,0.03,0.68l-1.86,1.41c-0.4,0.3-0.51,0.86-0.26,1.3l1.87,3.23c0.25,0.44,0.79,0.62,1.25,0.42 l2.15-0.91c0.37,0.26,0.76,0.49,1.17,0.68l0.29,2.31C9.2,21.62,9.63,22,10.13,22h3.73c0.5,0,0.93-0.38,0.99-0.88l0.29-2.31 c0.41-0.19,0.8-0.42,1.17-0.68l2.15,0.91c0.46,0.2,1,0.02,1.25-0.42l1.87-3.23c0.25-0.44,0.14-0.99-0.26-1.3l-1.86-1.41 C19.49,12.45,19.5,12.23,19.5,12z M12.04,15.5c-1.93,0-3.5-1.57-3.5-3.5s1.57-3.5,3.5-3.5s3.5,1.57,3.5,3.5S13.97,15.5,12.04,15.5z"/></svg>',
hideAdvancedMessage:
'<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor"><path d="M0 0h24v24H0V0z" fill="none" opacity=".87"/><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm4.3 14.3c-.39.39-1.02.39-1.41 0L12 13.41 9.11 16.3c-.39.39-1.02.39-1.41 0-.39-.39-.39-1.02 0-1.41L10.59 12 7.7 9.11c-.39-.39-.39-1.02 0-1.41.39-.39 1.02-.39 1.41 0L12 10.59l2.89-2.89c.39-.39 1.02-.39 1.41 0 .39.39.39 1.02 0 1.41L13.41 12l2.89 2.89c.38.38.38 1.02 0 1.41z"/></svg>',
links: appConfig.links,
};
/* Change language */
function localizeHtmlPage() {
//Localize by replacing __MSG_***__ meta tags
var objects = document.getElementsByTagName("html");
for (var j = 0; j < objects.length; j++) {
var obj = objects[j];
var valStrH = obj.innerHTML.toString();
var valNewH = valStrH.replace(/__MSG_(\w+)__/g, function (match, v1) {
return v1 ? chrome.i18n.getMessage(v1) : "";
});
if (valNewH != valStrH) {
obj.innerHTML = valNewH;
}
}
}
localizeHtmlPage();
/* Links */
createLink(config.links.website, "link_website");
createLink(config.links.github, "link_github");
createLink(config.links.discord, "link_discord");
createLink(config.links.faq, "link_faq");
createLink(config.links.donate, "link_donate");
createLink(config.links.help, "link_help");
createLink(config.links.changelog, "link_changelog");
function createLink(url, id) {
document.getElementById(id).addEventListener("click", () => {
chrome.tabs.create({ url: url });
});
}
document.getElementById("disable_vote_submission").addEventListener("click", (ev) => {
chrome.storage.sync.set({ disableVoteSubmission: ev.target.checked });
});
document.getElementById("disable_logging").addEventListener("click", (ev) => {
chrome.storage.sync.set({ disableLogging: ev.target.checked });
});
document.getElementById("colored_thumbs").addEventListener("click", (ev) => {
chrome.storage.sync.set({ coloredThumbs: ev.target.checked });
});
document.getElementById("colored_bar").addEventListener("click", (ev) => {
chrome.storage.sync.set({ coloredBar: ev.target.checked });
});
document.getElementById("color_theme").addEventListener("click", (ev) => {
chrome.storage.sync.set({ colorTheme: ev.target.value });
});
document.getElementById("number_format").addEventListener("change", (ev) => {
chrome.storage.sync.set({ numberDisplayFormat: ev.target.value });
});
document.getElementById("show_tooltip_percentage").addEventListener("click", (ev) => {
chrome.storage.sync.set({ showTooltipPercentage: ev.target.checked });
});
document.getElementById("tooltip_percentage_mode").addEventListener("change", (ev) => {
chrome.storage.sync.set({ tooltipPercentageMode: ev.target.value });
});
document.getElementById("number_reformat_likes").addEventListener("click", (ev) => {
chrome.storage.sync.set({ numberDisplayReformatLikes: ev.target.checked });
});
document.getElementById("hide_premium_teaser").addEventListener("click", (ev) => {
chrome.storage.sync.set({ hidePremiumTeaser: ev.target.checked });
});
function initPatreonAuth() {
const loggedOutView = document.getElementById("patreon-logged-out");
const loggedInView = document.getElementById("patreon-logged-in");
const loginBtn = document.getElementById("patreon-login-btn");
const logoutBtn = document.getElementById("patreon-logout-btn");
const userAvatar = document.getElementById("patreon-user-avatar");
const userName = document.getElementById("patreon-user-name");
const userTier = document.getElementById("patreon-tier");
chrome.storage.sync.get(["patreonUser", "patreonSessionToken"], (data) => {
const cachedUser = data.patreonUser;
const sessionToken = data.patreonSessionToken;
if (sessionToken && cachedUser) {
// Show cached state immediately to avoid flicker on popup reopen.
showLoggedInView(cachedUser);
verifySession(sessionToken).then((result) => {
if (result.status === "valid") {
if (result.membershipTier && result.membershipTier !== cachedUser.membershipTier) {
const updatedUser = { ...cachedUser, membershipTier: result.membershipTier, hasActiveMembership: true };
showLoggedInView(updatedUser);
chrome.storage.sync.set({ patreonUser: updatedUser });
} else if (cachedUser.hasActiveMembership !== true) {
const updatedUser = { ...cachedUser, hasActiveMembership: true };
showLoggedInView(updatedUser);
chrome.storage.sync.set({ patreonUser: updatedUser });
}
} else if (result.status === "inactive") {
const updatedUser = {
...cachedUser,
hasActiveMembership: false,
membershipTier: result.membershipTier || cachedUser.membershipTier || "none",
};
showLoggedInView(updatedUser);
chrome.storage.sync.set({ patreonUser: updatedUser });
} else if (result.status === "error") {
console.warn("Patreon session verification skipped:", result.reason || "network_error");
} else {
showLoggedOutView();
chrome.storage.sync.remove(["patreonUser", "patreonSessionToken"]);
}
});
} else {
showLoggedOutView();
}
});
function showLoggedOutView() {
loggedOutView.style.display = "block";
loggedInView.style.display = "none";
}
function showLoggedInView(user) {
loggedOutView.style.display = "none";
loggedInView.style.display = "block";
userName.textContent = user.fullName || user.email || chrome.i18n.getMessage("patreonUserFallback");
if (user.imageUrl) {
userAvatar.src = user.imageUrl;
userAvatar.style.display = "block";
} else {
userAvatar.src = "";
userAvatar.style.display = "none";
}
const tierLabels = {
premium: chrome.i18n.getMessage("patreonTierPremium"),
supporter: chrome.i18n.getMessage("patreonTierSupporter"),
basic: chrome.i18n.getMessage("patreonTierBasic"),
none: chrome.i18n.getMessage("patreonTierNone"),
};
userTier.textContent = tierLabels[user.membershipTier] || chrome.i18n.getMessage("patreonTierChecking");
if (user.hasActiveMembership) {
userTier.style.color = "#f96854";
} else {
userTier.style.color = "var(--lightGrey)";
}
}
async function verifySession(token) {
try {
const response = await fetch(getApiEndpoint("/api/auth/verify"), {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ sessionToken: token }),
});
const data = await response.json().catch(() => null);
if (!data) {
return { status: "error", reason: "invalid_response" };
}
const failureReason = typeof data.failureReason === "string" ? data.failureReason : null;
const membershipTier = typeof data.membershipTier === "string" ? data.membershipTier : null;
if (data.valid === true) {
return { status: "valid", membershipTier };
}
if (failureReason === "membershipinactive") {
return { status: "inactive", membershipTier };
}
if (failureReason === "expired" || failureReason === "legacyformat") {
return { status: "expired", membershipTier };
}
if (failureReason === "invalid") {
return { status: "invalid", membershipTier, failureReason };
}
if (!failureReason) {
return { status: "error", reason: "unknown_failure" };
}
return { status: "error", reason: failureReason };
} catch (error) {
console.error("Session verification failed:", error);
return { status: "error", reason: "network_error" };
}
}
// Wrapper for cross-browser identity API
function getIdentityApi() {
if (typeof browser !== "undefined" && browser.identity) return browser.identity; // prefer Firefox promise API
if (typeof chrome !== "undefined" && chrome.identity) return chrome.identity;
return null;
}
function launchWebAuthFlow(url) {
try {
if (
typeof browser !== "undefined" &&
browser.identity &&
typeof browser.identity.launchWebAuthFlow === "function"
) {
// Promise-based API (Firefox)
return browser.identity.launchWebAuthFlow({ url, interactive: true });
}
} catch (_) {}
const chromeId = (typeof chrome !== "undefined" && chrome.identity) || null;
if (!chromeId || typeof chromeId.launchWebAuthFlow !== "function") {
return Promise.reject(new Error("identity API not available"));
}
// Callback-based API (Chrome)
return new Promise((resolve, reject) => {
chromeId.launchWebAuthFlow({ url, interactive: true }, (responseUrl) => {
const err = chrome.runtime && chrome.runtime.lastError;
if (err) reject(err);
else resolve(responseUrl);
});
});
}
function extractOAuthParams(responseUrl) {
try {
const u = new URL(responseUrl);
let code = u.searchParams.get("code");
let state = u.searchParams.get("state");
if (!code && u.hash) {
const hashParams = new URLSearchParams(u.hash.startsWith("#") ? u.hash.substring(1) : u.hash);
code = hashParams.get("code");
state = state || hashParams.get("state");
}
return { code, state };
} catch (_) {
return { code: null, state: null };
}
}
// Request identity permission immediately within the user click (no awaits prior)
function ensureIdentityPermission(onResult) {
try {
const mf = chrome && chrome.runtime && chrome.runtime.getManifest ? chrome.runtime.getManifest() : null;
// If manifest cannot request identity dynamically (e.g., Firefox), proceed if API is available
if (mf && (!Array.isArray(mf.optional_permissions) || !mf.optional_permissions.includes("identity"))) {
const id = getIdentityApi();
onResult(Boolean(id && typeof id.getRedirectURL === "function"));
return;
}
const perms =
(typeof chrome !== "undefined" && chrome.permissions) ||
(typeof browser !== "undefined" && browser.permissions);
if (!perms || !perms.contains) return onResult(false);
const afterContains = (has) => {
if (typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.lastError) has = false;
if (has) return onResult(true);
if (!perms.request) return onResult(false);
const reqResult = perms.request({ permissions: ["identity"] }, (granted) => {
if (typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.lastError) return onResult(false);
onResult(Boolean(granted));
});
// Firefox may return a promise
if (reqResult && typeof reqResult.then === "function") {
reqResult.then((granted) => onResult(Boolean(granted))).catch(() => onResult(false));
}
};
const result = perms.contains({ permissions: ["identity"] }, afterContains);
if (result && typeof result.then === "function") {
result.then(afterContains).catch(() => onResult(false));
}
} catch (_) {
onResult(false);
}
}
loginBtn.addEventListener("click", () => {
// Request permission immediately within this user gesture
ensureIdentityPermission(async (granted) => {
const identityNow = getIdentityApi();
if (!granted || !identityNow || typeof identityNow.getRedirectURL !== "function") {
alert(chrome.i18n.getMessage("patreonPermissionRequired"));
return;
}
// Delegate OAuth to background so it persists if the popup closes
chrome.runtime.sendMessage({ message: "patreon_oauth_login" }, (resp) => {
if (chrome.runtime && chrome.runtime.lastError) {
console.error("Login failed:", chrome.runtime.lastError.message);
alert(chrome.i18n.getMessage("patreonLoginStartFailed"));
return;
}
if (resp && resp.success) {
const user = resp.user;
showLoggedInView(user);
} else {
console.error("Login failed:", resp && resp.error);
alert(chrome.i18n.getMessage("patreonLoginCompleteFailed"));
}
});
});
});
logoutBtn.addEventListener("click", () => {
chrome.storage.sync.remove(["patreonUser", "patreonSessionToken"], () => {
showLoggedOutView();
chrome.runtime.sendMessage({ message: "patreon_logout" });
});
});
}
initPatreonAuth();
/* Advanced Toggle */
const advancedToggle = document.getElementById("advancedToggle");
advancedToggle.addEventListener("click", () => {
const adv = document.getElementById("advancedSettings");
if (config.advanced) {
adv.style.transform = "scale(1.1)";
adv.style.pointerEvents = "none";
adv.style.opacity = "0";
advancedToggle.innerHTML = config.showAdvancedMessage;
} else {
adv.style.transform = "scale(1)";
adv.style.pointerEvents = "auto";
adv.style.opacity = "1";
advancedToggle.innerHTML = config.hideAdvancedMessage;
}
config.advanced = !config.advanced;
});
initConfig();
function initConfig() {
initializeDisableVoteSubmission();
initializeDisableLogging();
initializeVersionNumber();
initializeColoredThumbs();
initializeColoredBar();
initializeColorTheme();
initializeNumberDisplayFormat();
initializeTooltipPercentage();
initializeTooltipPercentageMode();
initializeNumberDisplayReformatLikes();
initializeHidePremiumTeaser();
}
function initializeVersionNumber() {
const version = chrome.runtime.getManifest().version;
document.getElementById("ext-version").innerHTML = "v" + version;
fetch(
"https://raw.githubusercontent.com/Anarios/return-youtube-dislike/main/Extensions/combined/manifest-chrome.json",
)
.then((response) => response.json())
.then((json) => {
if (compareVersions(json.version, version)) {
document.getElementById("ext-update").innerHTML = chrome.i18n.getMessage("textUpdate") + " v" + json.version;
document.getElementById("ext-update").style.padding = ".25rem .5rem";
}
});
// .catch(console.error);
}
// returns whether current < latest
function compareVersions(latestStr, currentStr) {
let latestarr = latestStr.split(".");
let currentarr = currentStr.split(".");
let outdated = false;
// goes through version numbers from left to right from greatest to least significant
for (let i = 0; i < Math.max(latestarr.length, currentarr.length); i++) {
let latest = i < latestarr.length ? parseInt(latestarr[i]) : 0;
let current = i < currentarr.length ? parseInt(currentarr[i]) : 0;
if (latest > current) {
outdated = true;
break;
} else if (latest < current) {
outdated = false;
break;
}
}
return outdated;
}
function initializeDisableVoteSubmission() {
chrome.storage.sync.get(["disableVoteSubmission"], (res) => {
handleDisableVoteSubmissionChangeEvent(res.disableVoteSubmission);
});
}
function initializeDisableLogging() {
chrome.storage.sync.get(["disableLogging"], (res) => {
handleDisableLoggingChangeEvent(res.disableLogging);
});
}
function initializeColoredThumbs() {
chrome.storage.sync.get(["coloredThumbs"], (res) => {
handleColoredThumbsChangeEvent(res.coloredThumbs);
});
}
function initializeColoredBar() {
chrome.storage.sync.get(["coloredBar"], (res) => {
handleColoredBarChangeEvent(res.coloredBar);
});
}
function initializeColorTheme() {
chrome.storage.sync.get(["colorTheme"], (res) => {
handleColorThemeChangeEvent(res.colorTheme);
});
}
function initializeTooltipPercentage() {
chrome.storage.sync.get(["showTooltipPercentage"], (res) => {
handleShowTooltipPercentageChangeEvent(res.showTooltipPercentage);
});
}
function initializeTooltipPercentageMode() {
chrome.storage.sync.get(["tooltipPercentageMode"], (res) => {
handleTooltipPercentageModeChangeEvent(res.tooltipPercentageMode);
});
}
function initializeNumberDisplayFormat() {
chrome.storage.sync.get(["numberDisplayFormat"], (res) => {
handleNumberDisplayFormatChangeEvent(res.numberDisplayFormat);
});
updateNumberDisplayFormatContent();
}
function updateNumberDisplayFormatContent() {
let testValue = 123456;
document.getElementById("number_format_compactShort").innerHTML =
getNumberFormatter("compactShort").format(testValue);
document.getElementById("number_format_compactLong").innerHTML = getNumberFormatter("compactLong").format(testValue);
document.getElementById("number_format_standard").innerHTML = getNumberFormatter("standard").format(testValue);
}
function initializeNumberDisplayReformatLikes() {
chrome.storage.sync.get(["numberDisplayReformatLikes"], (res) => {
handleNumberDisplayReformatLikesChangeEvent(res.numberDisplayReformatLikes);
});
}
function initializeHidePremiumTeaser() {
chrome.storage.sync.get(["hidePremiumTeaser"], (res) => {
handleHidePremiumTeaserChangeEvent(res.hidePremiumTeaser);
});
}
chrome.storage.onChanged.addListener(storageChangeHandler);
function storageChangeHandler(changes, area) {
if (changes.disableVoteSubmission !== undefined) {
handleDisableVoteSubmissionChangeEvent(changes.disableVoteSubmission.newValue);
}
if (changes.disableLogging !== undefined) {
handleDisableLoggingChangeEvent(changes.disableLogging.newValue);
}
if (changes.coloredThumbs !== undefined) {
handleColoredThumbsChangeEvent(changes.coloredThumbs.newValue);
}
if (changes.coloredBar !== undefined) {
handleColoredBarChangeEvent(changes.coloredBar.newValue);
}
if (changes.colorTheme !== undefined) {
handleColorThemeChangeEvent(changes.colorTheme.newValue);
}
if (changes.numberDisplayFormat !== undefined) {
handleNumberDisplayFormatChangeEvent(changes.numberDisplayFormat.newValue);
}
if (changes.showTooltipPercentage !== undefined) {
handleShowTooltipPercentageChangeEvent(changes.showTooltipPercentage.newValue);
}
if (changes.numberDisplayReformatLikes !== undefined) {
handleNumberDisplayReformatLikesChangeEvent(changes.numberDisplayReformatLikes.newValue);
}
if (changes.hidePremiumTeaser !== undefined) {
handleHidePremiumTeaserChangeEvent(changes.hidePremiumTeaser.newValue);
}
}
function handleDisableVoteSubmissionChangeEvent(value) {
config.disableVoteSubmission = value;
document.getElementById("disable_vote_submission").checked = value;
}
function handleDisableLoggingChangeEvent(value) {
config.disableLogging = value;
document.getElementById("disable_logging").checked = value;
}
function handleColoredThumbsChangeEvent(value) {
config.coloredThumbs = value;
document.getElementById("colored_thumbs").checked = value;
}
function handleColoredBarChangeEvent(value) {
config.coloredBar = value;
document.getElementById("colored_bar").checked = value;
}
function handleColorThemeChangeEvent(value) {
if (!value) {
value = "classic";
}
config.colorTheme = value;
document.getElementById("color_theme").querySelector('option[value="' + value + '"]').selected = true;
updateColorThemePreviewContent(value);
}
function updateColorThemePreviewContent(themeName) {
document.getElementById("color_theme_example_like").style.backgroundColor = getColorFromTheme(themeName, true);
document.getElementById("color_theme_example_dislike").style.backgroundColor = getColorFromTheme(themeName, false);
}
function handleNumberDisplayFormatChangeEvent(value) {
config.numberDisplayFormat = value;
document.getElementById("number_format").querySelector('option[value="' + value + '"]').selected = true;
}
function handleShowTooltipPercentageChangeEvent(value) {
config.showTooltipPercentage = value;
document.getElementById("show_tooltip_percentage").checked = value;
}
function handleTooltipPercentageModeChangeEvent(value) {
if (!value) {
value = "dash_like";
}
config.tooltipPercentageMode = value;
document.getElementById("tooltip_percentage_mode").querySelector('option[value="' + value + '"]').selected = true;
}
function handleNumberDisplayReformatLikesChangeEvent(value) {
config.numberDisplayReformatLikes = value;
document.getElementById("number_reformat_likes").checked = value;
}
function handleHidePremiumTeaserChangeEvent(value) {
const normalized = value === true;
config.hidePremiumTeaser = normalized;
document.getElementById("hide_premium_teaser").checked = normalized;
}
function getNumberFormatter(optionSelect) {
let formatterNotation;
let formatterCompactDisplay;
let userLocales;
try {
userLocales = new URL(
Array.from(document.querySelectorAll("head > link[rel='search']"))
?.find((n) => n?.getAttribute("href")?.includes("?locale="))
?.getAttribute("href"),
)?.searchParams?.get("locale");
} catch {}
switch (optionSelect) {
case "compactLong":
formatterNotation = "compact";
formatterCompactDisplay = "long";
break;
case "standard":
formatterNotation = "standard";
formatterCompactDisplay = "short";
break;
case "compactShort":
default:
formatterNotation = "compact";
formatterCompactDisplay = "short";
}
const formatter = Intl.NumberFormat(document.documentElement.lang || userLocales || navigator.language, {
notation: formatterNotation,
compactDisplay: formatterCompactDisplay,
});
return formatter;
}
(async function getStatus() {
let status = document.getElementById("status");
let serverStatus = document.getElementById("server-status");
let resp = await fetch("https://returnyoutubedislikeapi.com/votes?videoId=YbJOTdZBX1g");
let result = await resp.status;
if (result === 200) {
status.innerText = chrome.i18n.getMessage("apiStatusOnline");
status.style.color = "green";
serverStatus.style.filter =
"invert(58%) sepia(81%) saturate(2618%) hue-rotate(81deg) brightness(119%) contrast(129%)";
} else {
status.innerText = chrome.i18n.getMessage("apiStatusOffline");
status.style.color = "red";
serverStatus.style.filter =
"invert(11%) sepia(100%) saturate(6449%) hue-rotate(3deg) brightness(116%) contrast(115%)";
}
})();
function getColorFromTheme(colorTheme, voteIsLike) {
let colorString;
switch (colorTheme) {
case "accessible":
if (voteIsLike === true) {
colorString = "dodgerblue";
} else {
colorString = "gold";
}
break;
case "neon":
if (voteIsLike === true) {
colorString = "aqua";
} else {
colorString = "magenta";
}
break;
case "classic":
default:
if (voteIsLike === true) {
colorString = "lime";
} else {
colorString = "red";
}
}
return colorString;
}
/* popup-script.js
document.querySelector('#login')
.addEventListener('click', function () {
chrome.runtime.sendMessage({ message: 'get_auth_token' });
});
document.querySelector("#log_off").addEventListener("click", function () {
chrome.runtime.sendMessage({ message: "log_off" });
});
*/