refactor: unify media type detection

This commit is contained in:
Tomáš Mládek 2022-10-23 11:15:19 +02:00
parent 4c0d352bd3
commit 23b3388ea5
3 changed files with 72 additions and 60 deletions

View file

@ -6,43 +6,26 @@
import VideoViewer from "./blobs/VideoViewer.svelte"; import VideoViewer from "./blobs/VideoViewer.svelte";
import HashBadge from "./HashBadge.svelte"; import HashBadge from "./HashBadge.svelte";
import { API_URL } from "../../lib/api"; import { API_URL } from "../../lib/api";
import { GROUP_TYPE_ADDR } from "upend/constants";
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
import { getTypes } from "../../util/mediatypes";
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
export let address: string; export let address: string;
export let recurse = 3; export let recurse = 3;
$: ({ entity, entityInfo } = useEntity(address)); $: ({ entity, entityInfo } = useEntity(address));
$: types = getTypes($entity, $entityInfo);
$: mimeType = String($entity?.get("FILE_MIME"));
$: audio =
["audio", "application/x-riff"].some((p) => mimeType.startsWith(p)) &&
!video;
$: video =
["video", "application/x-matroska"].some((p) => mimeType.startsWith(p)) ||
$entity?.identify().some((l) => l.endsWith(".avi"));
$: image = mimeType.startsWith("image");
$: text = mimeType.startsWith("text");
$: model =
mimeType?.startsWith("model") ||
$entity?.identify().some((l) => l.endsWith(".stl"));
$: web = $entityInfo?.t == "Url";
$: fragment = Boolean($entity?.get("ANNOTATES"));
$: group = $entity?.get("IS") == GROUP_TYPE_ADDR;
$: handled = $: handled =
!$entity || !$entity ||
audio || types.audio ||
video || types.video ||
image || types.image ||
text || types.text ||
model || types.model ||
web || types.web ||
fragment || types.fragment ||
(group && recurse > 0); (types.group && recurse > 0);
$: dispatch("handled", handled); $: dispatch("handled", handled);
@ -80,7 +63,7 @@
<div class="preview" bind:clientHeight> <div class="preview" bind:clientHeight>
{#if handled} {#if handled}
{#if group} {#if types.group}
<ul class="group"> <ul class="group">
{#each groupChildren as address (address)} {#each groupChildren as address (address)}
<li> <li>
@ -94,9 +77,9 @@
</li> </li>
{/each} {/each}
</ul> </ul>
{:else if model} {:else if types.model}
<ModelViewer lookonly src="{API_URL}/raw/{address}" /> <ModelViewer lookonly src="{API_URL}/raw/{address}" />
{:else if web} {:else if types.web}
{#if imageLoaded != address} {#if imageLoaded != address}
<Spinner /> <Spinner />
{/if} {/if}
@ -106,11 +89,11 @@
on:load={() => (imageLoaded = address)} on:load={() => (imageLoaded = address)}
on:error={() => (handled = false)} on:error={() => (handled = false)}
/> />
{:else if fragment} {:else if types.fragment}
<FragmentViewer {address} detail={false} /> <FragmentViewer {address} detail={false} />
{:else if video} {:else if types.video}
<VideoViewer {address} detail={false} /> <VideoViewer {address} detail={false} />
{:else if audio} {:else if types.audio}
<div class="audiopreview image"> <div class="audiopreview image">
{#if handled && imageLoaded != address} {#if handled && imageLoaded != address}
<div class="spinner"> <div class="spinner">
@ -137,7 +120,7 @@
</div> </div>
{/if} {/if}
<img <img
src="{API_URL}/{mimeType?.includes('svg+xml') src="{API_URL}/{types.mimeType?.includes('svg+xml')
? 'raw' ? 'raw'
: 'thumb'}/{address}?size=512&quality=75" : 'thumb'}/{address}?size=512&quality=75"
alt="Thumbnail for {address}..." alt="Thumbnail for {address}..."

View file

@ -10,6 +10,7 @@
import UpLink from "./UpLink.svelte"; import UpLink from "./UpLink.svelte";
import { API_URL } from "../../lib/api"; import { API_URL } from "../../lib/api";
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
import { getTypes } from "../../util/mediatypes";
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
export let address: string; export let address: string;
@ -19,26 +20,17 @@
let handled = false; let handled = false;
$: ({ entity, entityInfo } = useEntity(address)); $: ({ entity, entityInfo } = useEntity(address));
$: types = getTypes($entity, $entityInfo);
$: mimeType = String($entity?.get("FILE_MIME"));
$: audio =
["audio", "application/x-riff"].some((p) => mimeType.startsWith(p)) &&
!video;
$: video =
["video", "application/x-matroska"].some((p) => mimeType.startsWith(p)) ||
$entity?.identify().some((l) => l.endsWith(".avi"));
$: image = mimeType.startsWith("image");
$: text = mimeType.startsWith("text");
$: pdf = mimeType.startsWith("application/pdf");
$: model =
mimeType?.startsWith("model") ||
$entity?.identify().some((l) => l.endsWith(".stl"));
$: web = $entityInfo?.t == "Url";
$: fragment = Boolean($entity?.get("ANNOTATES"));
$: handled = $: handled =
audio || video || image || text || pdf || model || web || fragment; types.audio ||
types.video ||
types.image ||
types.text ||
types.pdf ||
types.model ||
types.web ||
types.fragment;
$: dispatch("handled", handled); $: dispatch("handled", handled);
@ -47,30 +39,30 @@
{#if handled} {#if handled}
<div class="preview" class:detail> <div class="preview" class:detail>
{#if text} {#if types.text}
<div class="text"> <div class="text">
<TextViewer {address} /> <TextViewer {address} />
</div> </div>
{/if} {/if}
{#if audio} {#if types.audio}
<AudioViewer {address} {detail} {editable} /> <AudioViewer {address} {detail} {editable} />
{/if} {/if}
{#if video} {#if types.video}
<VideoViewer detail {address} /> <VideoViewer detail {address} />
{/if} {/if}
{#if image} {#if types.image}
<ImageViewer {address} {editable} {detail} /> <ImageViewer {address} {editable} {detail} />
{/if} {/if}
{#if pdf} {#if types.pdf}
<iframe <iframe
src="{API_URL}/raw/{address}?inline" src="{API_URL}/raw/{address}?inline"
title="PDF document of {address}" title="PDF document of {address}"
/> />
{/if} {/if}
{#if model} {#if types.model}
<ModelViewer src="{API_URL}/raw/{address}" /> <ModelViewer src="{API_URL}/raw/{address}" />
{/if} {/if}
{#if web} {#if types.web}
{#if imageLoaded != address} {#if imageLoaded != address}
<Spinner /> <Spinner />
{/if} {/if}
@ -81,7 +73,7 @@
on:error={() => (handled = false)} on:error={() => (handled = false)}
/> />
{/if} {/if}
{#if fragment} {#if types.fragment}
<UpLink passthrough to={{ entity: String($entity.get("ANNOTATES")) }}> <UpLink passthrough to={{ entity: String($entity.get("ANNOTATES")) }}>
<FragmentViewer {address} {detail} /> <FragmentViewer {address} {detail} />
</UpLink> </UpLink>

View file

@ -0,0 +1,37 @@
import type { EntityInfo } from "src/lib/entity";
import type { UpObject } from "upend";
import { GROUP_TYPE_ADDR } from "upend/constants";
export function getTypes(entity: UpObject, entityInfo: EntityInfo) {
const mimeType = String(entity?.get("FILE_MIME"));
const video =
["video", "application/x-matroska"].some((p) => mimeType.startsWith(p)) ||
entity?.identify().some((l) => l.endsWith(".avi"));
const audio =
["audio", "application/x-riff"].some((p) => mimeType.startsWith(p)) &&
!video;
const image = mimeType.startsWith("image");
const text = mimeType.startsWith("text");
const pdf = mimeType.startsWith("application/pdf");
const model =
mimeType?.startsWith("model") ||
entity?.identify().some((l) => l.endsWith(".stl"));
const web = entityInfo?.t == "Url";
const fragment = Boolean(entity?.get("ANNOTATES"));
const group = entity?.get("IS") == GROUP_TYPE_ADDR;
return {
mimeType,
audio,
video,
image,
text,
pdf,
model,
web,
fragment,
group,
};
}