|
@@ -2,7 +2,7 @@
|
|
|
// @name Return YouTube Dislike
|
|
|
// @namespace https://www.returnyoutubedislike.com/
|
|
|
// @homepage https://www.returnyoutubedislike.com/
|
|
|
-// @version 0.9.0
|
|
|
+// @version 3.0.0
|
|
|
// @encoding utf-8
|
|
|
// @description Return of the YouTube Dislike, Based off https://www.returnyoutubedislike.com/
|
|
|
// @icon https://github.com/Anarios/return-youtube-dislike/raw/main/Icons/Return%20Youtube%20Dislike%20-%20Transparent.png
|
|
@@ -22,6 +22,21 @@
|
|
|
// @grant GM_addStyle
|
|
|
// @run-at document-end
|
|
|
// ==/UserScript==
|
|
|
+
|
|
|
+const extConfig = {
|
|
|
+// BEGIN USER OPTIONS
|
|
|
+// You may change the following variables to allowed values listed in the corresponding brackets (* means default). Keep the style and keywords intact.
|
|
|
+ showUpdatePopup: false, // [true, false*] Show a popup tab after extension update (See what's new)
|
|
|
+ disableVoteSubmission: false, // [true, false*] Disable like/dislike submission (Stops counting your likes and dislikes)
|
|
|
+ coloredThumbs: false, // [true, false*] Colorize thumbs (Use custom colors for thumb icons)
|
|
|
+ coloredBar: false, // [true, false*] Colorize ratio bar (Use custom colors for ratio bar)
|
|
|
+ colorTheme: "classic", // [classic*, accessible, neon] Color theme (red/green, blue/yellow, pink/cyan)
|
|
|
+ numberDisplayFormat: "compactShort", // [compactShort*, compactLong, standard] Number format (For non-English locale users, you may be able to improve appearance with a different option. Please file a feature request if your locale is not covered)
|
|
|
+ numberDisplayRoundDown: true, // [true*, false] Round down numbers (Show rounded down numbers)
|
|
|
+ numberDisplayReformatLikes: false, // [true, false*] Re-format like numbers (Make likes and dislikes format consistent)
|
|
|
+// END USER OPTIONS
|
|
|
+};
|
|
|
+
|
|
|
const LIKED_STATE = "LIKED_STATE";
|
|
|
const DISLIKED_STATE = "DISLIKED_STATE";
|
|
|
const NEUTRAL_STATE = "NEUTRAL_STATE";
|
|
@@ -82,6 +97,36 @@ function getDislikeButton() {
|
|
|
return getButtons().children[1];
|
|
|
}
|
|
|
|
|
|
+let mutationObserver = new Object();
|
|
|
+
|
|
|
+if (isShorts() && mutationObserver.exists !== true) {
|
|
|
+ cLog('initializing mutation observer')
|
|
|
+ mutationObserver.options = {
|
|
|
+ childList: false,
|
|
|
+ attributes: true,
|
|
|
+ subtree: false
|
|
|
+ };
|
|
|
+ mutationObserver.exists = true;
|
|
|
+ mutationObserver.observer = new MutationObserver( function(mutationList, observer) {
|
|
|
+ mutationList.forEach( (mutation) => {
|
|
|
+ if (mutation.type === 'attributes' &&
|
|
|
+ mutation.target.nodeName === 'TP-YT-PAPER-BUTTON' &&
|
|
|
+ mutation.target.id === 'button') {
|
|
|
+ cLog('Short thumb button status changed');
|
|
|
+ if (mutation.target.getAttribute('aria-pressed') === 'true') {
|
|
|
+ mutation.target.style.color =
|
|
|
+ (mutation.target.parentElement.parentElement.id === 'like-button') ?
|
|
|
+ getColorFromTheme(true) : getColorFromTheme(false);
|
|
|
+ } else {
|
|
|
+ mutation.target.style.color = 'unset';
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ cLog('unexpected mutation observer event: ' + mutation.target + mutation.type);
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
function isVideoLiked() {
|
|
|
if (isMobile) {
|
|
|
return (
|
|
@@ -154,6 +199,19 @@ function setDislikes(dislikesCount) {
|
|
|
getButtons().children[1].querySelector("#text").innerText = dislikesCount;
|
|
|
}
|
|
|
|
|
|
+function getLikeCountFromButton() {
|
|
|
+ if (isShorts()) {
|
|
|
+ //Youtube Shorts don't work with this query. It's not nessecary; we can skip it and still see the results.
|
|
|
+ //It should be possible to fix this function, but it's not critical to showing the dislike count.
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ let likesStr = getLikeButton()
|
|
|
+ .querySelector("button")
|
|
|
+ .getAttribute("aria-label")
|
|
|
+ .replace(/\D/g, "");
|
|
|
+ return likesStr.length > 0 ? parseInt(likesStr) : false;
|
|
|
+}
|
|
|
+
|
|
|
(typeof GM_addStyle != "undefined"
|
|
|
? GM_addStyle
|
|
|
: (styles) => {
|
|
@@ -205,6 +263,13 @@ function createRateBar(likes, dislikes) {
|
|
|
likes + dislikes > 0 ? (likes / (likes + dislikes)) * 100 : 50;
|
|
|
|
|
|
if (!rateBar && !isMobile) {
|
|
|
+ let colorLikeStyle = "";
|
|
|
+ let colorDislikeStyle = "";
|
|
|
+ if (extConfig.coloredBar) {
|
|
|
+ colorLikeStyle = "; background-color: " + getColorFromTheme(true);
|
|
|
+ colorDislikeStyle = "; background-color: " + getColorFromTheme(false);
|
|
|
+ }
|
|
|
+
|
|
|
document.getElementById("menu-container").insertAdjacentHTML(
|
|
|
"beforeend",
|
|
|
`
|
|
@@ -212,11 +277,11 @@ function createRateBar(likes, dislikes) {
|
|
|
<div class="ryd-tooltip-bar-container">
|
|
|
<div
|
|
|
id="return-youtube-dislike-bar-container"
|
|
|
- style="width: 100%; height: 2px;"
|
|
|
+ style="width: 100%; height: 2px;${colorDislikeStyle}"
|
|
|
>
|
|
|
<div
|
|
|
id="return-youtube-dislike-bar"
|
|
|
- style="width: ${widthPercent}%; height: 100%"
|
|
|
+ style="width: ${widthPercent}%; height: 100%${colorDislikeStyle}"
|
|
|
></div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -236,6 +301,13 @@ function createRateBar(likes, dislikes) {
|
|
|
document.querySelector(
|
|
|
"#ryd-dislike-tooltip > #tooltip"
|
|
|
).innerHTML = `${likes.toLocaleString()} / ${dislikes.toLocaleString()}`;
|
|
|
+
|
|
|
+ if (extConfig.coloredBar) {
|
|
|
+ document.getElementById("return-youtube-dislike-bar-container").style.backgroundColor =
|
|
|
+ getColorFromTheme(false);
|
|
|
+ document.getElementById("return-youtube-dislike-bar").style.backgroundColor =
|
|
|
+ getColorFromTheme(true);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -253,7 +325,30 @@ function setState() {
|
|
|
likesvalue = likes;
|
|
|
dislikesvalue = dislikes;
|
|
|
setDislikes(numberFormat(dislikes));
|
|
|
+ if (extConfig.numberDisplayReformatLikes === true) {
|
|
|
+ const nativeLikes = getLikeCountFromButton();
|
|
|
+ if (nativeLikes !== false) {
|
|
|
+ setLikes(numberFormat(nativeLikes));
|
|
|
+ }
|
|
|
+ }
|
|
|
createRateBar(likes, dislikes);
|
|
|
+ if (extConfig.coloredThumbs === true) {
|
|
|
+ if (isShorts()) { // for shorts, leave deactived buttons in default color
|
|
|
+ let shortLikeButton = getLikeButton().querySelector('tp-yt-paper-button#button');
|
|
|
+ let shortDislikeButton = getDislikeButton().querySelector('tp-yt-paper-button#button');
|
|
|
+ if (shortLikeButton.getAttribute('aria-pressed') === 'true') {
|
|
|
+ shortLikeButton.style.color = getColorFromTheme(true);
|
|
|
+ }
|
|
|
+ if (shortDislikeButton.getAttribute('aria-pressed') === 'true') {
|
|
|
+ shortDislikeButton.style.color = getColorFromTheme(false);
|
|
|
+ }
|
|
|
+ mutationObserver.observer.observe(shortLikeButton, mutationObserver.options);
|
|
|
+ mutationObserver.observer.observe(shortDislikeButton, mutationObserver.options);
|
|
|
+ } else {
|
|
|
+ getLikeButton().style.color = getColorFromTheme(true);
|
|
|
+ getDislikeButton().style.color = getColorFromTheme(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
});
|
|
|
});
|
|
@@ -347,14 +442,73 @@ function numberFormat(numberState) {
|
|
|
?.getAttribute("href")
|
|
|
)?.searchParams?.get("locale");
|
|
|
} catch {}
|
|
|
+
|
|
|
+ let numberDisplay;
|
|
|
+ if (extConfig.numberDisplayRoundDown === false) {
|
|
|
+ numberDisplay = numberState;
|
|
|
+ } else {
|
|
|
+ numberDisplay = roundDown(numberState);
|
|
|
+ }
|
|
|
+ return getNumberFormatter(extConfig.numberDisplayFormat).format(
|
|
|
+ numberDisplay
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+function getNumberFormatter(optionSelect) {
|
|
|
+ let formatterNotation;
|
|
|
+ let formatterCompactDisplay;
|
|
|
+
|
|
|
+ switch (optionSelect) {
|
|
|
+ case "compactLong":
|
|
|
+ formatterNotation = "compact";
|
|
|
+ formatterCompactDisplay = "long";
|
|
|
+ break;
|
|
|
+ case "standard":
|
|
|
+ formatterNotation = "standard";
|
|
|
+ formatterCompactDisplay = "short";
|
|
|
+ break;
|
|
|
+ case "compactShort":
|
|
|
+ default:
|
|
|
+ formatterNotation = "compact";
|
|
|
+ formatterCompactDisplay = "short";
|
|
|
+ }
|
|
|
+
|
|
|
const formatter = Intl.NumberFormat(
|
|
|
document.documentElement.lang || userLocales || navigator.language,
|
|
|
{
|
|
|
- notation: "compact",
|
|
|
+ notation: formatterNotation,
|
|
|
+ compactDisplay: formatterCompactDisplay,
|
|
|
}
|
|
|
);
|
|
|
+ return formatter;
|
|
|
+}
|
|
|
|
|
|
- return formatter.format(roundDown(numberState));
|
|
|
+function getColorFromTheme(voteIsLike) {
|
|
|
+ let colorString;
|
|
|
+ switch (extConfig.colorTheme) {
|
|
|
+ case "accessible":
|
|
|
+ if (voteIsLike === true) {
|
|
|
+ colorString = "dodgerblue";
|
|
|
+ } else {
|
|
|
+ colorString = "gold";
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case "neon":
|
|
|
+ if (voteIsLike === true) {
|
|
|
+ colorString = "aqua";
|
|
|
+ } else {
|
|
|
+ colorString = "magenta";
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case "classic":
|
|
|
+ default:
|
|
|
+ if (voteIsLike === true) {
|
|
|
+ colorString = "lime";
|
|
|
+ } else {
|
|
|
+ colorString = "red";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return colorString;
|
|
|
}
|
|
|
|
|
|
function setEventListeners(evt) {
|