upend/webui/src/components/display/BlobPreview.svelte

81 lines
1.8 KiB
Svelte

<script lang="ts">
import { useEntity } from "../../lib/entity";
import Spinner from "../utils/Spinner.svelte";
import ModelViewer from "./blobs/ModelViewer.svelte";
import TextViewer from "./blobs/TextViewer.svelte";
export let address: string;
$: ({ entity } = useEntity(address));
$: mimeType = String($entity?.get("FILE_MIME"));
$: handled =
Boolean(mimeType) &&
["audio", "video", "image", "model", "text"].some((prefix) =>
mimeType.startsWith(prefix)
);
let imageLoaded = null;
</script>
{#if handled}
<div class="preview">
{#if mimeType?.startsWith("text")}
<div class="text">
<TextViewer {address} />
</div>
{/if}
{#if mimeType?.startsWith("audio")}
<audio controls preload="auto" src="/api/raw/{address}" />
{/if}
{#if mimeType?.startsWith("video")}
<!-- svelte-ignore a11y-media-has-caption -->
<video
controls
preload="auto"
src="/api/raw/{address}"
poster="/api/thumb/{address}"
/>
{/if}
{#if mimeType?.startsWith("image")}
<a target="_blank" href="/api/raw/{address}">
{#if imageLoaded != address}
<Spinner />
{/if}
<img
src="/api/thumb/{address}"
alt={address}
on:load={() => (imageLoaded = address)}
/>
</a>
{/if}
{#if mimeType?.startsWith("model")}
<ModelViewer src="/api/raw/{address}" />
{/if}
</div>
{/if}
<style scoped lang="scss">
.preview {
display: flex;
justify-content: center;
align-items: center;
}
audio,
video,
img,
.text {
width: 100%;
max-height: 25em;
}
.text {
display: flex;
margin-bottom: 1rem;
}
video {
background: rgba(128, 128, 128, 128);
}
</style>