sourcehypertextpubliclinkrolldecorate.js

function init() {
	if (localStorage["linkroll-theme"]) {
		swapTheme(localStorage["linkroll-theme"], false);
	}

	colourEntries();

	$$("#tag-navbar button[data-tag-slug]").forEach(el => {
		el.$(".tag-entry-count").innerText = $$(
			`#grid .entry.${el.dataset.tagSlug}`
		).length;
	});

	$(".press-your-luck").on("click", () => {
		const links = $("#grid").$$('a[href^="http"]');
		window.location.href =
			links[Math.floor(Math.random() * links.length)].href;
	});

	drawBarChart();
}

function showAll() {
	for (const entry of $$(".entry:not(#description)")) {
		entry.style.display = "inline-block";
	}
	$("#description").style.display = "none";
	colourEntries();
}

function showTag(tag, hue) {
	for (const entry of $$(".entry:not(#description)")) {
		entry.style.display = entry.classList.contains(tag)
			? "inline-block"
			: "none";
	}

	$("#description").style.display = "inline-block";
	for (const entry of $$(`#description .entry-text:not(.${tag})`)) {
		entry.style.display = "none";
	}
	$(`#description .entry-text.${tag}`).style.display = "block";

	colourEntries(tag == "new" ? 0 : hue);
}

function colourEntries(baseHue = 0) {
	// Change up the hues for the entries!
	$$(".entry").forEach(el => {
		if (el.style.display !== "none") {
			const entryHue =
				(330 * el.offsetTop) / $("#grid").clientHeight -
				(120 * el.offsetLeft) / $("#grid").clientWidth +
				baseHue;
			el.style.setProperty("--accent-hue", `${entryHue}`);
		}
	});
}

function drawBarChart() {
	const dates = [...$$("div.dates")].map(
		el => +el.innerText.match(/Created( c\.)? ([0-9]{4})/)[2]
	);

	const minDate = Math.min(...dates);
	const minDecade = Math.floor(minDate / 10);
	const maxDate = Math.max(...dates);
	const maxDecade = Math.floor(maxDate / 10);
	const decadeRange = 1 + maxDecade - minDecade;

	let dateStats = [];

	for (let year = minDate; year <= maxDate; year++) {
		dateStats.push({
			year: year,
			sites: dates.filter(el => el == year).length,
			decadeHue: (360 * (Math.floor(year / 10) - minDecade)) / decadeRange
		});
	}

	const barChart = $("#bar-chart");
	const chartHeight = barChart.getBoundingClientRect().height;
	const effectiveChartHeight = chartHeight - 15;
	const chartWidth = barChart.getBoundingClientRect().width;
	const maxSitesPerYear = Math.max(...dateStats.map(el => el.sites));

	dateStats.forEach((el, idx) => {
		barChart.innerHTML += `<rect x="${
			(idx * chartWidth) / dateStats.length
		}" y="${
			effectiveChartHeight * (1 - el.sites / maxSitesPerYear)
		}" height="${
			(effectiveChartHeight * el.sites) / maxSitesPerYear
		}" width="${chartWidth / dateStats.length}" fill="hsla(${
			el.decadeHue
		}, 80%, 80%, ${idx % 2 ? "0.8" : "1"})"><title>${el.year} (${
			el.sites
		} ${el.sites == 1 ? "site" : "sites"})</title></rect>`;
	});

	for (let decade = minDecade * 10; decade <= maxDecade * 10; decade += 10) {
		const midpoint =
			(((Math.max(minDate, decade) + Math.min(1 + maxDate, decade + 10)) /
				2 -
				minDate) *
				chartWidth) /
			(1 + maxDate - minDate);
		barChart.innerHTML += `<text text-anchor="middle" x="${midpoint}" y="${
			chartHeight - 2
		}">${decade}s</text>`;
	}
}

function swapTheme(themeName, colour = true) {
	localStorage.setItem("linkroll-theme", themeName);
	$("html").setAttribute("class", themeName);

	if (colour) {
		colourEntries();
	}
}

document.on("DOMContentLoaded", init);