66 lines
1.3 KiB
Svelte
66 lines
1.3 KiB
Svelte
<script lang="ts">
|
|
import {
|
|
type CustomEmojiAsset,
|
|
loadCustomEmoji,
|
|
} from "#lib/api/custom-emoji.js";
|
|
|
|
interface Props {
|
|
id: string;
|
|
size?: number;
|
|
}
|
|
|
|
let { id, size = 1.25 }: Props = $props();
|
|
|
|
let asset = $state<CustomEmojiAsset | null>(null);
|
|
|
|
$effect(() => {
|
|
asset = null;
|
|
let active = true;
|
|
loadCustomEmoji(id).then((resolved) => {
|
|
if (active) {
|
|
asset = resolved;
|
|
}
|
|
});
|
|
return () => {
|
|
active = false;
|
|
};
|
|
});
|
|
|
|
const isVideo = $derived(asset?.mime.startsWith("video/") ?? false);
|
|
const isImage = $derived(asset?.mime.startsWith("image/") ?? false);
|
|
</script>
|
|
|
|
<span class="CustomEmoji" style="--emoji-size: {size}rem;">
|
|
{#if asset && isVideo}
|
|
<video autoplay loop muted playsinline src={asset.url}></video>
|
|
{:else if asset && isImage}
|
|
<img alt="emoji" src={asset.url}>
|
|
{:else}
|
|
<span class="placeholder">🧩</span>
|
|
{/if}
|
|
</span>
|
|
|
|
<style lang="scss">
|
|
.CustomEmoji {
|
|
display: inline-flex;
|
|
flex-shrink: 0;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: var(--emoji-size);
|
|
height: var(--emoji-size);
|
|
vertical-align: middle;
|
|
}
|
|
|
|
img,
|
|
video {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: contain;
|
|
}
|
|
|
|
.placeholder {
|
|
font-size: calc(var(--emoji-size) * 0.85);
|
|
line-height: 1;
|
|
}
|
|
</style>
|