diff options
| author | Fuwn <[email protected]> | 2023-12-20 02:20:37 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2023-12-20 02:20:37 -0800 |
| commit | a87fee111ccb501121b5aa3c1e48601f4869198a (patch) | |
| tree | c1c55fc24a03bc7be848ee753ff76a76f397b4e2 /src/routes/schedule | |
| parent | feat(attributions): add more anilist details (diff) | |
| download | due.moe-a87fee111ccb501121b5aa3c1e48601f4869198a.tar.xz due.moe-a87fee111ccb501121b5aa3c1e48601f4869198a.zip | |
feat(schedule): match media to anilist
Diffstat (limited to 'src/routes/schedule')
| -rw-r--r-- | src/routes/schedule/+page.svelte | 153 |
1 files changed, 95 insertions, 58 deletions
diff --git a/src/routes/schedule/+page.svelte b/src/routes/schedule/+page.svelte index c629f820..2a975c46 100644 --- a/src/routes/schedule/+page.svelte +++ b/src/routes/schedule/+page.svelte @@ -5,8 +5,14 @@ import settings from '../../stores/settings'; import { parseOrDefault } from '$lib/Tools/tool'; import { browser } from '$app/environment'; + import type { Media } from '$lib/AniList/media'; + import { scheduleMediaListCollection } from '$lib/AniList/schedule'; + import { season } from '$lib/Media/Anime/season'; + import { findClosestMedia } from '$lib/Media/Anime/airing'; + import MediaTitleDisplay from '$lib/List/MediaTitleDisplay.svelte'; let subsPleasePromise: Promise<SubsPlease>; + let scheduledMediaPromise: Promise<Partial<Media[]>>; const urlParameters = browser ? new URLSearchParams(window.location.search) : null; let timeZone = parseOrDefault( urlParameters, @@ -14,11 +20,13 @@ Intl.DateTimeFormat().resolvedOptions().timeZone ); - onMount( - async () => (subsPleasePromise = fetch(`/api/subsplease?tz=${timeZone}`).then((r) => r.json())) - ); + onMount(async () => { + subsPleasePromise = fetch(`/api/subsplease?tz=${timeZone}`).then((r) => r.json()); + scheduledMediaPromise = scheduleMediaListCollection(new Date().getFullYear(), season()); + }); let hoveredItem: SubsPleaseEpisode | null = null; + let hoveredMedia: Media | null = null; let imageStyle = ''; let imageHeight = 0; @@ -58,67 +66,94 @@ return shiftedSchedule; }; + + const associateMedia = (media: (Media | undefined)[], title: string) => + findClosestMedia(media as Media[], title); </script> {#await subsPleasePromise} Loading ... {:then subsPlease} {#if subsPlease} - <blockquote> - {timeZone.split('/').reverse().join(', ').replace(/_/g, ' ')} - </blockquote> - - <p> - <select - bind:value={timeZone} - on:change={() => - (subsPleasePromise = fetch(`/api/subsplease?tz=${timeZone}`).then((r) => r.json()))} - > - {#each Intl.supportedValuesOf('timeZone') as zone} - <option value={zone}> - {zone.split('/').reverse().join(', ').replace(/_/g, ' ')} - </option> - {/each} - </select> - </p> - - <div id="list-container"> - {#each Object.entries(shiftSubsPleaseSchedule(subsPlease.schedule)) as [day, scheduleEntry]} - <details - open - class="list" - class:today={day === new Date().toLocaleString('en-us', { weekday: 'long' })} - > - <summary>{day}</summary> - - <ul> - {#each Object.values(scheduleEntry) as entry} - <li - class="entry" - on:mouseenter={() => (hoveredItem = entry)} - on:mouseleave={() => (hoveredItem = null)} - on:mousemove={onMouseMove} - > - <a - href={`https://anilist.co/search?search=${encodeURIComponent(entry.title)}`} - target="_blank" - > - {entry.title} - </a> - {#if !$settings.displayCountdownRightAligned} - <span style="opacity: 50%;">|</span> - {/if} - <span class:countdown={$settings.displayCountdownRightAligned}> - {entry.time} - </span> - </li> + {#await scheduledMediaPromise} + Loading ... + {:then scheduledMedia} + {#if scheduledMedia} + <blockquote> + {timeZone.split('/').reverse().join(', ').replace(/_/g, ' ')} + </blockquote> + + <p> + <select + bind:value={timeZone} + on:change={() => + (subsPleasePromise = fetch(`/api/subsplease?tz=${timeZone}`).then((r) => r.json()))} + > + {#each Intl.supportedValuesOf('timeZone') as zone} + <option value={zone}> + {zone.split('/').reverse().join(', ').replace(/_/g, ' ')} + </option> {/each} - </ul> - - <p /> - </details> - {/each} - </div> + </select> + </p> + + <div id="list-container"> + {#each Object.entries(shiftSubsPleaseSchedule(subsPlease.schedule)) as [day, scheduleEntry]} + <details + open + class="list" + class:today={day === new Date().toLocaleString('en-us', { weekday: 'long' })} + > + <summary>{day}</summary> + + <ul> + {#each Object.values(scheduleEntry) as entry} + {@const media = associateMedia(scheduledMedia, entry.title)} + + <li + class="entry" + on:mouseenter={() => { + hoveredItem = entry; + hoveredMedia = media; + }} + on:mouseleave={() => { + hoveredItem = null; + hoveredMedia = null; + }} + on:mousemove={onMouseMove} + > + <a + href={media + ? `https://anilist.co/anime/${media.id}` + : `https://anilist.co/search?search=${encodeURIComponent(entry.title)}`} + target="_blank" + > + {#if media} + <MediaTitleDisplay title={media.title} /> + {:else} + {entry.title} + {/if} + </a> + {#if !$settings.displayCountdownRightAligned} + <span style="opacity: 50%;">|</span> + {/if} + <span class:countdown={$settings.displayCountdownRightAligned}> + {entry.time} + </span> + </li> + {/each} + </ul> + + <p /> + </details> + {/each} + </div> + {:else} + Loading ... + {/if} + {:catch} + <Error type="Media" loginSessionError={false} /> + {/await} {:else} Loading ... {/if} @@ -129,7 +164,9 @@ {#if hoveredItem} <img class="hover-image show" - src={`https://subsplease.org${hoveredItem.image_url}`} + src={hoveredMedia + ? hoveredMedia.coverImage.extraLarge + : `https://subsplease.org${hoveredItem.image_url}`} alt="Media Cover" style={imageStyle} /> |