Work on migrating files from sveltekit to svelte
This commit is contained in:
@@ -72,7 +72,7 @@
|
|||||||
<MoviesPage container={contentContainer} />
|
<MoviesPage container={contentContainer} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="library">
|
<Route path="library">
|
||||||
<LibraryPage container={contentContainer} />
|
<LibraryPage parent={contentContainer} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="manage">
|
<Route path="manage">
|
||||||
<ManagePage container={contentContainer} />
|
<ManagePage container={contentContainer} />
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { components, paths } from '$lib/apis/jellyfin/jellyfin.generated';
|
|
||||||
import type { DeviceProfile } from '$lib/apis/jellyfin/playback-profiles';
|
|
||||||
import { settings } from '$lib/stores/settings.store';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import createClient from 'openapi-fetch';
|
import createClient from 'openapi-fetch';
|
||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
|
import type { components, paths } from './jellyfin.generated';
|
||||||
|
import { settings } from '../../stores/settings.store';
|
||||||
|
import type { DeviceProfile } from './playback-profiles';
|
||||||
|
|
||||||
export type JellyfinItem = components['schemas']['BaseItemDto'];
|
export type JellyfinItem = components['schemas']['BaseItemDto'];
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ function getJellyfinApi() {
|
|||||||
|
|
||||||
export const getJellyfinContinueWatching = async (): Promise<JellyfinItem[] | undefined> =>
|
export const getJellyfinContinueWatching = async (): Promise<JellyfinItem[] | undefined> =>
|
||||||
getJellyfinApi()
|
getJellyfinApi()
|
||||||
?.get('/Users/{userId}/Items/Resume', {
|
?.GET('/Users/{userId}/Items/Resume', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
userId: get(settings)?.jellyfin.userId || ''
|
userId: get(settings)?.jellyfin.userId || ''
|
||||||
@@ -41,7 +41,7 @@ export const getJellyfinContinueWatching = async (): Promise<JellyfinItem[] | un
|
|||||||
|
|
||||||
export const getJellyfinNextUp = async () =>
|
export const getJellyfinNextUp = async () =>
|
||||||
getJellyfinApi()
|
getJellyfinApi()
|
||||||
?.get('/Shows/NextUp', {
|
?.GET('/Shows/NextUp', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
userId: get(settings)?.jellyfin.userId || '',
|
userId: get(settings)?.jellyfin.userId || '',
|
||||||
@@ -53,7 +53,7 @@ export const getJellyfinNextUp = async () =>
|
|||||||
|
|
||||||
export const getJellyfinItems = async () =>
|
export const getJellyfinItems = async () =>
|
||||||
getJellyfinApi()
|
getJellyfinApi()
|
||||||
?.get('/Users/{userId}/Items', {
|
?.GET('/Users/{userId}/Items', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
userId: get(settings)?.jellyfin.userId || ''
|
userId: get(settings)?.jellyfin.userId || ''
|
||||||
@@ -84,7 +84,7 @@ export const getJellyfinItems = async () =>
|
|||||||
|
|
||||||
export const getJellyfinEpisodes = async (parentId = '') =>
|
export const getJellyfinEpisodes = async (parentId = '') =>
|
||||||
getJellyfinApi()
|
getJellyfinApi()
|
||||||
?.get('/Users/{userId}/Items', {
|
?.GET('/Users/{userId}/Items', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
userId: get(settings)?.jellyfin.userId || ''
|
userId: get(settings)?.jellyfin.userId || ''
|
||||||
@@ -126,7 +126,7 @@ export const getJellyfinEpisodesInSeasons = async (seriesId: string) =>
|
|||||||
|
|
||||||
export const getJellyfinItem = async (itemId: string) =>
|
export const getJellyfinItem = async (itemId: string) =>
|
||||||
getJellyfinApi()
|
getJellyfinApi()
|
||||||
?.get('/Users/{userId}/Items/{itemId}', {
|
?.GET('/Users/{userId}/Items/{itemId}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
itemId,
|
itemId,
|
||||||
@@ -146,7 +146,7 @@ export const getJellyfinPlaybackInfo = async (
|
|||||||
maxStreamingBitrate = 140000000
|
maxStreamingBitrate = 140000000
|
||||||
) =>
|
) =>
|
||||||
getJellyfinApi()
|
getJellyfinApi()
|
||||||
?.post('/Items/{itemId}/PlaybackInfo', {
|
?.POST('/Items/{itemId}/PlaybackInfo', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
itemId: itemId
|
itemId: itemId
|
||||||
@@ -184,7 +184,7 @@ export const reportJellyfinPlaybackStarted = (
|
|||||||
audioStreamIndex?: number,
|
audioStreamIndex?: number,
|
||||||
subtitleStreamIndex?: number
|
subtitleStreamIndex?: number
|
||||||
) =>
|
) =>
|
||||||
getJellyfinApi()?.post('/Sessions/Playing', {
|
getJellyfinApi()?.POST('/Sessions/Playing', {
|
||||||
body: {
|
body: {
|
||||||
CanSeek: true,
|
CanSeek: true,
|
||||||
ItemId: itemId,
|
ItemId: itemId,
|
||||||
@@ -201,7 +201,7 @@ export const reportJellyfinPlaybackProgress = (
|
|||||||
isPaused: boolean,
|
isPaused: boolean,
|
||||||
positionTicks: number
|
positionTicks: number
|
||||||
) =>
|
) =>
|
||||||
getJellyfinApi()?.post('/Sessions/Playing/Progress', {
|
getJellyfinApi()?.POST('/Sessions/Playing/Progress', {
|
||||||
body: {
|
body: {
|
||||||
ItemId: itemId,
|
ItemId: itemId,
|
||||||
PlaySessionId: sessionId,
|
PlaySessionId: sessionId,
|
||||||
@@ -217,7 +217,7 @@ export const reportJellyfinPlaybackStopped = (
|
|||||||
sessionId: string,
|
sessionId: string,
|
||||||
positionTicks: number
|
positionTicks: number
|
||||||
) =>
|
) =>
|
||||||
getJellyfinApi()?.post('/Sessions/Playing/Stopped', {
|
getJellyfinApi()?.POST('/Sessions/Playing/Stopped', {
|
||||||
body: {
|
body: {
|
||||||
ItemId: itemId,
|
ItemId: itemId,
|
||||||
PlaySessionId: sessionId,
|
PlaySessionId: sessionId,
|
||||||
@@ -227,7 +227,7 @@ export const reportJellyfinPlaybackStopped = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const delteActiveEncoding = (playSessionId: string) =>
|
export const delteActiveEncoding = (playSessionId: string) =>
|
||||||
getJellyfinApi()?.del('/Videos/ActiveEncodings', {
|
getJellyfinApi()?.DELETE('/Videos/ActiveEncodings', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
deviceId: JELLYFIN_DEVICE_ID,
|
deviceId: JELLYFIN_DEVICE_ID,
|
||||||
@@ -237,7 +237,7 @@ export const delteActiveEncoding = (playSessionId: string) =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const setJellyfinItemWatched = async (jellyfinId: string) =>
|
export const setJellyfinItemWatched = async (jellyfinId: string) =>
|
||||||
getJellyfinApi()?.post('/Users/{userId}/PlayedItems/{itemId}', {
|
getJellyfinApi()?.POST('/Users/{userId}/PlayedItems/{itemId}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
userId: get(settings)?.jellyfin.userId || '',
|
userId: get(settings)?.jellyfin.userId || '',
|
||||||
@@ -250,7 +250,7 @@ export const setJellyfinItemWatched = async (jellyfinId: string) =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const setJellyfinItemUnwatched = async (jellyfinId: string) =>
|
export const setJellyfinItemUnwatched = async (jellyfinId: string) =>
|
||||||
getJellyfinApi()?.del('/Users/{userId}/PlayedItems/{itemId}', {
|
getJellyfinApi()?.DELETE('/Users/{userId}/PlayedItems/{itemId}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
userId: get(settings)?.jellyfin.userId || '',
|
userId: get(settings)?.jellyfin.userId || '',
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { components, paths } from '$lib/apis/radarr/radarr.generated';
|
|
||||||
import { getTmdbMovie } from '$lib/apis/tmdb/tmdbApi';
|
|
||||||
import { settings } from '$lib/stores/settings.store';
|
|
||||||
import { log } from '$lib/utils';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import createClient from 'openapi-fetch';
|
import createClient from 'openapi-fetch';
|
||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
|
import { settings } from '../../stores/settings.store';
|
||||||
|
import type { components, paths } from './radarr.generated';
|
||||||
|
import { getTmdbMovie } from '../tmdb/tmdbApi';
|
||||||
|
import { log } from '../../utils';
|
||||||
|
|
||||||
export type RadarrMovie = components['schemas']['MovieResource'];
|
export type RadarrMovie = components['schemas']['MovieResource'];
|
||||||
export type MovieFileResource = components['schemas']['MovieFileResource'];
|
export type MovieFileResource = components['schemas']['MovieFileResource'];
|
||||||
@@ -43,14 +43,14 @@ function getRadarrApi() {
|
|||||||
|
|
||||||
export const getRadarrMovies = (): Promise<RadarrMovie[]> =>
|
export const getRadarrMovies = (): Promise<RadarrMovie[]> =>
|
||||||
getRadarrApi()
|
getRadarrApi()
|
||||||
?.get('/api/v3/movie', {
|
?.GET('/api/v3/movie', {
|
||||||
params: {}
|
params: {}
|
||||||
})
|
})
|
||||||
.then((r) => r.data || []) || Promise.resolve([]);
|
.then((r) => r.data || []) || Promise.resolve([]);
|
||||||
|
|
||||||
export const getRadarrMovieByTmdbId = (tmdbId: string): Promise<RadarrMovie | undefined> =>
|
export const getRadarrMovieByTmdbId = (tmdbId: string): Promise<RadarrMovie | undefined> =>
|
||||||
getRadarrApi()
|
getRadarrApi()
|
||||||
?.get('/api/v3/movie', {
|
?.GET('/api/v3/movie', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
tmdbId: Number(tmdbId)
|
tmdbId: Number(tmdbId)
|
||||||
@@ -82,7 +82,7 @@ export const addMovieToRadarr = async (tmdbId: number) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
getRadarrApi()
|
getRadarrApi()
|
||||||
?.post('/api/v3/movie', {
|
?.POST('/api/v3/movie', {
|
||||||
params: {},
|
params: {},
|
||||||
body: options
|
body: options
|
||||||
})
|
})
|
||||||
@@ -92,7 +92,7 @@ export const addMovieToRadarr = async (tmdbId: number) => {
|
|||||||
|
|
||||||
export const cancelDownloadRadarrMovie = async (downloadId: number) => {
|
export const cancelDownloadRadarrMovie = async (downloadId: number) => {
|
||||||
const deleteResponse = await getRadarrApi()
|
const deleteResponse = await getRadarrApi()
|
||||||
?.del('/api/v3/queue/{id}', {
|
?.DELETE('/api/v3/queue/{id}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
id: downloadId
|
id: downloadId
|
||||||
@@ -110,12 +110,12 @@ export const cancelDownloadRadarrMovie = async (downloadId: number) => {
|
|||||||
|
|
||||||
export const fetchRadarrReleases = (movieId: number) =>
|
export const fetchRadarrReleases = (movieId: number) =>
|
||||||
getRadarrApi()
|
getRadarrApi()
|
||||||
?.get('/api/v3/release', { params: { query: { movieId: movieId } } })
|
?.GET('/api/v3/release', { params: { query: { movieId: movieId } } })
|
||||||
.then((r) => r.data || []) || Promise.resolve([]);
|
.then((r) => r.data || []) || Promise.resolve([]);
|
||||||
|
|
||||||
export const downloadRadarrMovie = (guid: string, indexerId: number) =>
|
export const downloadRadarrMovie = (guid: string, indexerId: number) =>
|
||||||
getRadarrApi()
|
getRadarrApi()
|
||||||
?.post('/api/v3/release', {
|
?.POST('/api/v3/release', {
|
||||||
params: {},
|
params: {},
|
||||||
body: {
|
body: {
|
||||||
indexerId,
|
indexerId,
|
||||||
@@ -126,7 +126,7 @@ export const downloadRadarrMovie = (guid: string, indexerId: number) =>
|
|||||||
|
|
||||||
export const deleteRadarrMovie = (id: number) =>
|
export const deleteRadarrMovie = (id: number) =>
|
||||||
getRadarrApi()
|
getRadarrApi()
|
||||||
?.del('/api/v3/moviefile/{id}', {
|
?.DELETE('/api/v3/moviefile/{id}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
id
|
id
|
||||||
@@ -137,7 +137,7 @@ export const deleteRadarrMovie = (id: number) =>
|
|||||||
|
|
||||||
export const getRadarrDownloads = (): Promise<RadarrDownload[]> =>
|
export const getRadarrDownloads = (): Promise<RadarrDownload[]> =>
|
||||||
getRadarrApi()
|
getRadarrApi()
|
||||||
?.get('/api/v3/queue', {
|
?.GET('/api/v3/queue', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
includeMovie: true
|
includeMovie: true
|
||||||
@@ -155,7 +155,7 @@ export const getRadarrDownloadsByTmdbId = (tmdbId: number) =>
|
|||||||
|
|
||||||
const lookupRadarrMovieByTmdbId = (tmdbId: number) =>
|
const lookupRadarrMovieByTmdbId = (tmdbId: number) =>
|
||||||
getRadarrApi()
|
getRadarrApi()
|
||||||
?.get('/api/v3/movie/lookup/tmdb', {
|
?.GET('/api/v3/movie/lookup/tmdb', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
tmdbId
|
tmdbId
|
||||||
@@ -166,12 +166,12 @@ const lookupRadarrMovieByTmdbId = (tmdbId: number) =>
|
|||||||
|
|
||||||
export const getDiskSpace = (): Promise<DiskSpaceInfo[]> =>
|
export const getDiskSpace = (): Promise<DiskSpaceInfo[]> =>
|
||||||
getRadarrApi()
|
getRadarrApi()
|
||||||
?.get('/api/v3/diskspace', {})
|
?.GET('/api/v3/diskspace', {})
|
||||||
.then((d) => d.data || []) || Promise.resolve([]);
|
.then((d) => d.data || []) || Promise.resolve([]);
|
||||||
|
|
||||||
export const removeFromRadarr = (id: number) =>
|
export const removeFromRadarr = (id: number) =>
|
||||||
getRadarrApi()
|
getRadarrApi()
|
||||||
?.del('/api/v3/movie/{id}', {
|
?.DELETE('/api/v3/movie/{id}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
id
|
id
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { components, paths } from '$lib/apis/sonarr/sonarr.generated';
|
|
||||||
import { settings } from '$lib/stores/settings.store';
|
|
||||||
import { log } from '$lib/utils';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import createClient from 'openapi-fetch';
|
import createClient from 'openapi-fetch';
|
||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
import { getTmdbSeries } from '../tmdb/tmdbApi';
|
import { getTmdbSeries } from '../tmdb/tmdbApi';
|
||||||
|
import type { components, paths } from './sonarr.generated';
|
||||||
|
import { settings } from '../../stores/settings.store';
|
||||||
|
import { log } from '../../utils';
|
||||||
|
|
||||||
export type SonarrSeries = components['schemas']['SeriesResource'];
|
export type SonarrSeries = components['schemas']['SeriesResource'];
|
||||||
export type SonarrReleaseResource = components['schemas']['ReleaseResource'];
|
export type SonarrReleaseResource = components['schemas']['ReleaseResource'];
|
||||||
@@ -58,14 +58,14 @@ function getSonarrApi() {
|
|||||||
|
|
||||||
export const getSonarrSeries = (): Promise<SonarrSeries[]> =>
|
export const getSonarrSeries = (): Promise<SonarrSeries[]> =>
|
||||||
getSonarrApi()
|
getSonarrApi()
|
||||||
?.get('/api/v3/series', {
|
?.GET('/api/v3/series', {
|
||||||
params: {}
|
params: {}
|
||||||
})
|
})
|
||||||
.then((r) => r.data || []) || Promise.resolve([]);
|
.then((r) => r.data || []) || Promise.resolve([]);
|
||||||
|
|
||||||
export const getSonarrSeriesByTvdbId = (tvdbId: number): Promise<SonarrSeries | undefined> =>
|
export const getSonarrSeriesByTvdbId = (tvdbId: number): Promise<SonarrSeries | undefined> =>
|
||||||
getSonarrApi()
|
getSonarrApi()
|
||||||
?.get('/api/v3/series', {
|
?.GET('/api/v3/series', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
tvdbId: tvdbId
|
tvdbId: tvdbId
|
||||||
@@ -76,7 +76,7 @@ export const getSonarrSeriesByTvdbId = (tvdbId: number): Promise<SonarrSeries |
|
|||||||
|
|
||||||
export const getDiskSpace = (): Promise<DiskSpaceInfo[]> =>
|
export const getDiskSpace = (): Promise<DiskSpaceInfo[]> =>
|
||||||
getSonarrApi()
|
getSonarrApi()
|
||||||
?.get('/api/v3/diskspace', {})
|
?.GET('/api/v3/diskspace', {})
|
||||||
.then((d) => d.data || []) || Promise.resolve([]);
|
.then((d) => d.data || []) || Promise.resolve([]);
|
||||||
|
|
||||||
export const addSeriesToSonarr = async (tmdbId: number) => {
|
export const addSeriesToSonarr = async (tmdbId: number) => {
|
||||||
@@ -101,7 +101,7 @@ export const addSeriesToSonarr = async (tmdbId: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return getSonarrApi()
|
return getSonarrApi()
|
||||||
?.post('/api/v3/series', {
|
?.POST('/api/v3/series', {
|
||||||
params: {},
|
params: {},
|
||||||
body: options
|
body: options
|
||||||
})
|
})
|
||||||
@@ -110,7 +110,7 @@ export const addSeriesToSonarr = async (tmdbId: number) => {
|
|||||||
|
|
||||||
export const cancelDownloadSonarrEpisode = async (downloadId: number) => {
|
export const cancelDownloadSonarrEpisode = async (downloadId: number) => {
|
||||||
const deleteResponse = await getSonarrApi()
|
const deleteResponse = await getSonarrApi()
|
||||||
?.del('/api/v3/queue/{id}', {
|
?.DELETE('/api/v3/queue/{id}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
id: downloadId
|
id: downloadId
|
||||||
@@ -128,7 +128,7 @@ export const cancelDownloadSonarrEpisode = async (downloadId: number) => {
|
|||||||
|
|
||||||
export const downloadSonarrEpisode = (guid: string, indexerId: number) =>
|
export const downloadSonarrEpisode = (guid: string, indexerId: number) =>
|
||||||
getSonarrApi()
|
getSonarrApi()
|
||||||
?.post('/api/v3/release', {
|
?.POST('/api/v3/release', {
|
||||||
params: {},
|
params: {},
|
||||||
body: {
|
body: {
|
||||||
indexerId,
|
indexerId,
|
||||||
@@ -139,7 +139,7 @@ export const downloadSonarrEpisode = (guid: string, indexerId: number) =>
|
|||||||
|
|
||||||
export const deleteSonarrEpisode = (id: number) =>
|
export const deleteSonarrEpisode = (id: number) =>
|
||||||
getSonarrApi()
|
getSonarrApi()
|
||||||
?.del('/api/v3/episodefile/{id}', {
|
?.DELETE('/api/v3/episodefile/{id}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
id
|
id
|
||||||
@@ -150,7 +150,7 @@ export const deleteSonarrEpisode = (id: number) =>
|
|||||||
|
|
||||||
export const getSonarrDownloads = (): Promise<SonarrDownload[]> =>
|
export const getSonarrDownloads = (): Promise<SonarrDownload[]> =>
|
||||||
getSonarrApi()
|
getSonarrApi()
|
||||||
?.get('/api/v3/queue', {
|
?.GET('/api/v3/queue', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
includeEpisode: true,
|
includeEpisode: true,
|
||||||
@@ -171,7 +171,7 @@ export const getSonarrDownloadsById = (sonarrId: number) =>
|
|||||||
|
|
||||||
export const removeFromSonarr = (id: number): Promise<boolean> =>
|
export const removeFromSonarr = (id: number): Promise<boolean> =>
|
||||||
getSonarrApi()
|
getSonarrApi()
|
||||||
?.del('/api/v3/series/{id}', {
|
?.DELETE('/api/v3/series/{id}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
id
|
id
|
||||||
@@ -183,7 +183,7 @@ export const removeFromSonarr = (id: number): Promise<boolean> =>
|
|||||||
export const getSonarrEpisodes = async (seriesId: number) => {
|
export const getSonarrEpisodes = async (seriesId: number) => {
|
||||||
const episodesPromise =
|
const episodesPromise =
|
||||||
getSonarrApi()
|
getSonarrApi()
|
||||||
?.get('/api/v3/episode', {
|
?.GET('/api/v3/episode', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
seriesId
|
seriesId
|
||||||
@@ -194,7 +194,7 @@ export const getSonarrEpisodes = async (seriesId: number) => {
|
|||||||
|
|
||||||
const episodeFilesPromise =
|
const episodeFilesPromise =
|
||||||
getSonarrApi()
|
getSonarrApi()
|
||||||
?.get('/api/v3/episodefile', {
|
?.GET('/api/v3/episodefile', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
seriesId
|
seriesId
|
||||||
@@ -214,7 +214,7 @@ export const getSonarrEpisodes = async (seriesId: number) => {
|
|||||||
|
|
||||||
export const fetchSonarrReleases = async (episodeId: number) =>
|
export const fetchSonarrReleases = async (episodeId: number) =>
|
||||||
getSonarrApi()
|
getSonarrApi()
|
||||||
?.get('/api/v3/release', {
|
?.GET('/api/v3/release', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
episodeId
|
episodeId
|
||||||
@@ -225,7 +225,7 @@ export const fetchSonarrReleases = async (episodeId: number) =>
|
|||||||
|
|
||||||
export const fetchSonarrSeasonReleases = async (seriesId: number, seasonNumber: number) =>
|
export const fetchSonarrSeasonReleases = async (seriesId: number, seasonNumber: number) =>
|
||||||
getSonarrApi()
|
getSonarrApi()
|
||||||
?.get('/api/v3/release', {
|
?.GET('/api/v3/release', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
seriesId,
|
seriesId,
|
||||||
@@ -238,7 +238,7 @@ export const fetchSonarrSeasonReleases = async (seriesId: number, seasonNumber:
|
|||||||
export const fetchSonarrEpisodes = async (seriesId: number): Promise<SonarrEpisode[]> => {
|
export const fetchSonarrEpisodes = async (seriesId: number): Promise<SonarrEpisode[]> => {
|
||||||
return (
|
return (
|
||||||
getSonarrApi()
|
getSonarrApi()
|
||||||
?.get('/api/v3/episode', {
|
?.GET('/api/v3/episode', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
seriesId
|
seriesId
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { browser } from '$app/environment';
|
|
||||||
import { TMDB_API_KEY, TMDB_BACKDROP_SMALL } from '$lib/constants';
|
|
||||||
import { settings } from '$lib/stores/settings.store';
|
|
||||||
import createClient from 'openapi-fetch';
|
import createClient from 'openapi-fetch';
|
||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
import type { operations, paths } from './tmdb.generated';
|
import type { operations, paths } from './tmdb.generated';
|
||||||
import type { TitleType } from '$lib/types';
|
import { TMDB_API_KEY, TMDB_BACKDROP_SMALL } from '../../constants';
|
||||||
|
import { settings } from '../../stores/settings.store';
|
||||||
|
import type { TitleType } from '../../types';
|
||||||
|
|
||||||
const CACHE_ONE_DAY = 'max-age=86400';
|
const CACHE_ONE_DAY = 'max-age=86400';
|
||||||
const CACHE_FOUR_DAYS = 'max-age=345600';
|
const CACHE_FOUR_DAYS = 'max-age=345600';
|
||||||
@@ -39,8 +38,8 @@ export interface TmdbSeriesFull2 extends TmdbSeries2 {
|
|||||||
images: operations['tv-series-images']['responses']['200']['content']['application/json'];
|
images: operations['tv-series-images']['responses']['200']['content']['application/json'];
|
||||||
}
|
}
|
||||||
|
|
||||||
const backdropCache = browser ? window?.caches?.open('backdrops') : undefined;
|
const backdropCache = window?.caches?.open('backdrops') || undefined;
|
||||||
const posterCache = browser ? window?.caches?.open('posters') : undefined;
|
const posterCache = window?.caches?.open('posters') || undefined;
|
||||||
|
|
||||||
const getTmdbCache = async (
|
const getTmdbCache = async (
|
||||||
cachePromise: typeof backdropCache,
|
cachePromise: typeof backdropCache,
|
||||||
@@ -72,7 +71,7 @@ export const TmdbApiOpen = createClient<paths>({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const getTmdbMovie = async (tmdbId: number) =>
|
export const getTmdbMovie = async (tmdbId: number) =>
|
||||||
await TmdbApiOpen.get('/3/movie/{movie_id}', {
|
await TmdbApiOpen.GET('/3/movie/{movie_id}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
movie_id: tmdbId
|
movie_id: tmdbId
|
||||||
@@ -85,7 +84,7 @@ export const getTmdbMovie = async (tmdbId: number) =>
|
|||||||
}).then((res) => res.data as TmdbMovieFull2 | undefined);
|
}).then((res) => res.data as TmdbMovieFull2 | undefined);
|
||||||
|
|
||||||
export const getTmdbSeriesFromTvdbId = async (tvdbId: string) =>
|
export const getTmdbSeriesFromTvdbId = async (tvdbId: string) =>
|
||||||
TmdbApiOpen.get('/3/find/{external_id}', {
|
TmdbApiOpen.GET('/3/find/{external_id}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
external_id: tvdbId
|
external_id: tvdbId
|
||||||
@@ -107,7 +106,7 @@ export const getTmdbIdFromTvdbId = async (tvdbId: number) =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const getTmdbSeries = async (tmdbId: number): Promise<TmdbSeriesFull2 | undefined> =>
|
export const getTmdbSeries = async (tmdbId: number): Promise<TmdbSeriesFull2 | undefined> =>
|
||||||
await TmdbApiOpen.get('/3/tv/{series_id}', {
|
await TmdbApiOpen.GET('/3/tv/{series_id}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
series_id: tmdbId
|
series_id: tmdbId
|
||||||
@@ -126,7 +125,7 @@ export const getTmdbSeriesSeason = async (
|
|||||||
tmdbId: number,
|
tmdbId: number,
|
||||||
season: number
|
season: number
|
||||||
): Promise<TmdbSeason | undefined> =>
|
): Promise<TmdbSeason | undefined> =>
|
||||||
TmdbApiOpen.get('/3/tv/{series_id}/season/{season_number}', {
|
TmdbApiOpen.GET('/3/tv/{series_id}/season/{season_number}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
series_id: tmdbId,
|
series_id: tmdbId,
|
||||||
@@ -141,7 +140,7 @@ export const getTmdbSeriesSeasons = async (tmdbId: number, seasons: number) =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const getTmdbSeriesImages = async (tmdbId: number) =>
|
export const getTmdbSeriesImages = async (tmdbId: number) =>
|
||||||
TmdbApiOpen.get('/3/tv/{series_id}/images', {
|
TmdbApiOpen.GET('/3/tv/{series_id}/images', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
series_id: tmdbId
|
series_id: tmdbId
|
||||||
@@ -153,7 +152,7 @@ export const getTmdbSeriesImages = async (tmdbId: number) =>
|
|||||||
}).then((res) => res.data);
|
}).then((res) => res.data);
|
||||||
|
|
||||||
export const getTmdbMovieImages = async (tmdbId: number) =>
|
export const getTmdbMovieImages = async (tmdbId: number) =>
|
||||||
await TmdbApiOpen.get('/3/movie/{movie_id}/images', {
|
await TmdbApiOpen.GET('/3/movie/{movie_id}/images', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
movie_id: tmdbId
|
movie_id: tmdbId
|
||||||
@@ -203,7 +202,7 @@ export const getTmdbMoviePoster = async (tmdbId: number) =>
|
|||||||
/** Discover */
|
/** Discover */
|
||||||
|
|
||||||
export const getTmdbPopularMovies = () =>
|
export const getTmdbPopularMovies = () =>
|
||||||
TmdbApiOpen.get('/3/movie/popular', {
|
TmdbApiOpen.GET('/3/movie/popular', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
language: get(settings)?.language,
|
language: get(settings)?.language,
|
||||||
@@ -213,7 +212,7 @@ export const getTmdbPopularMovies = () =>
|
|||||||
}).then((res) => res.data?.results || []);
|
}).then((res) => res.data?.results || []);
|
||||||
|
|
||||||
export const getTmdbPopularSeries = () =>
|
export const getTmdbPopularSeries = () =>
|
||||||
TmdbApiOpen.get('/3/tv/popular', {
|
TmdbApiOpen.GET('/3/tv/popular', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
language: get(settings)?.language
|
language: get(settings)?.language
|
||||||
@@ -222,7 +221,7 @@ export const getTmdbPopularSeries = () =>
|
|||||||
}).then((res) => res.data?.results || []);
|
}).then((res) => res.data?.results || []);
|
||||||
|
|
||||||
export const getTmdbNetworkSeries = (networkId: number) =>
|
export const getTmdbNetworkSeries = (networkId: number) =>
|
||||||
TmdbApiOpen.get('/3/discover/tv', {
|
TmdbApiOpen.GET('/3/discover/tv', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
with_networks: networkId
|
with_networks: networkId
|
||||||
@@ -231,7 +230,7 @@ export const getTmdbNetworkSeries = (networkId: number) =>
|
|||||||
}).then((res) => res.data?.results || []);
|
}).then((res) => res.data?.results || []);
|
||||||
|
|
||||||
export const getTmdbGenreMovies = (genreId: number) =>
|
export const getTmdbGenreMovies = (genreId: number) =>
|
||||||
TmdbApiOpen.get('/3/discover/movie', {
|
TmdbApiOpen.GET('/3/discover/movie', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
with_genres: String(genreId)
|
with_genres: String(genreId)
|
||||||
@@ -240,7 +239,7 @@ export const getTmdbGenreMovies = (genreId: number) =>
|
|||||||
}).then((res) => res.data?.results || []);
|
}).then((res) => res.data?.results || []);
|
||||||
|
|
||||||
export const getTmdbSeriesRecommendations = (tmdbId: number) =>
|
export const getTmdbSeriesRecommendations = (tmdbId: number) =>
|
||||||
TmdbApiOpen.get('/3/tv/{series_id}/recommendations', {
|
TmdbApiOpen.GET('/3/tv/{series_id}/recommendations', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
series_id: tmdbId
|
series_id: tmdbId
|
||||||
@@ -249,7 +248,7 @@ export const getTmdbSeriesRecommendations = (tmdbId: number) =>
|
|||||||
}).then((res) => res.data?.results || []);
|
}).then((res) => res.data?.results || []);
|
||||||
|
|
||||||
export const getTmdbSeriesSimilar = (tmdbId: number) =>
|
export const getTmdbSeriesSimilar = (tmdbId: number) =>
|
||||||
TmdbApiOpen.get('/3/tv/{series_id}/similar', {
|
TmdbApiOpen.GET('/3/tv/{series_id}/similar', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
series_id: String(tmdbId)
|
series_id: String(tmdbId)
|
||||||
@@ -258,7 +257,7 @@ export const getTmdbSeriesSimilar = (tmdbId: number) =>
|
|||||||
}).then((res) => res.data?.results || []);
|
}).then((res) => res.data?.results || []);
|
||||||
|
|
||||||
export const getTmdbSeriesCredits = (tmdbId: number) =>
|
export const getTmdbSeriesCredits = (tmdbId: number) =>
|
||||||
TmdbApiOpen.get('/3/tv/{series_id}/credits', {
|
TmdbApiOpen.GET('/3/tv/{series_id}/credits', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
series_id: tmdbId
|
series_id: tmdbId
|
||||||
@@ -267,7 +266,7 @@ export const getTmdbSeriesCredits = (tmdbId: number) =>
|
|||||||
}).then((res) => res.data?.cast || []);
|
}).then((res) => res.data?.cast || []);
|
||||||
|
|
||||||
export const getTmdbMovieRecommendations = (tmdbId: number) =>
|
export const getTmdbMovieRecommendations = (tmdbId: number) =>
|
||||||
TmdbApiOpen.get('/3/movie/{movie_id}/recommendations', {
|
TmdbApiOpen.GET('/3/movie/{movie_id}/recommendations', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
movie_id: tmdbId
|
movie_id: tmdbId
|
||||||
@@ -276,7 +275,7 @@ export const getTmdbMovieRecommendations = (tmdbId: number) =>
|
|||||||
}).then((res) => res.data?.results || []);
|
}).then((res) => res.data?.results || []);
|
||||||
|
|
||||||
export const getTmdbMovieSimilar = (tmdbId: number) =>
|
export const getTmdbMovieSimilar = (tmdbId: number) =>
|
||||||
TmdbApiOpen.get('/3/movie/{movie_id}/similar', {
|
TmdbApiOpen.GET('/3/movie/{movie_id}/similar', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
movie_id: tmdbId
|
movie_id: tmdbId
|
||||||
@@ -285,7 +284,7 @@ export const getTmdbMovieSimilar = (tmdbId: number) =>
|
|||||||
}).then((res) => res.data?.results || []);
|
}).then((res) => res.data?.results || []);
|
||||||
|
|
||||||
export const searchTmdbTitles = (query: string) =>
|
export const searchTmdbTitles = (query: string) =>
|
||||||
TmdbApiOpen.get('/3/search/multi', {
|
TmdbApiOpen.GET('/3/search/multi', {
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
query
|
query
|
||||||
@@ -334,7 +333,7 @@ export const getPosterProps = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getTmdbPerson = async (person_id: number) =>
|
export const getTmdbPerson = async (person_id: number) =>
|
||||||
TmdbApiOpen.get('/3/person/{person_id}', {
|
TmdbApiOpen.GET('/3/person/{person_id}', {
|
||||||
params: {
|
params: {
|
||||||
path: {
|
path: {
|
||||||
person_id: person_id
|
person_id: person_id
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Selectable from '../components/Selectable.svelte';
|
import Selectable from '../components/Selectable.svelte';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useNavigate } from 'svelte-navigator';
|
import { useNavigate } from 'svelte-navigator';
|
||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
import { Container } from '../actions/focusAction';
|
import { Container } from '../actions/focusAction';
|
||||||
|
|
||||||
export let to: string;
|
export let to: string;
|
||||||
export let parentContainer: Container;
|
export let parentContainer: Container;
|
||||||
const { container, hasFocus } = parentContainer.createChild('navBarItem').getStores();
|
const { container, hasFocus } = parentContainer.createChild('navBarItem').getStores();
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
function handleClick() {
|
function handleClick() {
|
||||||
navigate(to);
|
navigate(to);
|
||||||
get(Container.focusedObject)?.giveFocus('right');
|
get(Container.focusedObject)?.giveFocus('right');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button on:click={handleClick}>
|
<button on:click={handleClick}>
|
||||||
<Selectable {container}>
|
<Selectable {container}>
|
||||||
<div
|
<div
|
||||||
class={classNames('flex items-center my-2', {
|
class={classNames('flex items-center my-2', {
|
||||||
'text-amber-200': $hasFocus
|
'text-amber-200': $hasFocus
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<slot name="icon" />
|
<slot name="icon" />
|
||||||
<slot name="text" />
|
<slot name="text" />
|
||||||
</div>
|
</div>
|
||||||
</Selectable>
|
</Selectable>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
|
|
||||||
export let index = 0;
|
export let index = 0;
|
||||||
export let size: 'dynamic' | 'md' | 'lg' = 'md';
|
export let size: 'dynamic' | 'md' | 'lg' = 'md';
|
||||||
export let orientation: 'portrait' | 'landscape' = 'landscape';
|
export let orientation: 'portrait' | 'landscape' = 'landscape';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class={classNames('rounded-xl overflow-hidden shadow-lg placeholder shrink-0', {
|
class={classNames('rounded-xl overflow-hidden shadow-lg placeholder shrink-0', {
|
||||||
'aspect-video': orientation === 'landscape',
|
'aspect-video': orientation === 'landscape',
|
||||||
'aspect-[2/3]': orientation === 'portrait',
|
'aspect-[2/3]': orientation === 'portrait',
|
||||||
'w-44': size === 'md' && orientation === 'portrait',
|
'w-44': size === 'md' && orientation === 'portrait',
|
||||||
'h-44': size === 'md' && orientation === 'landscape',
|
'h-44': size === 'md' && orientation === 'landscape',
|
||||||
'w-60': size === 'lg' && orientation === 'portrait',
|
'w-60': size === 'lg' && orientation === 'portrait',
|
||||||
'h-60': size === 'lg' && orientation === 'landscape',
|
'h-60': size === 'lg' && orientation === 'landscape',
|
||||||
'w-full': size === 'dynamic'
|
'w-full': size === 'dynamic'
|
||||||
})}
|
})}
|
||||||
style={'animation-delay: ' + ((index * 100) % 2000) + 'ms;'}
|
style={'animation-delay: ' + ((index * 100) % 2000) + 'ms;'}
|
||||||
transition:fade|global
|
transition:fade|global
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,73 +1,73 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
import IconButton from '../IconButton.svelte';
|
import IconButton from '../IconButton.svelte';
|
||||||
import { ChevronLeft, ChevronRight } from 'radix-icons-svelte';
|
import { ChevronLeft, ChevronRight } from 'radix-icons-svelte';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import type { Registerer } from '../../actions/focusAction';
|
import type { Registerer } from '../../actions/focusAction';
|
||||||
|
|
||||||
export let gradientFromColor = 'from-stone-950';
|
export let gradientFromColor = 'from-stone-950';
|
||||||
export let heading = '';
|
export let heading = '';
|
||||||
|
|
||||||
let carousel: HTMLDivElement | undefined;
|
let carousel: HTMLDivElement | undefined;
|
||||||
let scrollX = 0;
|
let scrollX = 0;
|
||||||
export let scrollClass = '';
|
export let scrollClass = '';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class={classNames('flex flex-col gap-4 group/carousel', $$restProps.class)}>
|
<div class={classNames('flex flex-col gap-4 group/carousel', $$restProps.class)}>
|
||||||
<div class={'flex justify-between items-center gap-4 ' + scrollClass}>
|
<div class={'flex justify-between items-center gap-4 ' + scrollClass}>
|
||||||
<slot name="title">
|
<slot name="title">
|
||||||
<div class="font-semibold text-xl">{heading}</div>
|
<div class="font-semibold text-xl">{heading}</div>
|
||||||
</slot>
|
</slot>
|
||||||
<div
|
<div
|
||||||
class={classNames(
|
class={classNames(
|
||||||
'flex gap-2 sm:opacity-0 transition-opacity sm:group-hover/carousel:opacity-100',
|
'flex gap-2 sm:opacity-0 transition-opacity sm:group-hover/carousel:opacity-100',
|
||||||
{
|
{
|
||||||
hidden: (carousel?.scrollWidth || 0) === (carousel?.clientWidth || 0)
|
hidden: (carousel?.scrollWidth || 0) === (carousel?.clientWidth || 0)
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
carousel?.scrollTo({ left: scrollX - carousel?.clientWidth * 0.8, behavior: 'smooth' });
|
carousel?.scrollTo({ left: scrollX - carousel?.clientWidth * 0.8, behavior: 'smooth' });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ChevronLeft size={20} />
|
<ChevronLeft size={20} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton
|
<IconButton
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
carousel?.scrollTo({ left: scrollX + carousel?.clientWidth * 0.8, behavior: 'smooth' });
|
carousel?.scrollTo({ left: scrollX + carousel?.clientWidth * 0.8, behavior: 'smooth' });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ChevronRight size={20} />
|
<ChevronRight size={20} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
class={classNames(
|
class={classNames(
|
||||||
'flex overflow-x-scroll items-center overflow-y-visible gap-4 relative scrollbar-hide p-1',
|
'flex overflow-x-scroll items-center overflow-y-visible gap-4 relative scrollbar-hide p-1',
|
||||||
scrollClass
|
scrollClass
|
||||||
)}
|
)}
|
||||||
bind:this={carousel}
|
bind:this={carousel}
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
on:scroll={() => (scrollX = carousel?.scrollLeft || scrollX)}
|
on:scroll={() => (scrollX = carousel?.scrollLeft || scrollX)}
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
{#if scrollX > 50}
|
{#if scrollX > 50}
|
||||||
<div
|
<div
|
||||||
transition:fade={{ duration: 200 }}
|
transition:fade={{ duration: 200 }}
|
||||||
class={'absolute inset-y-0 left-0 w-0 sm:w-16 md:w-24 bg-gradient-to-r ' +
|
class={'absolute inset-y-0 left-0 w-0 sm:w-16 md:w-24 bg-gradient-to-r ' +
|
||||||
gradientFromColor}
|
gradientFromColor}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
{#if carousel && scrollX < carousel?.scrollWidth - carousel?.clientWidth - 50}
|
{#if carousel && scrollX < carousel?.scrollWidth - carousel?.clientWidth - 50}
|
||||||
<div
|
<div
|
||||||
transition:fade={{ duration: 200 }}
|
transition:fade={{ duration: 200 }}
|
||||||
class={'absolute inset-y-0 right-0 w-0 sm:w-16 md:w-24 bg-gradient-to-l ' +
|
class={'absolute inset-y-0 right-0 w-0 sm:w-16 md:w-24 bg-gradient-to-l ' +
|
||||||
gradientFromColor}
|
gradientFromColor}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,37 +1,37 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import CardPlaceholder from '../Card/CardPlaceholder.svelte';
|
import CardPlaceholder from '../Card/CardPlaceholder.svelte';
|
||||||
import { Container } from '../../actions/focusAction';
|
import { Container } from '../../actions/focusAction';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
export let size: 'dynamic' | 'md' | 'lg' = 'md';
|
export let size: 'dynamic' | 'md' | 'lg' = 'md';
|
||||||
export let orientation: 'landscape' | 'portrait' = 'landscape';
|
export let orientation: 'landscape' | 'portrait' = 'landscape';
|
||||||
|
|
||||||
export let container: Container;
|
export let container: Container;
|
||||||
let carousel = container.createChild('carousel').setDirection('horizontal');
|
let carousel = container.createChild('carousel').setDirection('horizontal');
|
||||||
let focusIndexStore = carousel.focusIndex;
|
let focusIndexStore = carousel.focusIndex;
|
||||||
let focusWithinStore = carousel.hasFocusWithin;
|
let focusWithinStore = carousel.hasFocusWithin;
|
||||||
|
|
||||||
Container.focusedObject.subscribe((fo) => console.log('focusedObject', fo));
|
Container.focusedObject.subscribe((fo) => console.log('focusedObject', fo));
|
||||||
carousel.hasFocus.subscribe((hf) => console.log('hasFocus', hf));
|
carousel.hasFocus.subscribe((hf) => console.log('hasFocus', hf));
|
||||||
|
|
||||||
let registerer = carousel.getChildRegisterer();
|
let registerer = carousel.getChildRegisterer();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<p
|
<p
|
||||||
class={classNames({
|
class={classNames({
|
||||||
'bg-blue-500': $focusWithinStore
|
'bg-blue-500': $focusWithinStore
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
Index: {$focusIndexStore}
|
Index: {$focusIndexStore}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{#each Array(10) as _, i (i)}
|
{#each Array(10) as _, i (i)}
|
||||||
<div
|
<div
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
use:registerer
|
use:registerer
|
||||||
class={classNames({
|
class={classNames({
|
||||||
'bg-red-500': $focusIndexStore === i && $focusWithinStore
|
'bg-red-500': $focusIndexStore === i && $focusWithinStore
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<CardPlaceholder {size} index={i} {orientation} />
|
<CardPlaceholder {size} index={i} {orientation} />
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Container } from '../actions/focusAction';
|
import { Container } from '../actions/focusAction';
|
||||||
|
|
||||||
export let container: Container;
|
export let container: Container;
|
||||||
const registerer = container.getHtmlElementRegisterer();
|
const registerer = container.getHtmlElementRegisterer();
|
||||||
|
|
||||||
export let handleClick = () => {
|
export let handleClick = () => {
|
||||||
container.focus();
|
container.focus();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button use:registerer tabindex="0" on:click={handleClick} class="outline-none ring-0">
|
<button use:registerer tabindex="0" on:click={handleClick} class="outline-none ring-0">
|
||||||
<slot />
|
<slot />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Container } from '../actions/focusAction';
|
import { Container } from '../actions/focusAction';
|
||||||
import Carousel from '../components/Carousel/Carousel.svelte';
|
import Carousel from '../components/Carousel/Carousel.svelte';
|
||||||
import CarouselPlaceholderItems from '../components/Carousel/CarouselPlaceholderItems.svelte';
|
import CarouselPlaceholderItems from '../components/Carousel/CarouselPlaceholderItems.svelte';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
export let container: Container;
|
export let container: Container;
|
||||||
const focusWithin = container.hasFocusWithin;
|
const focusWithin = container.hasFocusWithin;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class={classNames('flex flex-col', {
|
class={classNames('flex flex-col', {
|
||||||
'bg-green-100': $focusWithin
|
'bg-green-100': $focusWithin
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Carousel>
|
<Carousel>
|
||||||
<CarouselPlaceholderItems {container} />
|
<CarouselPlaceholderItems {container} />
|
||||||
</Carousel>
|
</Carousel>
|
||||||
<Carousel>
|
<Carousel>
|
||||||
<CarouselPlaceholderItems {container} />
|
<CarouselPlaceholderItems {container} />
|
||||||
</Carousel>
|
</Carousel>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,34 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Container } from '../actions/focusAction';
|
import type { Container } from '../actions/focusAction';
|
||||||
|
import { settings } from '../stores/settings.store';
|
||||||
|
import { jellyfinItemsStore } from '../stores/data.store';
|
||||||
|
import Carousel from '../components/Carousel/Carousel.svelte';
|
||||||
|
import CarouselPlaceholderItems from '../components/Carousel/CarouselPlaceholderItems.svelte';
|
||||||
|
|
||||||
export let container: Container;
|
export let parent: Container;
|
||||||
let registerer = container.getChildRegisterer();
|
let registerer = parent.getChildRegisterer();
|
||||||
|
|
||||||
|
settings.update((prev) => ({
|
||||||
|
...prev,
|
||||||
|
initialised: true,
|
||||||
|
jellyfin: {
|
||||||
|
...prev.jellyfin,
|
||||||
|
apiKey: import.meta.env.VITE_JELLYFIN_API_KEY,
|
||||||
|
baseUrl: import.meta.env.VITE_JELLYFIN_BASE_URL,
|
||||||
|
userId: import.meta.env.VITE_JELLYFIN_USER_ID
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
jellyfinItemsStore.subscribe((items) => {
|
||||||
|
console.warn('GOT ITEMS', items.data);
|
||||||
|
});
|
||||||
|
let asd: HTMLDivElement;
|
||||||
|
$: console.log('asd', asd);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div use:registerer>LibraryPage</div>
|
<div use:registerer bind:this={asd}>
|
||||||
|
<div>LibraryPage</div>
|
||||||
|
<Carousel>
|
||||||
|
<CarouselPlaceholderItems container={parent} />
|
||||||
|
</Carousel>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Container } from '../actions/focusAction';
|
import type { Container } from '../actions/focusAction';
|
||||||
|
|
||||||
export let container: Container;
|
export let container: Container;
|
||||||
let registerer = container.getChildRegisterer();
|
let registerer = container.getChildRegisterer();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div use:registerer>ManagePage</div>
|
<div use:registerer>ManagePage</div>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Container } from '../actions/focusAction';
|
import type { Container } from '../actions/focusAction';
|
||||||
|
|
||||||
export let container: Container;
|
export let container: Container;
|
||||||
let registerer = container.getChildRegisterer();
|
let registerer = container.getChildRegisterer();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div use:registerer>MoviesPage</div>
|
<div use:registerer>MoviesPage</div>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Container } from '../actions/focusAction';
|
import type { Container } from '../actions/focusAction';
|
||||||
|
|
||||||
export let container: Container;
|
export let container: Container;
|
||||||
let registerer = container.getChildRegisterer();
|
let registerer = container.getChildRegisterer();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div use:registerer>SearchPage</div>
|
<div use:registerer>SearchPage</div>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Container } from '../actions/focusAction';
|
import type { Container } from '../actions/focusAction';
|
||||||
|
|
||||||
export let container: Container;
|
export let container: Container;
|
||||||
let registerer = container.getChildRegisterer();
|
let registerer = container.getChildRegisterer();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div use:registerer>SeriesPage</div>
|
<div use:registerer>SeriesPage</div>
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
import { getJellyfinItems, type JellyfinItem } from '$lib/apis/jellyfin/jellyfinApi';
|
import { derived, writable } from 'svelte/store';
|
||||||
import {
|
import { settings } from './settings.store';
|
||||||
getRadarrDownloads,
|
import { getJellyfinItems, type JellyfinItem } from '../apis/jellyfin/jellyfinApi';
|
||||||
getRadarrMovies,
|
|
||||||
type RadarrDownload
|
|
||||||
} from '$lib/apis/radarr/radarrApi';
|
|
||||||
import {
|
import {
|
||||||
getSonarrDownloads,
|
getSonarrDownloads,
|
||||||
getSonarrSeries,
|
getSonarrSeries,
|
||||||
type SonarrDownload,
|
type SonarrDownload,
|
||||||
type SonarrSeries
|
type SonarrSeries
|
||||||
} from '$lib/apis/sonarr/sonarrApi';
|
} from '../apis/sonarr/sonarrApi';
|
||||||
import { derived, writable } from 'svelte/store';
|
import { getRadarrDownloads, getRadarrMovies, type RadarrDownload } from '../apis/radarr/radarrApi';
|
||||||
import { settings } from './settings.store';
|
|
||||||
|
|
||||||
async function waitForSettings() {
|
async function waitForSettings() {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
|
|||||||
2
tizen/.gitignore
vendored
2
tizen/.gitignore
vendored
@@ -1,2 +1,2 @@
|
|||||||
.sign/*
|
.sign/*
|
||||||
*.wgt
|
*.wgt
|
||||||
@@ -1,24 +1,24 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<projectDescription>
|
<projectDescription>
|
||||||
<name>Reiverr</name>
|
<name>Reiverr</name>
|
||||||
<comment></comment>
|
<comment></comment>
|
||||||
<projects>
|
<projects>
|
||||||
</projects>
|
</projects>
|
||||||
<buildSpec>
|
<buildSpec>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>json.validation.builder</name>
|
<name>json.validation.builder</name>
|
||||||
<arguments>
|
<arguments>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.tizen.web.project.builder.WebBuilder</name>
|
<name>org.tizen.web.project.builder.WebBuilder</name>
|
||||||
<arguments>
|
<arguments>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
<natures>
|
<natures>
|
||||||
<nature>json.validation.nature</nature>
|
<nature>json.validation.nature</nature>
|
||||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||||
<nature>org.tizen.web.project.builder.WebNature</nature>
|
<nature>org.tizen.web.project.builder.WebNature</nature>
|
||||||
</natures>
|
</natures>
|
||||||
</projectDescription>
|
</projectDescription>
|
||||||
|
|||||||
Reference in New Issue
Block a user