Improved cards, library and discover page performance
This commit is contained in:
48
README.md
48
README.md
@@ -1,38 +1,14 @@
|
||||
# create-svelte
|
||||
# Reiverr
|
||||
|
||||
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
|
||||
TODO:
|
||||
- [ ] Sonarr support
|
||||
- [ ] Onboarding setup & sources
|
||||
- [ ] Settings page
|
||||
- [ ] Plex and Jellyfin sync
|
||||
- [ ] Mass edit local files & show space left
|
||||
- [ ] Finish discover page
|
||||
- [ ] Event notifications & show indexer status
|
||||
|
||||
## Creating a project
|
||||
|
||||
If you're seeing this, you've probably already done this step. Congrats!
|
||||
|
||||
```bash
|
||||
# create a new project in the current directory
|
||||
npm create svelte@latest
|
||||
|
||||
# create a new project in my-app
|
||||
npm create svelte@latest my-app
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
|
||||
# or start the server and open the app in a new browser tab
|
||||
npm run dev -- --open
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
To create a production version of your app:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
You can preview the production build with `npm run preview`.
|
||||
|
||||
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
||||
Further ideas
|
||||
- [ ] Similar movies & shows, actor pages and recommendations
|
||||
- [ ] Watchlist management
|
||||
@@ -5,7 +5,7 @@ import type { components } from '$lib/radarr/radarr-types';
|
||||
import { fetchTmdbMovie } from '$lib/tmdb-api';
|
||||
import { RADARR_API_KEY, RADARR_BASE_URL } from '$env/static/private';
|
||||
|
||||
export type MovieResource = components['schemas']['MovieResource'];
|
||||
export type RadarrMovie = components['schemas']['MovieResource'];
|
||||
export type MovieFileResource = components['schemas']['MovieFileResource'];
|
||||
export type ReleaseResource = components['schemas']['ReleaseResource'];
|
||||
|
||||
@@ -134,4 +134,4 @@ const getMovieByTmdbIdByTmdbId = (tmdbId: string) =>
|
||||
tmdbId: Number(tmdbId)
|
||||
}
|
||||
}
|
||||
}).then((r) => r.data as any as MovieResource);
|
||||
}).then((r) => r.data as any as RadarrMovie);
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
<script lang="ts">
|
||||
import type { TmdbMovie, TmdbMovieFull } from '$lib/tmdb-api';
|
||||
import type { Genre, TmdbMovie, TmdbMovieFull } from '$lib/tmdb-api';
|
||||
import { formatGenres, formatMinutesToTime } from '$lib/utils';
|
||||
import classNames from 'classnames';
|
||||
import { TMDB_IMAGES } from '$lib/constants';
|
||||
import { onMount } from 'svelte';
|
||||
import { fetchTmdbMovie, fetchTmdbMovieImages, TmdbApi } from '$lib/tmdb-api';
|
||||
import CardPlaceholder from './CardPlaceholder.svelte';
|
||||
import { Clock, Star, StarFilled } from 'radix-icons-svelte';
|
||||
|
||||
export let tmdbId: string;
|
||||
export let tmdbId;
|
||||
export let title;
|
||||
export let genres: string[];
|
||||
export let runtimeMinutes;
|
||||
export let completionTime;
|
||||
export let backdropUrl;
|
||||
export let rating: number;
|
||||
|
||||
export let available = true;
|
||||
export let progress = 0;
|
||||
@@ -17,68 +24,64 @@
|
||||
if (randomProgress) {
|
||||
progress = Math.random() > 0.3 ? Math.random() * 100 : 0;
|
||||
}
|
||||
|
||||
let tmdbMovie: TmdbMovie;
|
||||
let backdropUrl;
|
||||
|
||||
onMount(async () => {
|
||||
if (!tmdbId) return;
|
||||
|
||||
fetchTmdbMovieImages(String(tmdbId))
|
||||
.then(
|
||||
(r) =>
|
||||
(backdropUrl = TMDB_IMAGES + r.backdrops.filter((b) => b.iso_639_1 === 'en')[0].file_path)
|
||||
)
|
||||
.catch((err) => (backdropUrl = null));
|
||||
fetchTmdbMovie(tmdbId).then((movie) => (tmdbMovie = movie));
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if !tmdbMovie || !backdropUrl}
|
||||
<CardPlaceholder {large} />
|
||||
{:else}
|
||||
<div
|
||||
class={classNames('rounded overflow-hidden relative shadow-2xl shrink-0', {
|
||||
'h-40 w-72': !large,
|
||||
'h-60 w-96': large
|
||||
})}
|
||||
>
|
||||
<div style={'width: ' + progress + '%'} class="h-[2px] bg-zinc-200 bottom-0 absolute z-[1]" />
|
||||
<div
|
||||
class={classNames('rounded overflow-hidden relative shadow-2xl shrink-0', {
|
||||
'h-40 w-72': !large,
|
||||
'h-60 w-96': large
|
||||
})}
|
||||
on:click={() => window.open('/movie/' + tmdbId, '_self')}
|
||||
class="h-full w-full opacity-0 hover:opacity-100 transition-opacity flex flex-col justify-between cursor-pointer p-2 px-3 relative z-[1] peer"
|
||||
style={progress > 0 ? 'padding-bottom: 0.6rem;' : ''}
|
||||
>
|
||||
<div style={'width: ' + progress + '%'} class="h-[2px] bg-zinc-200 bottom-0 absolute z-[1]" />
|
||||
<div
|
||||
on:click={() => window.open('/movie/' + tmdbMovie.id, '_self')}
|
||||
class="h-full w-full opacity-0 hover:opacity-100 transition-opacity flex flex-col justify-between cursor-pointer p-2 px-3 relative z-[1] peer"
|
||||
style={progress > 0 ? 'padding-bottom: 0.6rem;' : ''}
|
||||
>
|
||||
<div>
|
||||
<h1 class="font-bold tracking-wider text-lg">{tmdbMovie.original_title}</h1>
|
||||
<div class="text-xs text-zinc-300 tracking-wider font-medium">
|
||||
{formatGenres(tmdbMovie.genres)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between items-end">
|
||||
{#if progressType === 'watched'}
|
||||
<div class="text-sm font-medium text-zinc-200">
|
||||
{progress
|
||||
? formatMinutesToTime(tmdbMovie.runtime - tmdbMovie.runtime * (progress / 100)) +
|
||||
' left'
|
||||
: formatMinutesToTime(tmdbMovie.runtime)}
|
||||
</div>
|
||||
{:else if progressType === 'downloading'}
|
||||
<div class="text-sm font-medium text-zinc-200">
|
||||
{Math.floor(progress) + '% Downloaded'}
|
||||
</div>
|
||||
{/if}
|
||||
<div>
|
||||
<h1 class="font-bold tracking-wider text-lg">{title}</h1>
|
||||
<div class="text-xs text-zinc-300 tracking-wider font-medium">
|
||||
{genres.map((genre) => genre.charAt(0).toUpperCase() + genre.slice(1)).join(', ')}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={"background-image: url('" + backdropUrl + "')"}
|
||||
class="absolute inset-0 bg-center bg-cover peer-hover:scale-105 transition-transform"
|
||||
/>
|
||||
<div
|
||||
class={classNames('absolute inset-0 transition-opacity', {
|
||||
'bg-darken opacity-0 peer-hover:opacity-100': available,
|
||||
'bg-[#00000055] peer-hover:bg-darken': !available
|
||||
})}
|
||||
/>
|
||||
<div class="flex justify-between items-end">
|
||||
{#if completionTime}
|
||||
<div class="text-sm font-medium text-zinc-200 tracking-wide">
|
||||
Downloaded in <b
|
||||
>{formatMinutesToTime((new Date(completionTime).getTime() - Date.now()) / 1000 / 60)}</b
|
||||
>
|
||||
</div>
|
||||
{:else}
|
||||
{#if runtimeMinutes}
|
||||
<div class="flex gap-1.5 items-center">
|
||||
<Clock />
|
||||
<div class="text-sm text-zinc-200">
|
||||
{progress
|
||||
? formatMinutesToTime(runtimeMinutes - runtimeMinutes * (progress / 100)) + ' left'
|
||||
: formatMinutesToTime(runtimeMinutes)}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if rating}
|
||||
<div class="flex gap-1.5 items-center">
|
||||
<Star />
|
||||
<div class="text-sm text-zinc-200">
|
||||
{rating.toFixed(1)}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div
|
||||
style={"background-image: url('" + TMDB_IMAGES + backdropUrl + "')"}
|
||||
class="absolute inset-0 bg-center bg-cover peer-hover:scale-105 transition-transform"
|
||||
/>
|
||||
<div
|
||||
class={classNames('absolute inset-0 transition-opacity', {
|
||||
'bg-darken opacity-0 peer-hover:opacity-100': available,
|
||||
'bg-[#00000055] peer-hover:bg-darken': !available
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
38
src/routes/components/Card/CardProvider.svelte
Normal file
38
src/routes/components/Card/CardProvider.svelte
Normal file
@@ -0,0 +1,38 @@
|
||||
<script lang="ts">
|
||||
import type { TmdbMovie } from '$lib/tmdb-api';
|
||||
import { onMount } from 'svelte';
|
||||
import { fetchTmdbMovie, fetchTmdbMovieImages } from '$lib/tmdb-api';
|
||||
import { TMDB_IMAGES } from '$lib/constants';
|
||||
import { getJellyfinItemByTmdbId } from '$lib/jellyfin/jellyfin';
|
||||
import CardPlaceholder from './CardPlaceholder.svelte';
|
||||
import Card from './Card.svelte';
|
||||
|
||||
export let tmdbId: string;
|
||||
|
||||
export let type: 'default' | 'download' | 'in-library' = 'default';
|
||||
|
||||
let tmdbMoviePromise: Promise<TmdbMovie>;
|
||||
let jellyfinItemPromise;
|
||||
let radarrItemPromise;
|
||||
let backdropUrlPromise;
|
||||
|
||||
onMount(async () => {
|
||||
if (!tmdbId) throw new Error('No tmdbId provided');
|
||||
|
||||
backdropUrlPromise = fetchTmdbMovieImages(String(tmdbId)).then(
|
||||
(r) => TMDB_IMAGES + r.backdrops.filter((b) => b.iso_639_1 === 'en')[0].file_path
|
||||
);
|
||||
tmdbMoviePromise = fetchTmdbMovie(tmdbId);
|
||||
if (type === 'in-library') jellyfinItemPromise = getJellyfinItemByTmdbId(tmdbId);
|
||||
if (type === 'download')
|
||||
radarrItemPromise = fetch(`/movie/${tmdbId}/radarr`).then((r) => r.json());
|
||||
});
|
||||
</script>
|
||||
|
||||
{#await Promise.all([tmdbMoviePromise, jellyfinItemPromise, backdropUrlPromise])}
|
||||
<CardPlaceholder {...$$restProps} />
|
||||
{:then [tmdbMovie, jellyfinItem, backdropUrl]}
|
||||
<Card {...$$restProps} {tmdbMovie} {backdropUrl} {jellyfinItem} />
|
||||
{:catch err}
|
||||
Error
|
||||
{/await}
|
||||
42
src/routes/components/Card/card.ts
Normal file
42
src/routes/components/Card/card.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import type { RadarrMovie } from '$lib/radarr/radarr';
|
||||
import { fetchTmdbMovieImages } from '$lib/tmdb-api';
|
||||
import type { TmdbMovie } from '$lib/tmdb-api';
|
||||
|
||||
export interface CardProps {
|
||||
tmdbId: string;
|
||||
title: string;
|
||||
genres: string[];
|
||||
runtimeMinutes: number;
|
||||
backdropUrl: string;
|
||||
rating: number;
|
||||
}
|
||||
|
||||
export const fetchCardProps = async (movie: RadarrMovie): Promise<CardProps> => {
|
||||
const backdropUrl = fetchTmdbMovieImages(String(movie.tmdbId)).then(
|
||||
(r) => r.backdrops.filter((b) => b.iso_639_1 === 'en')[0].file_path
|
||||
);
|
||||
|
||||
return {
|
||||
tmdbId: String(movie.tmdbId),
|
||||
title: String(movie.title),
|
||||
genres: movie.genres as string[],
|
||||
runtimeMinutes: movie.runtime as any,
|
||||
backdropUrl: await backdropUrl,
|
||||
rating: movie.ratings?.tmdb?.value || movie.ratings?.imdb?.value || 0
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchCardPropsTmdb = async (movie: TmdbMovie): Promise<CardProps> => {
|
||||
const backdropUrl = fetchTmdbMovieImages(String(movie.id))
|
||||
.then((r) => r.backdrops.filter((b) => b.iso_639_1 === 'en')[0]?.file_path)
|
||||
.catch(console.error);
|
||||
|
||||
return {
|
||||
tmdbId: String(movie.id),
|
||||
title: String(movie.original_title),
|
||||
genres: movie.genres.map((g) => g.name),
|
||||
runtimeMinutes: movie.runtime,
|
||||
backdropUrl: (await backdropUrl) || '',
|
||||
rating: movie.vote_average || 0
|
||||
};
|
||||
};
|
||||
19
src/routes/discover/+page.server.ts
Normal file
19
src/routes/discover/+page.server.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { fetchTmdbMovie, fetchTmdbPopularMovies } from '$lib/tmdb-api';
|
||||
import { fetchCardPropsTmdb } from '../components/Card/card';
|
||||
|
||||
export const load = (() => {
|
||||
const popularMoviesPromise = fetchTmdbPopularMovies();
|
||||
|
||||
const popularMovies = popularMoviesPromise.then((movies) => {
|
||||
return Promise.all(
|
||||
movies.map(async (movie) => fetchCardPropsTmdb(await fetchTmdbMovie(String(movie.id))))
|
||||
);
|
||||
});
|
||||
|
||||
return {
|
||||
streamed: {
|
||||
popularMovies
|
||||
}
|
||||
};
|
||||
}) satisfies PageServerLoad;
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { fetchTmdbPopularMovies, requestTmdbPopularMovies } from '$lib/tmdb-api';
|
||||
import Card from '../components/Card/Card.svelte';
|
||||
import Carousel from '../components/Carousel/Carousel.svelte';
|
||||
import CarouselPlaceholderItems from '../components/Carousel/CarouselPlaceholderItems.svelte';
|
||||
@@ -7,17 +6,13 @@
|
||||
import HboCard from './HboCard.svelte';
|
||||
import DisneyCard from './DisneyCard.svelte';
|
||||
import AmazonCard from './AmazonCard.svelte';
|
||||
import AppleCard from './AppleCard.svelte';
|
||||
import HuluCard from './HuluCard.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import type { PageData } from './$types';
|
||||
|
||||
const headerStyle = 'uppercase tracking-widest font-bold';
|
||||
|
||||
let popularMovies;
|
||||
|
||||
onMount(() => {
|
||||
popularMovies = fetchTmdbPopularMovies();
|
||||
});
|
||||
export let data: PageData;
|
||||
$: console.log(data);
|
||||
</script>
|
||||
|
||||
<div class="pb-24 flex flex-col gap-4">
|
||||
@@ -25,11 +20,11 @@
|
||||
<div class="pt-24 bg-black">
|
||||
<Carousel>
|
||||
<div slot="title" class={headerStyle}>For You</div>
|
||||
{#await popularMovies}
|
||||
{#await data.streamed.popularMovies}
|
||||
<CarouselPlaceholderItems large={true} />
|
||||
{:then movies}
|
||||
{#each movies ? [...movies].reverse() : [] as movie (movie.id)}
|
||||
<Card large={true} tmdbId={movie.id} />
|
||||
{#each movies ? [...movies].reverse() : [] as movie (movie.tmdbId)}
|
||||
<Card large={true} {...movie} />
|
||||
{/each}
|
||||
{/await}
|
||||
</Carousel>
|
||||
@@ -37,11 +32,11 @@
|
||||
<div>
|
||||
<Carousel>
|
||||
<div slot="title" class={headerStyle}>Popular Movies</div>
|
||||
{#await popularMovies}
|
||||
{#await data.streamed.popularMovies}
|
||||
<CarouselPlaceholderItems />
|
||||
{:then movies}
|
||||
{#each movies || [] as movie (movie.id)}
|
||||
<Card tmdbId={movie.id} />
|
||||
{#each movies || [] as movie (movie.tmdbId)}
|
||||
<Card {...movie} />
|
||||
{/each}
|
||||
{/await}
|
||||
</Carousel>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { RadarrApi } from '$lib/radarr/radarr';
|
||||
import type { CardProps } from '../components/Card/card';
|
||||
import { fetchCardProps } from '../components/Card/card';
|
||||
|
||||
export const load = (() => {
|
||||
const radarrMovies = RadarrApi.get('/api/v3/movie', {
|
||||
@@ -14,42 +16,60 @@ export const load = (() => {
|
||||
}
|
||||
}).then((r) => r.data?.records?.filter((record) => record.movie));
|
||||
|
||||
const downloading = downloadingRadarrMovies.then(async (movies) => {
|
||||
return movies?.map((m) => ({
|
||||
tmdbId: m.movie?.tmdbId,
|
||||
size: m.size,
|
||||
sizeleft: m.sizeleft
|
||||
}));
|
||||
});
|
||||
|
||||
const unavailable = radarrMovies.then(async (movies) => {
|
||||
const downloadingMovies = await downloading;
|
||||
return movies?.filter(
|
||||
(m) =>
|
||||
(!m.movieFile || !m.hasFile || !m.isAvailable) &&
|
||||
!downloadingMovies?.find((d) => d.tmdbId === m.tmdbId)
|
||||
const unavailable: Promise<CardProps[]> = radarrMovies.then(async (movies) => {
|
||||
const downloadingMovies = await downloadingRadarrMovies;
|
||||
return await Promise.all(
|
||||
movies
|
||||
?.filter(
|
||||
(m) =>
|
||||
(!m.movieFile || !m.movieFile || !m.isAvailable) &&
|
||||
!downloadingMovies?.find((d) => d.movie?.tmdbId === m.tmdbId)
|
||||
)
|
||||
.map(async (m) => fetchCardProps(m)) || []
|
||||
);
|
||||
});
|
||||
|
||||
const available = radarrMovies.then(async (movies) => {
|
||||
const available: Promise<CardProps[]> = radarrMovies.then(async (movies) => {
|
||||
const downloadingMovies = await downloading;
|
||||
const unavailableMovies = await unavailable;
|
||||
|
||||
if (!downloadingMovies || !movies) return [];
|
||||
|
||||
return movies
|
||||
.filter((movie) => {
|
||||
return !downloadingMovies.find((downloadingMovie) => downloadingMovie.tmdbId === movie.id);
|
||||
})
|
||||
.filter(
|
||||
(movie) => !unavailableMovies?.find((unavailableMovie) => unavailableMovie.id === movie.id)
|
||||
);
|
||||
return await Promise.all(
|
||||
movies
|
||||
.filter((movie) => {
|
||||
return !downloadingMovies.find(
|
||||
(downloadingMovie) => downloadingMovie.tmdbId === String(movie.tmdbId)
|
||||
);
|
||||
})
|
||||
.filter(
|
||||
(movie) =>
|
||||
!unavailableMovies?.find(
|
||||
(unavailableMovie) => unavailableMovie.tmdbId === String(movie.tmdbId)
|
||||
)
|
||||
)
|
||||
.map(async (m) => fetchCardProps(m)) || []
|
||||
);
|
||||
});
|
||||
|
||||
const downloading: Promise<CardProps[]> = downloadingRadarrMovies.then(async (movies) => {
|
||||
return Promise.all(
|
||||
movies
|
||||
?.filter((m) => m?.movie?.tmdbId)
|
||||
?.map(async (m) => ({
|
||||
...(await fetchCardProps(m.movie as any)),
|
||||
progress: m.sizeleft && m.size ? ((m.size - m.sizeleft) / m.size) * 100 : 0,
|
||||
completionTime: m.estimatedCompletionTime
|
||||
})) || []
|
||||
);
|
||||
});
|
||||
|
||||
// radarrMovies.then((d) => console.log(d.map((m) => m.ratings)));
|
||||
|
||||
return {
|
||||
streamed: {
|
||||
available,
|
||||
downloading,
|
||||
available,
|
||||
unavailable
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<script lang="ts">
|
||||
import type { PageData } from './$types';
|
||||
import SmallHorizontalPoster from '../components/Card/Card.svelte';
|
||||
import type { TmdbMovieFull } from '$lib/tmdb-api';
|
||||
import Card from '../components/Card/Card.svelte';
|
||||
import { TMDB_IMAGES } from '$lib/constants.js';
|
||||
import { afterNavigate, beforeNavigate } from '$app/navigation';
|
||||
import CardPlaceholder from '../components/Card/CardPlaceholder.svelte';
|
||||
import CardProvider from '../components/Card/CardProvider.svelte';
|
||||
export let data: PageData;
|
||||
const watched = [];
|
||||
|
||||
@@ -33,11 +32,12 @@
|
||||
<h1 class={headerStyle}>Downloading</h1>
|
||||
<div class={posterGridStyle}>
|
||||
{#each downloading as movie (movie.tmdbId)}
|
||||
<SmallHorizontalPoster
|
||||
tmdbId={movie.tmdbId}
|
||||
progress={(movie.sizeleft / movie.size) * 100}
|
||||
<Card
|
||||
{...movie}
|
||||
progress={movie.progress}
|
||||
progressType="downloading"
|
||||
available={false}
|
||||
type="download"
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
@@ -47,7 +47,7 @@
|
||||
<h1 class={headerStyle}>Available</h1>
|
||||
<div class={posterGridStyle}>
|
||||
{#each available as movie (movie.tmdbId)}
|
||||
<SmallHorizontalPoster randomProgress={true} tmdbId={movie.tmdbId} />
|
||||
<Card {...movie} randomProgress={false} />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -56,7 +56,7 @@
|
||||
<h1 class={headerStyle}>Unavailable</h1>
|
||||
<div class={posterGridStyle}>
|
||||
{#each unavailable as movie (movie.tmdbId)}
|
||||
<SmallHorizontalPoster available={false} tmdbId={movie.tmdbId} />
|
||||
<Card {...movie} available={false} />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -3,14 +3,7 @@ import { json } from '@sveltejs/kit';
|
||||
import { parseMovieId } from '../+server';
|
||||
import { addRadarrMovie, deleteRadarrMovie } from '$lib/radarr/radarr';
|
||||
|
||||
export const POST = (async ({ params }) => {
|
||||
const tmdbId = parseMovieId(params);
|
||||
|
||||
const response = await addRadarrMovie(tmdbId);
|
||||
|
||||
return json(response);
|
||||
}) satisfies RequestHandler;
|
||||
|
||||
// Delete download
|
||||
export const DELETE = (async ({ params }) => {
|
||||
const radarrMovieId = parseMovieId(params);
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { parseMovieId } from '../+server';
|
||||
import { addRadarrMovie } from '$lib/radarr/radarr';
|
||||
import { addRadarrMovie, getRadarrMovie } from '$lib/radarr/radarr';
|
||||
import { json } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
|
||||
// Add to radarr
|
||||
export const POST = (async ({ params }) => {
|
||||
const tmdbId = parseMovieId(params);
|
||||
|
||||
@@ -10,3 +11,11 @@ export const POST = (async ({ params }) => {
|
||||
|
||||
return json(response);
|
||||
}) satisfies RequestHandler;
|
||||
|
||||
export const GET = (async ({ params }) => {
|
||||
const tmdbId = parseMovieId(params);
|
||||
|
||||
const response = await getRadarrMovie(tmdbId);
|
||||
|
||||
return json(response);
|
||||
}) satisfies RequestHandler;
|
||||
|
||||
Reference in New Issue
Block a user