diff --git a/src/app.css b/src/app.css index 7ef7fc9..6ef239f 100644 --- a/src/app.css +++ b/src/app.css @@ -7,8 +7,7 @@ a { } .placeholder { - @apply bg-[#ffffff11]; - @apply animate-pulse; + @apply bg-zinc-700 bg-opacity-40 animate-pulse; } .selectable { diff --git a/src/lib/apis/tmdb/tmdbApi.ts b/src/lib/apis/tmdb/tmdbApi.ts index 89d8502..0b8c216 100644 --- a/src/lib/apis/tmdb/tmdbApi.ts +++ b/src/lib/apis/tmdb/tmdbApi.ts @@ -6,6 +6,9 @@ import createClient from 'openapi-fetch'; import { get } from 'svelte/store'; import type { operations, paths } from './tmdb.generated'; +const CACHE_ONE_DAY = 'max-age=86400'; +const CACHE_FOUR_DAYS = 'max-age=345600'; + export type TmdbMovie2 = operations['movie-details']['responses']['200']['content']['application/json']; export type TmdbSeries2 = @@ -23,6 +26,7 @@ export interface TmdbSeriesFull2 extends TmdbSeries2 { videos: operations['tv-series-videos']['responses']['200']['content']['application/json']; credits: operations['tv-series-credits']['responses']['200']['content']['application/json']; external_ids: operations['tv-series-external-ids']['responses']['200']['content']['application/json']; + images: operations['tv-series-images']['responses']['200']['content']['application/json']; } export const TmdbApiOpen = createClient({ @@ -55,7 +59,7 @@ export const getTmdbSeriesFromTvdbId = async (tvdbId: number) => } }, headers: { - 'Cache-Control': 'max-age=86400' + 'Cache-Control': CACHE_ONE_DAY } }).then((res) => res.data?.tv_results?.[0] as TmdbSeries2 | undefined); @@ -69,8 +73,12 @@ export const getTmdbSeries = async (tmdbId: number): Promise res.data as TmdbSeriesFull2 | undefined); @@ -100,7 +108,7 @@ export const getTmdbSeriesImages = async (tmdbId: number) => } }, headers: { - 'Cache-Control': 'max-age=345600' // 4 days + 'Cache-Control': CACHE_FOUR_DAYS // 4 days } }).then((res) => res.data); @@ -123,7 +131,7 @@ export const getTmdbMovieImages = async (tmdbId: number) => } }, headers: { - 'Cache-Control': 'max-age=345600' // 4 days + 'Cache-Control': CACHE_FOUR_DAYS // 4 days } }).then((res) => res.data); @@ -241,7 +249,7 @@ export const fetchTmdbMovieVideos = async (tmdbId: string): Promise => export const fetchTmdbMovieImages = async (tmdbId: string): Promise => await TmdbApi.get('/movie/' + tmdbId + '/images', { headers: { - 'Cache-Control': 'max-age=345600' // 4 days + 'Cache-Control': CACHE_FOUR_DAYS // 4 days } }).then((res) => res.data); diff --git a/src/lib/components/Button.svelte b/src/lib/components/Button.svelte index 5af6391..8f98b02 100644 --- a/src/lib/components/Button.svelte +++ b/src/lib/components/Button.svelte @@ -9,7 +9,7 @@ export let disabled = false; export let href: string | undefined = undefined; - export let target: string | undefined = undefined; + export let target: string | undefined = '_self'; let buttonStyle: string; // $: buttonStyle = classNames( @@ -44,8 +44,7 @@ const handleClick = (event: MouseEvent) => { if (href) { - if (target === '_blank') window.open(href, target)?.focus(); - else window.open(href, target as string); + window.open(href, target)?.focus(); } else { dispatch('click', event); } diff --git a/src/lib/components/Card/CardPlaceholder.svelte b/src/lib/components/Card/CardPlaceholder.svelte index 8ce49bc..d39fdc0 100644 --- a/src/lib/components/Card/CardPlaceholder.svelte +++ b/src/lib/components/Card/CardPlaceholder.svelte @@ -1,15 +1,17 @@
diff --git a/src/lib/components/Carousel/CarouselPlaceholderItems.svelte b/src/lib/components/Carousel/CarouselPlaceholderItems.svelte index cd24876..1dcb72c 100644 --- a/src/lib/components/Carousel/CarouselPlaceholderItems.svelte +++ b/src/lib/components/Carousel/CarouselPlaceholderItems.svelte @@ -4,5 +4,5 @@ {#each Array(10) as _, i (i)} - + {/each} diff --git a/src/lib/components/EpisodeCard/EpisodeCard.svelte b/src/lib/components/EpisodeCard/EpisodeCard.svelte index ba1ba6c..cc78d6d 100644 --- a/src/lib/components/EpisodeCard/EpisodeCard.svelte +++ b/src/lib/components/EpisodeCard/EpisodeCard.svelte @@ -3,6 +3,7 @@ import classNames from 'classnames'; import { TriangleRight } from 'radix-icons-svelte'; import IconButton from '../IconButton.svelte'; + import { fade } from 'svelte/transition'; export let backdropPath: string; export let title: string; @@ -18,7 +19,7 @@
-->
- diff --git a/src/lib/stores/library.store.ts b/src/lib/stores/library.store.ts index 4b5fcca..8d0d95e 100644 --- a/src/lib/stores/library.store.ts +++ b/src/lib/stores/library.store.ts @@ -16,11 +16,9 @@ import { type SonarrSeries } from '$lib/apis/sonarr/sonarrApi'; import { - fetchTmdbMovieImages, getTmdbMovieBackdrop, getTmdbSeriesBackdrop, - getTmdbSeriesFromTvdbId, - getTmdbSeriesImages + getTmdbSeriesFromTvdbId } from '$lib/apis/tmdb/tmdbApi'; import { get, writable } from 'svelte/store'; @@ -159,7 +157,7 @@ async function getLibrary(): Promise { return { type: 'series' as const, - tmdbId, + tmdbId: tmdbId || 0, tmdbRating: tmdbItem?.vote_average || 0, cardBackdropUrl: backdropUrl || '', download, diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 4a21992..363a9ab 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -75,7 +75,7 @@ export const getFadeIndex = () => { return obj; }; -export function log(arg: any) { +export function log(arg: T): T { console.log('LOGGER', arg); return arg; } diff --git a/src/routes/series/[id]/+page.svelte b/src/routes/series/[id]/+page.svelte index e8578c3..6954ad1 100644 --- a/src/routes/series/[id]/+page.svelte +++ b/src/routes/series/[id]/+page.svelte @@ -1,40 +1,145 @@ -{#if data.series} - {@const series = data.series} - {@const lastEpisode = series.last_episode_to_air} - g.name || '') || []} - runtime={series.episode_run_time?.[0] || 0} - tmdbRating={series.vote_average || 0} - starring={series.credits?.cast || []} - videos={series.videos?.results || []} - showDetails={true} - lastEpisode={lastEpisode?.still_path && lastEpisode?.name - ? { - backdropPath: lastEpisode.still_path, - title: lastEpisode.name, - subtitle: 'Latest Episode', - runtime: lastEpisode.runtime || 0, - episodeNumber: - (lastEpisode.season_number ? `S${lastEpisode.season_number}` : '') + - (lastEpisode.episode_number ? `E${lastEpisode.episode_number}` : '') - } - : undefined} - /> -{/if} +
+ +{#await tmdbSeriesPromise.series then series} +
+
+
+
+ +
+
+ +
+ {#each series?.seasons || [] as season, i} + {@const isSelected = season?.season_number === visibleSeason} + + {/each} +
+ {#each episodeProps[visibleSeason] || [] as props} + + {:else} + + {/each} +
+
+
+ +
+
+
+

{series?.tagline || series?.name}

+

{series?.overview}

+
+
+
+
+

Directed By

+

{series?.created_by?.map((c) => c.name).join(', ')}

+
+
+
+
+
+

No sources found

+

Check your source settings

+
+ +
+ +
Cast & Crew
+ +
+ +
Recommended
+ +
+ +
Similar Titles
+ +
+{/await} diff --git a/src/routes/series/[id]/+page.ts b/src/routes/series/[id]/+page.ts index 9df4ade..7f19f60 100644 --- a/src/routes/series/[id]/+page.ts +++ b/src/routes/series/[id]/+page.ts @@ -1,8 +1,7 @@ -import { getTmdbSeries } from '$lib/apis/tmdb/tmdbApi'; import type { PageLoad } from './$types'; export const load = (async ({ params }) => { return { - series: await getTmdbSeries(Number(params.id)) + tmdbId: params.id }; }) satisfies PageLoad;