Browse Source

Merge branch 'main' into patch-1

modifiedAlex 3 years ago
parent
commit
28d25ccd27
42 changed files with 401 additions and 2101 deletions
  1. 1 0
      .gitignore
  2. 8 0
      Extensions/combined/debug.js
  3. 0 393
      Extensions/combined/dist/chrome/bundled-content-script.js
  4. 0 26
      Extensions/combined/dist/chrome/content-style.css
  5. BIN
      Extensions/combined/dist/chrome/icons/icon128.png
  6. BIN
      Extensions/combined/dist/chrome/icons/icon48.png
  7. BIN
      Extensions/combined/dist/chrome/icons/icon_hold128.png
  8. 0 1
      Extensions/combined/dist/chrome/icons/server.svg
  9. 0 41
      Extensions/combined/dist/chrome/manifest.json
  10. 0 127
      Extensions/combined/dist/chrome/popup.css
  11. 0 60
      Extensions/combined/dist/chrome/popup.html
  12. 0 116
      Extensions/combined/dist/chrome/popup.js
  13. 0 272
      Extensions/combined/dist/chrome/ryd.background.js
  14. 0 393
      Extensions/combined/dist/firefox/bundled-content-script.js
  15. 0 26
      Extensions/combined/dist/firefox/content-style.css
  16. BIN
      Extensions/combined/dist/firefox/icons/icon128.png
  17. BIN
      Extensions/combined/dist/firefox/icons/icon48.png
  18. BIN
      Extensions/combined/dist/firefox/icons/icon_hold128.png
  19. 0 1
      Extensions/combined/dist/firefox/icons/server.svg
  20. 0 26
      Extensions/combined/dist/firefox/manifest.json
  21. 0 127
      Extensions/combined/dist/firefox/popup.css
  22. 0 60
      Extensions/combined/dist/firefox/popup.html
  23. 0 116
      Extensions/combined/dist/firefox/popup.js
  24. 0 272
      Extensions/combined/dist/firefox/ryd.background.js
  25. 4 0
      Extensions/combined/manifest-chrome.json
  26. 5 0
      Extensions/combined/manifest-firefox.json
  27. 6 10
      Extensions/combined/popup.js
  28. 5 5
      Extensions/combined/src/events.js
  29. 4 2
      README.md
  30. 6 20
      Website/layouts/default.vue
  31. 10 3
      Website/nuxt.config.js
  32. 60 0
      Website/package-lock.json
  33. 1 0
      Website/package.json
  34. 68 0
      Website/pages/debug.vue
  35. 60 0
      Website/pages/documentation.vue
  36. 19 0
      Website/pages/documentation/endpoints.vue
  37. 78 0
      Website/pages/documentation/fetching.vue
  38. 8 0
      Website/pages/documentation/index.vue
  39. 17 0
      Website/pages/documentation/url.vue
  40. 30 0
      Website/pages/documentation/usage-rights.vue
  41. 3 2
      Website/pages/faq.vue
  42. 8 2
      Website/pages/index.vue

+ 1 - 0
.gitignore

@@ -37,3 +37,4 @@ Extensions/combined/bundled-content-script.js
 # Dist Files
 Extensions/combined/dist/*
 package-lock.json
+Website/package-lock.json

+ 8 - 0
Extensions/combined/debug.js

@@ -0,0 +1,8 @@
+//---   Get Extension Information   ---//
+const extension = chrome.runtime.getManifest();
+
+//---   Get Debug Elements   ---//
+const ver = document.getElementById("extension-version");
+
+//---   Set Debug Elements   ---//
+ver.innerHTML = extension.version;

+ 0 - 393
Extensions/combined/dist/chrome/bundled-content-script.js

@@ -1,393 +0,0 @@
-/******/ (() => { // webpackBootstrap
-/******/ 	"use strict";
-var __webpack_exports__ = {};
-
-;// CONCATENATED MODULE: ./Extensions/combined/src/bar.js
-
-
-function createRateBar(likes, dislikes) {
-  var rateBar = document.getElementById("ryd-bar-container");
-  var widthPx = buttons_getButtons().children[0].clientWidth + buttons_getButtons().children[1].clientWidth + 8;
-  var widthPercent = likes + dislikes > 0 ? likes / (likes + dislikes) * 100 : 50;
-
-  if (!rateBar) {
-    (document.getElementById("menu-container") || document.querySelector("ytm-slim-video-action-bar-renderer")).insertAdjacentHTML("beforeend", "\n          <div class=\"ryd-tooltip\" style=\"width: ".concat(widthPx, "px\">\n          <div class=\"ryd-tooltip-bar-container\">\n             <div\n                id=\"ryd-bar-container\"\n                style=\"width: 100%; height: 2px;\"\n                >\n                <div\n                   id=\"ryd-bar\"\n                   style=\"width: ").concat(widthPercent, "%; height: 100%\"\n                   ></div>\n             </div>\n          </div>\n          <tp-yt-paper-tooltip position=\"top\" id=\"ryd-dislike-tooltip\" class=\"style-scope ytd-sentiment-bar-renderer\" role=\"tooltip\" tabindex=\"-1\">\n             <!--css-build:shady-->").concat(likes.toLocaleString(), "&nbsp;/&nbsp;").concat(dislikes.toLocaleString(), "\n          </tp-yt-paper-tooltip>\n          </div>\n  "));
-  } else {
-    document.getElementById("ryd-bar-container").style.width = widthPx + "px";
-    document.getElementById("ryd-bar").style.width = widthPercent + "%";
-    document.querySelector("#ryd-dislike-tooltip > #tooltip").innerHTML = "".concat(likes.toLocaleString(), "&nbsp;/&nbsp;").concat(dislikes.toLocaleString());
-  }
-}
-
-
-;// CONCATENATED MODULE: ./Extensions/combined/src/utils.js
-function roundDown(num) {
-  if (num < 1000) return num;
-
-  var _int = Math.floor(Math.log10(num) - 2);
-
-  var decimal = _int + (_int % 3 ? 1 : 0);
-  var value = Math.floor(num / Math.pow(10, decimal));
-  return value * Math.pow(10, decimal);
-}
-
-function numberFormat(numberState) {
-  var userLocales;
-
-  try {
-    var _URL, _URL$searchParams, _Array$from, _Array$from$find;
-
-    userLocales = (_URL = new URL((_Array$from = Array.from(document.querySelectorAll("head > link[rel='search']"))) === null || _Array$from === void 0 ? void 0 : (_Array$from$find = _Array$from.find(function (n) {
-      var _n$getAttribute;
-
-      return n === null || n === void 0 ? void 0 : (_n$getAttribute = n.getAttribute("href")) === null || _n$getAttribute === void 0 ? void 0 : _n$getAttribute.includes("?locale=");
-    })) === null || _Array$from$find === void 0 ? void 0 : _Array$from$find.getAttribute("href"))) === null || _URL === void 0 ? void 0 : (_URL$searchParams = _URL.searchParams) === null || _URL$searchParams === void 0 ? void 0 : _URL$searchParams.get("locale");
-  } catch (_unused) {}
-
-  var formatter = Intl.NumberFormat(document.documentElement.lang || userLocales || navigator.language, {
-    notation: "compact"
-  });
-  return formatter.format(roundDown(numberState));
-}
-
-function getBrowser() {
-  if (typeof chrome !== "undefined" && typeof chrome.runtime !== "undefined") {
-    return chrome;
-  } else if (typeof browser !== "undefined" && typeof browser.runtime !== "undefined") {
-    return browser;
-  } else {
-    console.log("browser is not supported");
-    return false;
-  }
-}
-
-function getVideoId(url) {
-  var urlObject = new URL(url);
-  var pathname = urlObject.pathname;
-
-  if (pathname.startsWith("/clip")) {
-    return document.querySelector("meta[itemprop='videoId']").content;
-  } else {
-    return urlObject.searchParams.get("v");
-  }
-}
-
-function isVideoLoaded() {
-  var videoId = getVideoId(window.location.href);
-  return document.querySelector("ytd-watch-flexy[video-id='".concat(videoId, "']")) !== null || // mobile: no video-id attribute
-  document.querySelector('#player[loading="false"]:not([hidden])') !== null;
-}
-
-function cLog(message, writer) {
-  message = "[return youtube dislike]: ".concat(message);
-
-  if (writer) {
-    writer(message);
-  } else {
-    console.log(message);
-  }
-}
-
-
-;// CONCATENATED MODULE: ./Extensions/combined/src/events.js
-
-
-
-
-
-function sendVote(vote) {
-  if (extConfig.disableVoteSubmission !== true) {
-    getBrowser().runtime.sendMessage({
-      message: "send_vote",
-      vote: vote,
-      videoId: getVideoId(window.location.href)
-    });
-  }
-}
-
-function sendVideoIds() {
-  var links = Array.from(document.getElementsByClassName("yt-simple-endpoint ytd-compact-video-renderer")).concat(Array.from(document.getElementsByClassName("yt-simple-endpoint ytd-thumbnail"))); // Also try mobile
-
-  if (links.length < 1) links = Array.from(document.querySelectorAll(".large-media-item-metadata > a, a.large-media-item-thumbnail-container"));
-  var ids = links.filter(function (x) {
-    return x.href && x.href.indexOf("/watch?v=") > 0;
-  }).map(function (x) {
-    return getVideoId(x.href);
-  });
-  getBrowser().runtime.sendMessage({
-    message: "send_links",
-    videoIds: ids
-  });
-}
-
-function likeClicked() {
-  if (checkForSignInButton() === false) {
-    if (storedData.previousState === DISLIKED_STATE) {
-      sendVote(1);
-      storedData.dislikes--;
-      storedData.likes++;
-      createRateBar(storedData.likes, storedData.dislikes);
-      setDislikes(numberFormat(storedData.dislikes));
-      storedData.previousState = LIKED_STATE;
-    } else if (storedData.previousState === NEUTRAL_STATE) {
-      sendVote(1);
-      storedData.likes++;
-      createRateBar(storedData.likes, storedData.dislikes);
-      storedData.previousState = LIKED_STATE;
-    } else if (storedData.previousState = LIKED_STATE) {
-      sendVote(0);
-      storedData.likes--;
-      createRateBar(storedData.likes, storedData.dislikes);
-      storedData.previousState = NEUTRAL_STATE;
-    }
-  }
-}
-
-function dislikeClicked() {
-  if (checkForSignInButton() == false) {
-    if (storedData.previousState === NEUTRAL_STATE) {
-      sendVote(-1);
-      storedData.dislikes++;
-      setDislikes(numberFormat(storedData.dislikes));
-      createRateBar(storedData.likes, storedData.dislikes);
-      storedData.previousState = DISLIKED_STATE;
-    } else if (storedData.previousState === DISLIKED_STATE) {
-      sendVote(0);
-      storedData.dislikes--;
-      setDislikes(numberFormat(storedData.dislikes));
-      createRateBar(storedData.likes, storedData.dislikes);
-      storedData.previousState = NEUTRAL_STATE;
-    } else if (storedData.previousState === LIKED_STATE) {
-      sendVote(-1);
-      storedData.likes--;
-      storedData.dislikes++;
-      setDislikes(numberFormat(storedData.dislikes));
-      createRateBar(storedData.likes, storedData.dislikes);
-      storedData.previousState = DISLIKED_STATE;
-    }
-  }
-}
-
-function addLikeDislikeEventListener() {
-  var buttons = buttons_getButtons();
-
-  if (!window.returnDislikeButtonlistenersSet) {
-    buttons.children[0].addEventListener("click", likeClicked);
-    buttons.children[1].addEventListener("click", dislikeClicked);
-    window.returnDislikeButtonlistenersSet = true;
-  }
-}
-
-function storageChangeHandler(changes, area) {
-  if (changes.disableVoteSubmission !== undefined) {
-    handleDisableVoteSubmissionChangeEvent(changes.disableVoteSubmission.newValue);
-  }
-}
-
-function handleDisableVoteSubmissionChangeEvent(value) {
-  extConfig.disableVoteSubmission = value;
-}
-
-
-;// CONCATENATED MODULE: ./Extensions/combined/src/state.js
-
-
-
-
-var LIKED_STATE = "LIKED_STATE";
-var DISLIKED_STATE = "DISLIKED_STATE";
-var NEUTRAL_STATE = "NEUTRAL_STATE";
-var extConfig = {
-  disableVoteSubmission: false
-};
-var storedData = {
-  likes: 0,
-  dislikes: 0,
-  previousState: NEUTRAL_STATE
-};
-
-function isMobile() {
-  return location.hostname == "m.youtube.com";
-}
-
-function isVideoLiked() {
-  if (isMobile()) {
-    return getLikeButton().querySelector("button").getAttribute("aria-label") == "true";
-  }
-
-  return getLikeButton().classList.contains("style-default-active");
-}
-
-function isVideoDisliked() {
-  if (isMobile()) {
-    return getDislikeButton().querySelector("button").getAttribute("aria-label") == "true";
-  }
-
-  return getDislikeButton().classList.contains("style-default-active");
-}
-
-function getState(storedData) {
-  if (isVideoLiked()) {
-    return {
-      current: LIKED_STATE,
-      previous: storedData.previousState
-    };
-  }
-
-  if (isVideoDisliked()) {
-    return {
-      current: DISLIKED_STATE,
-      previous: storedData.previousState
-    };
-  }
-
-  return {
-    current: NEUTRAL_STATE,
-    previous: storedData.previousState
-  };
-} //---   Sets The Likes And Dislikes Values   ---//
-
-
-function setLikes(likesCount) {
-  getButtons().children[0].querySelector("#text").innerText = likesCount;
-}
-
-function setDislikes(dislikesCount) {
-  if (isMobile()) {
-    buttons_getButtons().children[1].querySelector(".button-renderer-text").innerText = dislikesCount;
-    return;
-  }
-
-  buttons_getButtons().children[1].querySelector("#text").innerText = dislikesCount;
-}
-
-function getLikeCountFromButton() {
-  var likesStr = getLikeButton().querySelector("button").getAttribute("aria-label").replace(/\D/g, "");
-  return likesStr.length > 0 ? parseInt(likesStr) : false;
-}
-
-function processResponse(response, storedData) {
-  var formattedDislike = numberFormat(response.dislikes);
-  setDislikes(formattedDislike);
-  storedData.dislikes = parseInt(response.dislikes);
-  storedData.likes = getLikeCountFromButton() || parseInt(response.likes);
-  createRateBar(storedData.likes, storedData.dislikes);
-}
-
-function setState(storedData) {
-  storedData.previousState = isVideoDisliked() ? DISLIKED_STATE : isVideoLiked() ? LIKED_STATE : NEUTRAL_STATE;
-  var statsSet = false;
-  getBrowser().runtime.sendMessage({
-    message: "set_state",
-    videoId: getVideoId(window.location.href),
-    state: getState(storedData).current,
-    likeCount: getLikeCountFromButton() || null
-  }, function (response) {
-    cLog("response from api:");
-    cLog(JSON.stringify(response));
-
-    if (response !== undefined && !("traceId" in response) && !statsSet) {
-      processResponse(response, storedData);
-    } else {}
-  });
-}
-
-function setInitialState() {
-  setState(storedData);
-  setTimeout(function () {
-    sendVideoIds();
-  }, 1500);
-}
-
-function initExtConfig() {
-  initializeDisableVoteSubmission();
-}
-
-function initializeDisableVoteSubmission() {
-  getBrowser().storage.sync.get(['disableVoteSubmission'], function (res) {
-    if (res.disableVoteSubmission === undefined) {
-      getBrowser().storage.sync.set({
-        disableVoteSubmission: false
-      });
-    } else {
-      extConfig.disableVoteSubmission = res.disableVoteSubmission;
-    }
-  });
-}
-
-
-;// CONCATENATED MODULE: ./Extensions/combined/src/buttons.js
-
-
-function buttons_getButtons() {
-  var _document$getElementB;
-
-  if (isMobile()) {
-    return document.querySelector(".slim-video-action-bar-actions");
-  } //---   If Menu Element Is Displayed:   ---//
-
-
-  if (((_document$getElementB = document.getElementById("menu-container")) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.offsetParent) === null) {
-    return document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div"); //---   If Menu Element Isnt Displayed:   ---//
-  } else {
-    var _document$getElementB2;
-
-    return (_document$getElementB2 = document.getElementById("menu-container")) === null || _document$getElementB2 === void 0 ? void 0 : _document$getElementB2.querySelector("#top-level-buttons-computed");
-  }
-}
-
-function getLikeButton() {
-  return buttons_getButtons().children[0];
-}
-
-function getDislikeButton() {
-  return buttons_getButtons().children[1];
-}
-
-function checkForSignInButton() {
-  if (document.querySelector("a[href^='https://accounts.google.com/ServiceLogin']")) {
-    return true;
-  } else {
-    return false;
-  }
-}
-
-
-;// CONCATENATED MODULE: ./Extensions/combined/ryd.content-script.js
-
-
-
-
-
-initExtConfig();
-var jsInitChecktimer = null;
-
-function setEventListeners(evt) {
-  function checkForJS_Finish() {
-    var _getButtons;
-
-    if ((_getButtons = buttons_getButtons()) !== null && _getButtons !== void 0 && _getButtons.offsetParent && isVideoLoaded()) {
-      clearInterval(jsInitChecktimer);
-      jsInitChecktimer = null;
-      addLikeDislikeEventListener();
-      setInitialState();
-      getBrowser().storage.onChanged.addListener(storageChangeHandler);
-    }
-  }
-
-  if (window.location.href.indexOf("watch?") >= 0) {
-    jsInitChecktimer = setInterval(checkForJS_Finish, 111);
-  }
-}
-
-setEventListeners();
-document.addEventListener("yt-navigate-finish", function (event) {
-  if (jsInitChecktimer !== null) clearInterval(jsInitChecktimer);
-  window.returnDislikeButtonlistenersSet = false;
-  setEventListeners();
-});
-setTimeout(function () {
-  return sendVideoIds();
-}, 2500);
-/******/ })()
-;

