mirror of
https://github.com/aleksilassila/reiverr.git
synced 2026-04-23 01:05:13 +02:00
Fully working sonarr integration
This commit is contained in:
@@ -7,13 +7,15 @@
|
||||
import HeightHider from '../HeightHider.svelte';
|
||||
import IconButton from '../IconButton.svelte';
|
||||
import Modal from '../Modal/Modal.svelte';
|
||||
import ModalContent from '../Modal/ModalContent.svelte';
|
||||
import ModalContent from '../Modal/ModalContainer.svelte';
|
||||
import ModalHeader from '../Modal/ModalHeader.svelte';
|
||||
import type { ModalProps } from '../Modal/Modal';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
// TODO: Switch to grid
|
||||
export let visible = true; // FIXME
|
||||
export let title = 'Releases';
|
||||
export let modalProps: ModalProps;
|
||||
export let radarrId: number | undefined = undefined;
|
||||
export let sonarrEpisodeId: number | undefined = undefined;
|
||||
|
||||
@@ -22,12 +24,6 @@
|
||||
let downloadFetchingGuid: string | undefined;
|
||||
let downloadingGuid: string | undefined;
|
||||
|
||||
let releasesResponse: ReturnType<typeof fetchReleases>;
|
||||
|
||||
$: if (visible && !releasesResponse) {
|
||||
releasesResponse = fetchReleases();
|
||||
}
|
||||
|
||||
async function fetchReleases() {
|
||||
if (!radarrId && !sonarrEpisodeId) {
|
||||
return {
|
||||
@@ -85,18 +81,12 @@
|
||||
showDetailsId = id;
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
visible = false;
|
||||
downloadFetchingGuid = undefined;
|
||||
downloadingGuid = undefined;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal {visible} {close}>
|
||||
<Modal {...modalProps}>
|
||||
<ModalContent>
|
||||
<ModalHeader {close} text="Releases" />
|
||||
{#await releasesResponse}
|
||||
<ModalHeader {...modalProps} text={title} />
|
||||
{#await fetchReleases()}
|
||||
<div class="text-sm text-zinc-200 opacity-50 font-light p-4">Loading...</div>
|
||||
{:then { releases, filtered, releasesSkipped }}
|
||||
{#if showAllReleases ? releases?.length : filtered?.length}
|
||||
@@ -150,7 +140,9 @@
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
{#if releasesSkipped > 0}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class="text-sm text-zinc-200 opacity-50 font-light px-4 py-2 hover:underline cursor-pointer"
|
||||
on:click={toggleShowAll}
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { fetchSonarrEpisodes, type SonarrEpisode } from '$lib/apis/sonarr/sonarrApi';
|
||||
import { ChevronUp } from 'radix-icons-svelte';
|
||||
import IconButton from '../IconButton.svelte';
|
||||
import { createModalProps, type ModalProps } from '../Modal/Modal';
|
||||
import Modal from '../Modal/Modal.svelte';
|
||||
import ModalContent from '../Modal/ModalContent.svelte';
|
||||
import ModalContainer from '../Modal/ModalContainer.svelte';
|
||||
import ModalHeader from '../Modal/ModalHeader.svelte';
|
||||
import RequestModal from './RequestModal.svelte';
|
||||
import ModalContent from '../Modal/ModalContent.svelte';
|
||||
|
||||
export let visible = false;
|
||||
export let modalProps: ModalProps;
|
||||
export let sonarrId: number;
|
||||
|
||||
let episodesPromise: ReturnType<typeof fetchEpisodes>;
|
||||
|
||||
$: if (visible && !episodesPromise) {
|
||||
episodesPromise = fetchEpisodes(sonarrId);
|
||||
}
|
||||
|
||||
function close() {
|
||||
visible = false;
|
||||
}
|
||||
let selectedEpisode: SonarrEpisode | undefined;
|
||||
let requestModalProps = createModalProps(() => {
|
||||
modalProps.close();
|
||||
selectedEpisode = undefined;
|
||||
});
|
||||
|
||||
async function fetchEpisodes(sonarrId: number) {
|
||||
return fetchSonarrEpisodes(sonarrId).then((episodes) => {
|
||||
@@ -37,43 +38,64 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal {visible} {close}>
|
||||
<ModalContent>
|
||||
<ModalHeader {close} text="Seasons" />
|
||||
<div class="flex flex-col gap-2 sm:gap-4">
|
||||
{#await episodesPromise then seasons}
|
||||
{console.log('saesons', seasons)}
|
||||
{#each seasons as episodes, i}
|
||||
{#if i > 0}
|
||||
<div class="border-t border-gray-200" />
|
||||
{/if}
|
||||
|
||||
{#each episodes as episode}
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<div class="flex flex-col">
|
||||
<div class="text-sm font-medium text-gray-900">
|
||||
{episode.episodeNumber}. {episode.title}
|
||||
</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
{episode.airDate}
|
||||
</div>
|
||||
<Modal {...modalProps}>
|
||||
<ModalContainer>
|
||||
<ModalHeader {...modalProps} text="Seasons" />
|
||||
<ModalContent>
|
||||
<div class="flex flex-col divide-y divide-zinc-700">
|
||||
{#await fetchEpisodes(sonarrId)}
|
||||
Loading...
|
||||
{:then seasons}
|
||||
{#each seasons as episodes, i}
|
||||
<div class="pb-2">
|
||||
<div
|
||||
class="px-4 py-3 flex justify-between items-center cursor-pointer text-zinc-300 group-hover:text-zinc-300"
|
||||
>
|
||||
<div class="uppercase font-bold text-sm">
|
||||
Season {i + 1}
|
||||
</div>
|
||||
<ChevronUp size={20} />
|
||||
</div>
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<div class="flex flex-col">
|
||||
<div class="text-sm font-medium text-gray-900">
|
||||
{episode.episodeNumber}. {episode.title}
|
||||
</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
{episode.airDate}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
{#if episodes.length === 0}
|
||||
<div class="px-4 py-1 text-xs text-gray-400">No episodes</div>
|
||||
{:else}
|
||||
{#each episodes as episode}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div
|
||||
class="px-4 py-1 flex flex-row items-center justify-between cursor-pointer hover:bg-lighten"
|
||||
on:click={() => (selectedEpisode = episode)}
|
||||
>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-sm font-medium">{episode.title}</div>
|
||||
<div class="text-xs text-gray-400">
|
||||
{episode.episodeNumber ? `Episode ${episode.episodeNumber}` : 'Special'}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-xs text-gray-400">
|
||||
{new Date(episode.airDate || Date.now()).toLocaleDateString('en', {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
{/each}
|
||||
{/await}
|
||||
</div>
|
||||
</ModalContent>
|
||||
{/await}
|
||||
</div>
|
||||
</ModalContent>
|
||||
</ModalContainer>
|
||||
</Modal>
|
||||
|
||||
{#if selectedEpisode?.id}
|
||||
<RequestModal
|
||||
modalProps={requestModalProps}
|
||||
sonarrEpisodeId={selectedEpisode.id}
|
||||
title={selectedEpisode.title || undefined}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user