YouTube - Force Compact Grid (increases max # videos per row)

Force YouTube to show compact grid (max 6 videos per row) rather than "slim" grid (max 3 videos per row)

2023-02-02 या दिनांकाला. सर्वात नवीन आवृत्ती पाहा.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         YouTube - Force Compact Grid (increases max # videos per row)
// @namespace    https://gist.github.com/lbmaian/8c6961584c0aebf41ee7496609f60bc3
// @version      0.1
// @description  Force YouTube to show compact grid (max 6 videos per row) rather than "slim" grid (max 3 videos per row)
// @author       lbmaian
// @match        https://www.youtube.com/*
// @exclude      https://www.youtube.com/embed/*
// @icon         https://www.youtube.com/favicon.ico
// @run-at       document-start
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const DEBUG = false;

    const logContext = '[YouTube - Force Compact Grid]';

    var debug;
    if (DEBUG) {
        debug = function(...args) {
            console.debug(logContext, ...args);
        };
    } else {
        debug = function() {};
    }

    function log(...args) {
        console.log(logContext, ...args);
    }

    function info(...args) {
        console.info(logContext, ...args);
    }

    function warn(...args) {
        console.warn(logContext, ...args);
    }

    function error(...args) {
        console.error(logContext, ...args);
    }

    function updateResponseData(response, label) {
        const tabs = response?.contents?.twoColumnBrowseResultsRenderer?.tabs;
        debug(label, 'contents.twoColumnBrowseResultsRenderer.tabs', tabs);
        if (tabs) {
            for (const tab of tabs) {
                const tabRenderer = tab.tabRenderer;
                if (tabRenderer) {
                    const richGridRenderer = tabRenderer.content?.richGridRenderer;
                    if (richGridRenderer && richGridRenderer.style == 'RICH_GRID_STYLE_SLIM') {
                        log(label, 'tab', tabRenderer.title, 'tabRenderer.content.richGridRenderer.style:', richGridRenderer.style, '=> RICH_GRID_STYLE_COMPACT');
                        richGridRenderer.style = 'RICH_GRID_STYLE_COMPACT';
                    }
                }
            }
        }
    }

    // Note: Both of the following event listeners are too late:
    // ytd-app's own yt-page-data-fetched event listener (onYtPageDataFetched) already fires
    // by the time our own yt-page-data-fetched event listener fires,
    // and yt-page-data-fetched fires before yt-navigate-finish fires

    // document.addEventListener('yt-page-data-fetched', evt => {
    //     debug('Navigated to', evt.detail.pageData.url);
    //     debug(evt);
    //     updateResponseData(evt.detail.pageData.response, 'yt-page-data-fetched pageData.response');
    // });

    // document.addEventListener('yt-navigate-finish', evt => {
    //     debug('Navigated to', evt.detail.response.url);
    //     debug(evt);
    //     updateResponseData(evt.detail.response.response, 'yt-navigate-finish response.response');
    // });

    document.addEventListener('DOMContentLoaded', evt => {
        // Handle the initial page
        debug('ytInitialData', window.ytInitialData);
        updateResponseData(window.ytInitialData, 'ytInitialData');

        // Handle changing tabs (e.g. 'videos' or 'live' tab)
        // Need to hook into ytd-app's ytd-app's own yt-page-data-fetched event listener (onYtPageDataFetched),
        // so that we can modify the data before that event listener fires
        const ytdApp = document.getElementsByTagName('ytd-app')[0];
        debug('ytd-app', ytdApp);
        if (!ytdApp) {
            error('unexpectedly could not find ytd-app after page load');
            return;
        }
        const origOnYtPageDataFetched = ytdApp.onYtPageDataFetched;
        ytdApp.onYtPageDataFetched = function(evt, detail) {
            debug('Navigated to', detail.pageData.url);
            debug(evt);
            updateResponseData(evt.detail.pageData.response, 'yt-page-data-fetched pageData.response');
            return origOnYtPageDataFetched.call(this, evt, detail);
        };
    });
})();