+ 0 - 26
Extensions/combined/dist/chrome/content-style.css

@@ -1,26 +0,0 @@
-#ryd-bar-container {
-  background: var(--yt-spec-icon-disabled);
-  border-radius: 2px;
-}
-
-#ryd-bar {
-  background: var(--yt-spec-text-primary);
-  border-radius: 2px;
-  transition: all 0.15s ease-in-out;
-}
-
-.ryd-tooltip {
-  position: relative;
-  display: block;
-  height: 2px;
-  top: 9px;
-}
-
-.ryd-tooltip-bar-container {
-  width: 100%;
-  height: 2px;
-  position: absolute;
-  padding-top: 6px;
-  padding-bottom: 28px;
-  top: -6px;
-}

BIN
Extensions/combined/dist/chrome/icons/icon128.png


BIN
Extensions/combined/dist/chrome/icons/icon48.png


BIN
Extensions/combined/dist/chrome/icons/icon_hold128.png


+ 0 - 1
Extensions/combined/dist/chrome/icons/server.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M480 160H32c-17.673 0-32-14.327-32-32V64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24z"/></svg>

+ 0 - 41
Extensions/combined/dist/chrome/manifest.json

@@ -1,41 +0,0 @@
-{
-  "name": "Return YouTube Dislike",
-  "description": "Returns ability to see dislikes",
-  "version": "2.0.0.3",
-  "manifest_version": 3,
-  "background": {
-    "service_worker": "ryd.background.js"
-  },
-  "icons": {
-    "48": "icons/icon48.png",
-    "128": "icons/icon128.png"
-  },
-  "host_permissions": ["*://*.youtube.com/*"],
-  "permissions": [
-    "storage"
-  ],
-  "action": {
-    "default_popup": "popup.html"
-  },
-  "content_scripts": [
-    {
-      "matches": [
-        "*://youtube.com/*",
-        "*://www.youtube.com/*",
-        "*://m.youtube.com/*"
-      ],
-      "exclude_matches": ["*://*.music.youtube.com/*"],
-      "js": ["bundled-content-script.js"],
-      "css": ["content-style.css"]
-    }
-  ],
-  "externally_connectable": {
-    "matches": ["*://*.youtube.com/*"]
-  },
-  "web_accessible_resources": [
-    {
-      "resources": ["ryd.script.js"],
-      "matches": ["*://*.youtube.com/*"]
-    }
-  ]
-}

+ 0 - 127
Extensions/combined/dist/chrome/popup.css

