Last active
April 29, 2024 23:58
-
-
Save c6p/463892bb243f611f2a3cfa4268c6435e to your computer and use it in GitHub Desktop.
Reddit Multi Column
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Reddit Multi Column | |
// @namespace https://gist.github.com/c6p/463892bb243f611f2a3cfa4268c6435e | |
// @version 0.1.15 | |
// @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; | |
// https://codepen.io/jpkempf/pen/MbePGB | |
function debounce(fn, wait) { | |
var timeout; | |
return function() { | |
var context = this; | |
var args = arguments; | |
clearTimeout(timeout); | |
timeout = setTimeout(function() { | |
fn.apply(context, args); | |
}, wait); | |
}; | |
} | |
const OUTER = '#SHORTCUT_FOCUSABLE_DIV > div > div > div > div > div:nth-child(2) > div:last-child' | |
const cardButton = () => document.querySelector('#layoutSwitch--card') // old | |
|| document.querySelector('#LayoutSwitch--picker > span:nth-child(2)') // new | |
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 select = function() { | |
let outer = document.querySelector(OUTER) | |
let inner = outer !== null ? outer.firstChild.firstChild : null | |
if (window.location.pathname === '/original/') // fix for OC | |
{ | |
inner = outer.firstChild.firstChild.lastChild.previousSibling | |
} | |
else | |
{ | |
while (inner.childElementCount <= 5) { | |
inner = inner.nextSibling | |
} | |
} | |
return { outer, inner }; | |
} | |
const makeLayout = function(changes=[]) { | |
// TODO if changes not empty, update only changed | |
const { outer, inner } = select(); | |
if (inner === null) return; | |
const c = cleanup; | |
if (c) { | |
outer.style = 'max-width: 100%' | |
outer.firstChild.removeAttribute("style"); | |
inner.removeAttribute("style"); | |
} else { | |
outer.style = 'width: 100%; max-width: 100%'; | |
outer.firstChild.style = 'width: 100%; max-width: 100%'; | |
inner.setAttribute("style", "width: 100%; position: relative;"); | |
} | |
const cols = Math.floor(inner.offsetWidth / MIN_WIDTH); | |
//if (changes.length === 0 && cols === columns) return; | |
columns = cols; | |
const WIDTH = Math.floor((100-columns)/columns); | |
let posts = inner.children; | |
let heights = Array(columns).fill(0); | |
for (let i=0; i<posts.length; i++) { | |
const post = posts[i]; | |
const col = indexOfSmallest(heights); | |
let s = post.style | |
s.position = c ? "" : "absolute"; | |
s.width = c ? "" : `${WIDTH}%`; | |
s.left = c ? "" : `${col*(WIDTH+1)}%`; | |
s.top = c ? "" : `${heights[col]}px`; | |
s.zIndex = "10"; | |
heights[col] += post.offsetHeight; | |
} | |
inner.style.height = c ? "" : `${Math.max(...heights)}px`; | |
}; | |
const setLayout = function(changes, observer) { | |
const button = cardButton(); | |
const c = button.nodeName === "BUTTON" | |
? button.getAttribute("aria-pressed") === "false" // old | |
: button.textContent !== "card" // new | |
console.warn(c) | |
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) { | |
const { inner } = select(); | |
if (inner === null) return; | |
pageChange.observe(inner, {childList: true}); | |
layoutSwitch.observe(cardButton(), {attributes: true, subtree: true, characterData: true}); | |
}; | |
const apply = new MutationObserver(watch); | |
const page = document.querySelector('#SHORTCUT_FOCUSABLE_DIV'); | |
apply.observe(page, {childList: true, subtree: true}); | |
//watch(); | |
setLayout(); | |
window.requestAnimationFrame(makeLayout); | |
})(); |
@dmax511 I've looked into it, but Twitter is cycling element content with scroll position. It is possible, however very hard, with this approach. So I can't make any promises.
ok thanks for looking into it
it doesn't seem to work anymore. Is there a fix for it ?
it doesn't seem to work anymore. Is there a fix for it ?
I started using this userscript Reddit 2023 Ui Revert to forward www.reddit.com to new.reddit.com, then add:
// @match https://new.reddit.com/*
to the top of Reddit Multi Column script and it will work again
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
could you do this for twitter?