fix, refactor: AudioPreview component, fix duration overflow
parent
616245aa18
commit
e7c21c8dbd
|
@ -8,9 +8,9 @@
|
|||
import api from "../../lib/api";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { getTypes } from "../../util/mediatypes";
|
||||
import { formatDuration } from "../../util/fragments/time";
|
||||
import { concurrentImage } from "../imageQueue";
|
||||
import { ATTR_IN } from "upend/constants";
|
||||
import AudioPreview from "./blobs/AudioPreview.svelte";
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let address: string;
|
||||
|
@ -57,20 +57,11 @@
|
|||
loaded = groupChildren.every(
|
||||
(addr) => loadedChildren.includes(addr) || failedChildren.includes(addr),
|
||||
);
|
||||
|
||||
let clientHeight = 0;
|
||||
let mediaDuration = "";
|
||||
$: {
|
||||
let duration = $entity?.get("MEDIA_DURATION") as number | undefined;
|
||||
if (duration) {
|
||||
mediaDuration = formatDuration(duration);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="preview">
|
||||
{#if handled}
|
||||
<div class="inner" bind:clientHeight>
|
||||
<div class="inner">
|
||||
{#if !loaded}
|
||||
<Spinner centered="absolute" />
|
||||
{/if}
|
||||
|
@ -113,20 +104,11 @@
|
|||
on:loaded={() => (loaded = address)}
|
||||
/>
|
||||
{:else if types.audio}
|
||||
<div class="audiopreview image">
|
||||
<img
|
||||
class:loaded={loaded === address}
|
||||
alt="Thumbnail for {address}"
|
||||
use:concurrentImage={`${api.apiUrl}/thumb/${address}?mime=audio`}
|
||||
on:load={() => (loaded = address)}
|
||||
on:error={() => (handled = false)}
|
||||
/>
|
||||
{#if mediaDuration}
|
||||
<div class="duration" style="--font-size: {clientHeight * 0.66}px">
|
||||
{mediaDuration}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<AudioPreview
|
||||
{address}
|
||||
on:loaded={() => (loaded = address)}
|
||||
on:error={() => (handled = false)}
|
||||
/>
|
||||
{:else if types.video}
|
||||
<VideoViewer
|
||||
{address}
|
||||
|
@ -196,23 +178,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.audiopreview {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.duration {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
font-size: var(--font-size);
|
||||
font-weight: bold;
|
||||
color: var(--foreground-lightest);
|
||||
text-shadow: 0px 0px 0.2em var(--background-lighter);
|
||||
}
|
||||
}
|
||||
|
||||
.group {
|
||||
padding: 0;
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<script lang="ts">
|
||||
import { useEntity } from "../../../lib/entity";
|
||||
import api from "../../../lib/api";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { formatDuration } from "../../../util/fragments/time";
|
||||
import { concurrentImage } from "../../imageQueue";
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let address: string;
|
||||
|
||||
$: ({ entity } = useEntity(address));
|
||||
|
||||
let loaded = null;
|
||||
let handled = true;
|
||||
$: dispatch("handled", handled);
|
||||
$: dispatch("loaded", Boolean(loaded));
|
||||
|
||||
let clientHeight = 0;
|
||||
let clientWidth = 0;
|
||||
$: fontSize = Math.min(clientHeight, clientWidth) * 0.66;
|
||||
let mediaDuration = "";
|
||||
$: {
|
||||
let duration = $entity?.get("MEDIA_DURATION") as number | undefined;
|
||||
if (duration) {
|
||||
mediaDuration = formatDuration(duration);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="audiopreview" bind:clientWidth bind:clientHeight>
|
||||
<img
|
||||
class:loaded={loaded === address}
|
||||
alt="Thumbnail for {address}"
|
||||
use:concurrentImage={`${api.apiUrl}/thumb/${address}?mime=audio`}
|
||||
on:load={() => (loaded = address)}
|
||||
on:error
|
||||
/>
|
||||
{#if mediaDuration}
|
||||
<div class="duration" style="--font-size: {fontSize}px">
|
||||
{mediaDuration}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.audiopreview {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
|
||||
&:not(.loaded) {
|
||||
flex-grow: 1;
|
||||
height: 6rem;
|
||||
max-height: 100%;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.duration {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
font-size: var(--font-size);
|
||||
font-weight: bold;
|
||||
color: var(--foreground-lightest);
|
||||
text-shadow: 0px 0px 0.2em var(--background-lighter);
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue