import { useEffect, useMemo, useState } from 'react'; import { isNewer } from '@/utils/componentHelpers/appUpdaterHelpers'; import { fetchRegistry, getCachedRegistry, type Registry, type RegistryTheme } from '@/utils/themes/themeRegistry'; import { useInstalledThemesStore } from '@/store/installedThemesStore'; // Refresh the registry from source once per app launch (not just from the // cache). This surfaces newly published themes and updates without the user // having to hit the manual refresh in the Theme Store, and it feeds the // sidebar update notice. Subsequent reads this session use the cache. let sessionRefreshStarted = false; /** * Registry entries for installed community themes that have a newer version * available. Returns the full registry theme (css path, version, metadata) so a * caller can update in place. Seeds from the last-cached registry synchronously, * then revalidates (forced on the first call this session). Recomputes when the * installed set changes, so the list shrinks as the user updates themes. */ export function useThemeUpdates(): RegistryTheme[] { const installed = useInstalledThemesStore(s => s.themes); const [registry, setRegistry] = useState(() => getCachedRegistry()); useEffect(() => { let alive = true; const opts = sessionRefreshStarted ? undefined : { force: true }; sessionRefreshStarted = true; fetchRegistry(opts) .then(r => { if (alive) setRegistry(r.registry); }) .catch(() => { /* offline: keep whatever the cache gave us */ }); return () => { alive = false; }; }, []); return useMemo(() => { if (!registry) return []; const installedVersionById = new Map(installed.map(t => [t.id, t.version])); return registry.themes.filter(rt => { const current = installedVersionById.get(rt.id); return current != null && isNewer(rt.version, current); }); }, [registry, installed]); } /** * Stable signature of an update set, used to remember a dismissal: the sidebar * notice stays hidden until a new or bumped update changes this string. */ export function themeUpdateSignature(updates: Array<{ id: string; version: string }>): string { return updates.map(u => `${u.id}@${u.version}`).sort().join(','); }