diff options
Diffstat (limited to 'Extensions/UserScript/Return Youtube Dislike.user.js')
-rw-r--r-- | Extensions/UserScript/Return Youtube Dislike.user.js | 122 |
1 files changed, 71 insertions, 51 deletions
diff --git a/Extensions/UserScript/Return Youtube Dislike.user.js b/Extensions/UserScript/Return Youtube Dislike.user.js index 47ddaac..a0a6df0 100644 --- a/Extensions/UserScript/Return Youtube Dislike.user.js +++ b/Extensions/UserScript/Return Youtube Dislike.user.js @@ -4,7 +4,7 @@ // @version 0.5 // @description Return of the YouTube Dislike, Based off https://www.returnyoutubedislike.com/ // @author Anarios & JRWR -// @match *://*.youtube.com/watch* +// @match *://*.youtube.com/* // @compatible chrome // @compatible firefox // @compatible opera @@ -16,36 +16,12 @@ // ==/UserScript== function cLog(text, subtext = '') { subtext = subtext.trim() === '' ? '' : `(${subtext})`; - console.log(`[Return Youtube Dislikes] ${text} ${subtext}`); -} - -function doXHR(opts) { - if (typeof GM_xmlhttpRequest === 'function') { - return GM_xmlhttpRequest(opts); - } - if (typeof GM !== 'undefined') /*This will prevent from throwing "Uncaught ReferenceError: GM is not defined"*/{ - if (typeof GM.xmlHttpRequest === 'function') { - return GM.xmlHttpRequest(opts); - } - } - - console.warn('Unable to detect UserScript plugin, falling back to native XHR.'); - - const xhr = new XMLHttpRequest(); - - xhr.open(opts.method, opts.url, true); - xhr.onload = () => opts.onload({ - response: JSON.parse(xhr.responseText), - }); - xhr.onerror = err => console.error('XHR Failed', err); - xhr.send(); + console.log(`[Return YouTube Dislikes] ${text} ${subtext}`); } function getButtons() { if (document.getElementById("menu-container").offsetParent === null) { - return document.querySelector( - "ytd-menu-renderer.ytd-watch-metadata > div" - ); + return document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div"); } else { return document .getElementById("menu-container") @@ -96,9 +72,7 @@ function setDislikes(dislikesCount) { } function createRateBar(likes, dislikes) { - var rateBar = document.getElementById( - "return-youtube-dislike-bar-container" - ); + var rateBar = document.getElementById("return-youtube-dislike-bar-container"); const widthPx = getButtons().children[0].clientWidth + @@ -144,32 +118,46 @@ function createRateBar(likes, dislikes) { } function setState() { - cLog('Fetching votes...'); - - doXHR({ - method: "GET", - responseType: "json", - url: - "https://return-youtube-dislike-api.azurewebsites.net/votes?videoId=" + - getVideoId(), - onload: function (xhr) { - if (xhr != undefined) { - const { dislikes, likes } = xhr.response; + cLog("Fetching votes..."); + let statsSet = false; + + fetch(`https://www.youtube.com/watch?v=${getVideoId()}`).then((response) => { + response.text().then((text) => { + let result = getDislikesFromYoutubeResponse(text); + if (result) { + cLog("response from youtube:"); + cLog(JSON.stringify(result)); + if (result.likes || result.dislikes) { + const formattedDislike = numberFormat(result.dislikes); + setDislikes(formattedDislike); + createRateBar(result.likes, result.dislikes); + statsSet = true; + } + } + }); + }); + + fetch( + `https://return-youtube-dislike-api.azurewebsites.net/votes?videoId=${getVideoId()}` + ).then((response) => { + response.json().then((json) => { + if (json && !statsSet) { + const { dislikes, likes } = json; cLog(`Received count: ${dislikes}`); setDislikes(numberFormat(dislikes)); createRateBar(likes, dislikes); } - }, + }); }); } function likeClicked() { - cLog('Like clicked', getState()); + cLog("Like clicked", getState()); setState(); } function dislikeClicked() { - cLog('Dislike clicked', getState()); + cLog("Dislike clicked", getState()); setState(); } @@ -194,21 +182,53 @@ function isVideoLoaded() { function roundDown(num) { if (num < 1000) return num; - const decimal = Math.floor(Math.log10(num) - 1); + const int = Math.floor(Math.log10(num) - 2); + const decimal = int + (int % 3 ? 1 : 0); const value = Math.floor(num / 10 ** decimal); - return value * (10 ** decimal); + return value * 10 ** decimal; } function numberFormat(numberState) { const userLocales = navigator.language; const formatter = Intl.NumberFormat(userLocales, { - notation: 'compact', + notation: "compact", minimumFractionDigits: 1, - maximumFractionDigits: 1 + maximumFractionDigits: 1, }); - return formatter.format(roundDown(numberState)).replace('.0', ''); + return formatter.format(roundDown(numberState)).replace(/\.0|,0/, ""); +} + +function getDislikesFromYoutubeResponse(htmlResponse) { + let start = + htmlResponse.indexOf('"videoDetails":') + '"videoDetails":'.length; + let end = + htmlResponse.indexOf('"isLiveContent":false}', start) + + '"isLiveContent":false}'.length; + if (end < start) { + end = + htmlResponse.indexOf('"isLiveContent":true}', start) + + '"isLiveContent":true}'.length; + } + let jsonStr = htmlResponse.substring(start, end); + let jsonResult = JSON.parse(jsonStr); + let rating = jsonResult.averageRating; + + start = htmlResponse.indexOf('"topLevelButtons":[', end); + start = + htmlResponse.indexOf('"accessibilityData":', start) + + '"accessibilityData":'.length; + end = htmlResponse.indexOf("}", start); + let likes = +htmlResponse.substring(start, end).replace(/\D/g, ""); + let dislikes = (likes * (5 - rating)) / (rating - 1); + let result = { + likes, + dislikes: Math.round(dislikes), + rating, + viewCount: +jsonResult.viewCount, + }; + return result; } function setEventListeners(evt) { @@ -218,7 +238,7 @@ function setEventListeners(evt) { const buttons = getButtons(); if (!window.returnDislikeButtonlistenersSet) { - cLog('Registering button listeners...'); + cLog("Registering button listeners..."); buttons.children[0].addEventListener("click", likeClicked); buttons.children[1].addEventListener("click", dislikeClicked); window.returnDislikeButtonlistenersSet = true; @@ -228,7 +248,7 @@ function setEventListeners(evt) { } if (window.location.href.indexOf("watch?") >= 0) { - cLog('Setting up...'); + cLog("Setting up..."); var jsInitChecktimer = setInterval(checkForJS_Finish, 111); } } |