import { useCallback, useState } from "react"; import type { AppEntry } from "./menuEntries.js"; /** * Tracks the favorite state the user has changed while the menu is open. * * The changes are applied optimistically on top of the article rows and rolled * back if the handler rejects. The overrides are kept for the lifetime of the * menu, since the article list is only loaded the first time it is opened and * would otherwise show a stale state the second time around. */ export function useFavorites(onToggleFavorite?: (id: string, favorite: boolean) => void | Promise) { let [overrides, setOverrides] = useState>({}); let applyOverrides = useCallback( (entries: AppEntry[]) => { if (Object.keys(overrides).length === 0) return entries; return entries.map((entry) => (entry.id in overrides ? { ...entry, isFavorite: overrides[entry.id] } : entry)); }, [overrides], ); let toggleFavorite = useCallback( async (id: string, favorite: boolean) => { setOverrides((current) => ({ ...current, [id]: favorite })); try { await onToggleFavorite?.(id, favorite); } catch (error) { console.error(error); setOverrides((current) => ({ ...current, [id]: !favorite })); } }, [onToggleFavorite], ); return { applyOverrides, toggleFavorite: onToggleFavorite ? toggleFavorite : undefined }; }