refactor: migrate from htmx:afterSwap to onHtmxLoad

This commit is contained in:
2026-06-06 16:51:12 +02:00
parent 392bc10b99
commit 78b36452ae
4 changed files with 25 additions and 27 deletions

View File

@@ -20,6 +20,7 @@ import {
displayTimeFromAbsolute, displayTimeFromAbsolute,
} from "./timeline"; } from "./timeline";
import { formatTime } from "./controls"; import { formatTime } from "./controls";
import { onHtmxLoad, onReady } from "../utils";
let currentContainer: HTMLElement | null = null; let currentContainer: HTMLElement | null = null;
let cleanup: (() => void) | null = null; let cleanup: (() => void) | null = null;
@@ -113,10 +114,9 @@ const initPlayer = (): void => {
}; };
// build video src from mode, token, and saved quality preference // build video src from mode, token, and saved quality preference
// Only set if not already provided by the inline script during HTML parsing
const preferredQuality = safeLocalStorage.getItem("mal:preferred-quality") || "best"; const preferredQuality = safeLocalStorage.getItem("mal:preferred-quality") || "best";
const streamToken = state.modeSources[state.currentMode]?.token; const streamToken = state.modeSources[state.currentMode]?.token;
if (!state.video.src && streamToken) { if (streamToken) {
state.video.src = `${state.streamURL}?mode=${encodeURIComponent(state.currentMode)}&token=${encodeURIComponent(streamToken)}${preferredQuality !== "best" ? `&quality=${encodeURIComponent(preferredQuality)}` : ""}`; state.video.src = `${state.streamURL}?mode=${encodeURIComponent(state.currentMode)}&token=${encodeURIComponent(streamToken)}${preferredQuality !== "best" ? `&quality=${encodeURIComponent(preferredQuality)}` : ""}`;
} }
@@ -205,8 +205,6 @@ const initPlayer = (): void => {
}; };
state.video.addEventListener("loadedmetadata", onLoadedMetadata, { signal }); state.video.addEventListener("loadedmetadata", onLoadedMetadata, { signal });
// inline script runs during HTML parsing before initPlayer; if metadata
// already loaded, fire the handler immediately
if (state.video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) { if (state.video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
onLoadedMetadata(); onLoadedMetadata();
} }
@@ -389,10 +387,11 @@ const initPlayer = (): void => {
setupThumbnails(); setupThumbnails();
}; };
document.addEventListener("DOMContentLoaded", initPlayer); onReady(initPlayer);
document.body.addEventListener("htmx:afterSwap", (e: Event) => { onHtmxLoad((root) => {
const target = (e as CustomEvent).detail?.target as HTMLElement | null; if (root.matches("[data-video-player]") || root.querySelector("[data-video-player]")) {
if (target?.querySelector("[data-video-player]")) initPlayer(); initPlayer();
}
}); });
document.body.addEventListener("htmx:beforeSwap", (e: Event) => { document.body.addEventListener("htmx:beforeSwap", (e: Event) => {

View File

@@ -1,3 +1,4 @@
import { onHtmxLoad, onReady } from "./utils";
import { isJstTimezone, normalizeWeekday, parseHHMM } from "./shared/broadcast"; import { isJstTimezone, normalizeWeekday, parseHHMM } from "./shared/broadcast";
export {}; export {};
@@ -328,13 +329,13 @@ const buildBoard = (section: HTMLElement): void => {
}; };
const initScheduleBoard = (): void => { const initScheduleBoard = (): void => {
const run = (): void => { const run = (root: ParentNode): void => {
const sections = document.querySelectorAll<HTMLElement>("[data-schedule-section]"); const sections = root.querySelectorAll<HTMLElement>("[data-schedule-section]");
sections.forEach(buildBoard); sections.forEach(buildBoard);
}; };
document.addEventListener("DOMContentLoaded", run); onReady(() => run(document));
document.body.addEventListener("htmx:afterSwap", run); onHtmxLoad((root) => run(root));
}; };
initScheduleBoard(); initScheduleBoard();

View File

@@ -7,6 +7,8 @@ import {
export {}; export {};
import { onHtmxLoad } from "./utils";
interface ParsedBroadcast { interface ParsedBroadcast {
day: string; day: string;
hour: number; hour: number;
@@ -188,16 +190,14 @@ const updateNode = (node: Element, localOffsetMinutes: number): void => {
updateNextAiring(node, parsed); updateNextAiring(node, parsed);
}; };
const updateAll = (): void => { const updateAll = (root: ParentNode): void => {
const localOffsetMinutes = -new Date().getTimezoneOffset(); const localOffsetMinutes = -new Date().getTimezoneOffset();
const nodes = document.querySelectorAll("[data-jst-text]"); const nodes = root.querySelectorAll("[data-jst-text]");
nodes.forEach((node) => updateNode(node, localOffsetMinutes)); nodes.forEach((node) => updateNode(node, localOffsetMinutes));
}; };
const initTimezoneConversion = (): void => { const initTimezoneConversion = (): void => {
// run on initial load and after htmx swaps (content may change) onHtmxLoad((root) => updateAll(root));
document.addEventListener("DOMContentLoaded", updateAll);
document.body.addEventListener("htmx:afterSwap", updateAll);
}; };
initTimezoneConversion(); initTimezoneConversion();

View File

@@ -24,8 +24,8 @@ const getTopPickCarousel = (root: HTMLElement): TopPickCarousel | null => {
return { track, previous, next, previousFade, nextFade }; return { track, previous, next, previousFade, nextFade };
}; };
const topPickCarousels = (): HTMLElement[] => const topPickCarousels = (root: ParentNode = document): HTMLElement[] =>
Array.from(document.querySelectorAll<HTMLElement>("[data-top-pick-carousel]")); Array.from(root.querySelectorAll<HTMLElement>("[data-top-pick-carousel]"));
const maxScrollLeft = (track: HTMLElement): number => const maxScrollLeft = (track: HTMLElement): number =>
Math.max(0, track.scrollWidth - track.clientWidth); Math.max(0, track.scrollWidth - track.clientWidth);
@@ -56,8 +56,8 @@ const updateTopPickCarousel = (root: HTMLElement): void => {
carousel.nextFade.classList.toggle("hidden", !hasNext); carousel.nextFade.classList.toggle("hidden", !hasNext);
}; };
const updateTopPickCarousels = (): void => { const updateTopPickCarousels = (root: ParentNode = document): void => {
topPickCarousels().forEach(updateTopPickCarousel); topPickCarousels(root).forEach(updateTopPickCarousel);
}; };
const carouselScrollAmount = (track: HTMLElement): number => { const carouselScrollAmount = (track: HTMLElement): number => {
@@ -145,9 +145,7 @@ document.addEventListener(
true, true,
); );
document.addEventListener("DOMContentLoaded", updateTopPickCarousels); onReady(() => updateTopPickCarousels());
document.addEventListener("htmx:afterSwap", updateTopPickCarousels); onHtmxLoad((root) => updateTopPickCarousels(root));
document.addEventListener("htmx:afterSettle", updateTopPickCarousels); window.addEventListener("resize", () => updateTopPickCarousels());
window.addEventListener("resize", updateTopPickCarousels); import { onHtmxLoad, onReady } from "./utils";
updateTopPickCarousels();