Greasy Fork is available in English.

Reddit Multi Column

Multi column layout for reddit redesign

// ==UserScript==
// @name         Reddit Multi Column
// @namespace    https://gist.github.com/c6p/463892bb243f611f2a3cfa4268c6435e
// @version      0.2.0
// @description  Multi column layout for reddit redesign
// @author       Can Altıparmak
// @homepageURL  https://gist.github.com/c6p/463892bb243f611f2a3cfa4268c6435e
// @match        https://www.reddit.com/*
// @grant        none
// ==/UserScript==
/* jshint esversion: 6 */

(function() {
    'use strict';
    const MIN_WIDTH = 400;
    const COLUMNS = 4;
    let columns = COLUMNS;
    let cleanup = null;

    let parent = null;
    const cardIcon = () => document?.querySelector('shreddit-sort-dropdown[header-text="View"]')?.shadowRoot?.querySelector('svg');
    const shouldClean =(icon) => icon === undefined ? false : icon.getAttribute('icon-name') !== "view-card-outline";
    cleanup = shouldClean()

    const indexOfSmallest = function (a) {
        let lowest = 0;
        for (let i = 1; i<a.length; i++) {
            if (a[i] < a[lowest]) lowest = i;
        }
        return lowest;
    };

    const makeLayout = function(changes=[]) {
        if (cleanup) return;
        if (!parent) return;

        document.getElementById("main-content").style.maxWidth = "100%";
        document.querySelector("div.subgrid-container").classList.remove("m:w-[1120px]") // make wide
        document.getElementById("right-sidebar-container").style.display = "none" // hide sidebar
        parent.style.position = "relative"

        const cols = Math.floor(parent.offsetWidth / MIN_WIDTH);
        columns = cols;
        const WIDTH = Math.floor((100-columns)/columns);

        let heights = Array(columns).fill(0);

        for (const article of parent.querySelectorAll("article, faceplate-partial").values()) {
            const col = indexOfSmallest(heights);
            article.setAttribute("style", cleanup ? "" : `position:absolute; width:${WIDTH}%; top:${heights[col]}px; left:${col*(WIDTH+1)}%`)
            heights[col] += article.offsetHeight;
        }
    };

    const setLayout = function(changes, observer) {
        const c = shouldClean(cardIcon());
        if (c !== cleanup) {
            cleanup = c;
            window.requestAnimationFrame(makeLayout)
        }
    };

    const pageChange = new MutationObserver(makeLayout);
    window.addEventListener('resize', makeLayout);
    const layoutSwitch = new MutationObserver(setLayout);

    const watch = function(changes, observer) {
        parent = document.querySelector("article + hr + faceplate-partial").parentNode
        if (parent === null) return;
        pageChange.observe(parent, {childList: true});
        const timeout = setTimeout(() => {
            const icon = cardIcon();
            if (icon !== undefined) {
                clearTimeout(timeout);
                layoutSwitch.observe(icon, {attributes: true});
            }
        })
        window.requestAnimationFrame(makeLayout);
    };

    const apply = new MutationObserver(watch);
    const app = document.querySelector("shreddit-app")
    apply.observe(app, {attributes: true});
    watch();
})();