@@ -1,127 +0,0 @@
-/* Variables */
-:root {
-  --primary: #cc2929;
-  --accent: #581111;
-
-  --background: #111;
-  --secondary: #272727;
-  --tertiary: #333333;
-  --lightGrey: #999;
-  --white: #fff;
-}
-
-/* Window Styling */
-html,
-body {
-  background-color: var(--background);
-  color: var(--white);
-  min-width: 300px;
-  padding: 0.5em;
-  font-family: "Roboto", Arial, Helvetica, sans-serif;
-  font-size: 14px;
-}
-
-h1 {
-  font-size: 26px;
-}
-
-button {
-  color: var(--white);
-  background: var(--secondary);
-  cursor: pointer;
-  padding: 5px 16px;
-  border: none;
-  border-radius: 4px;
-  font-weight: 500;
-  box-shadow: 0 2px 4px -1px rgb(0 0 0 / 20%), 0 4px 5px 0 rgb(0 0 0 / 14%),
-    0 1px 10px 0 rgb(0 0 0 / 12%);
-  transition: 0.4s;
-}
-
-button:hover {
-  background: #444;
-}
-
-#advancedToggle {
-  margin-top: 1em;
-  margin-bottom: 2em;
-}
-
-#advancedSettings {
-  display: none;
-  border: 2px solid var(--secondary);
-  border-radius: 0.5rem;
-  padding: 1rem;
-}
-
-#advancedLegend {
-  color: var(--tertiary) !important;
-  /* margin: auto; */ /* Center the label */
-  /* padding: .25rem .5rem; */
-  /* border-radius: .25rem; */
-  /* border: .25rem solid var(--secondary); */
-}
-
-/*   Switches   */
-.switch {
-  position: relative;
-  display: inline-block;
-  width: 30px;
-  height: 17px;
-  margin-bottom: 1rem;
-}
-
-.switch:last-of-type {
-  margin-bottom: 0;
-}
-
-.switch input {
-  display: none;
-}
-
-.slider {
-  position: absolute;
-  cursor: pointer;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: var(--secondary);
-  transition: 0.4s;
-  border-radius: 34px;
-}
-
-.slider:before {
-  position: absolute;
-  content: "";
-  height: 13px;
-  width: 13px;
-  left: 2px;
-  bottom: 2px;
-  background: var(--lightGrey);
-  transition: 0.4s;
-  border-radius: 50%;
-}
-
-input:checked + .slider {
-  background: var(--accent);
-}
-
-input:checked + .slider:before {
-  transform: translateX(13px);
-  background: var(--primary);
-}
-
-.switchLabel {
-  margin-left: 0.5rem;
-  width: 250px !important;
-  transform: translateX(35px);
-  display: inline-block;
-}
-
-#server-status {
-  height: 72px;
-  width: 90px;
-  /* filter: invert(21%) sepia(100%) saturate(3618%) hue-rotate(102deg)
-    brightness(96%) contrast(108%); */
-}

+ 0 - 60
Extensions/combined/dist/chrome/popup.html

@@ -1,60 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta content="text/html; charset=utf-8" />
-    <title>Return YouTube Dislike</title>
-    <link rel="stylesheet" href="popup.css" />
-    <link rel="preconnect" href="https://fonts.googleapis.com" />
-    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
-    <link
-      href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&display=swap"
-      rel="stylesheet"
-    />
-  </head>
-  <body>
-    <center>
-      <svg width="48" viewBox="0 0 24 24">
-        <path
-          d="M14.9 3H6c-.9 0-1.6.5-1.9 1.2l-3 7c-.1.3-.1.5-.1.7v2c0 1.1.9 2 2 2h6.3l-.9 4.5c-.1.5 0 1 .4 1.4l1.1 1.1 6.5-6.6c.4-.4.6-.9.6-1.4V5c-.1-1.1-1-2-2.1-2zm7.4 12.8h-2.9c-.4 0-.7-.3-.7-.7V3.9c0-.4.3-.7.7-.7h2.9c.4 0 .7.3.7.7V15c0 .4-.3.8-.7.8z"
-          fill="red"
-        />
-        <path d="m8 12.5 5.1-2.9L8 6.7v5.8z" fill="#fff" />
-      </svg>
-      <h1>Return YouTube Dislike</h1>
-      <img id="server-status" src="./icons/server.svg" alt="" />
-      <p>API Status: <span id="status"></span></p>
-      <p>by Dmitrii Selivanov & Community</p>
-
-      <button id="link_website">Website</button>
-      <button id="link_github">GitHub</button>
-      <button id="link_discord">Discord</button>
-
-      <br /><br />
-      <button id="link_faq">FAQ</button>
-      <button id="link_donate">Donate</button>
-      <br />
-
-      <br />
-      <button id="advancedToggle">Show Settings</button>
-      <br />
-    </center>
-
-    <fieldset id="advancedSettings">
-      <legend id="advancedLegend">Settings</legend>
-
-      <label class="switch">
-        <input type="checkbox" id="disable_vote_submission" />
-        <span class="slider" />
-        <span class="switchLabel">Disable like/dislike submission</span>
-      </label>
-      <br />
-
-      <!-- <label class="switch">
-        <input type="checkbox" id="disable_api_unlisted" />
-        <span class="slider" />
-        <span class="switchLabel">Lorem ipsum dolor sit amet</span> </label
-      ><br /> -->
-    </fieldset>
-  </body>
-  <script src="popup.js"></script>
-</html>

+ 0 - 116
Extensions/combined/dist/chrome/popup.js

@@ -1,116 +0,0 @@
-/*   Config   */
-const config = {
-  advanced: false,
-  showAdvancedMessage: "Show Settings",
-  hideAdvancedMessage: "Hide Settings",
-  disableVoteSubmission: false,
-
-  links: {
-    website: "https://returnyoutubedislike.com",
-    github: "https://github.com/Anarios/return-youtube-dislike",
-    discord: "https://discord.gg/mYnESY4Md5",
-    donate: "https://returnyoutubedislike.com/donate",
-    faq: "https://returnyoutubedislike.com/faq",
-  },
-};
-
-/*   Links   */
-document.getElementById("link_website").addEventListener("click", () => {
-  chrome.tabs.create({ url: config.links.website });
-});
-
-document.getElementById("link_github").addEventListener("click", () => {
-  chrome.tabs.create({ url: config.links.github });
-});
-
-document.getElementById("link_discord").addEventListener("click", () => {
-  chrome.tabs.create({ url: config.links.discord });
-});
-
-document.getElementById("link_faq").addEventListener("click", () => {
-  chrome.tabs.create({ url: config.links.faq });
-});
-
-document.getElementById("link_donate").addEventListener("click", () => {
-  chrome.tabs.create({ url: config.links.donate });
-});
-
-document
-  .getElementById("disable_vote_submission")
-  .addEventListener("click", (ev) => {
-    chrome.storage.sync.set({ disableVoteSubmission: ev.target.checked });
-  });
-
-/*   Advanced Toggle   */
-const advancedToggle = document.getElementById("advancedToggle");
-advancedToggle.addEventListener("click", () => {
-  const adv = document.getElementById("advancedSettings");
-  if (config.advanced) {
-    adv.style.display = "none";
-    advancedToggle.innerHTML = config.showAdvancedMessage;
-    config.advanced = false;
-  } else {
-    adv.style.display = "block";
-    advancedToggle.innerHTML = config.hideAdvancedMessage;
-    config.advanced = true;
-  }
-});
-
-initConfig();
-
-function initConfig() {
-  initializeDisableVoteSubmission();
-}
-
-function initializeDisableVoteSubmission() {
-  chrome.storage.sync.get(["disableVoteSubmission"], (res) => {
-    handleDisableVoteSubmissionChangeEvent(res.disableVoteSubmission);
-  });
-}
-
-chrome.storage.onChanged.addListener(storageChangeHandler);
-
-function storageChangeHandler(changes, area) {
-  if (changes.disableVoteSubmission !== undefined) {
-    handleDisableVoteSubmissionChangeEvent(
-      changes.disableVoteSubmission.newValue
-    );
-  }
-}
-
-function handleDisableVoteSubmissionChangeEvent(value) {
-  config.disableVoteSubmission = value;
-  document.getElementById("disable_vote_submission").checked = value;
-}
-
-(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 = "Online";
-    status.style.color = "green";
-    serverStatus.style.filter =
-      "invert(58%) sepia(81%) saturate(2618%) hue-rotate(81deg) brightness(119%) contrast(129%)";
-  } else {
-    status.innerText = "Offline";
-    status.style.color = "red";
-    serverStatus.style.filter =
-      "invert(11%) sepia(100%) saturate(6449%) hue-rotate(3deg) brightness(116%) contrast(115%)";
-  }
-})();
-
-/* 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" });
-});
-*/

+ 0 - 272
Extensions/combined/dist/chrome/ryd.background.js

@@ -1,272 +0,0 @@
-const apiUrl = "https://returnyoutubedislikeapi.com";
-const voteDisabledIconName = 'icon_hold128.png';
-const defaultIconName = 'icon128.png';
-let api;
-
-/** stores extension's global config */
-let extConfig = {
-  disableVoteSubmission: false
-}
-
-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;
-  }
-});
-
-async function sendVote(videoId, vote) {
-  api.storage.sync.get(null, async (storageResult) => {
-    if (!storageResult.userId || !storageResult.registrationConfirmed) {
-      await register();
-      return;
-    }
-    fetch(`${apiUrl}/interact/vote`, {
-      method: "POST",
-      headers: {
-        "Content-Type": "application/json",
-      },
-      body: JSON.stringify({
-        userId: storageResult.userId,
-        videoId,
-        value: vote,
-      }),
-    })
-      .then(async (response) => {
-        if (response.status == 401) {
-          await register();
-          await sendVote(videoId, vote);
-          return;
-        }
-        return response.json()
-      })
-      .then((response) => {
-        solvePuzzle(response).then((solvedPuzzle) => {
-          fetch(`${apiUrl}/interact/confirmVote`, {
-            method: "POST",
-            headers: {
-              "Content-Type": "application/json",
-            },
-            body: JSON.stringify({
-              ...solvedPuzzle,
-              userId: storageResult.userId,
-              videoId,
-            }),
-          });
-        });
-      });
-  });
-}
-
-function register() {
-  let userId = generateUserID();
-  api.storage.sync.set({ userId });
-  return fetch(`${apiUrl}/puzzle/registration?userId=${userId}`, {
-    method: "GET",
-    headers: {
-      Accept: "application/json",
-    },
-  })
-    .then((response) => response.json())
-    .then((response) => {
-      return solvePuzzle(response).then((solvedPuzzle) => {
-        return fetch(`${apiUrl}/puzzle/registration?userId=${userId}`, {
-          method: "POST",
-          headers: {
-            "Content-Type": "application/json",
-          },
-          body: JSON.stringify(solvedPuzzle),
-        }).then((response) =>
-          response.json().then((result) => {
-            if (result === true) {
-              return api.storage.sync.set({ registrationConfirmed: true });
-            }
-          })
-        );
-      });
-    })
-    .catch();
-}
-
-api.storage.sync.get(null, (res) => {
-  if (!res || !res.userId || !res.registrationConfirmed) {
-    register();
-  }
-});
-
-const sentIds = new Set();
-let toSend = [];
-
-function sendUserSubmittedStatisticsToApi(statistics) {
-  fetch(`${apiUrl}/votes/user-submitted`, {
-    method: "POST",
-    headers: {
-      "Content-Type": "application/json",
-    },
-    body: JSON.stringify(statistics),
-  });
-}
-
-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);
-  let maxCount = Math.pow(2, puzzle.difficulty) * 5;
-  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))),
-      };
-    }
-  }
-}
-
-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;
-  }
-}
-
-function storageChangeHandler(changes, area) {
-  if (changes.disableVoteSubmission !== undefined) {
-    handleDisableVoteSubmissionChangeEvent(changes.disableVoteSubmission.newValue);
-  }
-}
-
-function handleDisableVoteSubmissionChangeEvent(value) {
-  extConfig.disableVoteSubmission = value;
-  if (value === true) {
-    changeIcon(voteDisabledIconName);
-  } else {
-    changeIcon(defaultIconName);
-  }
-}
-
-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');
-}
-
-api.storage.onChanged.addListener(storageChangeHandler);
-
-function initExtConfig() {
-  initializeDisableVoteSubmission();
-}
-
-function initializeDisableVoteSubmission() {
-  api.storage.sync.get(['disableVoteSubmission'], (res) => {
-    if (res.disableVoteSubmission === undefined) {
-      api.storage.sync.set({disableVoteSubmission: false});
-    }
-    else {
-      extConfig.disableVoteSubmission = res.disableVoteSubmission;
-      if (res.disableVoteSubmission) changeIcon(voteDisabledIconName);
-    }
-  });
-}
-
-function isChrome() {
-  return typeof chrome !== "undefined" && typeof chrome.runtime !== "undefined";
-}
-
-function isFirefox() {
-  return typeof browser !== "undefined" && typeof browser.runtime !== "undefined";
-}

