aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-06-09 18:50:09 -0700
committerFuwn <[email protected]>2025-06-09 18:50:09 -0700
commit2a7f59b4137ee511c0dfa6aa99e505b5f9e5b569 (patch)
treeee2726159937c40c1f413530e591f20336dc77cc /src
parentfix(feeds): Remove duplicate whitespace (diff)
downloaddue.moe-2a7f59b4137ee511c0dfa6aa99e505b5f9e5b569.tar.xz
due.moe-2a7f59b4137ee511c0dfa6aa99e505b5f9e5b569.zip
feat(List): List filtering
Diffstat (limited to 'src')
-rw-r--r--src/lib/Data/AniList/media.ts3
-rw-r--r--src/lib/List/Anime/CleanAnimeList.svelte28
-rw-r--r--src/lib/List/CleanGrid.svelte3
-rw-r--r--src/lib/List/CleanList.svelte2
-rw-r--r--src/lib/List/Manga/CleanMangaList.svelte28
-rw-r--r--src/lib/Settings/Categories/Display.svelte3
-rw-r--r--src/stores/settings.ts2
7 files changed, 61 insertions, 8 deletions
diff --git a/src/lib/Data/AniList/media.ts b/src/lib/Data/AniList/media.ts
index c032edaa..2d98f7be 100644
--- a/src/lib/Data/AniList/media.ts
+++ b/src/lib/Data/AniList/media.ts
@@ -75,6 +75,7 @@ export interface Media {
};
createdAt: number;
updatedAt: number;
+ customLists: Map<string, boolean>;
};
startDate: {
year: number;
@@ -153,7 +154,7 @@ const collectionQueryTemplate = (type: Type, userId: number, options: Collection
title { romaji english native }
nextAiringEpisode { episode airingAt }
mediaListEntry {
- progress progressVolumes status repeat createdAt updatedAt
+ progress progressVolumes status repeat createdAt updatedAt customLists
score(format: POINT_100) startedAt { year month day } completedAt { year month day }
}
startDate { year month }
diff --git a/src/lib/List/Anime/CleanAnimeList.svelte b/src/lib/List/Anime/CleanAnimeList.svelte
index 5a93c731..fabbeec5 100644
--- a/src/lib/List/Anime/CleanAnimeList.svelte
+++ b/src/lib/List/Anime/CleanAnimeList.svelte
@@ -49,6 +49,20 @@
);
})
.reduce((a, b) => a + b, 0);
+ const lists = Array.from(
+ new Set(
+ media
+ .flatMap((m) => Object.entries(m.mediaListEntry?.customLists ?? {}))
+ .filter(([_, value]) => value)
+ .map(([key]) => key)
+ )
+ );
+ let selectedList = 'All';
+
+ $: filteredMedia =
+ selectedList === 'All'
+ ? media
+ : media.filter((m) => m.mediaListEntry?.customLists?.[selectedList]);
onMount(() => {
if (dummy) return;
@@ -124,11 +138,21 @@
No anime to display. <button on:click={() => (animeLists = cleanCache(user, $identity))}>
Force refresh
</button>
+{:else if $settings.displayMediaListFilter}
+ <select bind:value={selectedList}>
+ <option value="All">All</option>
+
+ {#each lists as list}
+ <option value={list}>{list}</option>
+ {/each}
+ </select>
+
+ <p />
{/if}
{#if $settings.displayCoverModeAnime}
<CleanGrid
- {media}
+ media={filteredMedia}
{dummy}
type="anime"
{upcoming}
@@ -157,7 +181,7 @@
</CleanGrid>
{:else}
<CleanList
- {media}
+ media={filteredMedia}
type="anime"
{upcoming}
{notYetReleased}
diff --git a/src/lib/List/CleanGrid.svelte b/src/lib/List/CleanGrid.svelte
index 549d388f..1bd65feb 100644
--- a/src/lib/List/CleanGrid.svelte
+++ b/src/lib/List/CleanGrid.svelte
@@ -15,7 +15,8 @@
export let reverseSort = false;
let uniqueID = new Date().getTime();
- let processedMedia = reverseSort ? media.reverse() : media;
+
+ $: processedMedia = reverseSort ? media.reverse() : media;
</script>
<div
diff --git a/src/lib/List/CleanList.svelte b/src/lib/List/CleanList.svelte
index 82f0709b..79011ea8 100644
--- a/src/lib/List/CleanList.svelte
+++ b/src/lib/List/CleanList.svelte
@@ -12,7 +12,7 @@
export let lastUpdatedMedia: number;
export let reverseSort = false;
- let processedMedia = reverseSort ? media.reverse() : media;
+ $: processedMedia = reverseSort ? media.reverse() : media;
</script>
<ul>
diff --git a/src/lib/List/Manga/CleanMangaList.svelte b/src/lib/List/Manga/CleanMangaList.svelte
index 139297d2..623f7c37 100644
--- a/src/lib/List/Manga/CleanMangaList.svelte
+++ b/src/lib/List/Manga/CleanMangaList.svelte
@@ -39,6 +39,20 @@
return (manga.episodes || 1) - (manga.mediaListEntry?.progress || 0);
})
.reduce((a, b) => a + b, 0);
+ const lists = Array.from(
+ new Set(
+ media
+ .flatMap((m) => Object.entries(m.mediaListEntry?.customLists ?? {}))
+ .filter(([_, value]) => value)
+ .map(([key]) => key)
+ )
+ );
+ let selectedList = 'All';
+
+ $: filteredMedia =
+ selectedList === 'All'
+ ? media
+ : media.filter((m) => m.mediaListEntry?.customLists?.[selectedList]);
onMount(() => {
serviceStatusResponse = fetch(proxy('https://api.mangadex.org/ping'));
@@ -117,10 +131,20 @@
>
You can re-enable it later in the <a href={root('/settings')}>Settings</a>.
</span>
+{:else if $settings.displayMediaListFilter}
+ <select bind:value={selectedList}>
+ <option value="All">All</option>
+
+ {#each lists as list}
+ <option value={list}>{list}</option>
+ {/each}
+ </select>
+
+ <p />
{/if}
{#if $settings.displayCoverModeManga || dummy}
- <CleanGrid {media} {dummy} type="manga">
+ <CleanGrid media={filteredMedia} {dummy} type="manga">
<div slot="title" let:title={manga} let:progress>
{pendingUpdate === manga.id ? progress + 1 : progress}{#if !due}
<span class="opaque">/{manga.chapters || '?'}</span>
@@ -147,7 +171,7 @@
</div>
</CleanGrid>
{:else}
- <CleanList {media} type="manga" {lastUpdatedMedia}>
+ <CleanList media={filteredMedia} type="manga" {lastUpdatedMedia}>
<span slot="information" let:title={manga} let:progress>
<span class="opaque">|</span>
{pendingUpdate === manga.id ? progress + 1 : progress}{#if !due}
diff --git a/src/lib/Settings/Categories/Display.svelte b/src/lib/Settings/Categories/Display.svelte
index a2803d98..dbc1c447 100644
--- a/src/lib/Settings/Categories/Display.svelte
+++ b/src/lib/Settings/Categories/Display.svelte
@@ -315,7 +315,7 @@
<p />
-<b>List sort</b><br />
+<b>List sort & filter</b><br />
<select bind:value={$settings.displayAnimeSort}>
<option value="time_remaining">Time Remaining Until Next Airing Episode</option>
<option value="difference">Difference Between Progress and Next Airing Episode</option>
@@ -325,6 +325,7 @@
Anime sort order
<br />
<SettingCheckboxToggle setting="displayReverseSort" text="Reverse anime sort order" />
+<SettingCheckboxToggle setting="displayMediaListFilter" text="Enable media list filter" />
<br />
<b>{$locale().settings.display.categories.media.title}</b><br />
diff --git a/src/stores/settings.ts b/src/stores/settings.ts
index df2691b5..d250e1c1 100644
--- a/src/stores/settings.ts
+++ b/src/stores/settings.ts
@@ -68,6 +68,7 @@ export interface Settings {
displayScheduleFilterList: boolean;
displayReverseSort: boolean;
displayAnimeSort: 'difference' | 'start_date' | 'end_date' | 'time_remaining';
+ displayMediaListFilter: boolean;
}
const defaultSettings: Settings = {
@@ -112,6 +113,7 @@ const defaultSettings: Settings = {
displayScheduleFilterList: false,
displayReverseSort: false,
displayAnimeSort: 'time_remaining',
+ displayMediaListFilter: false,
// Debug
debugDummyLists: false,