popup.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. import { cLog } from "./src/utils";
  2. /* Config */
  3. const config = {
  4. advanced: false,
  5. disableVoteSubmission: false,
  6. coloredThumbs: false,
  7. coloredBar: false,
  8. colorTheme: "classic",
  9. numberDisplayFormat: "compactShort",
  10. showTooltipPercentage: false,
  11. tooltipPercentageMode: "dash_like",
  12. numberDisplayReformatLikes: false,
  13. showAdvancedMessage:
  14. '<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>',
  15. hideAdvancedMessage:
  16. '<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>',
  17. links: {
  18. website: "https://returnyoutubedislike.com",
  19. github: "https://github.com/Anarios/return-youtube-dislike",
  20. discord: "https://discord.gg/mYnESY4Md5",
  21. donate: "https://returnyoutubedislike.com/donate",
  22. faq: "https://returnyoutubedislike.com/faq",
  23. help: "https://returnyoutubedislike.com/help",
  24. changelog: "/changelog/3/changelog_3.0.html",
  25. },
  26. };
  27. /* Change language */
  28. function localizeHtmlPage() {
  29. //Localize by replacing __MSG_***__ meta tags
  30. var objects = document.getElementsByTagName("html");
  31. for (var j = 0; j < objects.length; j++) {
  32. var obj = objects[j];
  33. var valStrH = obj.innerHTML.toString();
  34. var valNewH = valStrH.replace(/__MSG_(\w+)__/g, function (match, v1) {
  35. return v1 ? chrome.i18n.getMessage(v1) : "";
  36. });
  37. if (valNewH != valStrH) {
  38. obj.innerHTML = valNewH;
  39. }
  40. }
  41. }
  42. localizeHtmlPage();
  43. /* Links */
  44. createLink(config.links.website, "link_website");
  45. createLink(config.links.github, "link_github");
  46. createLink(config.links.discord, "link_discord");
  47. createLink(config.links.faq, "link_faq");
  48. createLink(config.links.donate, "link_donate");
  49. createLink(config.links.help, "link_help");
  50. createLink(config.links.changelog, "link_changelog");
  51. function createLink(url, id) {
  52. document.getElementById(id).addEventListener("click", () => {
  53. chrome.tabs.create({ url: url });
  54. });
  55. }
  56. document
  57. .getElementById("disable_vote_submission")
  58. .addEventListener("click", (ev) => {
  59. chrome.storage.sync.set({ disableVoteSubmission: ev.target.checked });
  60. });
  61. document.getElementById("colored_thumbs").addEventListener("click", (ev) => {
  62. chrome.storage.sync.set({ coloredThumbs: ev.target.checked });
  63. });
  64. document.getElementById("colored_bar").addEventListener("click", (ev) => {
  65. chrome.storage.sync.set({ coloredBar: ev.target.checked });
  66. });
  67. document.getElementById("color_theme").addEventListener("click", (ev) => {
  68. chrome.storage.sync.set({ colorTheme: ev.target.value });
  69. });
  70. document.getElementById("number_format").addEventListener("change", (ev) => {
  71. chrome.storage.sync.set({ numberDisplayFormat: ev.target.value });
  72. });
  73. document
  74. .getElementById("show_tooltip_percentage")
  75. .addEventListener("click", (ev) => {
  76. chrome.storage.sync.set({ showTooltipPercentage: ev.target.checked });
  77. });
  78. document
  79. .getElementById("tooltip_percentage_mode")
  80. .addEventListener("change", (ev) => {
  81. chrome.storage.sync.set({ tooltipPercentageMode: ev.target.value });
  82. });
  83. document
  84. .getElementById("number_reformat_likes")
  85. .addEventListener("click", (ev) => {
  86. chrome.storage.sync.set({ numberDisplayReformatLikes: ev.target.checked });
  87. });
  88. /* Advanced Toggle */
  89. const advancedToggle = document.getElementById("advancedToggle");
  90. advancedToggle.addEventListener("click", () => {
  91. const adv = document.getElementById("advancedSettings");
  92. if (config.advanced) {
  93. adv.style.transform = "scale(1.1)";
  94. adv.style.pointerEvents = "none";
  95. adv.style.opacity = "0";
  96. advancedToggle.innerHTML = config.showAdvancedMessage;
  97. } else {
  98. adv.style.transform = "scale(1)";
  99. adv.style.pointerEvents = "auto";
  100. adv.style.opacity = "1";
  101. advancedToggle.innerHTML = config.hideAdvancedMessage;
  102. }
  103. config.advanced = !config.advanced;
  104. });
  105. initConfig();
  106. function initConfig() {
  107. initializeDisableVoteSubmission();
  108. initializeVersionNumber();
  109. initializeColoredThumbs();
  110. initializeColoredBar();
  111. initializeColorTheme();
  112. initializeNumberDisplayFormat();
  113. initializeTooltipPercentage();
  114. initializeTooltipPercentageMode();
  115. initializeNumberDisplayReformatLikes();
  116. }
  117. function initializeVersionNumber() {
  118. const version = chrome.runtime.getManifest().version;
  119. document.getElementById("ext-version").innerHTML = "v" + version;
  120. fetch(
  121. "https://raw.githubusercontent.com/Anarios/return-youtube-dislike/main/Extensions/combined/manifest-chrome.json"
  122. )
  123. .then((response) => response.json())
  124. .then((json) => {
  125. if (compareVersions(json.version, version)) {
  126. document.getElementById("ext-update").innerHTML =
  127. chrome.i18n.getMessage("textUpdate") + " v" + json.version;
  128. document.getElementById("ext-update").style.padding = ".25rem .5rem";
  129. }
  130. });
  131. // .catch(console.error);
  132. }
  133. // returns whether current < latest
  134. function compareVersions(latestStr, currentStr) {
  135. let latestarr = latestStr.split(".");
  136. let currentarr = currentStr.split(".");
  137. let outdated = false;
  138. // goes through version numbers from left to right from greatest to least significant
  139. for (let i = 0; i < Math.max(latestarr.length, currentarr.length); i++) {
  140. let latest = i < latestarr.length ? parseInt(latestarr[i]) : 0;
  141. let current = i < currentarr.length ? parseInt(currentarr[i]) : 0;
  142. if (latest > current) {
  143. outdated = true;
  144. break;
  145. } else if (latest < current) {
  146. outdated = false;
  147. break;
  148. }
  149. }
  150. return outdated;
  151. }
  152. function initializeDisableVoteSubmission() {
  153. chrome.storage.sync.get(["disableVoteSubmission"], (res) => {
  154. handleDisableVoteSubmissionChangeEvent(res.disableVoteSubmission);
  155. });
  156. }
  157. function initializeColoredThumbs() {
  158. chrome.storage.sync.get(["coloredThumbs"], (res) => {
  159. handleColoredThumbsChangeEvent(res.coloredThumbs);
  160. });
  161. }
  162. function initializeColoredBar() {
  163. chrome.storage.sync.get(["coloredBar"], (res) => {
  164. handleColoredBarChangeEvent(res.coloredBar);
  165. });
  166. }
  167. function initializeColorTheme() {
  168. chrome.storage.sync.get(["colorTheme"], (res) => {
  169. handleColorThemeChangeEvent(res.colorTheme);
  170. });
  171. }
  172. function initializeTooltipPercentage() {
  173. chrome.storage.sync.get(["showTooltipPercentage"], (res) => {
  174. handleShowTooltipPercentageChangeEvent(res.showTooltipPercentage);
  175. });
  176. }
  177. function initializeTooltipPercentageMode() {
  178. chrome.storage.sync.get(["tooltipPercentageMode"], (res) => {
  179. handleTooltipPercentageModeChangeEvent(res.tooltipPercentageMode);
  180. });
  181. }
  182. function initializeNumberDisplayFormat() {
  183. chrome.storage.sync.get(["numberDisplayFormat"], (res) => {
  184. handleNumberDisplayFormatChangeEvent(res.numberDisplayFormat);
  185. });
  186. updateNumberDisplayFormatContent();
  187. }
  188. function updateNumberDisplayFormatContent() {
  189. let testValue = 123456;
  190. document.getElementById("number_format_compactShort").innerHTML =
  191. getNumberFormatter("compactShort").format(testValue);
  192. document.getElementById("number_format_compactLong").innerHTML =
  193. getNumberFormatter("compactLong").format(testValue);
  194. document.getElementById("number_format_standard").innerHTML =
  195. getNumberFormatter("standard").format(testValue);
  196. }
  197. function initializeNumberDisplayReformatLikes() {
  198. chrome.storage.sync.get(["numberDisplayReformatLikes"], (res) => {
  199. handleNumberDisplayReformatLikesChangeEvent(res.numberDisplayReformatLikes);
  200. });
  201. }
  202. chrome.storage.onChanged.addListener(storageChangeHandler);
  203. function storageChangeHandler(changes, area) {
  204. if (changes.disableVoteSubmission !== undefined) {
  205. handleDisableVoteSubmissionChangeEvent(
  206. changes.disableVoteSubmission.newValue
  207. );
  208. }
  209. if (changes.coloredThumbs !== undefined) {
  210. handleColoredThumbsChangeEvent(changes.coloredThumbs.newValue);
  211. }
  212. if (changes.coloredBar !== undefined) {
  213. handleColoredBarChangeEvent(changes.coloredBar.newValue);
  214. }
  215. if (changes.colorTheme !== undefined) {
  216. handleColorThemeChangeEvent(changes.colorTheme.newValue);
  217. }
  218. if (changes.numberDisplayFormat !== undefined) {
  219. handleNumberDisplayFormatChangeEvent(changes.numberDisplayFormat.newValue);
  220. }
  221. if (changes.showTooltipPercentage !== undefined) {
  222. handleShowTooltipPercentageChangeEvent(
  223. changes.showTooltipPercentage.newValue
  224. );
  225. }
  226. if (changes.numberDisplayReformatLikes !== undefined) {
  227. handleNumberDisplayReformatLikesChangeEvent(
  228. changes.numberDisplayReformatLikes.newValue
  229. );
  230. }
  231. }
  232. function handleDisableVoteSubmissionChangeEvent(value) {
  233. config.disableVoteSubmission = value;
  234. document.getElementById("disable_vote_submission").checked = value;
  235. }
  236. function handleColoredThumbsChangeEvent(value) {
  237. config.coloredThumbs = value;
  238. document.getElementById("colored_thumbs").checked = value;
  239. }
  240. function handleColoredBarChangeEvent(value) {
  241. config.coloredBar = value;
  242. document.getElementById("colored_bar").checked = value;
  243. }
  244. function handleColorThemeChangeEvent(value) {
  245. if (!value) {
  246. value = "classic";
  247. }
  248. config.colorTheme = value;
  249. document
  250. .getElementById("color_theme")
  251. .querySelector('option[value="' + value + '"]').selected = true;
  252. updateColorThemePreviewContent(value);
  253. }
  254. function updateColorThemePreviewContent(themeName) {
  255. document.getElementById("color_theme_example_like").style.backgroundColor =
  256. getColorFromTheme(themeName, true);
  257. document.getElementById("color_theme_example_dislike").style.backgroundColor =
  258. getColorFromTheme(themeName, false);
  259. }
  260. function handleNumberDisplayFormatChangeEvent(value) {
  261. config.numberDisplayFormat = value;
  262. document
  263. .getElementById("number_format")
  264. .querySelector('option[value="' + value + '"]').selected = true;
  265. }
  266. function handleShowTooltipPercentageChangeEvent(value) {
  267. config.showTooltipPercentage = value;
  268. document.getElementById("show_tooltip_percentage").checked = value;
  269. }
  270. function handleTooltipPercentageModeChangeEvent(value) {
  271. if (!value) {
  272. value = "dash_like";
  273. }
  274. config.tooltipPercentageMode = value;
  275. document
  276. .getElementById("tooltip_percentage_mode")
  277. .querySelector('option[value="' + value + '"]').selected = true;
  278. }
  279. function handleNumberDisplayReformatLikesChangeEvent(value) {
  280. config.numberDisplayReformatLikes = value;
  281. document.getElementById("number_reformat_likes").checked = value;
  282. }
  283. function getNumberFormatter(optionSelect) {
  284. let formatterNotation;
  285. let formatterCompactDisplay;
  286. let userLocales;
  287. try {
  288. userLocales = new URL(
  289. Array.from(document.querySelectorAll("head > link[rel='search']"))
  290. ?.find((n) => n?.getAttribute("href")?.includes("?locale="))
  291. ?.getAttribute("href")
  292. )?.searchParams?.get("locale");
  293. } catch {}
  294. switch (optionSelect) {
  295. case "compactLong":
  296. formatterNotation = "compact";
  297. formatterCompactDisplay = "long";
  298. break;
  299. case "standard":
  300. formatterNotation = "standard";
  301. formatterCompactDisplay = "short";
  302. break;
  303. case "compactShort":
  304. default:
  305. formatterNotation = "compact";
  306. formatterCompactDisplay = "short";
  307. }
  308. const formatter = Intl.NumberFormat(
  309. document.documentElement.lang || userLocales || navigator.language,
  310. {
  311. notation: formatterNotation,
  312. compactDisplay: formatterCompactDisplay,
  313. }
  314. );
  315. return formatter;
  316. }
  317. (async function getStatus() {
  318. let status = document.getElementById("status");
  319. let serverStatus = document.getElementById("server-status");
  320. let resp = await fetch(
  321. "https://returnyoutubedislikeapi.com/votes?videoId=YbJOTdZBX1g"
  322. );
  323. let result = await resp.status;
  324. if (result === 200) {
  325. status.innerText = "Online";
  326. status.style.color = "green";
  327. serverStatus.style.filter =
  328. "invert(58%) sepia(81%) saturate(2618%) hue-rotate(81deg) brightness(119%) contrast(129%)";
  329. } else {
  330. status.innerText = "Offline";
  331. status.style.color = "red";
  332. serverStatus.style.filter =
  333. "invert(11%) sepia(100%) saturate(6449%) hue-rotate(3deg) brightness(116%) contrast(115%)";
  334. }
  335. })();
  336. function getColorFromTheme(colorTheme, voteIsLike) {
  337. let colorString;
  338. switch (colorTheme) {
  339. case "accessible":
  340. if (voteIsLike === true) {
  341. colorString = "dodgerblue";
  342. } else {
  343. colorString = "gold";
  344. }
  345. break;
  346. case "neon":
  347. if (voteIsLike === true) {
  348. colorString = "aqua";
  349. } else {
  350. colorString = "magenta";
  351. }
  352. break;
  353. case "classic":
  354. default:
  355. if (voteIsLike === true) {
  356. colorString = "lime";
  357. } else {
  358. colorString = "red";
  359. }
  360. }
  361. return colorString;
  362. }
  363. /* popup-script.js
  364. document.querySelector('#login')
  365. .addEventListener('click', function () {
  366. chrome.runtime.sendMessage({ message: 'get_auth_token' });
  367. });
  368. document.querySelector("#log_off").addEventListener("click", function () {
  369. chrome.runtime.sendMessage({ message: "log_off" });
  370. });
  371. */