Raw Source
AUser0 / Dislike Estimator

'use strict';
// ==UserScript==
// @name         Dislike Estimator
// @description  Estimates the number of dislikes on a YouTube video
// @version      1.1
// @author       AUser0
// @match        https://www.youtube.com/*
// @grant        none
// @updateURL    https://github.com/Jekabs123/DislikeEstimator/raw/master/main.user.js
// @downloadURL  https://github.com/Jekabs123/DislikeEstimator/raw/master/main.user.js
// @require https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js
// @namespace    mailto:auser0@jekabs.dev
// @license GPL-3.0-or-later
// ==/UserScript==

const prcTotalReactions = 3; // Average percent of people who like or dislike the video
const prcRandomDislikes = 0.25; // There is always that someone who dislikes the video for no reason

// Don't change anything below unless you know what you are doing.

window.addEventListener('load', function () {
    estimateDislikes();
});

function estimateDislikes() {
    try {
        const dBtn = $('#top-level-buttons-computed ytd-toggle-button-renderer:eq(1) a yt-formatted-string')[0]; // Find the dislike element

        let amtLikes = $('#top-level-buttons-computed ytd-toggle-button-renderer:eq(0) a yt-formatted-string')[0].ariaLabel.replace(/\,/g, "").replace(/\./g, ""); // Find the amount of likes

        if (!isInteger(amtLikes)) { // When the amount of likes is more than 1000
            const regex = /([+-]?(?=\.\d|\d)(?:\d+)?(?:\.?\d*))(?:[eE]([+-]?\d+))?/i;
            const match = regex.exec(amtLikes);
            if (match != null) {
                amtLikes = Number(match[0]);
            }
        }
        const amtViews = $(".view-count")[0].innerText.replace(" ", " ").split(" ")[0].replace(/\,/g, "").replace(/\./g, ""); // Find the amount of views
        let estDislikes = (amtViews * prcTotalReactions / 100) - amtLikes;
        if (estDislikes < 0) {
            estDislikes = 0;
        }
        estDislikes += Math.ceil(amtViews * prcRandomDislikes / 100);
        let estDislikesStr = Math.round(estDislikes);
        if (estDislikes >= 1000000) {
            estDislikesStr = `${Math.round(estDislikes / 1000000)}M`;
        }
        else if (estDislikes >= 1000) {
            estDislikesStr = `${Math.round(estDislikes / 1000)}k`;
        }
        dBtn.innerText = estDislikesStr;

        setLikeBar(amtLikes, estDislikes);
    } catch (e) {}
    setTimeout(estimateDislikes, 1000);
}

function setLikeBar(amtLikes, amtDislikes) {
    // Adding a likebar
    const likebarWidth = $("#top-level-buttons-computed").children()[0].clientWidth + $("#top-level-buttons-computed").children()[1].clientWidth + 6;
    const likeBar = `
    <ytd-sentiment-bar-renderer id="sentiment" class="style-scope ytd-video-primary-info-renderer" system-icons="" style="width: ${likebarWidth}px">
    <div id="like-bar" class="style-scope ytd-sentiment-bar-renderer"</div>
    </div>
    <tp-yt-paper-tooltip position="top" class="style-scope ytd-sentiment-bar-renderer" role="tooltip" tabindex="-1">
    <div id="tooltip" class="style-scope tp-yt-paper-tooltip">
     
    </div>
    </tp-yt-paper-tooltip>
    </ytd-sentiment-bar-renderer>`;
    $("#sentiment")[0].outerHTML = likeBar;
    const likeRatio = (amtLikes / (amtLikes + amtDislikes)) * 100;
    $("#like-bar").css("width", `${likeRatio}%`);
}

function isInteger(value) {
    return /^\d+$/.test(value);
}