mirror of
https://github.com/maxdorninger/MediaManager.git
synced 2026-04-19 11:54:09 +02:00
Merge branch 'refs/heads/master' into fork/aasmoe/feat/multi-language-metadata
# Conflicts: # metadata_relay/app/tmdb.py # web/src/lib/api/api.d.ts
This commit is contained in:
109
web/src/lib/components/delete-media-dialog.svelte
Normal file
109
web/src/lib/components/delete-media-dialog.svelte
Normal file
@@ -0,0 +1,109 @@
|
||||
<script lang="ts">
|
||||
import type { components } from '$lib/api/api.ts';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import client from '$lib/api/index.ts';
|
||||
import { goto } from '$app/navigation';
|
||||
import { resolve } from '$app/paths';
|
||||
import { getFullyQualifiedMediaName } from '$lib/utils.ts';
|
||||
import * as AlertDialog from '$lib/components/ui/alert-dialog/index.js';
|
||||
import { Checkbox } from '$lib/components/ui/checkbox/index.js';
|
||||
import { Label } from '$lib/components/ui/label/index.js';
|
||||
import { buttonVariants } from '$lib/components/ui/button/index.js';
|
||||
|
||||
let {
|
||||
media,
|
||||
isShow
|
||||
}: {
|
||||
media: components['schemas']['PublicMovie'] | components['schemas']['PublicShow'];
|
||||
isShow: boolean;
|
||||
} = $props();
|
||||
let deleteDialogOpen = $state(false);
|
||||
let deleteFilesOnDisk = $state(false);
|
||||
let deleteTorrents = $state(false);
|
||||
|
||||
async function delete_movie() {
|
||||
if (!media.id) {
|
||||
toast.error('Movie ID is missing');
|
||||
return;
|
||||
}
|
||||
const { response } = await client.DELETE('/api/v1/movies/{movie_id}', {
|
||||
params: {
|
||||
path: { movie_id: media.id },
|
||||
query: { delete_files_on_disk: deleteFilesOnDisk, delete_torrents: deleteTorrents }
|
||||
}
|
||||
});
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
toast.error('Failed to delete movie: ' + errorText);
|
||||
} else {
|
||||
toast.success('Movie deleted successfully.');
|
||||
deleteDialogOpen = false;
|
||||
await goto(resolve('/dashboard/movies', {}), { invalidateAll: true });
|
||||
}
|
||||
}
|
||||
|
||||
async function delete_show() {
|
||||
const { response } = await client.DELETE('/api/v1/tv/shows/{show_id}', {
|
||||
params: {
|
||||
path: { show_id: media.id! },
|
||||
query: { delete_files_on_disk: deleteFilesOnDisk, delete_torrents: deleteTorrents }
|
||||
}
|
||||
});
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
toast.error('Failed to delete show: ' + errorText);
|
||||
} else {
|
||||
toast.success('Show deleted successfully.');
|
||||
deleteDialogOpen = false;
|
||||
await goto(resolve('/dashboard/tv', {}), { invalidateAll: true });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<AlertDialog.Root bind:open={deleteDialogOpen}>
|
||||
<AlertDialog.Trigger class={buttonVariants({ variant: 'destructive' })}>
|
||||
Delete {isShow ? ' Show' : ' Movie'}
|
||||
</AlertDialog.Trigger>
|
||||
<AlertDialog.Content>
|
||||
<AlertDialog.Header>
|
||||
<AlertDialog.Title>Delete - {getFullyQualifiedMediaName(media)}?</AlertDialog.Title>
|
||||
<AlertDialog.Description>
|
||||
This action cannot be undone. This will permanently delete
|
||||
<strong>{getFullyQualifiedMediaName(media)}</strong>.
|
||||
</AlertDialog.Description>
|
||||
</AlertDialog.Header>
|
||||
<div class="flex flex-col gap-3 py-4">
|
||||
<div class="flex items-center space-x-2">
|
||||
<Checkbox bind:checked={deleteFilesOnDisk} id="delete-files" />
|
||||
<Label
|
||||
for="delete-files"
|
||||
class="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
Also delete files on disk (this will only remove imported files, not downloads)
|
||||
</Label>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<Checkbox bind:checked={deleteTorrents} id="delete-torrents" />
|
||||
<Label
|
||||
for="delete-torrents"
|
||||
class="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
Also delete torrents (this will remove torrents from your download clients)
|
||||
</Label>
|
||||
</div>
|
||||
</div>
|
||||
<AlertDialog.Footer>
|
||||
<AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
|
||||
<AlertDialog.Action
|
||||
onclick={() => {
|
||||
if (isShow) {
|
||||
delete_show();
|
||||
} else delete_movie();
|
||||
}}
|
||||
class={buttonVariants({ variant: 'destructive' })}
|
||||
>
|
||||
Delete
|
||||
</AlertDialog.Action>
|
||||
</AlertDialog.Footer>
|
||||
</AlertDialog.Content>
|
||||
</AlertDialog.Root>
|
||||
@@ -22,6 +22,7 @@
|
||||
let email = $state('');
|
||||
let password = $state('');
|
||||
let errorMessage = $state('');
|
||||
let successMessage = $state('');
|
||||
let isLoading = $state(false);
|
||||
|
||||
async function handleLogin(event: Event) {
|
||||
@@ -29,6 +30,7 @@
|
||||
|
||||
isLoading = true;
|
||||
errorMessage = '';
|
||||
successMessage = '';
|
||||
|
||||
const { error, response } = await client.POST('/api/v1/auth/cookie/login', {
|
||||
body: {
|
||||
@@ -45,8 +47,8 @@
|
||||
if (!error) {
|
||||
console.log('Login successful!');
|
||||
console.log('Received User Data: ', response);
|
||||
errorMessage = 'Login successful! Redirecting...';
|
||||
toast.success(errorMessage);
|
||||
successMessage = 'Login successful! Redirecting...';
|
||||
toast.success(successMessage);
|
||||
goto(resolve('/dashboard', {}));
|
||||
} else {
|
||||
toast.error('Login failed!');
|
||||
@@ -100,6 +102,13 @@
|
||||
</Alert.Root>
|
||||
{/if}
|
||||
|
||||
{#if successMessage}
|
||||
<Alert.Root variant="default">
|
||||
<Alert.Title>Success</Alert.Title>
|
||||
<Alert.Description>{successMessage}</Alert.Description>
|
||||
</Alert.Root>
|
||||
{/if}
|
||||
|
||||
{#if isLoading}
|
||||
<LoadingBar />
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user