+ 0 - 393
Extensions/combined/dist/firefox/bundled-content-script.js

@@ -1,393 +0,0 @@
-/******/ (() => { // webpackBootstrap
-/******/ 	"use strict";
-var __webpack_exports__ = {};
-
-;// CONCATENATED MODULE: ./Extensions/combined/src/bar.js
-
-
-function createRateBar(likes, dislikes) {
-  var rateBar = document.getElementById("ryd-bar-container");
-  var widthPx = buttons_getButtons().children[0].clientWidth + buttons_getButtons().children[1].clientWidth + 8;
-  var widthPercent = likes + dislikes > 0 ? likes / (likes + dislikes) * 100 : 50;
-
-  if (!rateBar) {
-    (document.getElementById("menu-container") || document.querySelector("ytm-slim-video-action-bar-renderer")).insertAdjacentHTML("beforeend", "\n          <div class=\"ryd-tooltip\" style=\"width: ".concat(widthPx, "px\">\n          <div class=\"ryd-tooltip-bar-container\">\n             <div\n                id=\"ryd-bar-container\"\n                style=\"width: 100%; height: 2px;\"\n                >\n                <div\n                   id=\"ryd-bar\"\n                   style=\"width: ").concat(widthPercent, "%; height: 100%\"\n                   ></div>\n             </div>\n          </div>\n          <tp-yt-paper-tooltip position=\"top\" id=\"ryd-dislike-tooltip\" class=\"style-scope ytd-sentiment-bar-renderer\" role=\"tooltip\" tabindex=\"-1\">\n             <!--css-build:shady-->").concat(likes.toLocaleString(), "&nbsp;/&nbsp;").concat(dislikes.toLocaleString(), "\n          </tp-yt-paper-tooltip>\n          </div>\n  "));
-  } else {
-    document.getElementById("ryd-bar-container").style.width = widthPx + "px";
-    document.getElementById("ryd-bar").style.width = widthPercent + "%";
-    document.querySelector("#ryd-dislike-tooltip > #tooltip").innerHTML = "".concat(likes.toLocaleString(), "&nbsp;/&nbsp;").concat(dislikes.toLocaleString());
-  }
-}
-
-
-;// CONCATENATED MODULE: ./Extensions/combined/src/utils.js
-function roundDown(num) {
-  if (num < 1000) return num;
-
-  var _int = Math.floor(Math.log10(num) - 2);
-
-  var decimal = _int + (_int % 3 ? 1 : 0);
-  var value = Math.floor(num / Math.pow(10, decimal));
-  return value * Math.pow(10, decimal);
-}
-
-function numberFormat(numberState) {
-  var userLocales;
-
-  try {
-    var _URL, _URL$searchParams, _Array$from, _Array$from$find;
-
-    userLocales = (_URL = new URL((_Array$from = Array.from(document.querySelectorAll("head > link[rel='search']"))) === null || _Array$from === void 0 ? void 0 : (_Array$from$find = _Array$from.find(function (n) {
-      var _n$getAttribute;
-
-      return n === null || n === void 0 ? void 0 : (_n$getAttribute = n.getAttribute("href")) === null || _n$getAttribute === void 0 ? void 0 : _n$getAttribute.includes("?locale=");
-    })) === null || _Array$from$find === void 0 ? void 0 : _Array$from$find.getAttribute("href"))) === null || _URL === void 0 ? void 0 : (_URL$searchParams = _URL.searchParams) === null || _URL$searchParams === void 0 ? void 0 : _URL$searchParams.get("locale");
-  } catch (_unused) {}
-
-  var formatter = Intl.NumberFormat(document.documentElement.lang || userLocales || navigator.language, {
-    notation: "compact"
-  });
-  return formatter.format(roundDown(numberState));
-}
-
-function getBrowser() {
-  if (typeof chrome !== "undefined" && typeof chrome.runtime !== "undefined") {
-    return chrome;
-  } else if (typeof browser !== "undefined" && typeof browser.runtime !== "undefined") {
-    return browser;
-  } else {
-    console.log("browser is not supported");
-    return false;
-  }
-}
-
-function getVideoId(url) {
-  var urlObject = new URL(url);
-  var pathname = urlObject.pathname;
-
-  if (pathname.startsWith("/clip")) {
-    return document.querySelector("meta[itemprop='videoId']").content;
-  } else {
-    return urlObject.searchParams.get("v");
-  }
-}
-
-function isVideoLoaded() {
-  var videoId = getVideoId(window.location.href);
-  return document.querySelector("ytd-watch-flexy[video-id='".concat(videoId, "']")) !== null || // mobile: no video-id attribute
-  document.querySelector('#player[loading="false"]:not([hidden])') !== null;
-}
-
-function cLog(message, writer) {
-  message = "[return youtube dislike]: ".concat(message);
-
-  if (writer) {
-    writer(message);
-  } else {
-    console.log(message);
-  }
-}
-
-
-;// CONCATENATED MODULE: ./Extensions/combined/src/events.js
-
-
-
-
-
-function sendVote(vote) {
-  if (extConfig.disableVoteSubmission !== true) {
-    getBrowser().runtime.sendMessage({
-      message: "send_vote",
-      vote: vote,
-      videoId: getVideoId(window.location.href)
-    });
-  }
-}
-
-function sendVideoIds() {
-  var links = Array.from(document.getElementsByClassName("yt-simple-endpoint ytd-compact-video-renderer")).concat(Array.from(document.getElementsByClassName("yt-simple-endpoint ytd-thumbnail"))); // Also try mobile
-
-  if (links.length < 1) links = Array.from(document.querySelectorAll(".large-media-item-metadata > a, a.large-media-item-thumbnail-container"));
-  var ids = links.filter(function (x) {
-    return x.href && x.href.indexOf("/watch?v=") > 0;
-  }).map(function (x) {
-    return getVideoId(x.href);
-  });
-  getBrowser().runtime.sendMessage({
-    message: "send_links",
-    videoIds: ids
-  });
-}
-
-function likeClicked() {
-  if (checkForSignInButton() === false) {
-    if (storedData.previousState === DISLIKED_STATE) {
-      sendVote(1);
-      storedData.dislikes--;
-      storedData.likes++;
-      createRateBar(storedData.likes, storedData.dislikes);
-      setDislikes(numberFormat(storedData.dislikes));
-      storedData.previousState = LIKED_STATE;
-    } else if (storedData.previousState === NEUTRAL_STATE) {
-      sendVote(1);
-      storedData.likes++;
-      createRateBar(storedData.likes, storedData.dislikes);
-      storedData.previousState = LIKED_STATE;
-    } else if (storedData.previousState = LIKED_STATE) {
-      sendVote(0);
-      storedData.likes--;
-      createRateBar(storedData.likes, storedData.dislikes);
-      storedData.previousState = NEUTRAL_STATE;
-    }
-  }
-}
-
-function dislikeClicked() {
-  if (checkForSignInButton() == false) {
-    if (storedData.previousState === NEUTRAL_STATE) {
-      sendVote(-1);
-      storedData.dislikes++;
-      setDislikes(numberFormat(storedData.dislikes));
-      createRateBar(storedData.likes, storedData.dislikes);
-      storedData.previousState = DISLIKED_STATE;
-    } else if (storedData.previousState === DISLIKED_STATE) {
-      sendVote(0);
-      storedData.dislikes--;
-      setDislikes(numberFormat(storedData.dislikes));
-      createRateBar(storedData.likes, storedData.dislikes);
-      storedData.previousState = NEUTRAL_STATE;
-    } else if (storedData.previousState === LIKED_STATE) {
-      sendVote(-1);
-      storedData.likes--;
-      storedData.dislikes++;
-      setDislikes(numberFormat(storedData.dislikes));
-      createRateBar(storedData.likes, storedData.dislikes);
-      storedData.previousState = DISLIKED_STATE;
-    }
-  }
-}
-
-function addLikeDislikeEventListener() {
-  var buttons = buttons_getButtons();
-
-  if (!window.returnDislikeButtonlistenersSet) {
-    buttons.children[0].addEventListener("click", likeClicked);
-    buttons.children[1].addEventListener("click", dislikeClicked);
-    window.returnDislikeButtonlistenersSet = true;
-  }
-}
-
-function storageChangeHandler(changes, area) {
-  if (changes.disableVoteSubmission !== undefined) {
-    handleDisableVoteSubmissionChangeEvent(changes.disableVoteSubmission.newValue);
-  }
-}
-
-function handleDisableVoteSubmissionChangeEvent(value) {
-  extConfig.disableVoteSubmission = value;
-}
-
-
-;// CONCATENATED MODULE: ./Extensions/combined/src/state.js
-
-
-
-
-var LIKED_STATE = "LIKED_STATE";
-var DISLIKED_STATE = "DISLIKED_STATE";
-var NEUTRAL_STATE = "NEUTRAL_STATE";
-var extConfig = {
-  disableVoteSubmission: false
-};
-var storedData = {
-  likes: 0,
-  dislikes: 0,
-  previousState: NEUTRAL_STATE
-};
-
-function isMobile() {
-  return location.hostname == "m.youtube.com";
-}
-
-function isVideoLiked() {
-  if (isMobile()) {
-    return getLikeButton().querySelector("button").getAttribute("aria-label") == "true";
-  }
-
-  return getLikeButton().classList.contains("style-default-active");
-}
-
-function isVideoDisliked() {
-  if (isMobile()) {
-    return getDislikeButton().querySelector("button").getAttribute("aria-label") == "true";
-  }
-
-  return getDislikeButton().classList.contains("style-default-active");
-}
-
-function getState(storedData) {
-  if (isVideoLiked()) {
-    return {
-      current: LIKED_STATE,
-      previous: storedData.previousState
-    };
-  }
-
-  if (isVideoDisliked()) {
-    return {
-      current: DISLIKED_STATE,
-      previous: storedData.previousState
-    };
-  }
-
-  return {
-    current: NEUTRAL_STATE,
-    previous: storedData.previousState
-  };
-} //---   Sets The Likes And Dislikes Values   ---//
-
-
-function setLikes(likesCount) {
-  getButtons().children[0].querySelector("#text").innerText = likesCount;
-}
-
-function setDislikes(dislikesCount) {
-  if (isMobile()) {
-    buttons_getButtons().children[1].querySelector(".button-renderer-text").innerText = dislikesCount;
-    return;
-  }
-
-  buttons_getButtons().children[1].querySelector("#text").innerText = dislikesCount;
-}
-
-function getLikeCountFromButton() {
-  var likesStr = getLikeButton().querySelector("button").getAttribute("aria-label").replace(/\D/g, "");
-  return likesStr.length > 0 ? parseInt(likesStr) : false;
-}
-
-function processResponse(response, storedData) {
-  var formattedDislike = numberFormat(response.dislikes);
-  setDislikes(formattedDislike);
-  storedData.dislikes = parseInt(response.dislikes);
-  storedData.likes = getLikeCountFromButton() || parseInt(response.likes);
-  createRateBar(storedData.likes, storedData.dislikes);
-}
-
-function setState(storedData) {
-  storedData.previousState = isVideoDisliked() ? DISLIKED_STATE : isVideoLiked() ? LIKED_STATE : NEUTRAL_STATE;
-  var statsSet = false;
-  getBrowser().runtime.sendMessage({
-    message: "set_state",
-    videoId: getVideoId(window.location.href),
-    state: getState(storedData).current,
-    likeCount: getLikeCountFromButton() || null
-  }, function (response) {
-    cLog("response from api:");
-    cLog(JSON.stringify(response));
-
-    if (response !== undefined && !("traceId" in response) && !statsSet) {
-      processResponse(response, storedData);
-    } else {}
-  });
-}
-
-function setInitialState() {
-  setState(storedData);
-  setTimeout(function () {
-    sendVideoIds();
-  }, 1500);
-}
-
-function initExtConfig() {
-  initializeDisableVoteSubmission();
-}
-
-function initializeDisableVoteSubmission() {
-  getBrowser().storage.sync.get(['disableVoteSubmission'], function (res) {
-    if (res.disableVoteSubmission === undefined) {
-      getBrowser().storage.sync.set({
-        disableVoteSubmission: false
-      });
-    } else {
-      extConfig.disableVoteSubmission = res.disableVoteSubmission;
-    }
-  });
-}
-
-
-;// CONCATENATED MODULE: ./Extensions/combined/src/buttons.js
-
-
-function buttons_getButtons() {
-  var _document$getElementB;
-
-  if (isMobile()) {
-    return document.querySelector(".slim-video-action-bar-actions");
-  } //---   If Menu Element Is Displayed:   ---//
-
-
-  if (((_document$getElementB = document.getElementById("menu-container")) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.offsetParent) === null) {
-    return document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div"); //---   If Menu Element Isnt Displayed:   ---//
-  } else {
-    var _document$getElementB2;
-
-    return (_document$getElementB2 = document.getElementById("menu-container")) === null || _document$getElementB2 === void 0 ? void 0 : _document$getElementB2.querySelector("#top-level-buttons-computed");
-  }
-}
-
-function getLikeButton() {
-  return buttons_getButtons().children[0];
-}
-
-function getDislikeButton() {
-  return buttons_getButtons().children[1];
-}
-
-function checkForSignInButton() {
-  if (document.querySelector("a[href^='https://accounts.google.com/ServiceLogin']")) {
-    return true;
-  } else {
-    return false;
-  }
-}
-
-
-;// CONCATENATED MODULE: ./Extensions/combined/ryd.content-script.js
-
-
-
-
-
-initExtConfig();
-var jsInitChecktimer = null;
-
-function setEventListeners(evt) {
-  function checkForJS_Finish() {
-    var _getButtons;
-
-    if ((_getButtons = buttons_getButtons()) !== null && _getButtons !== void 0 && _getButtons.offsetParent && isVideoLoaded()) {
-      clearInterval(jsInitChecktimer);
-      jsInitChecktimer = null;
-      addLikeDislikeEventListener();
-      setInitialState();
-      getBrowser().storage.onChanged.addListener(storageChangeHandler);
-    }
-  }
-
-  if (window.location.href.indexOf("watch?") >= 0) {
-    jsInitChecktimer = setInterval(checkForJS_Finish, 111);
-  }
-}
-
-setEventListeners();
-document.addEventListener("yt-navigate-finish", function (event) {
-  if (jsInitChecktimer !== null) clearInterval(jsInitChecktimer);
-  window.returnDislikeButtonlistenersSet = false;
-  setEventListeners();
-});
-setTimeout(function () {
-  return sendVideoIds();
-}, 2500);
-/******/ })()
-;

