diff options
| author | Fuwn <[email protected]> | 2024-10-09 01:27:40 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2024-10-09 01:27:40 -0700 |
| commit | e0e5ea6f25315a8ae4e39324131c7d90646943ce (patch) | |
| tree | 4acdff309b007a021310745f009cc7c1443dcc36 /src | |
| parent | chore(prettier): use spaces instead of tabs (diff) | |
| download | due.moe-e0e5ea6f25315a8ae4e39324131c7d90646943ce.tar.xz due.moe-e0e5ea6f25315a8ae4e39324131c7d90646943ce.zip | |
feat(schedule): filter media list entries toggle
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/Schedule/Days.svelte | 203 | ||||
| -rw-r--r-- | src/lib/Settings/Categories/Display.svelte | 4 | ||||
| -rw-r--r-- | src/routes/schedule/+page.svelte | 4 | ||||
| -rw-r--r-- | src/stores/settings.ts | 22 |
4 files changed, 142 insertions, 91 deletions
diff --git a/src/lib/Schedule/Days.svelte b/src/lib/Schedule/Days.svelte index f4075313..f7a49029 100644 --- a/src/lib/Schedule/Days.svelte +++ b/src/lib/Schedule/Days.svelte @@ -1,6 +1,6 @@ <script lang="ts"> import { browser } from '$app/environment'; - import type { Media } from '$lib/Data/AniList/media'; + import { mediaListCollection, Type, type Media } from '$lib/Data/AniList/media'; import { findClosestMedia } from '$lib/Media/Anime/Airing/Subtitled/match'; import type { SubsPlease, SubsPleaseEpisode } from '$lib/Media/Anime/Airing/Subtitled/subsPlease'; import { outboundLink } from '$lib/Media/links'; @@ -10,14 +10,39 @@ import '$lib/List/covers.css'; import ParallaxImage from '$lib/Image/ParallaxImage.svelte'; import LinkedTooltip from '$lib/Tooltip/LinkedTooltip.svelte'; + import { onMount } from 'svelte'; + import identity from '$stores/identity'; + import anime from '$stores/anime'; + import lastPruneTimes from '$stores/lastPruneTimes'; + import Message from '$lib/Loading/Message.svelte'; + import Skeleton from '$lib/Loading/Skeleton.svelte'; + import Error from '$lib/Error/RateLimited.svelte'; export let subsPlease: SubsPlease; export let scheduledMedia: Partial<Media[]>; export let forceListMode = false; + export let user; const urlParameters = browser ? new URLSearchParams(window.location.search) : null; let day: string | null = parseOrDefault(urlParameters, 'day', null); + let mediaListPromise: Promise<Media[]>; + + onMount(async () => { + if (user === undefined || $identity.id === -2) mediaListPromise = Promise.resolve([]); + else + mediaListPromise = mediaListCollection( + user, + $identity, + Type.Anime, + $anime, + $lastPruneTimes.anime, + { + all: true + } + ); + }); + const shiftSubsPleaseSchedule = (schedule: SubsPlease['schedule']) => { const shiftedSchedule: { [key: string]: SubsPleaseEpisode[] } = {}; @@ -52,8 +77,14 @@ return shiftedSchedule; }; - const associateMedia = (media: (Media | undefined)[], title: string) => - findClosestMedia(media as Media[], title); + const associateMedia = (media: (Media | undefined)[], title: string, mediaList: Media[]) => { + const closestMedia = findClosestMedia(media as Media[], title); + + if ($settings.displayScheduleFilterList && closestMedia && mediaList) + return mediaList.find((m) => m.id === closestMedia?.id) || null; + + return closestMedia; + }; const episode = (media: Media, weekday: string) => { if (media.nextAiringEpisode?.episode === 1) return 1; @@ -70,55 +101,86 @@ }; </script> -{#each Object.entries(shiftSubsPleaseSchedule(subsPlease.schedule)) as [day, scheduleEntry], dayIndex} - <details - open - class="list" - class:today={day === new Date().toLocaleString('en-us', { weekday: 'long' })} - > - <summary>{day}</summary> - - {#if !$settings.displayScheduleListMode && !forceListMode} - <div - class="covers" - style={`grid-template-columns: repeat(auto-fill, minmax(${$settings.displayCoverWidth}px, 1fr))`} - > - {#each Object.values(scheduleEntry) as entry, entryIndex} - {@const media = associateMedia(scheduledMedia, entry.title)} - - <div class="cover-card" id={`cover-${dayIndex}-${entryIndex}`}> - <LinkedTooltip - content={media ? media.title.english || media.title.romaji : entry.title} - pin={`cover-${dayIndex}-${entryIndex}`} - > - <a - href={outboundLink( - media ? media : null, - 'anime', - $settings.displayOutboundLinksTo, - media === null, - entry.title - )} - target="_blank" - > - <div class="cover-card-image"> - <ParallaxImage - source={media - ? $settings.displayDataSaver - ? media.coverImage.medium - : media.coverImage.extraLarge - : `https://subsplease.org${entry.image_url}`} - limit={12.5} - alternativeText="Cover" - /> - </div> - </a> - - <div class="cover-title"> - <div class="cover-title-element"> - <CoverBypass {media} {entry} cover={false} showTooltip={false} /> - </div> - +{#await mediaListPromise} + <Message message="Loading media lists ..." /> + + <Skeleton grid={true} count={7} height="15em" width="49.5%" /> +{:then mediaList} + {#each Object.entries(shiftSubsPleaseSchedule(subsPlease.schedule)) as [day, scheduleEntry], dayIndex} + <details + open + class="list" + class:today={day === new Date().toLocaleString('en-us', { weekday: 'long' })} + > + <summary>{day}</summary> + + {#if !$settings.displayScheduleListMode && !forceListMode} + <div + class="covers" + style={`grid-template-columns: repeat(auto-fill, minmax(${$settings.displayCoverWidth}px, 1fr))`} + > + {#each Object.values(scheduleEntry) as entry, entryIndex} + {@const media = associateMedia(scheduledMedia, entry.title, mediaList)} + + {#if ($settings.displayScheduleFilterList && media) || !$settings.displayScheduleFilterList} + <div class="cover-card" id={`cover-${dayIndex}-${entryIndex}`}> + <LinkedTooltip + content={media ? media.title.english || media.title.romaji : entry.title} + pin={`cover-${dayIndex}-${entryIndex}`} + > + <a + href={outboundLink( + media ? media : null, + 'anime', + $settings.displayOutboundLinksTo, + media === null, + entry.title + )} + target="_blank" + > + <div class="cover-card-image"> + <ParallaxImage + source={media + ? $settings.displayDataSaver + ? media.coverImage.medium + : media.coverImage.extraLarge + : `https://subsplease.org${entry.image_url}`} + limit={12.5} + alternativeText="Cover" + /> + </div> + </a> + + <div class="cover-title"> + <div class="cover-title-element"> + <CoverBypass {media} {entry} cover={false} showTooltip={false} /> + </div> + + <span class:countdown={$settings.displayCountdownRightAligned}> + {#if media && media.nextAiringEpisode} + <span class="opaque"> + {episode(media, day)}{media.episodes ? `/${media.episodes}` : ''} at + </span> + {/if} + {entry.time} + </span> + </div> + </LinkedTooltip> + </div> + {/if} + {/each} + </div> + {:else} + <ol> + {#each Object.values(scheduleEntry) as entry} + {@const media = associateMedia(scheduledMedia, entry.title, mediaList)} + + {#if ($settings.displayScheduleFilterList && media) || !$settings.displayScheduleFilterList} + <li class="entry"> + <CoverBypass {media} {entry} /> + {#if !$settings.displayCountdownRightAligned} + <span class="opaque">|</span> + {/if} <span class:countdown={$settings.displayCountdownRightAligned}> {#if media && media.nextAiringEpisode} <span class="opaque"> @@ -127,35 +189,16 @@ {/if} {entry.time} </span> - </div> - </LinkedTooltip> - </div> - {/each} - </div> - {:else} - <ol> - {#each Object.values(scheduleEntry) as entry} - {@const media = associateMedia(scheduledMedia, entry.title)} - - <li class="entry"> - <CoverBypass {media} {entry} /> - {#if !$settings.displayCountdownRightAligned} - <span class="opaque">|</span> + </li> {/if} - <span class:countdown={$settings.displayCountdownRightAligned}> - {#if media && media.nextAiringEpisode} - <span class="opaque"> - {episode(media, day)}{media.episodes ? `/${media.episodes}` : ''} at - </span> - {/if} - {entry.time} - </span> - </li> - {/each} - </ol> - {/if} - </details> -{/each} + {/each} + </ol> + {/if} + </details> + {/each} +{:catch} + <Error type="Media lists" loginSessionError={false} card list={false} /> +{/await} <style> .countdown { diff --git a/src/lib/Settings/Categories/Display.svelte b/src/lib/Settings/Categories/Display.svelte index 9f72f1e1..e1f96025 100644 --- a/src/lib/Settings/Categories/Display.svelte +++ b/src/lib/Settings/Categories/Display.svelte @@ -330,6 +330,10 @@ setting="displayTotalDueEpisodes" text="Display total number of due episodes instead of due media count" /> +<SettingCheckboxToggle + setting="displayScheduleFilterList" + text="Only display media on your media lists in Subtitle Schedule" +/> <select bind:value={$settings.displayTitleFormat}> <option value="english"> {$locale().settings.display.categories.media.fields.mediaTitleFormat.options.english} diff --git a/src/routes/schedule/+page.svelte b/src/routes/schedule/+page.svelte index 78744347..70b1e1e4 100644 --- a/src/routes/schedule/+page.svelte +++ b/src/routes/schedule/+page.svelte @@ -14,6 +14,8 @@ import Message from '$lib/Loading/Message.svelte'; import subsPlease from '$stores/subsPlease'; + export let data; + let scheduledMediaPromise: Promise<Partial<Media[]>>; const urlParameters = browser ? new URLSearchParams(window.location.search) : null; // let crunchyrollExpanded = false; @@ -64,7 +66,7 @@ {:then scheduledMedia} {#if scheduledMedia} <div class="schedule-container" id="schedule"> - <Days subsPlease={$subsPlease} {scheduledMedia} {forceListMode} /> + <Days subsPlease={$subsPlease} {scheduledMedia} {forceListMode} user={data.user} /> </div> {:else} <Message message="Loading schedule ..." /> diff --git a/src/stores/settings.ts b/src/stores/settings.ts index 0d96d419..e55eeb0d 100644 --- a/src/stores/settings.ts +++ b/src/stores/settings.ts @@ -30,16 +30,16 @@ export interface Settings { displayPlannedAnime: boolean; displayFurigana: boolean; displayAoButa: - | 'kaede' - | 'mai' - | 'mai_2' - | 'nodoka' - | 'rio' - | 'sakuta' - | 'shouko' - | 'tomoe' - | 'random' - | 'none'; + | 'kaede' + | 'mai' + | 'mai_2' + | 'nodoka' + | 'rio' + | 'sakuta' + | 'shouko' + | 'tomoe' + | 'random' + | 'none'; disableManga: boolean; disableAnime: boolean; disableUpcomingAnime: boolean; @@ -65,6 +65,7 @@ export interface Settings { displayFiltersIncludeCompleted: boolean; displayDataSaver: boolean; debugDummyLists: boolean; + displayScheduleFilterList: boolean; } const defaultSettings: Settings = { @@ -106,6 +107,7 @@ const defaultSettings: Settings = { displayAniListNotifications: false, displayFiltersIncludeCompleted: false, displayDataSaver: false, + displayScheduleFilterList: false, // Debug debugDummyLists: false, |