aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-10-09 01:27:40 -0700
committerFuwn <[email protected]>2024-10-09 01:27:40 -0700
commite0e5ea6f25315a8ae4e39324131c7d90646943ce (patch)
tree4acdff309b007a021310745f009cc7c1443dcc36 /src/lib
parentchore(prettier): use spaces instead of tabs (diff)
downloaddue.moe-e0e5ea6f25315a8ae4e39324131c7d90646943ce.tar.xz
due.moe-e0e5ea6f25315a8ae4e39324131c7d90646943ce.zip
feat(schedule): filter media list entries toggle
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Schedule/Days.svelte203
-rw-r--r--src/lib/Settings/Categories/Display.svelte4
2 files changed, 127 insertions, 80 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}