+ 0 - 26
Extensions/combined/dist/firefox/content-style.css

@@ -1,26 +0,0 @@
-#ryd-bar-container {
-  background: var(--yt-spec-icon-disabled);
-  border-radius: 2px;
-}
-
-#ryd-bar {
-  background: var(--yt-spec-text-primary);
-  border-radius: 2px;
-  transition: all 0.15s ease-in-out;
-}
-
-.ryd-tooltip {
-  position: relative;
-  display: block;
-  height: 2px;
-  top: 9px;
-}
-
-.ryd-tooltip-bar-container {
-  width: 100%;
-  height: 2px;
-  position: absolute;
-  padding-top: 6px;
-  padding-bottom: 28px;
-  top: -6px;
-}

BIN
Extensions/combined/dist/firefox/icons/icon128.png


BIN
Extensions/combined/dist/firefox/icons/icon48.png


BIN
Extensions/combined/dist/firefox/icons/icon_hold128.png


+ 0 - 1
Extensions/combined/dist/firefox/icons/server.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M480 160H32c-17.673 0-32-14.327-32-32V64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24z"/></svg>

+ 0 - 26
Extensions/combined/dist/firefox/manifest.json

@@ -1,26 +0,0 @@
-{
-  "name": "Return YouTube Dislike",
-  "description": "Returns ability to see dislikes",
-  "version": "2.0.0.3",
-  "manifest_version": 2,
-  "background": {
-    "scripts": ["ryd.background.js"]
-  },
-  "icons": {
-    "48": "icons/icon48.png",
-   "128": "icons/icon128.png"
-  },
-  "permissions": ["activeTab", "*://*.youtube.com/*", "storage"],
-  "browser_action": {
-    "default_popup": "popup.html"
-  },
-  "content_scripts": [
-    {
-      "matches": ["*://*.youtube.com/*"],
-      "exclude_matches": ["*://*.music.youtube.com/*"],
-      "run_at": "document_idle",
-      "css": ["content-style.css"],
-      "js": ["bundled-content-script.js"]
-    }
-  ]
-}

+ 0 - 127
Extensions/combined/dist/firefox/popup.css

@@ -1,127 +0,0 @@
-/* Variables */
-:root {
-  --primary: #cc2929;
-  --accent: #581111;
-
-  --background: #111;
-  --secondary: #272727;
-  --tertiary: #333333;
-  --lightGrey: #999;
-  --white: #fff;
-}
-
-/* Window Styling */
-html,
-body {
-  background-color: var(--background);
-  color: var(--white);
-  min-width: 300px;
-  padding: 0.5em;
-  font-family: "Roboto", Arial, Helvetica, sans-serif;
-  font-size: 14px;
-}
-
-h1 {
-  font-size: 26px;
-}
-
-button {
-  color: var(--white);
-  background: var(--secondary);
-  cursor: pointer;
-  padding: 5px 16px;
-  border: none;
-  border-radius: 4px;
-  font-weight: 500;
-  box-shadow: 0 2px 4px -1px rgb(0 0 0 / 20%), 0 4px 5px 0 rgb(0 0 0 / 14%),
-    0 1px 10px 0 rgb(0 0 0 / 12%);
-  transition: 0.4s;
-}
-
-button:hover {
-  background: #444;
-}
-
-#advancedToggle {
-  margin-top: 1em;
-  margin-bottom: 2em;
-}
-
-#advancedSettings {
-  display: none;
-  border: 2px solid var(--secondary);
-  border-radius: 0.5rem;
-  padding: 1rem;
-}
-
-#advancedLegend {
-  color: var(--tertiary) !important;
-  /* margin: auto; */ /* Center the label */
-  /* padding: .25rem .5rem; */
-  /* border-radius: .25rem; */
-  /* border: .25rem solid var(--secondary); */
-}
-
-/*   Switches   */
-.switch {
-  position: relative;
-  display: inline-block;
-  width: 30px;
-  height: 17px;
-  margin-bottom: 1rem;
-}
-
-.switch:last-of-type {
-  margin-bottom: 0;
-}
-
-.switch input {
-  display: none;
-}
-
-.slider {
-  position: absolute;
-  cursor: pointer;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: var(--secondary);
-  transition: 0.4s;
-  border-radius: 34px;
-}
-
-.slider:before {
-  position: absolute;
-  content: "";
-  height: 13px;
-  width: 13px;
-  left: 2px;
-  bottom: 2px;
-  background: var(--lightGrey);
-  transition: 0.4s;
-  border-radius: 50%;
-}
-
-input:checked + .slider {
-  background: var(--accent);
-}
-
-input:checked + .slider:before {
-  transform: translateX(13px);
-  background: var(--primary);
-}
-
-.switchLabel {
-  margin-left: 0.5rem;
-  width: 250px !important;
-  transform: translateX(35px);
-  display: inline-block;
-}
-
-#server-status {
-  height: 72px;
-  width: 90px;
-  /* filter: invert(21%) sepia(100%) saturate(3618%) hue-rotate(102deg)
-    brightness(96%) contrast(108%); */
-}

