Files
fileserver/frontend/src/components/FileViewer.svelte

58 lines
2.0 KiB
Svelte

<script lang="ts">
import {Button, Spinner} from 'flowbite-svelte';
import {Download} from 'carbon-icons-svelte';
import {api, rpc, token, workingWrapperR} from '../store';
import {onDestroy} from 'svelte';
export let node: api.Node;
let src = '';
let loading = false;
let mime: string|null;
let image: boolean, video: boolean, audio: boolean, pdf: boolean, can_display: boolean;
$: workingWrapperR<string>(() => rpc.FS_get_mime($token ?? '', node.id)).then(v => mime = v);
$: image = mime?.startsWith('image/') ?? false;
$: video = mime?.startsWith('video/') ?? false;
$: audio = mime?.startsWith('audio/') ?? false;
$: pdf = mime === 'application/pdf';
$: can_display = image || video || audio || pdf;
async function load() {
loading = true;
if (src.startsWith('blob'))
URL.revokeObjectURL(src);
const resp = await fetch('/download', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `token=${$token ?? ''}&node=${node.id}`
});
if (resp.status != 200)
return;
src = URL.createObjectURL(await resp.blob());
loading = false;
}
$: if (image || pdf) load();
onDestroy(() => { if (src.startsWith('blob')) URL.revokeObjectURL(src); });
</script>
<Button class="w-full mb-6"><Download />Download</Button>
{#if can_display && !loading && src === ''}
<Button class="w-full" outline on:click={load}>Load</Button>
{:else if loading}
<Spinner class="w-full" />
{:else if can_display && src !== ''}
{#if image}
<img class="w-full" alt="img" src={src} />
{:else if video}
<!-- svelte-ignore a11y-media-has-caption -->
<video class="w-full" src={src} controls autoplay />
{:else if audio}
<audio class="w-full" src={src} controls autoplay />
{:else if pdf}
<embed class="w-full" style="height: 75vh" src={src} type="application/pdf" />
{/if}
{/if}