diff options
| author | Adam Soltys <[email protected]> | 2026-03-06 23:53:50 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-03-06 23:53:50 -0800 |
| commit | c67d03fba0c1cc2fae9e8da4c7dedb41ea22d03f (patch) | |
| tree | 27e9a3b762365a2cbd08ae2fa5d061268fca8ca8 | |
| parent | c75c05020dcf9208adfeb82d81bae194e4104ab9 (diff) | |
| download | coinos-ui-c67d03fba0c1cc2fae9e8da4c7dedb41ea22d03f.tar.gz coinos-ui-c67d03fba0c1cc2fae9e8da4c7dedb41ea22d03f.zip | |
render imeta media directly instead of routing through parseContent
Co-Authored-By: Claude Opus 4.6 <[email protected]>
| -rw-r--r-- | src/components/ChatMessage.svelte | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/src/components/ChatMessage.svelte b/src/components/ChatMessage.svelte index 8dc276e8..53baafcd 100644 --- a/src/components/ChatMessage.svelte +++ b/src/components/ChatMessage.svelte @@ -3,25 +3,18 @@ let { content, tags = [] }: { content: string; tags?: any[] } = $props(); - // Parse imeta tags for URLs and MIME types - let imeta = $derived( + // Extract media from imeta tags (NIP-92) + let imetaMedia = $derived( tags .filter((t) => t[0] === "imeta") - .map((t) => { - const url = t.find((v) => v.startsWith("url "))?.slice(4); - const mime = t.find((v) => v.startsWith("m "))?.slice(2) || ""; - return { url, mime }; - }) - .filter((m): m is { url: string; mime: string } => !!m.url), + .map((t) => ({ + url: t.find((v) => v.startsWith("url "))?.slice(4) || "", + mime: t.find((v) => v.startsWith("m "))?.slice(2) || "", + })) + .filter((m) => m.url), ); - // URLs from imeta not already in content - let imetaUrls = $derived(imeta.filter((m) => !content.includes(m.url!)).map((m) => m.url)); - - // Check if a URL is an image according to imeta MIME types - const isImetaImage = (url: string) => imeta.some((m) => m.url === url && m.mime.startsWith("image/")); - - let parts = $derived(parseContent({ content: [content, ...imetaUrls].join("\n"), tags })); + let parts = $derived(parseContent({ content, tags })); const truncUrl = (url: string) => { const short = url.replace(/^https?:\/\/(www\.)?/, ""); @@ -40,13 +33,26 @@ }; </script> +{#each imetaMedia as media} + {#if media.mime.startsWith("image/")} + <a href={media.url} target="_blank" rel="noopener noreferrer"> + <img src={media.url} alt="" class="chat-img" /> + </a> + {:else if media.mime.startsWith("video/")} + <!-- svelte-ignore a11y_media_has_caption --> + <video src={media.url} controls class="chat-video"></video> + {:else} + <a href={media.url} target="_blank" rel="noopener noreferrer" class="chat-link">{truncUrl(media.url)}</a> + {/if} +{/each} + {#each parts as { type, value }} {#if type === "text"} {value} {:else if type === "newline"} <br /> {:else if type === "link"} - {#if isImage(value.url) || isImetaImage(value.url)} + {#if isImage(value.url)} <a href={value.url} target="_blank" rel="noopener noreferrer"> <img src={value.url} alt="" class="chat-img" /> </a> |