+ 0 - 60
Extensions/combined/dist/firefox/popup.html

@@ -1,60 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta content="text/html; charset=utf-8" />
-    <title>Return YouTube Dislike</title>
-    <link rel="stylesheet" href="popup.css" />
-    <link rel="preconnect" href="https://fonts.googleapis.com" />
-    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
-    <link
-      href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&display=swap"
-      rel="stylesheet"
-    />
-  </head>
-  <body>
-    <center>
-      <svg width="48" viewBox="0 0 24 24">
-        <path
-          d="M14.9 3H6c-.9 0-1.6.5-1.9 1.2l-3 7c-.1.3-.1.5-.1.7v2c0 1.1.9 2 2 2h6.3l-.9 4.5c-.1.5 0 1 .4 1.4l1.1 1.1 6.5-6.6c.4-.4.6-.9.6-1.4V5c-.1-1.1-1-2-2.1-2zm7.4 12.8h-2.9c-.4 0-.7-.3-.7-.7V3.9c0-.4.3-.7.7-.7h2.9c.4 0 .7.3.7.7V15c0 .4-.3.8-.7.8z"
-          fill="red"
-        />
-        <path d="m8 12.5 5.1-2.9L8 6.7v5.8z" fill="#fff" />
-      </svg>
-      <h1>Return YouTube Dislike</h1>
-      <img id="server-status" src="./icons/server.svg" alt="" />
-      <p>API Status: <span id="status"></span></p>
-      <p>by Dmitrii Selivanov & Community</p>
-
-      <button id="link_website">Website</button>
-      <button id="link_github">GitHub</button>
-      <button id="link_discord">Discord</button>
-
-      <br /><br />
-      <button id="link_faq">FAQ</button>
-      <button id="link_donate">Donate</button>
-      <br />
-
-      <br />
-      <button id="advancedToggle">Show Settings</button>
-      <br />
-    </center>
-
-    <fieldset id="advancedSettings">
-      <legend id="advancedLegend">Settings</legend>
-
-      <label class="switch">
-        <input type="checkbox" id="disable_vote_submission" />
-        <span class="slider" />
-        <span class="switchLabel">Disable like/dislike submission</span>
-      </label>
-      <br />
-
-      <!-- <label class="switch">
-        <input type="checkbox" id="disable_api_unlisted" />
-        <span class="slider" />
-        <span class="switchLabel">Lorem ipsum dolor sit amet</span> </label
-      ><br /> -->
-    </fieldset>
-  </body>
-  <script src="popup.js"></script>
-</html>

+ 0 - 116
Extensions/combined/dist/firefox/popup.js

@@ -1,116 +0,0 @@
-/*   Config   */
-const config = {
-  advanced: false,
-  showAdvancedMessage: "Show Settings",
-  hideAdvancedMessage: "Hide Settings",
-  disableVoteSubmission: false,
-
-  links: {
-    website: "https://returnyoutubedislike.com",
-    github: "https://github.com/Anarios/return-youtube-dislike",
-    discord: "https://discord.gg/mYnESY4Md5",
-    donate: "https://returnyoutubedislike.com/donate",
-    faq: "https://returnyoutubedislike.com/faq",
-  },
-};
-
-/*   Links   */
-document.getElementById("link_website").addEventListener("click", () => {
-  chrome.tabs.create({ url: config.links.website });
-});
-
-document.getElementById("link_github").addEventListener("click", () => {
-  chrome.tabs.create({ url: config.links.github });
-});
-
-document.getElementById("link_discord").addEventListener("click", () => {
-  chrome.tabs.create({ url: config.links.discord });
-});
-
-document.getElementById("link_faq").addEventListener("click", () => {
-  chrome.tabs.create({ url: config.links.faq });
-});
-
-document.getElementById("link_donate").addEventListener("click", () => {
-  chrome.tabs.create({ url: config.links.donate });
-});
-
-document
-  .getElementById("disable_vote_submission")
-  .addEventListener("click", (ev) => {
-    chrome.storage.sync.set({ disableVoteSubmission: ev.target.checked });
-  });
-
-/*   Advanced Toggle   */
-const advancedToggle = document.getElementById("advancedToggle");
-advancedToggle.addEventListener("click", () => {
-  const adv = document.getElementById("advancedSettings");
-  if (config.advanced) {
-    adv.style.display = "none";
-    advancedToggle.innerHTML = config.showAdvancedMessage;
-    config.advanced = false;
-  } else {
-    adv.style.display = "block";
-    advancedToggle.innerHTML = config.hideAdvancedMessage;
-    config.advanced = true;
-  }
-});
-
-initConfig();
-
-function initConfig() {
-  initializeDisableVoteSubmission();
-}
-
-function initializeDisableVoteSubmission() {
-  chrome.storage.sync.get(["disableVoteSubmission"], (res) => {
-    handleDisableVoteSubmissionChangeEvent(res.disableVoteSubmission);
-  });
-}
-
-chrome.storage.onChanged.addListener(storageChangeHandler);
-
-function storageChangeHandler(changes, area) {
-  if (changes.disableVoteSubmission !== undefined) {
-    handleDisableVoteSubmissionChangeEvent(
-      changes.disableVoteSubmission.newValue
-    );
-  }
-}
-
-function handleDisableVoteSubmissionChangeEvent(value) {
-  config.disableVoteSubmission = value;
-  document.getElementById("disable_vote_submission").checked = value;
-}
-
-(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 = "Online";
-    status.style.color = "green";
-    serverStatus.style.filter =
-      "invert(58%) sepia(81%) saturate(2618%) hue-rotate(81deg) brightness(119%) contrast(129%)";
-  } else {
-    status.innerText = "Offline";
-    status.style.color = "red";
-    serverStatus.style.filter =
-      "invert(11%) sepia(100%) saturate(6449%) hue-rotate(3deg) brightness(116%) contrast(115%)";
-  }
-})();
-
-/* 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" });
-});
-*/

+ 0 - 272
Extensions/combined/dist/firefox/ryd.background.js

@@ -1,272 +0,0 @@
-const apiUrl = "https://returnyoutubedislikeapi.com";
-const voteDisabledIconName = 'icon_hold128.png';
-const defaultIconName = 'icon128.png';
-let api;
-
-/** stores extension's global config */
-let extConfig = {
-  disableVoteSubmission: false
-}
-
-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;
-  }
-});
-
-async function sendVote(videoId, vote) {
-  api.storage.sync.get(null, async (storageResult) => {
-    if (!storageResult.userId || !storageResult.registrationConfirmed) {
-      await register();
-      return;
-    }
-    fetch(`${apiUrl}/interact/vote`, {
-      method: "POST",
-      headers: {
-        "Content-Type": "application/json",
-      },
-      body: JSON.stringify({
-        userId: storageResult.userId,
-        videoId,
-        value: vote,
-      }),
-    })
-      .then(async (response) => {
-        if (response.status == 401) {
-          await register();
-          await sendVote(videoId, vote);
-          return;
-        }
-        return response.json()
-      })
-      .then((response) => {
-        solvePuzzle(response).then((solvedPuzzle) => {
-          fetch(`${apiUrl}/interact/confirmVote`, {
-            method: "POST",
-            headers: {
-              "Content-Type": "application/json",
-            },
-            body: JSON.stringify({
-              ...solvedPuzzle,
-              userId: storageResult.userId,
-              videoId,
-            }),
-          });
-        });
-      });
-  });
-}
-
-function register() {
-  let userId = generateUserID();
-  api.storage.sync.set({ userId });
-  return fetch(`${apiUrl}/puzzle/registration?userId=${userId}`, {
-    method: "GET",
-    headers: {
-      Accept: "application/json",
-    },
-  })
-    .then((response) => response.json())
-    .then((response) => {
-      return solvePuzzle(response).then((solvedPuzzle) => {
-        return fetch(`${apiUrl}/puzzle/registration?userId=${userId}`, {
-          method: "POST",
-          headers: {
-            "Content-Type": "application/json",
-          },
-          body: JSON.stringify(solvedPuzzle),
-        }).then((response) =>
-          response.json().then((result) => {
-            if (result === true) {
-              return api.storage.sync.set({ registrationConfirmed: true });
-            }
-          })
-        );
-      });
-    })
-    .catch();
-}
-
-api.storage.sync.get(null, (res) => {
-  if (!res || !res.userId || !res.registrationConfirmed) {
-    register();
-  }
-});
-
-const sentIds = new Set();
-let toSend = [];
-
-function sendUserSubmittedStatisticsToApi(statistics) {
-  fetch(`${apiUrl}/votes/user-submitted`, {
-    method: "POST",
-    headers: {
-      "Content-Type": "application/json",
-    },
-    body: JSON.stringify(statistics),
-  });
-}
-
-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);
-  let maxCount = Math.pow(2, puzzle.difficulty) * 5;
-  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))),
-      };
-    }
-  }
-}
-
-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;
-  }
-}
-
-function storageChangeHandler(changes, area) {
-  if (changes.disableVoteSubmission !== undefined) {
-    handleDisableVoteSubmissionChangeEvent(changes.disableVoteSubmission.newValue);
-  }
-}
-
-function handleDisableVoteSubmissionChangeEvent(value) {
-  extConfig.disableVoteSubmission = value;
-  if (value === true) {
-    changeIcon(voteDisabledIconName);
-  } else {
-    changeIcon(defaultIconName);
-  }
-}
-
-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');
-}
-
-api.storage.onChanged.addListener(storageChangeHandler);
-
-function initExtConfig() {
-  initializeDisableVoteSubmission();
-}
-
-function initializeDisableVoteSubmission() {
-  api.storage.sync.get(['disableVoteSubmission'], (res) => {
-    if (res.disableVoteSubmission === undefined) {
-      api.storage.sync.set({disableVoteSubmission: false});
-    }
-    else {
-      extConfig.disableVoteSubmission = res.disableVoteSubmission;
-      if (res.disableVoteSubmission) changeIcon(voteDisabledIconName);
-    }
-  });
-}
-
-function isChrome() {
-  return typeof chrome !== "undefined" && typeof chrome.runtime !== "undefined";
-}
-
-function isFirefox() {
-  return typeof browser !== "undefined" && typeof browser.runtime !== "undefined";
-}

+ 4 - 0
Extensions/combined/manifest-chrome.json

@@ -27,6 +27,10 @@
       "exclude_matches": ["*://*.music.youtube.com/*"],
       "js": ["bundled-content-script.js"],
       "css": ["content-style.css"]
