diff --git a/src/lib/apis/sonarr/sonarr-api.ts b/src/lib/apis/sonarr/sonarr-api.ts index f23f6fd..332eb69 100644 --- a/src/lib/apis/sonarr/sonarr-api.ts +++ b/src/lib/apis/sonarr/sonarr-api.ts @@ -207,7 +207,7 @@ export class SonarrApi implements Api { ) as EpisodeDownload[]) || [] ) || Promise.resolve([]); - getSonarrDownloadsById = (sonarrId: number) => + getDownloadsBySeriesId = (sonarrId: number) => this.getSonarrDownloads().then((downloads) => downloads.filter((d) => d.seriesId === sonarrId) ) || Promise.resolve([]); @@ -266,7 +266,7 @@ export class SonarrApi implements Api { // })); // }; - fetchSonarrReleases = async (episodeId: number) => + getEpisodeReleases = async (episodeId: number) => this.getClient() ?.GET('/api/v3/release', { params: { @@ -277,7 +277,7 @@ export class SonarrApi implements Api { }) .then((r) => r.data || []) || Promise.resolve([]); - fetchSonarrSeasonReleases = async (seriesId: number, seasonNumber: number) => + getSeasonReleases = async (seriesId: number, seasonNumber: number) => this.getClient() ?.GET('/api/v3/release', { params: { diff --git a/src/lib/components/HeroCarousel/HeroCarousel.svelte b/src/lib/components/HeroCarousel/HeroCarousel.svelte index 05ac3d3..5a07786 100644 --- a/src/lib/components/HeroCarousel/HeroCarousel.svelte +++ b/src/lib/components/HeroCarousel/HeroCarousel.svelte @@ -1,11 +1,9 @@ -
+ {#await downloads} {#each new Array(5) as _, index} -
+
{/each} {:then downloads} {#each downloads as download, index} -
- + +
{:else}

No downloads found

{/each} {/await} - + diff --git a/src/lib/components/MediaManager/FileList.svelte b/src/lib/components/MediaManager/FileList.svelte index 601bae2..96dd857 100644 --- a/src/lib/components/MediaManager/FileList.svelte +++ b/src/lib/components/MediaManager/FileList.svelte @@ -5,21 +5,22 @@ import { formatSize } from '../../utils.js'; import type { FileResource } from '../../apis/combined-types'; import { scrollIntoView } from '../../selectable'; + import Container from '../../../Container.svelte'; export let files: Promise; export let handleSelectFile: (file: FileResource) => void; -
+ {#await files} {#each new Array(5) as _, index} -
+
{/each} {:then files} {#each files as file, index} -
+
+ diff --git a/src/lib/components/MediaManager/MMModal.svelte b/src/lib/components/MediaManager/MMModal.svelte new file mode 100644 index 0000000..1a7c0e8 --- /dev/null +++ b/src/lib/components/MediaManager/MMModal.svelte @@ -0,0 +1,27 @@ + + + { + if (detail.direction === 'left' && detail.willLeaveContainer) { + modalStack.close(modalId); + detail.preventNavigation(); + } + }} + focusOnMount + trapFocus + class={classNames('fixed inset-0 bg-stone-950/80 overflow-auto', { + 'opacity-0': hidden + })} + canFocusEmpty +> +
+ +
+
diff --git a/src/lib/components/MediaManager/ReleaseList.svelte b/src/lib/components/MediaManager/ReleaseList.svelte index 00e7d31..8c312a8 100644 --- a/src/lib/components/MediaManager/ReleaseList.svelte +++ b/src/lib/components/MediaManager/ReleaseList.svelte @@ -8,6 +8,7 @@ import { derived } from 'svelte/store'; import ButtonGhost from '../Ghosts/ButtonGhost.svelte'; import type { SonarrRelease } from '../../apis/sonarr/sonarr-api'; + import Container from '../../../Container.svelte'; type Release = RadarrRelease | SonarrRelease; @@ -33,16 +34,16 @@ }); -
+ {#if $isLoading} {#each new Array(5) as _, index} -
+
{/each} {:else} {#each (showAll ? $releases : $filteredReleases)?.filter((r) => r.guid && r.indexerId) || [] as release, index} -
+
{/if} {/if} -
+ diff --git a/src/lib/components/MediaManager/sonarr/SonarrMediaMangerModal.svelte b/src/lib/components/MediaManager/sonarr/SonarrMediaMangerModal.svelte index 8a39e90..d9c2bb0 100644 --- a/src/lib/components/MediaManager/sonarr/SonarrMediaMangerModal.svelte +++ b/src/lib/components/MediaManager/sonarr/SonarrMediaMangerModal.svelte @@ -22,7 +22,7 @@ promise: downloads, data: downloadsData, refresh: refreshDownloads - } = useRequest(sonarrApi.getSonarrDownloadsById, id); + } = useRequest(sonarrApi.getDownloadsBySeriesId, id); const handleGrabRelease = (guid: string, indexerId: number) => sonarrApi diff --git a/src/lib/components/MediaManager/sonarr/modals/EpisodeListModal.svelte b/src/lib/components/MediaManager/sonarr/modals/EpisodeListModal.svelte index d999733..c8e4d27 100644 --- a/src/lib/components/MediaManager/sonarr/modals/EpisodeListModal.svelte +++ b/src/lib/components/MediaManager/sonarr/modals/EpisodeListModal.svelte @@ -36,7 +36,7 @@ modalStack.create( ReleaseListModal, { - getReleases: () => sonarrApi.fetchSonarrReleases(id), + getReleases: () => sonarrApi.getEpisodeReleases(id), selectRelease: handleSelectRelease }, groupId @@ -47,7 +47,7 @@ modalStack.create( ReleaseListModal, { - getReleases: () => sonarrApi.fetchSonarrSeasonReleases(seriesId, seasonNumber), + getReleases: () => sonarrApi.getSeasonReleases(seriesId, seasonNumber), selectRelease: handleSelectRelease }, groupId diff --git a/src/lib/components/MediaManagerModal/EpisodeMediaManagerModal.svelte b/src/lib/components/MediaManagerModal/EpisodeMediaManagerModal.svelte new file mode 100644 index 0000000..306bbb7 --- /dev/null +++ b/src/lib/components/MediaManagerModal/EpisodeMediaManagerModal.svelte @@ -0,0 +1,53 @@ + + + + {#await sonarrEpisode then sonarrEpisode} + {#if !sonarrEpisode} + + {:else} + +

{sonarrEpisode?.title}

+

Season {season} Episode {episode}

+ + + +
+ {/if} + {/await} +
diff --git a/src/lib/components/MediaManagerModal/MMAddToLayout.svelte b/src/lib/components/MediaManagerModal/MMAddToLayout.svelte new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/components/MediaManagerModal/MMAddToSonarr.svelte b/src/lib/components/MediaManagerModal/MMAddToSonarr.svelte new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/components/MediaManagerModal/MMMainLayout.svelte b/src/lib/components/MediaManagerModal/MMMainLayout.svelte new file mode 100644 index 0000000..95522a2 --- /dev/null +++ b/src/lib/components/MediaManagerModal/MMMainLayout.svelte @@ -0,0 +1,31 @@ + + +
+
+
+ +
+
+ +
+
+ +
+

Releases

+ +
+
+
+

Local Files

+ +
+ +
+

Downloads

+ +
+
+
+
diff --git a/src/lib/components/MediaManagerModal/MovieMediaManagerModal.svelte b/src/lib/components/MediaManagerModal/MovieMediaManagerModal.svelte new file mode 100644 index 0000000..89c0e56 --- /dev/null +++ b/src/lib/components/MediaManagerModal/MovieMediaManagerModal.svelte @@ -0,0 +1,38 @@ + + + + {#await radarrItem then movie} + {#if !movie} + + {:else} + +

{movie?.title}

+ + + +
+ {/if} + {/await} +
diff --git a/src/lib/components/MediaManagerModal/SeasonMediaManagerModal.svelte b/src/lib/components/MediaManagerModal/SeasonMediaManagerModal.svelte new file mode 100644 index 0000000..a455cd9 --- /dev/null +++ b/src/lib/components/MediaManagerModal/SeasonMediaManagerModal.svelte @@ -0,0 +1,41 @@ + + + + {#await sonarrItem then series} + {#if !series} + + {:else} + +

{series?.title}

+

Season {season} Packs

+ + + +
+ {/if} + {/await} +
diff --git a/src/lib/components/Modal/modal.store.ts b/src/lib/components/Modal/modal.store.ts index dc8b382..11704a6 100644 --- a/src/lib/components/Modal/modal.store.ts +++ b/src/lib/components/Modal/modal.store.ts @@ -1,5 +1,8 @@ import type { ComponentType, SvelteComponentTyped } from 'svelte'; import { derived, writable } from 'svelte/store'; +import SeasonMediaManagerModal from '../MediaManagerModal/SeasonMediaManagerModal.svelte'; +import EpisodeMediaManagerModal from '../MediaManagerModal/EpisodeMediaManagerModal.svelte'; +import MovieMediaManagerModal from '../MediaManagerModal/MovieMediaManagerModal.svelte'; type ModalItem = { id: symbol; @@ -49,6 +52,15 @@ function createModalStack() { export const modalStack = createModalStack(); export const modalStackTop = modalStack.top; +export const openSeasonMediaManager = (tmdbId: number, season: number) => + modalStack.create(SeasonMediaManagerModal, { id: tmdbId, season }); + +export const openEpisodeMediaManager = (tmdbId: number, season: number, episode: number) => + modalStack.create(EpisodeMediaManagerModal, { id: tmdbId, season, episode }); + +export const openMovieMediaManager = (tmdbId: number) => + modalStack.create(MovieMediaManagerModal, { id: tmdbId }); + // let lastTitleModal: symbol | undefined = undefined; // export function openTitleModal(titleId: TitleId) { // if (lastTitleModal) { diff --git a/src/lib/components/SeriesPage/EpisodeGrid.svelte b/src/lib/components/SeriesPage/EpisodeGrid.svelte index 175e7a5..8dec429 100644 --- a/src/lib/components/SeriesPage/EpisodeGrid.svelte +++ b/src/lib/components/SeriesPage/EpisodeGrid.svelte @@ -12,6 +12,9 @@ import classNames from 'classnames'; import ScrollHelper from '../ScrollHelper.svelte'; import { useNavigate } from 'svelte-navigator'; + import ManageSeasonCard from './ManageSeasonCard.svelte'; + import { TMDB_BACKDROP_SMALL } from '../../constants'; + import { modalStack, openSeasonMediaManager } from '../Modal/modal.store'; const navigate = useNavigate(); @@ -107,5 +110,9 @@ on:clickOrSelect={() => handleOpenEpisodePage(episode)} /> {/each} + openSeasonMediaManager(id, seasonIndex + 1)} + /> diff --git a/src/lib/components/SeriesPage/ManageSeasonCard.svelte b/src/lib/components/SeriesPage/ManageSeasonCard.svelte new file mode 100644 index 0000000..a319ad4 --- /dev/null +++ b/src/lib/components/SeriesPage/ManageSeasonCard.svelte @@ -0,0 +1,33 @@ + + + + +
+
+
+ +
+
+ + diff --git a/src/lib/components/SeriesPage/SeriesPage.svelte b/src/lib/components/SeriesPage/SeriesPage.svelte index d075df0..7db1524 100644 --- a/src/lib/components/SeriesPage/SeriesPage.svelte +++ b/src/lib/components/SeriesPage/SeriesPage.svelte @@ -15,13 +15,13 @@ import { derived } from 'svelte/store'; import { scrollIntoView, useRegistrar } from '../../selectable'; import ScrollHelper from '../ScrollHelper.svelte'; - import SonarrMediaMangerModal from '../MediaManager/sonarr/SonarrMediaMangerModal.svelte'; import Carousel from '../Carousel/Carousel.svelte'; import TmdbPersonCard from '../PersonCard/TmdbPersonCard.svelte'; import TmdbCard from '../Card/TmdbCard.svelte'; import EpisodeGrid from './EpisodeGrid.svelte'; import { Route } from 'svelte-navigator'; import EpisodePage from '../../pages/EpisodePage.svelte'; + import SeriesMediaManagerModal from '../MediaManagerModal/SeasonMediaManagerModal.svelte'; export let id: string; @@ -168,29 +168,18 @@ {/if} - {#if sonarrItem} - - {:else} - - {/if} + {#if PLATFORM_WEB} {/await} - + diff --git a/src/lib/pages/MoviePage.svelte b/src/lib/pages/MoviePage.svelte index 53d111d..0861a8c 100644 --- a/src/lib/pages/MoviePage.svelte +++ b/src/lib/pages/MoviePage.svelte @@ -10,7 +10,7 @@ import { radarrApi } from '../apis/radarr/radarr-api'; import { useActionRequests, useRequest } from '../stores/data.store'; import DetachedPage from '../components/DetachedPage/DetachedPage.svelte'; - import { modalStack } from '../components/Modal/modal.store'; + import { modalStack, openMovieMediaManager } from '../components/Modal/modal.store'; import { playerState } from '../components/VideoPlayer/VideoPlayer'; import ManageMediaModal from '../components/MediaManager/radarr/RadarrMediaMangerModal.svelte'; @@ -98,13 +98,9 @@ {/if} {#if radarrItem} -