fix, refactor: AudioPreview component, fix duration overflow

feat/type-attributes
Tomáš Mládek 2023-08-25 23:21:24 +02:00
parent 616245aa18
commit e7c21c8dbd
2 changed files with 81 additions and 42 deletions

View File

@ -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;

View File

@ -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>