+    },
+    {
+      "matches": ["*://*.returnyoutubedislike.com/debug","http://localhost/debug"],
+      "js": ["debug.js"]
     }
   ],
   "externally_connectable": {

+ 5 - 0
Extensions/combined/manifest-firefox.json

@@ -21,6 +21,11 @@
       "run_at": "document_idle",
       "css": ["content-style.css"],
       "js": ["bundled-content-script.js"]
+    },
+    {
+      "matches": ["*://*.returnyoutubedislike.com/debug","http://localhost/debug"],
+      "run_at": "document_idle",
+      "js": ["debug.js"]
     }
   ]
 }

+ 6 - 10
Extensions/combined/popup.js

@@ -4,16 +4,6 @@ const config = {
   showAdvancedMessage: "Show Settings",
   hideAdvancedMessage: "Hide Settings",
   disableVoteSubmission: false,
-}
-
- function initConfig() {
-  initializeVersionNumber();
-  }
-
- function initializeVersionNumber() {
-  const version = chrome.runtime.getManifest().version;
-  document.getElementById('ext-version').innerHTML = 'v' + version;
-}
   
   links: {
     website: "https://returnyoutubedislike.com",
@@ -70,6 +60,12 @@ initConfig();
 
 function initConfig() {
   initializeDisableVoteSubmission();
+  initializeVersionNumber();
+}
+
+function initializeVersionNumber() {
+  const version = chrome.runtime.getManifest().version;
+  document.getElementById('ext-version').innerHTML = 'v' + version;
 }
 
 function initializeDisableVoteSubmission() {

+ 5 - 5
Extensions/combined/src/events.js

@@ -43,7 +43,7 @@ function likeClicked() {
   if (checkForSignInButton() === false) {
     if (storedData.previousState === DISLIKED_STATE) {
       sendVote(1);
-      storedData.dislikes--;
+      if (storedData.dislikes > 0) storedData.dislikes--;
       storedData.likes++;
       createRateBar(storedData.likes, storedData.dislikes);
       setDislikes(numberFormat(storedData.dislikes));
@@ -55,7 +55,7 @@ function likeClicked() {
       storedData.previousState = LIKED_STATE;
     } else if ((storedData.previousState = LIKED_STATE)) {
       sendVote(0);
-      storedData.likes--;
+      if (storedData.likes > 0) storedData.likes--;
       createRateBar(storedData.likes, storedData.dislikes);
       storedData.previousState = NEUTRAL_STATE;
     }
@@ -72,13 +72,13 @@ function dislikeClicked() {
       storedData.previousState = DISLIKED_STATE;
     } else if (storedData.previousState === DISLIKED_STATE) {
       sendVote(0);
-      storedData.dislikes--;
+      if (storedData.dislikes > 0) storedData.dislikes--;
       setDislikes(numberFormat(storedData.dislikes));
       createRateBar(storedData.likes, storedData.dislikes);
       storedData.previousState = NEUTRAL_STATE;
     } else if (storedData.previousState === LIKED_STATE) {
       sendVote(-1);
-      storedData.likes--;
+      if (storedData.likes > 0) storedData.likes--;
       storedData.dislikes++;
       setDislikes(numberFormat(storedData.dislikes));
       createRateBar(storedData.likes, storedData.dislikes);
@@ -113,4 +113,4 @@ export {
   dislikeClicked,
   addLikeDislikeEventListener,
   storageChangeHandler,
-};
+};

+ 4 - 2
README.md

@@ -25,8 +25,7 @@ Additionally, the `dislike` field in the YouTube API was [removed](https://suppo
 
 ## What it Does
 
-With the removal of dislike stats from the YouTube API, our backend switched to using a combination of scraped dislike stats, estimates extrapolated from extension user data
-and estimates based on view\like ratios.
+With the removal of dislike stats from the YouTube API, our backend switched to using a combination of scraped dislike stats, estimates extrapolated from extension user data.
 
 [FAQ](https://github.com/Anarios/return-youtube-dislike/blob/main/FAQ.md)
 
@@ -66,6 +65,9 @@ Example to get votes of a given YouTube video ID:
 None existing YouTube ID will return status code *404* "Not Found".  
 Wrong formed YouTube ID will return *400* "Bad Request".
 
+You can view all documentation on our website.
+[https://returnyoutubedislike.com/documentation/](https://returnyoutubedislike.com/documentation/)
+
 ## HELP WANTED
 
 We have an issue that is happening to a low percentage of Chrome users. Service worker (ex background script) goes to Inactive state and doesn't wake up even when youtube tab is reopened. Only switching the extension off and on in your extensions tab will help. This looks like a Chrome manifestv3 bug - so if anyone knows of a good workaround - please open an issue\create a PR.

+ 6 - 20
Website/layouts/default.vue

@@ -31,26 +31,12 @@
 export default {
   data: () => ({
     links: [
-      {
-        name: "Home",
-        path: "/",
-      },
-      {
-        name: "Install",
-        path: "/install",
-      },
-      {
-        name: "FAQ",
-        path: "/faq",
-      },
-      {
-        name: "Donate",
-        path: "/donate",
-      },
-      {
-        name: "Links",
-        path: "/links",
-      },
+      { name: "Home", path: "/" },
+      { name: "Install", path: "/install" },
+      { name: "FAQ", path: "/faq" },
+      { name: "Donate", path: "/donate" },
+      { name: "Links", path: "/links" },
+      { name: "API", path: "/documentation" },
     ],
   }),
 };

+ 10 - 3
Website/nuxt.config.js

@@ -27,12 +27,18 @@ export default {
     ],
   },
 
+  env: {
+    apiUrl: "https://returnyoutubedislikeapi.com",
+  },
+
+  //server: { host: '0.0.0.0', port: 80 }, //LINE FOR DEBUGGING ONLY
+
   target: "static",
   css: [],
   plugins: [],
   components: true,
   buildModules: ["@nuxtjs/vuetify"],
-  modules: [],
+  modules: ["nuxt-user-agent"],
 
   // Vuetify module configuration: https://go.nuxtjs.dev/config-vuetify
   vuetify: {
@@ -52,7 +58,7 @@ export default {
       },
     },
   },
-
+  /*
   build: {
     extend(config, ctx) {
       // Run ESLint on save (dev-only)
@@ -65,5 +71,6 @@ export default {
         });
       }
     },
-  },
+  }
+*/
 };

+ 60 - 0
Website/package-lock.json

@@ -10,9 +10,11 @@
       "dependencies": {
         "core-js": "^3.15.1",
         "nuxt": "^2.15.7",
+        "nuxt-user-agent": "^1.2.2",
         "vuetify": "^2.5.5"
       },
       "devDependencies": {
+        "@nuxtjs/device": "^2.1.0",
         "@nuxtjs/vuetify": "^1.12.1",
         "babel-eslint": "^10.1.0",
         "eslint": "^7.32.0",
@@ -2643,6 +2645,21 @@
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
     },
+    "node_modules/@nuxtjs/device": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@nuxtjs/device/-/device-2.1.0.tgz",
+      "integrity": "sha512-TYBdt1w2bmCCWp+MhgcBATZtqyUBi3nSdNpcLGILw5USLwCsC/yZtIkq9YisuEzuRnod9w/RZpoE80MxLftEuA==",
+      "dev": true,
+      "dependencies": {
+        "defu": "^3.2.2"
+      }
+    },
+    "node_modules/@nuxtjs/device/node_modules/defu": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/defu/-/defu-3.2.2.tgz",
+      "integrity": "sha512-8UWj5lNv7HD+kB0e9w77Z7TdQlbUYDVWqITLHNqFIn6khrNHv5WQo38Dcm1f6HeNyZf0U7UbPf6WeZDSdCzGDQ==",
+      "dev": true
+    },
     "node_modules/@nuxtjs/vuetify": {
       "version": "1.12.1",
       "resolved": "https://registry.npmjs.org/@nuxtjs/vuetify/-/vuetify-1.12.1.tgz",
@@ -8914,6 +8931,14 @@
         "nuxt": "bin/nuxt.js"
       }
     },
+    "node_modules/nuxt-user-agent": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/nuxt-user-agent/-/nuxt-user-agent-1.2.2.tgz",
+      "integrity": "sha512-Z9d+r1/PzJAvrr4rX70IWvRyI3qw3RukAGrRZPZ9WeByuCWmVKiW8G1AhdkUOyrDrVoBUC59iLqIVkop/NjSuQ==",
+      "dependencies": {
+        "woothee": "^1.8.1"
+      }
+    },
     "node_modules/object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -14548,6 +14573,11 @@
         "node": ">=8"
       }
     },
+    "node_modules/woothee": {
+      "version": "1.11.1",
+      "resolved": "https://registry.npmjs.org/woothee/-/woothee-1.11.1.tgz",
+      "integrity": "sha512-KdArM3MsNa5tlSBSL29w9ouy9MXZoFPeUdPVnL4QZH3iyV8HsqnwbWw2YLiXEx2wAh0bM55dnl0+qDE6KHBlhQ=="
+    },
     "node_modules/word-wrap": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
@@ -16628,6 +16658,23 @@
         }
       }
     },
+    "@nuxtjs/device": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@nuxtjs/device/-/device-2.1.0.tgz",
+      "integrity": "sha512-TYBdt1w2bmCCWp+MhgcBATZtqyUBi3nSdNpcLGILw5USLwCsC/yZtIkq9YisuEzuRnod9w/RZpoE80MxLftEuA==",
+      "dev": true,
+      "requires": {
+        "defu": "^3.2.2"
+      },
+      "dependencies": {
+        "defu": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/defu/-/defu-3.2.2.tgz",
+          "integrity": "sha512-8UWj5lNv7HD+kB0e9w77Z7TdQlbUYDVWqITLHNqFIn6khrNHv5WQo38Dcm1f6HeNyZf0U7UbPf6WeZDSdCzGDQ==",
+          "dev": true
+        }
+      }
+    },
     "@nuxtjs/vuetify": {
       "version": "1.12.1",
       "resolved": "https://registry.npmjs.org/@nuxtjs/vuetify/-/vuetify-1.12.1.tgz",
@@ -21504,6 +21551,14 @@
         "@nuxt/webpack": "2.15.8"
       }
     },
+    "nuxt-user-agent": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/nuxt-user-agent/-/nuxt-user-agent-1.2.2.tgz",
+      "integrity": "sha512-Z9d+r1/PzJAvrr4rX70IWvRyI3qw3RukAGrRZPZ9WeByuCWmVKiW8G1AhdkUOyrDrVoBUC59iLqIVkop/NjSuQ==",
+      "requires": {
+        "woothee": "^1.8.1"
+      }
+    },
     "object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -25917,6 +25972,11 @@
         "string-width": "^4.0.0"
       }
     },
