diff options
| author | Fuwn <[email protected]> | 2026-04-15 01:18:00 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-04-15 01:18:00 +0000 |
| commit | d06a7a9bb689849b2b7beced2606ceb98513f4bb (patch) | |
| tree | 8f54fc3fa12c70b21bf4bf421608c9b9400064da /src | |
| parent | feat(command-palette): add clear anime and manga list caches action (diff) | |
| download | due.moe-d06a7a9bb689849b2b7beced2606ceb98513f4bb.tar.xz due.moe-d06a7a9bb689849b2b7beced2606ceb98513f4bb.zip | |
feat(cache): instant list revalidation from command palette and debug menu
Replaces one-shot boolean revalidateAnime with a counter store so
multiple components can subscribe without race conditions. Adds
revalidateManga store and reactive refresh blocks to DueAnimeList
and MangaListTemplate. Extracts shared invalidateListCaches function
used by both the command palette action and the debug settings button.
Renames palette item to "Refresh" and debug button to "Invalidate".
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/CommandPalette/actions.ts | 31 | ||||
| -rw-r--r-- | src/lib/List/Anime/CleanAnimeList.svelte | 2 | ||||
| -rw-r--r-- | src/lib/List/Anime/DueAnimeList.svelte | 22 | ||||
| -rw-r--r-- | src/lib/List/Anime/UpcomingAnimeList.svelte | 36 | ||||
| -rw-r--r-- | src/lib/List/Manga/MangaListTemplate.svelte | 22 | ||||
| -rw-r--r-- | src/lib/Locale/english.ts | 2 | ||||
| -rw-r--r-- | src/lib/Locale/japanese.ts | 2 | ||||
| -rw-r--r-- | src/lib/Media/invalidate.ts | 18 | ||||
| -rw-r--r-- | src/lib/Settings/Categories/Debug.svelte | 16 | ||||
| -rw-r--r-- | src/stores/revalidateAnime.ts | 2 | ||||
| -rw-r--r-- | src/stores/revalidateManga.ts | 5 |
11 files changed, 106 insertions, 52 deletions
diff --git a/src/lib/CommandPalette/actions.ts b/src/lib/CommandPalette/actions.ts index 48603504..9915fe66 100644 --- a/src/lib/CommandPalette/actions.ts +++ b/src/lib/CommandPalette/actions.ts @@ -1,7 +1,4 @@ -import { browser } from "$app/environment"; -import localforage from "localforage"; -import { addNotification } from "$lib/Notification/store"; -import { options } from "$lib/Notification/options"; +import { invalidateListCaches } from "$lib/Media/invalidate"; export interface CommandPaletteAction { name: string; @@ -171,21 +168,19 @@ export const defaultActions: CommandPaletteAction[] = [ tags: ["user", "me", "settings"], }, { - name: "Clear Anime & Manga List Caches", + name: "Refresh Anime & Manga List Caches", url: "", preventDefault: true, - tags: ["cache", "clear", "refresh", "debug", "anime", "manga", "list"], - onClick: async () => { - if (!browser) return; - - await localforage.removeItem("anime"); - await localforage.removeItem("manga"); - - addNotification( - options({ - heading: "Anime and manga list caches successfully cleared", - }), - ); - }, + tags: [ + "cache", + "clear", + "refresh", + "invalidate", + "debug", + "anime", + "manga", + "list", + ], + onClick: invalidateListCaches, }, ]; diff --git a/src/lib/List/Anime/CleanAnimeList.svelte b/src/lib/List/Anime/CleanAnimeList.svelte index 808a8e5b..35a12314 100644 --- a/src/lib/List/Anime/CleanAnimeList.svelte +++ b/src/lib/List/Anime/CleanAnimeList.svelte @@ -193,7 +193,7 @@ onDestroy(() => clearAiringRefreshTimeout()); const increment = (anime: Media, progress: number) => { if (!dummy && pendingUpdate !== anime.id) { - $revalidateAnime = true; + $revalidateAnime = $revalidateAnime + 1; lastUpdatedMedia = anime.id; pendingUpdate = anime.id; diff --git a/src/lib/List/Anime/DueAnimeList.svelte b/src/lib/List/Anime/DueAnimeList.svelte index 2c707ffb..d2c47ebe 100644 --- a/src/lib/List/Anime/DueAnimeList.svelte +++ b/src/lib/List/Anime/DueAnimeList.svelte @@ -16,6 +16,7 @@ import { import { addNotification } from "$lib/Notification/store"; import locale from "$stores/locale"; import identity from "$stores/identity"; +import revalidateAnime from "$stores/revalidateAnime"; export let user: AniListAuthorisation; let animeLists: Promise<Media[]>; @@ -68,6 +69,27 @@ onMount(async () => { $: if (keyCacher && keyCacheMinutes !== $settings.cacheMinutes) restartKeyCacher($settings.cacheMinutes); +let lastAnimeRevalidation = 0; + +$: if ($revalidateAnime > lastAnimeRevalidation) { + lastAnimeRevalidation = $revalidateAnime; + + startTime = performance.now(); + endTime = -1; + + animeLists = mediaListCollection( + user, + $identity, + Type.Anime, + $anime, + $lastPruneTimes.anime, + { + forcePrune: true, + addNotification, + }, + ); +} + onDestroy(() => { if (keyCacher) clearInterval(keyCacher); }); diff --git a/src/lib/List/Anime/UpcomingAnimeList.svelte b/src/lib/List/Anime/UpcomingAnimeList.svelte index d9b91122..ed47f22f 100644 --- a/src/lib/List/Anime/UpcomingAnimeList.svelte +++ b/src/lib/List/Anime/UpcomingAnimeList.svelte @@ -96,22 +96,26 @@ const cleanMedia = ( return upcomingAnime; }; -$: { - if ($revalidateAnime) { - $revalidateAnime = false; - $lastPruneTimes.anime = -1; - animeLists = mediaListCollection( - user, - $identity, - Type.Anime, - $anime, - $lastPruneTimes.anime, - { - addNotification, - notificationType: "Upcoming Episodes", - }, - ); - } +let lastAnimeRevalidation = 0; + +$: if ($revalidateAnime > lastAnimeRevalidation) { + lastAnimeRevalidation = $revalidateAnime; + + startTime = performance.now(); + endTime = -1; + + animeLists = mediaListCollection( + user, + $identity, + Type.Anime, + $anime, + $lastPruneTimes.anime, + { + forcePrune: true, + addNotification, + notificationType: "Upcoming Episodes", + }, + ); } </script> diff --git a/src/lib/List/Manga/MangaListTemplate.svelte b/src/lib/List/Manga/MangaListTemplate.svelte index 52649098..df894910 100644 --- a/src/lib/List/Manga/MangaListTemplate.svelte +++ b/src/lib/List/Manga/MangaListTemplate.svelte @@ -19,6 +19,7 @@ import identity from "$stores/identity"; import lastPruneTimes from "$stores/lastPruneTimes"; import locale from "$stores/locale"; import manga from "$stores/manga"; +import revalidateManga from "$stores/revalidateManga"; import settings from "$stores/settings"; import ListTitle from "../ListTitle.svelte"; import CleanMangaList from "./CleanMangaList.svelte"; @@ -141,6 +142,27 @@ $: if ( ) restartKeyCacher(Math.max($settings.cacheMangaMinutes, 5)); +let lastMangaRevalidation = 0; + +$: if (!dummy && $revalidateManga > lastMangaRevalidation) { + lastMangaRevalidation = $revalidateManga; + + startTime = performance.now(); + endTime = -1; + + mangaLists = mediaListCollection( + user, + $identity, + Type.Manga, + $manga, + $lastPruneTimes.manga, + { + forcePrune: true, + addNotification, + }, + ); +} + onDestroy(() => { if (keyCacher) clearInterval(keyCacher); }); diff --git a/src/lib/Locale/english.ts b/src/lib/Locale/english.ts index 09a5f057..9918d98f 100644 --- a/src/lib/Locale/english.ts +++ b/src/lib/Locale/english.ts @@ -271,7 +271,7 @@ const English: Locale = { }, }, debug: { - clearCaches: "Clear anime and manga list caches", + clearCaches: "Invalidate anime and manga list caches", showListTimings: "Show media list timings", resetAllSettings: { title: "Reset ALL settings", diff --git a/src/lib/Locale/japanese.ts b/src/lib/Locale/japanese.ts index 3030a65f..79e15e96 100644 --- a/src/lib/Locale/japanese.ts +++ b/src/lib/Locale/japanese.ts @@ -271,7 +271,7 @@ const Japanese: Locale = { }, }, debug: { - clearCaches: "ブラウザのAniListアニメと漫画リストのキャッシュを消去する", + clearCaches: "ブラウザのAniListアニメと漫画リストのキャッシュを無効化する", showListTimings: "メディアリストの処理時間を表示する", resetAllSettings: { title: "すべての設定をリセット", diff --git a/src/lib/Media/invalidate.ts b/src/lib/Media/invalidate.ts new file mode 100644 index 00000000..3a9ff067 --- /dev/null +++ b/src/lib/Media/invalidate.ts @@ -0,0 +1,18 @@ +import { browser } from "$app/environment"; +import { addNotification } from "$lib/Notification/store"; +import { options } from "$lib/Notification/options"; +import revalidateAnime from "$stores/revalidateAnime"; +import revalidateManga from "$stores/revalidateManga"; + +export const invalidateListCaches = () => { + if (!browser) return; + + revalidateAnime.update((n) => n + 1); + revalidateManga.update((n) => n + 1); + + addNotification( + options({ + heading: "Anime and manga list caches successfully invalidated", + }), + ); +}; diff --git a/src/lib/Settings/Categories/Debug.svelte b/src/lib/Settings/Categories/Debug.svelte index c6b16086..ad388fee 100644 --- a/src/lib/Settings/Categories/Debug.svelte +++ b/src/lib/Settings/Categories/Debug.svelte @@ -7,19 +7,7 @@ import { options } from "$lib/Notification/options"; import locale from "$stores/locale"; import SettingCheckboxToggle from "../SettingCheckboxToggle.svelte"; import localforage from "localforage"; -import { browser } from "$app/environment"; - -const clearCaches = async () => { - if (!browser) return; - - await localforage.removeItem("anime"); - await localforage.removeItem("manga"); - addNotification( - options({ - heading: "Anime and manga list caches successfully cleared", - }), - ); -}; +import { invalidateListCaches } from "$lib/Media/invalidate"; </script> <SettingCheckboxToggle setting="debugDummyLists" text={$locale().debug.dummyLists} /> @@ -29,7 +17,7 @@ const clearCaches = async () => { /> <br /> -<button onclick={clearCaches}>{$locale().debug.clearCaches}</button> +<button onclick={invalidateListCaches}>{$locale().debug.clearCaches}</button> <Spacer /> diff --git a/src/stores/revalidateAnime.ts b/src/stores/revalidateAnime.ts index acbbf367..db3ccb2d 100644 --- a/src/stores/revalidateAnime.ts +++ b/src/stores/revalidateAnime.ts @@ -1,5 +1,5 @@ import { writable } from "svelte/store"; -const revalidateAnime = writable<boolean>(false); +const revalidateAnime = writable<number>(0); export default revalidateAnime; diff --git a/src/stores/revalidateManga.ts b/src/stores/revalidateManga.ts new file mode 100644 index 00000000..b72ea1af --- /dev/null +++ b/src/stores/revalidateManga.ts @@ -0,0 +1,5 @@ +import { writable } from "svelte/store"; + +const revalidateManga = writable<number>(0); + +export default revalidateManga; |