fix: sync server-rendered watchlist state to client

This commit is contained in:
2026-05-26 20:29:19 +02:00
parent 749a275dc0
commit 50159286b4
5 changed files with 46 additions and 4 deletions

View File

@@ -58,3 +58,13 @@ body {
background-color: var(--color-background);
color: var(--text);
}
[data-watchlist-toggle] .watchlist-icon,
[data-watchlist-toggle] .watchlist-icon path {
fill: none;
}
[data-watchlist-toggle][data-watchlist-state='in'] .watchlist-icon,
[data-watchlist-toggle][data-watchlist-state='in'] .watchlist-icon path {
fill: currentColor;
}

View File

@@ -66,6 +66,7 @@ const syncIconsForId = (id: number): void => {
const malId = toInt(button.dataset.malId);
if (malId !== id) return;
button.classList.toggle('in-watchlist', shouldBeInWatchlist);
button.dataset.watchlistState = shouldBeInWatchlist ? 'in' : 'out';
button.setAttribute(
'aria-label',
shouldBeInWatchlist ? 'Remove from Watchlist' : 'Add to Watchlist'
@@ -109,8 +110,18 @@ const closeClosestDropdown = (from: HTMLElement): void => {
});
};
const toggleWatchlist = async (id: number, title: string): Promise<void> => {
const toggleWatchlist = async (
id: number,
title: string,
renderedState: string | undefined
): Promise<void> => {
if (inflight.has(id)) return;
if (renderedState === 'in') {
watchlistIds.add(id);
} else if (renderedState === 'out') {
watchlistIds.delete(id);
}
const isInWatchlist = watchlistIds.has(id);
setBusy(id, true);
@@ -250,6 +261,20 @@ const initWatchlist = (ids: number[]): void => {
});
};
const getRenderedWatchlistIds = (): number[] => {
const ids = new Set<number>();
document
.querySelectorAll<HTMLElement>('[data-watchlist-toggle][data-watchlist-state="in"][data-mal-id]')
.forEach(button => {
const id = toInt(button.dataset.malId);
if (id === null) return;
ids.add(id);
});
return Array.from(ids);
};
const onReady = (fn: () => void): void => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', fn, { once: true });
@@ -272,7 +297,7 @@ const installDelegatedHandlers = (): void => {
const id = toInt(toggleButton.getAttribute('data-mal-id') ?? undefined);
if (id === null) return;
const title = toggleButton.getAttribute('data-watchlist-title') ?? 'anime';
void toggleWatchlist(id, title);
void toggleWatchlist(id, title, toggleButton.dataset.watchlistState);
return;
}
@@ -322,5 +347,10 @@ onReady(() => {
}
}
const renderedWatchlistIds = getRenderedWatchlistIds();
if (renderedWatchlistIds.length > 0) {
initWatchlist(renderedWatchlistIds);
}
installDelegatedHandlers();
});