+    "woothee": {
+      "version": "1.11.1",
+      "resolved": "https://registry.npmjs.org/woothee/-/woothee-1.11.1.tgz",
+      "integrity": "sha512-KdArM3MsNa5tlSBSL29w9ouy9MXZoFPeUdPVnL4QZH3iyV8HsqnwbWw2YLiXEx2wAh0bM55dnl0+qDE6KHBlhQ=="
+    },
     "word-wrap": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",

+ 1 - 0
Website/package.json

@@ -12,6 +12,7 @@
   "dependencies": {
     "core-js": "^3.15.1",
     "nuxt": "^2.15.7",
+    "nuxt-user-agent": "^1.2.2",
     "vuetify": "^2.5.5"
   },
   "devDependencies": {

+ 68 - 0
Website/pages/debug.vue

@@ -0,0 +1,68 @@
+<template>
+  <div>
+    <!--   Top Section // "Sections" Card   -->
+    <v-card max-width="600px" class="rounded-lg">
+      <v-card-title style="padding-bottom: 0">Debug Information</v-card-title>
+      <v-card-text style="text-align: left">
+        <!--   Gather Browser Information   -->
+        <span><b>Browser Information:</b></span
+        ><br />
+        <span>Browser: {{ device._parsed.name }}</span
+        ><br />
+        <span>Browser Vendor: {{ device._parsed.vendor }}</span
+        ><br />
+        <span>Version: {{ device._parsed.version }}</span
+        ><br />
+        <span>Operating System: {{ device._parsed.os }}</span
+        ><br />
+        <span>Operating System Version: {{ device._parsed.os_version }}</span
+        ><br />
+        <span>Device Type: {{ device._parsed.category }}</span
+        ><br /><br />
+        <!--   Gather Extension Information   -->
+        <span><b>Installed Extension Information:</b></span
+        ><br />
+        <span
+          >Extension Version:
+          <span id="extension-version">Waiting For Extension...</span></span
+        ><br />
+      </v-card-text>
+      <v-card-actions>
+        <v-spacer />
+        <v-btn @click="copy()">
+          <v-icon small style="margin-right: 0.25em">mdi-content-copy</v-icon
+          >Copy
+        </v-btn>
+      </v-card-actions>
+    </v-card>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      device: this.$ua,
+    };
+  },
+
+  methods: {
+    copy() {
+      const toCopy = `\`\`\`
+Browser Information:
+Browser: ${this.device._parsed.name}
+Browser Vendor: ${this.device._parsed.vendor}
+Version: ${this.device._parsed.version}
+Operating System: ${this.device._parsed.os}
+Operating System Version: ${this.device._parsed.os_version}
+Device Type: ${this.device._parsed.category}
+
+Installed Extension Information:
+Extension Version: ${document.getElementById("extension-version").innerHTML}
+\`\`\``;
+
+      navigator.clipboard.writeText(toCopy);
+    },
+  },
+};
+</script>

+ 60 - 0
Website/pages/documentation.vue

@@ -0,0 +1,60 @@
+<template>
+  <div>
+    <!--   Top Section // "Sections" Card   -->
+    <v-card max-width="600px" class="rounded-lg">
+      <v-card-title style="padding-bottom: 0">Sections</v-card-title>
+      <v-list>
+        <!--   Dynamically Generate Links From Below   -->
+        <v-list-item v-for="(item, i) in links" :key="i" router :to="item.to">
+          <v-list-item-icon>
+            <v-icon v-text="item.icon" />
+          </v-list-item-icon>
+          <v-list-item-title style="text-align: left">
+            <v-list-item-title v-text="item.text" />
+          </v-list-item-title>
+        </v-list-item>
+      </v-list>
+    </v-card>
+
+    <!--   Child Pages // Card   -->
+    <v-card
+      max-width="600px"
+      class="rounded-lg"
+      style="margin: 1em; padding: 0.75em; text-align: left"
+    >
+      <NuxtChild />
+    </v-card>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      //---   Links To Generate Above    ---//
+      links: [
+        {
+          text: "Usage Rights",
+          icon: "mdi-book-open-variant",
+          to: "/documentation/usage-rights",
+        },
+        {
+          text: "URL Information",
+          icon: "mdi-web",
+          to: "/documentation/url",
+        },
+        {
+          text: "Available Endpoints",
+          icon: "mdi-transit-connection-variant",
+          to: "/documentation/endpoints",
+        },
+        {
+          text: "Basic Fetching Tutorial",
+          icon: "mdi-school",
+          to: "/documentation/fetching",
+        },
+      ],
+    };
+  },
+};
+</script>

+ 19 - 0
Website/pages/documentation/endpoints.vue

@@ -0,0 +1,19 @@
+<template>
+  <div>
+    <h1 class="primary--text">Available Endpoints</h1>
+    List of available endpoints is available here:<br />
+    <a :href="endpointUrl" target="_blank" v-text="endpointUrl" />
+  </div>
+</template>
+
+<script>
+let apiUrl = process.env.apiUrl;
+export default {
+  data() {
+    return {
+      apiUrl: apiUrl,
+      endpointUrl: apiUrl + "/swagger/index.html",
+    };
+  },
+};
+</script>

+ 78 - 0
Website/pages/documentation/fetching.vue

@@ -0,0 +1,78 @@
+<template>
+  <div>
+    <h1 class="primary--text">Basic Fetching Tutorial</h1>
+
+    <span>Example to get votes of a given YouTube video ID:</span>
+    <a href="https://youtube.com/watch?v=kxOuG8jMIgI" target="_blank"
+      >kxOuG8jMIgI</a
+    ><br /><br />
+
+    <h2>Example Request:</h2>
+    <span><b>Request URL:</b></span>
+    <a
+      :href="apiUrl + '/votes?videoId=kxOuG8jMIgI'"
+      target="_blank"
+      v-text="apiUrl + '/votes?videoId=kxOuG8jMIgI'"
+    /><br />
+    <span
+      ><b>Request Method:</b>
+      <a
+        href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET"
+        target="_blank"
+        >HTTP/GET</a
+      ></span
+    ><br />
+    <span><b>Headers:</b></span
+    ><br />
+    <code class="code">
+      Accept: text/html,application/xhtml+xml,application/xml;q=0.9<br />
+      Pragma: no-cache<br />
+      Cache-Control: no-cache<br />
+      Connection: keep-alive </code
+    ><br />
+    <span><b>Response:</b></span
+    ><br />
+    <div class="code">
+      <code style="background-color: rgba(0, 0, 0, 0)">
+        {<br />
+        "id": "kxOuG8jMIgI",<br />
+        "dateCreated": "2021-12-20T12:25:54.418014Z",<br />
+        "likes": 27326,<br />
+        "dislikes": 498153,<br />
+        "rating": 1.212014408444885,<br />
+        "viewCount": 3149885,<br />
+        "deleted": false<br />
+        }
+      </code>
+    </div>
+    <br /><br />
+    <v-alert border="left" color="orange" text type="info">
+      <span>An invalid YouTube ID will return status code 404 "Not Found".</span
+      ><br />
+      <span
+        >An incorrectly formatted YouTube ID will return 400 "Bad
+        Request".</span
+      >
+    </v-alert>
+
+    <a :href="endpointUrl" target="_blank" v-text="endpointUrl" />
+  </div>
+</template>
+
+<style scoped>
+.code {
+  width: 100%;
+  background: #353535;
+  border-radius: 3px;
+}
+</style>
+
+<script>
+export default {
+  data() {
+    return {
+      apiUrl: process.env.apiUrl,
+    };
+  },
+};
+</script>

+ 8 - 0
Website/pages/documentation/index.vue

@@ -0,0 +1,8 @@
+<template>
+  <div>
+    <h1>
+      Welcome to the <span class="primary--text">official RYD docs</span>!
+    </h1>
+    <p>To get started, select a section.</p>
+  </div>
+</template>

+ 17 - 0
Website/pages/documentation/url.vue

@@ -0,0 +1,17 @@
+<template>
+  <div>
+    <h1 class="primary--text">URL Information</h1>
+    The API is accessible over the following base URL:<br />
+    <a :href="apiUrl" target="_blank" v-text="apiUrl" />
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      apiUrl: process.env.apiUrl,
+    };
+  },
+};
+</script>

+ 30 - 0
Website/pages/documentation/usage-rights.vue

@@ -0,0 +1,30 @@
+<template>
+  <div>
+    <h1 class="primary--text">Usage Rights</h1>
+    <p>
+      Third party use of this open API is allowed with the following
+      restrictions:
+    </p>
+    <ul>
+      <li>
+        <b>Attribution:</b> This project should be clearly attributed with
+        either a link to this repo or a link to returnyoutubedislike.com.
+      </li>
+      <li>
+        <b>Rate Limiting:</b> There are per client rate limits in place of 100
+        per minute and 10'000 per day. This will return a 429 status code
+        indicating that your application should back off.
+      </li>
+    </ul>
+  </div>
+</template>
+
+<style scoped>
+li {
+  margin-top: 0.5em;
+}
+
+b {
+  font-weight: 900 !important;
+}
+</style>

+ 3 - 2
Website/pages/faq.vue

@@ -49,8 +49,9 @@ export default {
           "The extension collects the video ID of the video you are watching, fetches the dislike (and other fields like views, likes etc) using our API. The extension then displays the dislike count and ratio on the page. If you like or dislike a video, that is recorded and sent to the database so an accurate dislike count can be extrapolated.",
       },
       {
-        question:
-        "Can I share my dislike count with you?",
+
+        question:"Can I share my dislike count with you?",
+
         answer:
           "Coming soon. We are looking into using Oauth or a different read only API with a limited scope so creators can share their dislike counts verifiability. ",
       },

+ 8 - 2
Website/pages/index.vue

@@ -97,8 +97,14 @@ export default {
         { name: "Piepacker", link: "https://piepacker.com/" },
         { name: "nodetube", link: "https://github.com/mayeaux/nodetube" },
         { name: "trig404" },
-        { name: "Peter33", link: "https://www.youtube.com/watch?v=G5kzUpWAusI" },
-        { name: "Seed4.Me VPN", link: "https://www.seed4.me/users/register?gift=ReturnYoutubeDislike" },
+        {
+          name: "Peter33",
+          link: "https://www.youtube.com/watch?v=G5kzUpWAusI",
+        },
+        {
+          name: "Seed4.Me VPN",
+          link: "https://www.seed4.me/users/register?gift=ReturnYoutubeDislike",
+        },
       ],
     };
   },