feat: web UI chat render, panels, presence + analytics

This commit is contained in:
hh committed 2026-05-31 19:41:37 +02:00
1 parent 75425d1bee
commit ed469ba8dd
83 files changed
+6034 -136

No files matched your search

@@ -0,0 +1,65 @@
<script lang="ts">
import {
type CustomEmojiAsset,
loadCustomEmoji,
} from "$lib/api/custom-emoji";
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 src={asset.url} autoplay loop muted playsinline></video>
{:else if asset && isImage}
<img src={asset.url} alt="emoji">
{: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>