tilde.club/tilde.js

66 lines
1.9 KiB
JavaScript

(() => {
/* DOM */
const ascii = document.getElementById('pref-ascii');
const force = document.getElementById('pref-force');
const themeRadios = document.getElementsByName('pref-theme');
const bodyClass = document.body.classList;
/* localStorage management */
const lsn = "~ddb:"; // localStorage namespace
const getPref = (pref) => localStorage.getItem(lsn + pref);
const setPref = (pref, value) => localStorage.setItem(lsn + pref, value);
const getPrefs = () => ({
prefASCII: getPref('ascii') === 'true',
prefForce: getPref('force') === 'true',
prefTheme: getPref('theme') || 'dark',
});
/* Update the state of the document based on client preferences. */
const renderPreferences = () => {
const { prefASCII, prefForce, prefTheme } = getPrefs();
if(prefASCII) {
bodyClass.add('ascii');
ascii.checked = "checked";
}
if(prefForce) {
bodyClass.add(prefTheme);
force.checked = "checked";
}
themeRadios.forEach(radio => {
if(radio.value === prefTheme) {
radio.checked = true;
}
});
};
renderPreferences();
/* ASCII aesthetic intensifies */
ascii.onchange = (evt) => {
const { prefASCII } = getPrefs();
bodyClass.toggle('ascii');
setPref('ascii', (!prefASCII).toString());
};
/* Manage theme forcing behavior */
const themes = Array.from(themeRadios).map(radio => radio.value);
force.onchange = () => {
const { prefForce, prefTheme } = getPrefs();
const nextForce = !prefForce;
themes.forEach(theme => bodyClass.remove(theme));
if (nextForce) {
bodyClass.add(prefTheme);
}
setPref('force', nextForce.toString())
};
/* Manage theme selection */
themeRadios.forEach(radio => radio.onchange = () => {
const { prefForce } = getPrefs();
setPref('theme', radio.value);
if(prefForce) {
themes.forEach(theme => bodyClass.remove(theme));
bodyClass.add(radio.value);
}
});
})()