fix: Episode page file requesting

This commit is contained in:
Aleksi Lassila
2024-06-08 16:56:09 +03:00
parent 88f1be68d5
commit 711fcd5e7f
8 changed files with 50 additions and 118 deletions

View File

@@ -1,108 +0,0 @@
<script lang="ts">
import { sonarrApi } from '../../apis/sonarr/sonarr-api';
import MMMainLayout from './MMMainLayout.svelte';
import MMModal from './MMModal.svelte';
import ReleaseList from './Releases/MMReleasesTab.svelte';
import DownloadList from '../MediaManager/DownloadList.svelte';
import FileList from './LocalFiles/MMLocalFilesTab.svelte';
import { log } from '../../utils';
import type { Release } from '../../apis/combined-types';
import type {
CancelDownloadFn,
CancelDownloadsFn,
DeleteFileFn,
DeleteFilesFn,
GrabReleaseFn
} from './MediaManagerModal';
import { onDestroy } from 'svelte';
import MMReleasesTab from './Releases/MMReleasesTab.svelte';
import MMLocalFilesTab from './LocalFiles/MMLocalFilesTab.svelte';
import MMTitle from './MMTitle.svelte';
export let id: number; // Tmdb ID
export let season: number;
export let episode: number;
export let modalId: symbol;
export let hidden: boolean;
const sonarrItem = sonarrApi.getSeriesByTmdbId(id);
const sonarrEpisode = sonarrItem.then((si) =>
sonarrApi
.getEpisodes(si?.id || -1, season)
.then((episodes) => episodes.find((e) => e.episodeNumber === episode))
);
let releases: Promise<Release[]> = getReleases();
// let files = getLocalFiles();
// let downloads = getDownloads();
// let refreshDownloadsTimeout: ReturnType<typeof setTimeout>;
const grabRelease: GrabReleaseFn = (release) =>
sonarrApi.downloadSonarrRelease(release.guid || '', release.indexerId || -1).then((r) => {
// refreshDownloadsTimeout = setTimeout(() => {
// downloads = getDownloads();
// }, 8000);
return r;
});
// const deleteFile: DeleteFileFn = (...args) =>
// sonarrApi.deleteSonarrEpisode(...args).then((r) => {
// files = getLocalFiles();
// return r;
// });
// const deleteFiles: DeleteFilesFn = (...args) =>
// sonarrApi.deleteSonarrEpisodes(...args).then((r) => {
// files = getLocalFiles();
// return r;
// });
// const cancelDownload: CancelDownloadFn = (...args) =>
// sonarrApi.cancelDownload(...args).then((r) => {
// downloads = getDownloads();
// return r;
// });
// const cancelDownloads: CancelDownloadsFn = (...args) =>
// sonarrApi.cancelDownloads(...args).then((r) => {
// downloads = getDownloads();
// return r;
// });
function getReleases() {
return sonarrEpisode.then((se) => sonarrApi.getEpisodeReleases(se?.id || -1));
}
// function getLocalFiles() {
// return sonarrItem.then((si) => sonarrApi.getFilesBySeriesId(si?.id || -1)); // TODO
// }
//
// function getDownloads() {
// return sonarrItem
// .then((si) => sonarrApi.getDownloadsBySeriesId(si?.id || -1))
// .then((ds) =>
// ds.filter((d) => d.episode?.seasonNumber === season && d.episode?.episodeNumber === episode)
// );
// }
// onDestroy(() => {
// clearTimeout(refreshDownloadsTimeout);
// });
</script>
<MMModal {modalId} {hidden}>
{#await sonarrEpisode then sonarrEpisode}
{#if !sonarrEpisode}
<!-- <MMAddToSonarr />-->
{:else}
<div class="pt-20 h-screen flex flex-col">
<MMTitle class="mb-32 mx-32">
<h1 slot="title">{sonarrEpisode?.title}</h1>
<h2 slot="subtitle">Season {season} Episode {episode}</h2>
</MMTitle>
<div class="mx-20 flex-1 overflow-y-auto scrollbar-hide pb-20">
<MMReleasesTab {releases} {grabRelease} />
</div>
</div>
{/if}
{/await}
</MMModal>

View File

@@ -28,7 +28,7 @@
export let title: string;
export let modalId: symbol;
export let onComplete: () => void = () => {};
export let onComplete: (() => void) | (() => Promise<any>) = () => Promise.resolve();
$: backgroundUrl = TMDB_BACKDROP_SMALL + backdropUri;
let tab: 'add-to-sonarr' | 'root-folders' | 'quality-profiles' | 'monitor-settings' =
@@ -63,7 +63,7 @@
});
addOptionsStore.subscribe(() => (tab = 'add-to-sonarr'));
function handleAddToSonarr() {
async function handleAddToSonarr() {
return sonarrApi
.addToSonarr(tmdbId as number, {
rootFolderPath: $addOptionsStore.rootFolderPath || undefined,
@@ -73,7 +73,7 @@
.then((success) => {
if (success) {
modalStack.close(modalId);
onComplete();
return onComplete();
}
});
}

View File

@@ -25,7 +25,7 @@
import EpisodeGrid from './EpisodeGrid.svelte';
import { formatSize } from '../../utils';
import FileDetailsDialog from './FileDetailsDialog.svelte';
import SeasonMediaManagerModal from '../MediaManagerModal/SeasonMediaManagerModal.svelte';
import SeasonMediaManagerModal from '../MediaManagerModal/SonarrMediaManagerModal.svelte';
import MMAddToSonarrDialog from '../MediaManagerModal/MMAddToSonarrDialog.svelte';
import ConfirmDialog from '../Dialog/ConfirmDialog.svelte';
import DownloadDetailsDialog from './DownloadDetailsDialog.svelte';

View File

@@ -9,7 +9,7 @@
import Button from '../components/Button.svelte';
import { jellyfinApi } from '../apis/jellyfin/jellyfin-api';
import { playerState } from '../components/VideoPlayer/VideoPlayer';
import { formatSize } from '../utils';
import { formatSize, retry, timeout } from '../utils';
import { createModal } from '../components/Modal/modal.store';
import ButtonGhost from '../components/Ghosts/ButtonGhost.svelte';
import {
@@ -19,8 +19,9 @@
type SonarrSeries
} from '../apis/sonarr/sonarr-api';
import MMAddToSonarrDialog from '../components/MediaManagerModal/MMAddToSonarrDialog.svelte';
import SeasonMediaManagerModal from '../components/MediaManagerModal/SeasonMediaManagerModal.svelte';
import SonarrMediaManagerModal from '../components/MediaManagerModal/SonarrMediaManagerModal.svelte';
import ConfirmDialog from '../components/Dialog/ConfirmDialog.svelte';
import { tick } from 'svelte';
export let id: string; // Series ID
export let season: string;
@@ -65,10 +66,21 @@
});
}
function handleRequestEpisode() {
async function handleAddedToSonarr() {
sonarrItem = sonarrApi.getSeriesByTmdbId(Number(id));
return retry(() => getSonarrEpisode(sonarrItem)).then((sonarrEpisode) => {
sonarrEpisode &&
createModal(SonarrMediaManagerModal, {
sonarrItem: sonarrEpisode,
onGrabRelease: () => {}
});
});
}
async function handleRequestEpisode() {
return Promise.all([sonarrEpisode, tmdbEpisode]).then(([sonarrEpisode, tmdbEpisode]) => {
if (sonarrEpisode) {
createModal(SeasonMediaManagerModal, {
createModal(SonarrMediaManagerModal, {
sonarrItem: sonarrEpisode,
onGrabRelease: () => {} // TODO
});
@@ -77,7 +89,7 @@
tmdbId: Number(id),
backdropUri: tmdbEpisode.still_path || '',
title: tmdbEpisode.name || '',
onComplete: () => (sonarrItem = sonarrApi.getSeriesByTmdbId(Number(id)))
onComplete: handleAddedToSonarr
});
} else {
console.error('No series found');

View File

@@ -25,7 +25,7 @@
import Carousel from '../components/Carousel/Carousel.svelte';
import TmdbPersonCard from '../components/PersonCard/TmdbPersonCard.svelte';
import TmdbCard from '../components/Card/TmdbCard.svelte';
import MovieMediaManagerModal from '../components/MediaManagerModal/MovieMediaManagerModal.svelte';
import MovieMediaManagerModal from '../components/MediaManagerModal/RadarrMediaManagerModal.svelte';
import MMAddToRadarrDialog from '../components/MediaManagerModal/MMAddToRadarrDialog.svelte';
import FileDetailsDialog from '../components/SeriesPage/FileDetailsDialog.svelte';
import DownloadDetailsDialog from '../components/SeriesPage/DownloadDetailsDialog.svelte';

View File

@@ -91,6 +91,34 @@ export function timeout<T>(ms: number, ret?: T) {
return new Promise<T | void>((resolve) => setTimeout(() => resolve(ret), ms));
}
export function retry<T>(
fn: () => Promise<T>,
successFn: (v: T) => boolean = (v) => !!v,
options: { retries?: number; delay?: number; reject?: boolean } = {}
) {
let { retries = 3, delay = 1000, reject = false } = options;
return new Promise<T>((resolve, _reject) => {
function attempt() {
fn().then((v) => {
if (successFn(v)) {
resolve(v);
} else {
if (retries > 0) {
retries--;
setTimeout(attempt, delay);
} else if (reject) {
_reject(new Error('Max retries reached'));
} else {
resolve(v);
}
}
});
}
attempt();
});
}
export function formatDateToYearMonthDay(date: Date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');