mirror of
https://github.com/nafnlj/nljfeeds.git
synced 2024-11-13 21:37:52 +00:00
114 lines
3.3 KiB
JavaScript
114 lines
3.3 KiB
JavaScript
closeAccordionByIds(getClosedAccordionIdsFromStorage());
|
|
handleAllClickEvents();
|
|
renderBuildTimestamp();
|
|
renderWeekday();
|
|
|
|
/**
|
|
* ====== UTILS ======
|
|
**/
|
|
|
|
function getClosedAccordionIdsFromPage() {
|
|
/**
|
|
* @type {HTMLDetailsElement[]}
|
|
*/
|
|
const accordions = [...document.querySelectorAll("[data-accordion-key]")];
|
|
const ids = accordions
|
|
.filter((element) => !element.open)
|
|
.map((element) => element.getAttribute("data-accordion-key"));
|
|
return [...new Set(ids)];
|
|
}
|
|
|
|
function closeAccordionByIds(ids) {
|
|
ids.forEach((id) => {
|
|
const element = document.querySelector(`[data-accordion-key="${id}"]`);
|
|
if (element) element.open = false;
|
|
});
|
|
}
|
|
|
|
function storeClosedAccordionIds(ids) {
|
|
localStorage.setItem("closedAccordionIds", JSON.stringify(ids));
|
|
}
|
|
|
|
function getClosedAccordionIdsFromStorage() {
|
|
const stateString = localStorage.getItem("closedAccordionIds");
|
|
try {
|
|
const parsed = JSON.parse(stateString);
|
|
if (!parsed?.length) return [];
|
|
return parsed;
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a few event handlers as possible to ensure healthy performance scaling
|
|
*/
|
|
function handleAllClickEvents() {
|
|
document.addEventListener("click", (event) => {
|
|
// Activate daily title as expanders
|
|
const action = event.target.closest("[data-action]");
|
|
if (action) {
|
|
switch (action.getAttribute("data-action")) {
|
|
case "toggle-accordions":
|
|
handleToggleAccordions(event);
|
|
break;
|
|
case "toggle-native-accordion":
|
|
handleToggleNativeAccordion(event);
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @param {KeyboardEvent=} event
|
|
*/
|
|
function handleToggleAccordions(event) {
|
|
// when ctrl is held, toggle every accordion in the document
|
|
const scope = event?.ctrlKey ? document : event.target.closest(".js-toggle-accordions-scope");
|
|
const detailsElements = [...scope.querySelectorAll("details")];
|
|
const isAnyOpen = detailsElements.some((element) => element.open);
|
|
detailsElements.forEach((element) => (element.open = !isAnyOpen));
|
|
|
|
storeClosedAccordionIds(getClosedAccordionIdsFromPage());
|
|
}
|
|
|
|
/**
|
|
* @param {KeyboardEvent=} event
|
|
*/
|
|
function handleToggleNativeAccordion() {
|
|
// wait until event settled
|
|
setTimeout(() => storeClosedAccordionIds(getClosedAccordionIdsFromPage()), 0);
|
|
}
|
|
|
|
/**
|
|
* Convert machine readable timestamp to locale time
|
|
*/
|
|
function renderBuildTimestamp() {
|
|
const timestamp = document.getElementById("build-timestamp");
|
|
timestamp.innerText = new Date(timestamp.getAttribute("datetime")).toLocaleString();
|
|
}
|
|
|
|
/**
|
|
* Convert the server timestamp to human readable weekday and dates.
|
|
* Note: the server is responsible for shifting the date based on config file.
|
|
* The client should parse the date as if it is in UTC timezone.
|
|
*/
|
|
function renderWeekday() {
|
|
document.querySelectorAll(".js-offset-weekday").forEach((element) => {
|
|
const weekday = new Date(element.getAttribute("data-offset-date")).toLocaleString(window.navigator.language, {
|
|
weekday: "long",
|
|
timeZone: "UTC",
|
|
});
|
|
element.innerText = weekday;
|
|
});
|
|
document.querySelectorAll(".js-offset-date").forEach((element) => {
|
|
const date = new Date(element.getAttribute("data-offset-date")).toLocaleString(window.navigator.language, {
|
|
month: "numeric",
|
|
day: "numeric",
|
|
timeZone: "UTC",
|
|
});
|
|
element.innerText = date;
|
|
});
|
|
}
|