Video background done
This commit is contained in:
45
package-lock.json
generated
45
package-lock.json
generated
@@ -11,6 +11,7 @@
|
||||
"@apollo/client": "^3.7.15",
|
||||
"axios": "^1.4.0",
|
||||
"graphql": "^16.6.0",
|
||||
"openapi-fetch": "^0.2.1",
|
||||
"radix-icons-svelte": "^1.2.1",
|
||||
"svelte-apollo": "^0.5.0"
|
||||
},
|
||||
@@ -34,6 +35,7 @@
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-svelte": "^2.26.0",
|
||||
"graphql-codegen-svelte-apollo": "^1.1.0",
|
||||
"openapi-typescript": "^6.2.7",
|
||||
"postcss": "^8.4.24",
|
||||
"prettier": "^2.8.0",
|
||||
"prettier-plugin-svelte": "^2.8.1",
|
||||
@@ -3265,6 +3267,15 @@
|
||||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-colors": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
|
||||
"integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-escapes": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
|
||||
@@ -6311,6 +6322,40 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/openapi-fetch": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/openapi-fetch/-/openapi-fetch-0.2.1.tgz",
|
||||
"integrity": "sha512-XrpiPz8fPUdYtgcXSU4u8jJ/At67PbFsj6XRZZbt6lMsrosKplWY7dUgnkstYaroschNz/NfYSPIiq0sOaY0nw=="
|
||||
},
|
||||
"node_modules/openapi-typescript": {
|
||||
"version": "6.2.7",
|
||||
"resolved": "https://registry.npmjs.org/openapi-typescript/-/openapi-typescript-6.2.7.tgz",
|
||||
"integrity": "sha512-SEdqtFLWmbc2CckzZVSF4/cpPgWlWZp02P0wVCLV/7mCE+7qKukIoiVCLfWJIVeklWuGLZkA/PdJ6OwWaqJ6Ig==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-colors": "^4.1.3",
|
||||
"fast-glob": "^3.2.12",
|
||||
"js-yaml": "^4.1.0",
|
||||
"supports-color": "^9.3.1",
|
||||
"undici": "^5.22.1",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"openapi-typescript": "bin/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/openapi-typescript/node_modules/supports-color": {
|
||||
"version": "9.3.1",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.3.1.tgz",
|
||||
"integrity": "sha512-knBY82pjmnIzK3NifMo3RxEIRD9E0kIzV4BKcyTZ9+9kWgLMxd4PrsTSMoFQUabgRBbF8KOLRDCyKgNV+iK44Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/optimism": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/optimism/-/optimism-0.16.2.tgz",
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-svelte": "^2.26.0",
|
||||
"graphql-codegen-svelte-apollo": "^1.1.0",
|
||||
"openapi-typescript": "^6.2.7",
|
||||
"postcss": "^8.4.24",
|
||||
"prettier": "^2.8.0",
|
||||
"prettier-plugin-svelte": "^2.8.1",
|
||||
@@ -48,6 +49,7 @@
|
||||
"@apollo/client": "^3.7.15",
|
||||
"axios": "^1.4.0",
|
||||
"graphql": "^16.6.0",
|
||||
"openapi-fetch": "^0.2.1",
|
||||
"radix-icons-svelte": "^1.2.1",
|
||||
"svelte-apollo": "^0.5.0"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Reiverr</title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client/core';
|
||||
|
||||
const client = new ApolloClient({
|
||||
link: new HttpLink({
|
||||
uri: 'http://localhost:4000/graphql'
|
||||
}),
|
||||
cache: new InMemoryCache({
|
||||
addTypename: false
|
||||
})
|
||||
});
|
||||
|
||||
export default client;
|
||||
2113
src/lib/graphql.ts
2113
src/lib/graphql.ts
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
mutation clearCache {
|
||||
result: clearRedisCache {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
mutation downloadOwnTorrent(
|
||||
$mediaId: Int!
|
||||
$mediaType: FileType!
|
||||
$torrent: String!
|
||||
) {
|
||||
downloadOwnTorrent(
|
||||
mediaId: $mediaId
|
||||
mediaType: $mediaType
|
||||
torrent: $torrent
|
||||
) {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
mutation startScanLibrary {
|
||||
result: startScanLibraryJob {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
|
||||
mutation startFindNewEpisodes {
|
||||
result: startFindNewEpisodesJob {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
|
||||
mutation startDownloadMissing {
|
||||
result: startDownloadMissingJob {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
mutation downloadMovie($movieId: Int!, $jackettResult: JackettInput!) {
|
||||
result: downloadMovie(movieId: $movieId, jackettResult: $jackettResult) {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
|
||||
mutation downloadTVEpisode($episodeId: Int!, $jackettResult: JackettInput!) {
|
||||
result: downloadTVEpisode(
|
||||
episodeId: $episodeId
|
||||
jackettResult: $jackettResult
|
||||
) {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
|
||||
mutation downloadSeason(
|
||||
$tvShowTMDBId: Int!
|
||||
$seasonNumber: Int!
|
||||
$jackettResult: JackettInput!
|
||||
) {
|
||||
result: downloadSeason(
|
||||
tvShowTMDBId: $tvShowTMDBId
|
||||
seasonNumber: $seasonNumber
|
||||
jackettResult: $jackettResult
|
||||
) {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
mutation removeMovie($tmdbId: Int!) {
|
||||
result: removeMovie(tmdbId: $tmdbId) {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
mutation removeTVShow($tmdbId: Int!) {
|
||||
result: removeTVShow(tmdbId: $tmdbId) {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
mutation resetLibrary($deleteFiles: Boolean!, $resetSettings: Boolean!) {
|
||||
result: resetLibrary(
|
||||
deleteFiles: $deleteFiles
|
||||
resetSettings: $resetSettings
|
||||
) {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
mutation saveQuality($qualities: [QualityInput!]!) {
|
||||
result: saveQualityParams(qualities: $qualities) {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
mutation saveTags($tags: [TagInput!]!) {
|
||||
result: saveTags(tags: $tags) {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
mutation trackMovie($title: String!, $tmdbId: Int!) {
|
||||
movie: trackMovie(title: $title, tmdbId: $tmdbId) {
|
||||
id
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
mutation trackTVShow($tmdbId: Int!, $seasonNumbers: [Int!]!) {
|
||||
tvShow: trackTVShow(tmdbId: $tmdbId, seasonNumbers: $seasonNumbers) {
|
||||
id
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
mutation updateParams($params: [UpdateParamsInput!]!) {
|
||||
result: updateParams(params: $params) {
|
||||
success
|
||||
message
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
query getCalendar {
|
||||
calendar: getCalendar {
|
||||
movies {
|
||||
id
|
||||
title
|
||||
state
|
||||
releaseDate
|
||||
}
|
||||
|
||||
tvEpisodes {
|
||||
id
|
||||
tvShow {
|
||||
id
|
||||
title
|
||||
}
|
||||
episodeNumber
|
||||
seasonNumber
|
||||
state
|
||||
releaseDate
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
query getDiscover(
|
||||
$entertainment: Entertainment
|
||||
$originLanguage: String
|
||||
$primaryReleaseYear: String
|
||||
$score: Float
|
||||
$genres: [Float!]
|
||||
$page: Float
|
||||
) {
|
||||
TMDBResults: discover(
|
||||
entertainment: $entertainment
|
||||
originLanguage: $originLanguage
|
||||
primaryReleaseYear: $primaryReleaseYear
|
||||
score: $score
|
||||
genres: $genres
|
||||
page: $page
|
||||
) {
|
||||
page
|
||||
totalResults
|
||||
totalPages
|
||||
results {
|
||||
id
|
||||
tmdbId
|
||||
title
|
||||
posterPath
|
||||
overview
|
||||
runtime
|
||||
voteAverage
|
||||
releaseDate
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
query getDownloading {
|
||||
searching: getSearchingMedias {
|
||||
id
|
||||
title
|
||||
resourceId
|
||||
resourceType
|
||||
}
|
||||
|
||||
downloading: getDownloadingMedias {
|
||||
id
|
||||
title
|
||||
tag
|
||||
quality
|
||||
torrent
|
||||
resourceId
|
||||
resourceType
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
query getGenres {
|
||||
genres: getGenres {
|
||||
movieGenres {
|
||||
id,
|
||||
name
|
||||
}
|
||||
|
||||
tvShowGenres {
|
||||
id,
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
query getLanguages {
|
||||
languages: getLanguages {
|
||||
code,
|
||||
language
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
query getLibraryMovies {
|
||||
movies: getMovies {
|
||||
id
|
||||
tmdbId
|
||||
title
|
||||
originalTitle
|
||||
state
|
||||
posterPath
|
||||
overview
|
||||
runtime
|
||||
voteAverage
|
||||
releaseDate
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
query getLibraryTVShows {
|
||||
tvShows: getTVShows {
|
||||
id
|
||||
tmdbId
|
||||
title
|
||||
originalTitle
|
||||
posterPath
|
||||
runtime
|
||||
overview
|
||||
voteAverage
|
||||
releaseDate
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
fragment MissingTVEpisodes on EnrichedTVEpisode {
|
||||
id
|
||||
seasonNumber
|
||||
episodeNumber
|
||||
releaseDate
|
||||
tvShow {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
|
||||
fragment MissingMovies on EnrichedMovie {
|
||||
id
|
||||
title
|
||||
releaseDate
|
||||
}
|
||||
|
||||
query getMissing {
|
||||
tvEpisodes: getMissingTVEpisodes {
|
||||
...MissingTVEpisodes
|
||||
}
|
||||
|
||||
movies: getMissingMovies {
|
||||
...MissingMovies
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
query getMovieFileDetails($tmdbId: Int!) {
|
||||
details: getMovieFileDetails(tmdbId: $tmdbId) {
|
||||
id
|
||||
libraryPath
|
||||
libraryFileSize
|
||||
torrentFileName
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
query getParams {
|
||||
params: getParams {
|
||||
region
|
||||
language
|
||||
tmdb_api_key
|
||||
jackett_api_key
|
||||
max_movie_download_size
|
||||
max_tvshow_episode_download_size
|
||||
organize_library_strategy
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
query getPopular {
|
||||
results: getPopular {
|
||||
movies {
|
||||
id
|
||||
tmdbId
|
||||
title
|
||||
releaseDate
|
||||
posterPath
|
||||
overview
|
||||
runtime
|
||||
voteAverage
|
||||
}
|
||||
|
||||
tvShows {
|
||||
id
|
||||
tmdbId
|
||||
title
|
||||
releaseDate
|
||||
posterPath
|
||||
overview
|
||||
runtime
|
||||
voteAverage
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
query getQuality($type: Entertainment!) {
|
||||
qualities: getQualityParams(type: $type) {
|
||||
id
|
||||
name
|
||||
match
|
||||
score
|
||||
updatedAt
|
||||
createdAt
|
||||
type
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
query getRecommended {
|
||||
tvShows: getRecommendedTVShows {
|
||||
id
|
||||
tmdbId
|
||||
title
|
||||
releaseDate
|
||||
posterPath
|
||||
overview
|
||||
runtime
|
||||
voteAverage
|
||||
}
|
||||
|
||||
movies: getRecommendedMovies {
|
||||
id
|
||||
tmdbId
|
||||
title
|
||||
releaseDate
|
||||
posterPath
|
||||
overview
|
||||
runtime
|
||||
voteAverage
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
query getTags {
|
||||
tags: getTags {
|
||||
id
|
||||
name
|
||||
score
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
query getTorrentStatus($torrents: [GetTorrentStatusInput!]!) {
|
||||
torrents: getTorrentStatus(torrents: $torrents) {
|
||||
id
|
||||
resourceId
|
||||
resourceType
|
||||
percentDone
|
||||
rateDownload
|
||||
rateUpload
|
||||
uploadRatio
|
||||
uploadedEver
|
||||
totalSize
|
||||
status
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
query getTVSeasonDetails($tvShowTMDBId: Int!, $seasonNumber: Int!) {
|
||||
episodes: getTVSeasonDetails(
|
||||
tvShowTMDBId: $tvShowTMDBId
|
||||
seasonNumber: $seasonNumber
|
||||
) {
|
||||
id
|
||||
episodeNumber
|
||||
seasonNumber
|
||||
state
|
||||
updatedAt
|
||||
voteAverage
|
||||
releaseDate
|
||||
createdAt
|
||||
tvShow {
|
||||
id
|
||||
title
|
||||
tmdbId
|
||||
updatedAt
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
query getTVShowSeasons($tvShowTMDBId: Int!) {
|
||||
seasons: getTVShowSeasons(tvShowTMDBId: $tvShowTMDBId) {
|
||||
id
|
||||
name
|
||||
seasonNumber
|
||||
episodeCount
|
||||
overview
|
||||
posterPath
|
||||
airDate
|
||||
inLibrary
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
query omdbSearch(
|
||||
$title: String!
|
||||
) {
|
||||
result: omdbSearch(
|
||||
title: $title
|
||||
) {
|
||||
ratings {
|
||||
IMDB
|
||||
rottenTomatoes
|
||||
metaCritic
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
query searchTorrent($query: String!) {
|
||||
results: searchJackett(query: $query) {
|
||||
id
|
||||
title
|
||||
quality
|
||||
qualityScore
|
||||
seeders
|
||||
peers
|
||||
link
|
||||
downloadLink
|
||||
tag
|
||||
tagScore
|
||||
normalizedTitle
|
||||
normalizedTitleParts
|
||||
size
|
||||
publishDate
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
query search($query: String!) {
|
||||
results: search(query: $query) {
|
||||
movies {
|
||||
id
|
||||
tmdbId
|
||||
title
|
||||
releaseDate
|
||||
posterPath
|
||||
overview
|
||||
runtime
|
||||
voteAverage
|
||||
}
|
||||
|
||||
tvShows {
|
||||
id
|
||||
tmdbId
|
||||
title
|
||||
releaseDate
|
||||
posterPath
|
||||
overview
|
||||
runtime
|
||||
voteAverage
|
||||
}
|
||||
}
|
||||
}
|
||||
5289
src/lib/radarr.d.ts
vendored
Normal file
5289
src/lib/radarr.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
18
src/lib/servarr-api.ts
Normal file
18
src/lib/servarr-api.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import createClient from 'openapi-fetch';
|
||||
import type { paths as radarrPaths } from '$lib/radarr';
|
||||
import type { paths as sonarrPaths } from '$lib/sonarr';
|
||||
import { PUBLIC_RADARR_API_KEY, PUBLIC_SONARR_API_KEY } from '$env/static/public';
|
||||
|
||||
export const radarrApi = createClient<radarrPaths>({
|
||||
baseUrl: 'http://radarr.home',
|
||||
headers: {
|
||||
'X-Api-Key': PUBLIC_RADARR_API_KEY
|
||||
}
|
||||
});
|
||||
|
||||
export const sonarrApi = createClient<sonarrPaths>({
|
||||
baseUrl: 'http://sonarr.home',
|
||||
headers: {
|
||||
'X-Api-Key': PUBLIC_SONARR_API_KEY
|
||||
}
|
||||
});
|
||||
5087
src/lib/sonarr.d.ts
vendored
Normal file
5087
src/lib/sonarr.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -7,3 +7,11 @@ export const TmdbApi = axios.create({
|
||||
Authorization: `Bearer ${PUBLIC_TMDB_API_KEY}`
|
||||
}
|
||||
});
|
||||
|
||||
export async function fetchMovieDetails(imdbId: string | number) {
|
||||
return {
|
||||
...(await TmdbApi.get('/movie/' + imdbId).then((res) => res.data)),
|
||||
videos: await TmdbApi.get('/movie/' + imdbId + '/videos').then((res) => res.data.results),
|
||||
credits: await TmdbApi.get('/movie/' + imdbId + '/credits').then((res) => res.data.cast)
|
||||
};
|
||||
}
|
||||
|
||||
6
src/lib/types.ts
Normal file
6
src/lib/types.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { components as radarrComponents } from '$lib/radarr';
|
||||
import type { components as sonarrComponents } from '$lib/sonarr';
|
||||
|
||||
export type MovieResource = radarrComponents['schemas']['MovieResource'];
|
||||
|
||||
export type SeriesResource = sonarrComponents['schemas']['SeriesResource'];
|
||||
@@ -1,10 +1,7 @@
|
||||
<script>
|
||||
import '../app.css';
|
||||
import { setClient } from 'svelte-apollo';
|
||||
import client from '$lib/apollo-client';
|
||||
import Navbar from './Navbar.svelte';
|
||||
|
||||
setClient(client);
|
||||
</script>
|
||||
|
||||
<div class="app">
|
||||
|
||||
@@ -1,156 +1,32 @@
|
||||
<script lang="ts">
|
||||
import { getPopular } from '$lib/graphql';
|
||||
import { ChevronDown, ChevronLeft, ChevronRight, Dot, DotFilled } from 'radix-icons-svelte';
|
||||
import SmallPoster from './SmallPoster.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import ResourceDetails from './ResourceDetails/ResourceDetails.svelte';
|
||||
import ResourceDetailsControls from './ResourceDetailsControls.svelte';
|
||||
|
||||
const popular = getPopular({});
|
||||
// let bgUrl = '';
|
||||
//
|
||||
// $: {
|
||||
// const popularMovie = $popular.data?.results?.movies[2];
|
||||
//
|
||||
// if (popularMovie) {
|
||||
// TmdbApi.get('/movie/' + popularMovie.tmdbId + '/images')
|
||||
// .then((res) => {
|
||||
// console.log('GOt response');
|
||||
// bgUrl = 'https://www.themoviedb.org/t/p/original/' + res.data.backdrops[0].file_path;
|
||||
// })
|
||||
// .catch(console.error);
|
||||
// }
|
||||
// }
|
||||
|
||||
const backgroundUrl = 'https://www.themoviedb.org/t/p/original/5AcP07WJl1VZbnloLZrMVgYjR2s.jpg';
|
||||
$: if ($popular.data.results) console.log($popular.data.results);
|
||||
export let data: PageData;
|
||||
let movies = data.showcases;
|
||||
let movie = movies[0];
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="h-screen w-screen bg-center bg-cover"
|
||||
style={"background-image: url('" + backgroundUrl + "')"}
|
||||
>
|
||||
<div
|
||||
class="bg-[#070501bf] h-full w-full flex px-16 pb-12 pt-32 grid grid-cols-[1fr_max-content] grid-rows-[1fr_min-content] gap-x-16 gap-y-8 relative"
|
||||
>
|
||||
<div class="flex flex-col justify-self-start min-w-0">
|
||||
<!-- <h2 class="tracking-wider font-display font-light text-amber-200">Popular Now</h2>-->
|
||||
<!-- <h1 class="uppercase text-8xl font-bold font-display">Top Gun: Maveric</h1>-->
|
||||
<!-- <h2 class="text-zinc-300 text-sm self-end">-->
|
||||
<!-- <span class="font-bold uppercase tracking-wider">September</span> 2022-->
|
||||
<!-- </h2>-->
|
||||
<div class="relative">
|
||||
<h2 class="text-zinc-300 text-sm self-end">
|
||||
<span class="font-bold uppercase tracking-wider">September</span> 2022
|
||||
</h2>
|
||||
<h2
|
||||
class="tracking-wider font-display font-extrabold text-amber-300 absolute opacity-10 text-8xl -ml-6 mt-8"
|
||||
>
|
||||
Popular Now
|
||||
</h2>
|
||||
<h1 class="uppercase text-8xl font-bold font-display z-[1] relative">Top Gun: Maveric</h1>
|
||||
</div>
|
||||
<ResourceDetails remoteResource={movie}>
|
||||
<ResourceDetailsControls slot="page-controls" />
|
||||
</ResourceDetails>
|
||||
|
||||
<div class="mt-auto max-w-3xl flex flex-col gap-4">
|
||||
<div class="text-xl font-semibold tracking-wider">Feel the need... The need for speed.</div>
|
||||
<div
|
||||
class="tracking-wider text-zinc-200 font-light leading-6 pl-4 border-l-2 border-zinc-300"
|
||||
>
|
||||
After more than thirty years of service as one of the Navy’s top aviators, and dodging the
|
||||
advancement in rank that would ground him, Pete “Maverick” Mitchell finds himself training
|
||||
a detachment of TOP GUN graduates for a specialized mission the likes of which no living
|
||||
pilot has ever seen.
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-6 mt-10">
|
||||
<div class="flex gap-1">
|
||||
<button
|
||||
class="bg-white border-2 border-white hover:bg-amber-400 hover:border-amber-400 transition-colors text-zinc-900 px-8 py-3.5 uppercase tracking-widest font-extrabold cursor-pointer text-xs"
|
||||
>Stream</button
|
||||
>
|
||||
<div
|
||||
class="hidden items-center justify-center border-2 border-white w-10 cursor-pointer hover:bg-white hover:text-zinc-900 transition-colors"
|
||||
>
|
||||
<ChevronDown size="20" />
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="border-2 border-white cursor-pointer transition-colors px-8 py-3.5 uppercase tracking-widest font-semibold text-xs hover:bg-white hover:text-black"
|
||||
>Watch Trailer</button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-6">
|
||||
<h3 class="text-xs tracking-wide uppercase">Details</h3>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="tracking-widest font-extralight text-sm">Action, Drama</div>
|
||||
<div class="tracking-widest font-extralight text-sm">2h 13min</div>
|
||||
<div class="tracking-widest font-extralight text-sm">Currently <b>Streaming</b></div>
|
||||
<div class="tracking-widest font-extralight text-sm"><b>83%</b> IMDB</div>
|
||||
<div class="flex mt-4">
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="text-white w-4"
|
||||
><g
|
||||
><path d="M0 0h24v24H0z" fill="none" /><path
|
||||
d="M11.29 3.814l2.02 5.707.395 1.116.007-4.81.01-4.818h4.27L18 11.871c.003 5.98-.003 10.89-.015 10.9-.012.009-.209 0-.436-.027-.989-.118-2.29-.236-3.34-.282a14.57 14.57 0 0 1-.636-.038c-.003-.004-.273-.762-.776-2.184v-.004l-2.144-6.061-.34-.954-.008 4.586c-.006 4.365-.01 4.61-.057 4.61-.163 0-1.57.09-2.04.136-.308.027-.926.09-1.37.145-.446.051-.816.085-.823.078C6.006 22.77 6 17.867 6 11.883V1.002h.005V1h4.288l.028.08c.007.016.065.176.157.437l.641 1.778.173.496-.001.023z"
|
||||
fill-rule="evenodd"
|
||||
fill="currentColor"
|
||||
/></g
|
||||
></svg
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="text-xs tracking-wide uppercase">Starring</h3>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="tracking-widest font-extralight text-sm">Tom Cruise</div>
|
||||
<div class="tracking-widest font-extralight text-sm">Miles Teller</div>
|
||||
<div class="tracking-widest font-extralight text-sm">Jennifer Connelly</div>
|
||||
<div class="tracking-widest font-extralight text-sm">Jon Hamm</div>
|
||||
<div class="tracking-widest font-extralight text-sm">Glen Powell</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative z-[1] flex gap-8 justify-between items-center col-span-2">
|
||||
<div class="p-4 cursor-pointer text-zinc-200 hover:text-zinc-100">
|
||||
<ChevronLeft size="24" />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<DotFilled size="15" />
|
||||
<DotFilled size="15" class="opacity-20" />
|
||||
<DotFilled size="15" class="opacity-20" />
|
||||
<DotFilled size="15" class="opacity-20" />
|
||||
<DotFilled size="15" class="opacity-20" />
|
||||
</div>
|
||||
|
||||
<div class="p-4 cursor-pointer text-zinc-200 hover:text-zinc-100">
|
||||
<ChevronRight size="24" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute inset-x-0 bottom-6 flex justify-center mx-auto opacity-50">
|
||||
<ChevronDown size="20" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if $popular.loading}
|
||||
{#if !data?.showcases?.length}
|
||||
<div>Loading</div>
|
||||
{:else if $popular.error}
|
||||
<div>Error: {$popular.error.message}</div>
|
||||
{:else}
|
||||
<div class="" style={"background-image: url('" + backgroundUrl + "')"}>
|
||||
<div class="p-8 flex flex-col gap-6 backdrop-blur-xl bg-[#000000ee]">
|
||||
<div
|
||||
class="bg-cover bg-center"
|
||||
style={"background-image: url('https://www.themoviedb.org/t/p/original/" +
|
||||
movie.backdrop_path +
|
||||
"')"}
|
||||
>
|
||||
<div class="p-8 flex flex-col gap-6 backdrop-blur-xl bg-[#000000dd]">
|
||||
<h1 class="uppercase tracking-widest font-bold">Continue Watching</h1>
|
||||
<!-- <h1-->
|
||||
<!-- class="text-black bg-white px-6 py-3 inline-block text-xs uppercase tracking-widest font-bold self-start"-->
|
||||
<!-- >-->
|
||||
<!-- Continue Watching-->
|
||||
<!-- </h1>-->
|
||||
<!-- <h1-->
|
||||
<!-- class="text-white px-6 py-3 inline-block text-xs uppercase tracking-widest font-bold self-start border-2 border-white"-->
|
||||
<!-- >-->
|
||||
<!-- Continue Watching-->
|
||||
<!-- </h1>-->
|
||||
<div class="flex gap-4 overflow-x-scroll">
|
||||
{#each $popular.data.results.movies.splice(0, 5) as item (item.id)}
|
||||
<SmallPoster tmdbId={item.tmdbId} />
|
||||
{/each}
|
||||
{#each $popular.data.results.tvShows.splice(0, 2) as item (item.id)}
|
||||
<SmallPoster type="tv" tmdbId={item.tmdbId} />
|
||||
{#each data.showcases.splice(0, 5) as item (item.id)}
|
||||
<SmallPoster tmdbId={item.id} />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
12
src/routes/+page.ts
Normal file
12
src/routes/+page.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { PageLoad } from './$types';
|
||||
import { radarrApi } from '$lib/servarr-api';
|
||||
import { fetchMovieDetails, TmdbApi } from '$lib/tmdb-api';
|
||||
|
||||
export const load = (async () => {
|
||||
const movies = await TmdbApi.get('/movie/popular').then((res) => res.data.results.slice(0, 5));
|
||||
|
||||
console.log('movies', movies);
|
||||
const showcases = await Promise.all(movies.map((m: any) => fetchMovieDetails(m.id)));
|
||||
console.log('showcases: ', showcases);
|
||||
return { showcases };
|
||||
}) satisfies PageLoad;
|
||||
@@ -1,11 +1,16 @@
|
||||
<script>
|
||||
import { MagnifyingGlass, Person } from 'radix-icons-svelte';
|
||||
import classNames from 'classnames';
|
||||
import { page } from '$app/stores';
|
||||
|
||||
let y = 0;
|
||||
let transparent = true;
|
||||
let baseStyle = '';
|
||||
|
||||
function getLinkStyle(path) {
|
||||
return $page.url.pathname === path ? 'text-amber-200' : 'hover:text-zinc-50 cursor-pointer';
|
||||
}
|
||||
|
||||
$: {
|
||||
transparent = y === 0;
|
||||
baseStyle = classNames(
|
||||
@@ -29,11 +34,11 @@
|
||||
<div
|
||||
class="flex items-center justify-center gap-8 font-normal text-sm tracking-wider text-zinc-200"
|
||||
>
|
||||
<div class="cursor-pointer text-amber-200">Home</div>
|
||||
<div class="hover:text-zinc-50 cursor-pointer">Discover</div>
|
||||
<div class="hover:text-zinc-50 cursor-pointer">Library</div>
|
||||
<div class="hover:text-zinc-50 cursor-pointer">Sources</div>
|
||||
<div class="hover:text-zinc-50 cursor-pointer">Settings</div>
|
||||
<a href="/" class={$page && getLinkStyle('/')}>Home</a>
|
||||
<a href="/discover" class={$page && getLinkStyle('/discover')}>Discover</a>
|
||||
<a href="/library" class={$page && getLinkStyle('/library')}>Library</a>
|
||||
<a href="/sources" class={$page && getLinkStyle('/sources')}>Sources</a>
|
||||
<a href="/settings" class={$page && getLinkStyle('/settings')}>Settings</a>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<div class="p-2 cursor-pointer text-zinc-200 hover:text-zinc-50">
|
||||
|
||||
206
src/routes/ResourceDetails/ResourceDetails.svelte
Normal file
206
src/routes/ResourceDetails/ResourceDetails.svelte
Normal file
@@ -0,0 +1,206 @@
|
||||
<script lang="ts">
|
||||
import type { MovieResource } from '$lib/types';
|
||||
import { ChevronDown, Clock } from 'radix-icons-svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import classNames from 'classnames';
|
||||
import { fade } from 'svelte/transition';
|
||||
|
||||
export let resource: MovieResource;
|
||||
export let trailer = true;
|
||||
export let remoteResource: any;
|
||||
|
||||
let video: any = remoteResource.videos.filter(
|
||||
(v) => v.site === 'YouTube' && v.type === 'Trailer'
|
||||
)?.[0];
|
||||
|
||||
const monthNames = [
|
||||
'January',
|
||||
'February',
|
||||
'March',
|
||||
'April',
|
||||
'May',
|
||||
'June',
|
||||
'July',
|
||||
'August',
|
||||
'September',
|
||||
'October',
|
||||
'November',
|
||||
'December'
|
||||
];
|
||||
const releaseDate = new Date(remoteResource.release_date);
|
||||
|
||||
let showTrailer = false;
|
||||
let focusTrailer = false;
|
||||
let trailerStartTime = 0;
|
||||
|
||||
function openTrailer() {
|
||||
window
|
||||
.open(
|
||||
'https://www.youtube.com/watch?v=' +
|
||||
video.key +
|
||||
'&autoplay=1&t=' +
|
||||
(trailerStartTime === 0 ? 0 : Math.floor((Date.now() - trailerStartTime) / 1000)),
|
||||
'_blank'
|
||||
)
|
||||
.focus();
|
||||
}
|
||||
|
||||
let opacityStyle;
|
||||
|
||||
const transitionStyle = 'transition: opacity 0.3s ease-in-out;';
|
||||
$: opacityStyle = (focusTrailer ? 'opacity: 0;' : 'opacity: 100;') + transitionStyle;
|
||||
|
||||
onMount(() => {
|
||||
setTimeout(() => {
|
||||
showTrailer = trailer;
|
||||
trailerStartTime = Date.now();
|
||||
}, 2500);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="h-screen w-screen bg-center bg-cover relative overflow-hidden"
|
||||
style={"background-image: url('https://www.themoviedb.org/t/p/original" +
|
||||
remoteResource.backdrop_path +
|
||||
"')"}
|
||||
>
|
||||
<div class="youtube-container absolute h-full scale-[150%]">
|
||||
{#if video.key}
|
||||
<iframe
|
||||
class={classNames('transition-opacity', {
|
||||
'opacity-100': showTrailer,
|
||||
'opacity-0': !showTrailer
|
||||
})}
|
||||
transition:fade
|
||||
src={'https://www.youtube.com/embed/' +
|
||||
video.key +
|
||||
'?autoplay=1&mute=1&loop=1&color=white&controls=0&modestbranding=1&playsinline=1&rel=0&enablejsapi=1'}
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
<div
|
||||
class={classNames(
|
||||
'bg-gradient-to-b from-[#070501bf] via-20% via-transparent transition-opacity absolute inset-0 z-[1]',
|
||||
{
|
||||
'opacity-100': focusTrailer,
|
||||
'opacity-0': !focusTrailer
|
||||
}
|
||||
)}
|
||||
/>
|
||||
<div
|
||||
class={classNames(
|
||||
'h-full w-full px-16 pb-12 pt-32',
|
||||
'grid grid-cols-[1fr_max-content] grid-rows-[1fr_min-content] gap-x-16 gap-y-8 relative z-[2]',
|
||||
'transition-colors',
|
||||
{
|
||||
'bg-[#070501bf]': !focusTrailer,
|
||||
'bg-[#00000000]': focusTrailer
|
||||
}
|
||||
)}
|
||||
>
|
||||
<div class="flex flex-col justify-self-start min-w-0 row-span-full">
|
||||
<div class="relative" style={opacityStyle}>
|
||||
<h2 class="text-zinc-300 text-sm self-end">
|
||||
<span class="font-bold uppercase tracking-wider"
|
||||
>{monthNames[releaseDate.getMonth()]}</span
|
||||
>
|
||||
{releaseDate.getFullYear()}
|
||||
</h2>
|
||||
<h2
|
||||
class="tracking-wider font-display font-extrabold text-amber-300 absolute opacity-10 text-8xl -ml-6 mt-8"
|
||||
>
|
||||
<slot name="reason">Popular Now</slot>
|
||||
</h2>
|
||||
<h1 class="uppercase text-8xl font-bold font-display z-[1] relative">
|
||||
{remoteResource.original_title}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="mt-auto max-w-3xl flex flex-col gap-4" style={opacityStyle}>
|
||||
<div class="text-xl font-semibold tracking-wider">{remoteResource.tagline}</div>
|
||||
<div
|
||||
class="tracking-wider text-zinc-200 font-light leading-6 pl-4 border-l-2 border-zinc-300"
|
||||
>
|
||||
{remoteResource.overview}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-6 mt-10">
|
||||
<div class="flex gap-1">
|
||||
<button
|
||||
class="bg-white border-2 border-white hover:bg-amber-400 hover:border-amber-400 transition-colors text-zinc-900 px-8 py-3.5 uppercase tracking-widest font-extrabold cursor-pointer text-xs"
|
||||
style={opacityStyle}>Stream</button
|
||||
>
|
||||
<div
|
||||
class="hidden items-center justify-center border-2 border-white w-10 cursor-pointer hover:bg-white hover:text-zinc-900 transition-colors"
|
||||
>
|
||||
<ChevronDown size="20" />
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
on:mouseover={() => (focusTrailer = true)}
|
||||
on:mouseleave={() => (focusTrailer = false)}
|
||||
on:click={openTrailer}
|
||||
class="border-2 border-white cursor-pointer transition-colors px-8 py-3.5 uppercase tracking-widest font-semibold text-xs hover:bg-white hover:text-black opacity-100"
|
||||
>Watch Trailer</button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-6 max-w-[14rem] row-span-full" style={opacityStyle}>
|
||||
<h3 class="text-xs tracking-wide uppercase">Details</h3>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="tracking-widest font-extralight text-sm">
|
||||
{remoteResource.genres
|
||||
.map((g) => g.name.charAt(0).toUpperCase() + g.name.slice(1))
|
||||
.join(', ')}
|
||||
</div>
|
||||
<div class="flex gap-1.5 items-center">
|
||||
<Clock size="14" />
|
||||
<div class="tracking-widest font-extralight text-sm">
|
||||
{Math.floor(remoteResource.runtime / 60)}h {remoteResource.runtime % 60}m
|
||||
</div>
|
||||
</div>
|
||||
<div class="tracking-widest font-extralight text-sm">Currently <b>Streaming</b></div>
|
||||
<div class="tracking-widest font-extralight text-sm">
|
||||
<b>{remoteResource.vote_average}</b> TMDB
|
||||
</div>
|
||||
<div class="flex mt-4">
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="text-white w-4"
|
||||
><g
|
||||
><path d="M0 0h24v24H0z" fill="none" /><path
|
||||
d="M11.29 3.814l2.02 5.707.395 1.116.007-4.81.01-4.818h4.27L18 11.871c.003 5.98-.003 10.89-.015 10.9-.012.009-.209 0-.436-.027-.989-.118-2.29-.236-3.34-.282a14.57 14.57 0 0 1-.636-.038c-.003-.004-.273-.762-.776-2.184v-.004l-2.144-6.061-.34-.954-.008 4.586c-.006 4.365-.01 4.61-.057 4.61-.163 0-1.57.09-2.04.136-.308.027-.926.09-1.37.145-.446.051-.816.085-.823.078C6.006 22.77 6 17.867 6 11.883V1.002h.005V1h4.288l.028.08c.007.016.065.176.157.437l.641 1.778.173.496-.001.023z"
|
||||
fill-rule="evenodd"
|
||||
fill="currentColor"
|
||||
/></g
|
||||
></svg
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="text-xs tracking-wide uppercase">Starring</h3>
|
||||
<div class="flex flex-col gap-1">
|
||||
{#each remoteResource.credits.slice(0, 5) as a}
|
||||
<div class="tracking-widest font-extralight text-sm">{a.name}</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<slot name="page-controls" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.youtube-container {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
aspect-ratio: 16/9;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.youtube-container iframe {
|
||||
width: 300%;
|
||||
height: 100%;
|
||||
margin-left: -100%;
|
||||
}
|
||||
</style>
|
||||
23
src/routes/ResourceDetailsControls.svelte
Normal file
23
src/routes/ResourceDetailsControls.svelte
Normal file
@@ -0,0 +1,23 @@
|
||||
<script lang="ts">
|
||||
import { ChevronDown, ChevronLeft, ChevronRight, DotFilled } from 'radix-icons-svelte';
|
||||
</script>
|
||||
|
||||
<div class="relative z-[1] flex gap-8 justify-between items-center col-span-2">
|
||||
<div class="p-4 cursor-pointer text-zinc-200 hover:text-zinc-100">
|
||||
<ChevronLeft size="24" />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<DotFilled size="15" />
|
||||
<DotFilled size="15" class="opacity-20" />
|
||||
<DotFilled size="15" class="opacity-20" />
|
||||
<DotFilled size="15" class="opacity-20" />
|
||||
<DotFilled size="15" class="opacity-20" />
|
||||
</div>
|
||||
|
||||
<div class="p-4 cursor-pointer text-zinc-200 hover:text-zinc-100">
|
||||
<ChevronRight size="24" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute inset-x-0 bottom-6 flex justify-center mx-auto opacity-50">
|
||||
<ChevronDown size="20" />
|
||||
</div>
|
||||
@@ -60,9 +60,10 @@
|
||||
class="bg-white border-2 border-white hover:bg-amber-400 hover:border-amber-400 transition-colors text-zinc-900 px-8 py-2.5 uppercase tracking-widest font-extrabold cursor-pointer text-xs"
|
||||
>Stream</button
|
||||
>
|
||||
<button
|
||||
class="border-2 border-white cursor-pointer transition-colors px-8 py-2.5 uppercase tracking-widest font-semibold text-xs hover:bg-amber-400 hover:text-black"
|
||||
>Details</button
|
||||
<a
|
||||
href={'/' + type + '/' + tmdbId}
|
||||
class="border-2 border-white cursor-pointer transition-colors px-8 py-2.5 uppercase tracking-widest font-semibold text-xs hover:bg-amber-400 hover:text-black text-center"
|
||||
>Details</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
9
src/routes/discover/+page.svelte
Normal file
9
src/routes/discover/+page.svelte
Normal file
@@ -0,0 +1,9 @@
|
||||
<div class="pt-24">
|
||||
Does not contain any of the titles in library.
|
||||
<div>Discover</div>
|
||||
<div>For You</div>
|
||||
<div>Popular Movies</div>
|
||||
<div>Popular TV Shows</div>
|
||||
<div>Networks</div>
|
||||
<div>Categories</div>
|
||||
</div>
|
||||
6
src/routes/library/+page.svelte
Normal file
6
src/routes/library/+page.svelte
Normal file
@@ -0,0 +1,6 @@
|
||||
<div class="pt-24">
|
||||
Contains all the titles available locally, the ones already watched previously (greyed out at the
|
||||
bottom), and the ones that are in some sort of watchlist and available via any source.
|
||||
|
||||
<div>Library</div>
|
||||
</div>
|
||||
9
src/routes/movie/[id]/+page.svelte
Normal file
9
src/routes/movie/[id]/+page.svelte
Normal file
@@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
import type { PageData } from './$types';
|
||||
import ResourceDetails from '../../ResourceDetails/ResourceDetails.svelte';
|
||||
import ResourceDetailsControls from '../../ResourceDetailsControls.svelte';
|
||||
export let data: PageData;
|
||||
console.log('data', data);
|
||||
</script>
|
||||
|
||||
<ResourceDetails resource={data.movie} remoteResource={data.remoteMovie} />
|
||||
18
src/routes/movie/[id]/+page.ts
Normal file
18
src/routes/movie/[id]/+page.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import type { PageLoad } from './$types';
|
||||
import { radarrApi } from '$lib/servarr-api';
|
||||
import { fetchMovieDetails, TmdbApi } from '$lib/tmdb-api';
|
||||
|
||||
export const load = (async ({ params }) => {
|
||||
return {
|
||||
movie: await radarrApi
|
||||
.get('/api/v3/movie', {
|
||||
params: {
|
||||
query: {
|
||||
tmdbId: Number(params.id)
|
||||
}
|
||||
}
|
||||
})
|
||||
.then((res) => res.data?.[0]),
|
||||
remoteMovie: fetchMovieDetails(params.id)
|
||||
};
|
||||
}) satisfies PageLoad;
|
||||
1
src/routes/settings/+page.svelte
Normal file
1
src/routes/settings/+page.svelte
Normal file
@@ -0,0 +1 @@
|
||||
<div>Settings</div>
|
||||
6
src/routes/show/[id]/+page.svelte
Normal file
6
src/routes/show/[id]/+page.svelte
Normal file
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { PageData } from './$types';
|
||||
export let data: PageData;
|
||||
</script>
|
||||
|
||||
<div>TV Show of {data.tmdbId}</div>
|
||||
3
src/routes/show/[id]/+page.ts
Normal file
3
src/routes/show/[id]/+page.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
export const load = (({ params }) => ({ tmdbId: params.id })) satisfies PageLoad;
|
||||
11
src/routes/sources/+page.svelte
Normal file
11
src/routes/sources/+page.svelte
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="pt-24">
|
||||
<div>Sources</div>
|
||||
<div>Streaming services</div>
|
||||
<div>(P2P network?)</div>
|
||||
<div>Configure Sonarr</div>
|
||||
<div>Configure Radarr</div>
|
||||
<div>(Configure Plex)</div>
|
||||
<div>(Configure Jellyfinn)</div>
|
||||
<div>(Configure IMDB)</div>
|
||||
<div>(Configure TMDB)</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user