diff --git a/src/lib/apis/tmdb/tmdbApi.ts b/src/lib/apis/tmdb/tmdbApi.ts index cf78bff..a51f17a 100644 --- a/src/lib/apis/tmdb/tmdbApi.ts +++ b/src/lib/apis/tmdb/tmdbApi.ts @@ -5,6 +5,7 @@ import axios from 'axios'; import createClient from 'openapi-fetch'; import { get } from 'svelte/store'; import type { operations, paths } from './tmdb.generated'; +import { browser } from '$app/environment'; const CACHE_ONE_DAY = 'max-age=86400'; const CACHE_FOUR_DAYS = 'max-age=345600'; @@ -30,6 +31,31 @@ export interface TmdbSeriesFull2 extends TmdbSeries2 { images: operations['tv-series-images']['responses']['200']['content']['application/json']; } +const backdropCache = browser ? window?.caches?.open('backdrops') : undefined; +const posterCache = browser ? window?.caches?.open('posters') : undefined; + +const getTmdbCache = async ( + cachePromise: typeof backdropCache, + tmdbId: number, + fn: () => Promise +) => { + const cache = await cachePromise; + + if (cache) { + const cacheRes = await cache.match(String(tmdbId)); + if (cacheRes) return cacheRes.text(); + else { + const backdropUri = await fn(); + if (backdropUri) { + cache.put(String(tmdbId), new Response(backdropUri)); + } + return backdropUri; + } + } else { + return fn(); + } +}; + export const TmdbApiOpen = createClient({ baseUrl: 'https://api.themoviedb.org', headers: { @@ -114,19 +140,6 @@ export const getTmdbSeriesImages = async (tmdbId: number) => } }).then((res) => res.data); -export const getTmdbSeriesBackdrop = async (tmdbId: number) => - getTmdbSeries(tmdbId) - .then((s) => s?.images) - .then( - (r) => - ( - r?.backdrops?.find((b) => b.iso_639_1 === get(settings).language) || - r?.backdrops?.find((b) => b.iso_639_1 === 'en') || - r?.backdrops?.find((b) => b.iso_639_1) || - r?.backdrops?.[0] - )?.file_path - ); - export const getTmdbMovieImages = async (tmdbId: number) => await TmdbApiOpen.get('/3/movie/{movie_id}/images', { params: { @@ -139,18 +152,41 @@ export const getTmdbMovieImages = async (tmdbId: number) => } }).then((res) => res.data); +export const getTmdbSeriesBackdrop = async (tmdbId: number) => + getTmdbCache(backdropCache, tmdbId, () => + getTmdbSeries(tmdbId) + .then((s) => s?.images) + .then( + (r) => + ( + r?.backdrops?.find((b) => b.iso_639_1 === get(settings).language) || + r?.backdrops?.find((b) => b.iso_639_1 === 'en') || + r?.backdrops?.find((b) => b.iso_639_1) || + r?.backdrops?.[0] + )?.file_path + ) + ); + export const getTmdbMovieBackdrop = async (tmdbId: number) => - getTmdbMovie(tmdbId) - .then((m) => m?.images) - .then( - (r) => - ( - r?.backdrops?.find((b) => b.iso_639_1 === get(settings).language) || - r?.backdrops?.find((b) => b.iso_639_1 === 'en') || - r?.backdrops?.find((b) => b.iso_639_1) || - r?.backdrops?.[0] - )?.file_path - ); + getTmdbCache(backdropCache, tmdbId, () => + getTmdbMovie(tmdbId) + .then((m) => m?.images) + .then( + (r) => + ( + r?.backdrops?.find((b) => b.iso_639_1 === get(settings).language) || + r?.backdrops?.find((b) => b.iso_639_1 === 'en') || + r?.backdrops?.find((b) => b.iso_639_1) || + r?.backdrops?.[0] + )?.file_path + ) + ); + +export const getTmdbSeriesPoster = async (tmdbId: number) => + getTmdbCache(posterCache, tmdbId, () => getTmdbSeries(tmdbId).then((s) => s?.poster_path)); + +export const getTmdbMoviePoster = async (tmdbId: number) => + getTmdbCache(posterCache, tmdbId, () => getTmdbMovie(tmdbId).then((m) => m?.poster_path)); export const getTmdbPopularMovies = () => TmdbApiOpen.get('/3/movie/popular', { diff --git a/src/lib/components/Button.svelte b/src/lib/components/Button.svelte index 7afed30..6a5bd9a 100644 --- a/src/lib/components/Button.svelte +++ b/src/lib/components/Button.svelte @@ -21,7 +21,7 @@ 'focus-visible:bg-zinc-200 focus-visible:text-zinc-800 hover:bg-zinc-200 hover:text-zinc-800': (type === 'secondary' || type === 'tertiary') && !disabled, 'rounded-full': type === 'tertiary', - 'py-3 px-6': size === 'lg', + 'py-2 px-6 sm:py-3 sm:px-6': size === 'lg', 'py-2 px-6': size === 'md', 'py-1 px-3': size === 'sm', 'opacity-50': disabled, diff --git a/src/lib/components/Carousel/Carousel.svelte b/src/lib/components/Carousel/Carousel.svelte index ee66c98..bc88276 100644 --- a/src/lib/components/Carousel/Carousel.svelte +++ b/src/lib/components/Carousel/Carousel.svelte @@ -4,58 +4,62 @@ import { ChevronLeft, ChevronRight } from 'radix-icons-svelte'; import classNames from 'classnames'; - export let gradientFromColor = 'from-stone-900'; + export let gradientFromColor = 'from-stone-950'; export let heading = ''; let carousel: HTMLDivElement | undefined; let scrollX = 0; -
- -
{heading}
-
-
- { - carousel?.scrollTo({ left: scrollX - carousel?.clientWidth * 0.8, behavior: 'smooth' }); - }} +
+
+ +
{heading}
+
+
- - - { - carousel?.scrollTo({ left: scrollX + carousel?.clientWidth * 0.8, behavior: 'smooth' }); - }} - > - - + { + carousel?.scrollTo({ left: scrollX - carousel?.clientWidth * 0.8, behavior: 'smooth' }); + }} + > + + + { + carousel?.scrollTo({ left: scrollX + carousel?.clientWidth * 0.8, behavior: 'smooth' }); + }} + > + + +
-
-
-
(scrollX = carousel?.scrollLeft || scrollX)} - > - +
+
(scrollX = carousel?.scrollLeft || scrollX)} + > + +
+ {#if scrollX > 50} +
+ {/if} + {#if carousel && scrollX < carousel?.scrollWidth - carousel?.clientWidth - 50} +
+ {/if}
- {#if scrollX > 50} -
- {/if} - {#if carousel && scrollX < carousel?.scrollWidth - carousel?.clientWidth - 50} -
- {/if}
diff --git a/src/lib/components/EpisodeCard/EpisodeCard.svelte b/src/lib/components/EpisodeCard/EpisodeCard.svelte index 5525c6b..bd5d3fe 100644 --- a/src/lib/components/EpisodeCard/EpisodeCard.svelte +++ b/src/lib/components/EpisodeCard/EpisodeCard.svelte @@ -63,7 +63,7 @@