df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 1 | <script lang="ts"> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 2 | import EmojiText from './EmojiText.svelte'; |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 3 | import RichNodes from './RichNodes.svelte'; |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 4 | import { parseCode } from './code'; |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 5 | import { segmentInline } from './inline'; |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 6 | import type { Mention } from './mentions'; |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 7 | import { parseRich } from './rich'; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 8 | |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 9 | export let text: string; |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 10 | export let html: string | null = null; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 11 | export let jumbo = false; |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 12 | export let mentions: Mention[] = []; |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 13 | export let self: string | null = null; |
787cdbbf0721 | atagen | 2026-10-24 06:50 UTC | 14 | export let nameOf: (userId: string) => string | null = () => null; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 15 | |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 16 | $: rich = html ? parseRich(html) : null; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 17 | $: segments = parseCode(text); |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 18 | $: pieces = segments.map((s) => (s.kind === 'text' ? segmentInline(s.text, mentions) : [])); |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 19 | $: single = segments.length === 1 && pieces[0].length === 1; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 20 | </script> |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 21 | |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 22 | {#if rich}<div class="rich"><RichNodes nodes={rich} {mentions} {self} {nameOf} /></div>{:else}{#each segments as s, i}{#if s.kind === 'inline'}<code class="inline">{s.text}</code>{:else if s.kind === 'block'}<pre class="block"><code>{s.text}</code></pre>{:else}{#each pieces[i] as p}{#if p.kind === 'mention'}<span class="mention" class:me={p.user_id === self} title={p.user_id}><EmojiText text={p.text === p.user_id ? (nameOf(p.user_id) ?? p.text) : p.text} /></span>{:else if p.kind === 'link'}<a class="link" href={p.href} target="_blank" rel="noopener noreferrer">{p.text}</a>{:else}<EmojiText text={p.text} jumbo={jumbo && single} />{/if}{/each}{/if}{/each}{/if} |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 23 | |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 24 | <style> |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 25 | code, .rich :global(code) { |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 26 | font-family: ui-monospace, 'JetBrains Mono', 'Fira Code', Menlo, monospace; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 27 | font-size: 0.9em; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 28 | } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 29 | .inline, .rich :global(:not(pre) > code) { |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 30 | padding: 1px 5px; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 31 | border-radius: 4px; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 32 | background: var(--bg-soft); |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 33 | border: 1px solid var(--border); |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 34 | } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 35 | .block, .rich :global(pre) { |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 36 | margin: 4px 0; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 37 | padding: 8px 10px; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 38 | border-radius: 6px; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 39 | background: var(--bg-soft); |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 40 | border: 1px solid var(--border); |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 41 | overflow-x: auto; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 42 | white-space: pre; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 43 | line-height: 1.4; |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 44 | } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 45 | .mention, .rich :global(.mention) { |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 46 | padding: 0 4px; |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 47 | border-radius: 4px; |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 48 | font-weight: 600; |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 49 | color: var(--accent); |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 50 | background: color-mix(in srgb, var(--accent) 18%, transparent); |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 51 | } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 52 | .mention.me, .rich :global(.mention.me) { |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 53 | color: var(--warn-text); |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 54 | background: color-mix(in srgb, var(--warn) 28%, transparent); |
705b1e1062c2 | atagen | 2026-10-23 09:05 UTC | 55 | } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 56 | .link, .rich :global(.link) { color: var(--accent); overflow-wrap: anywhere; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 57 | .link:hover, .rich :global(.link:hover) { text-decoration: underline; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 58 | .rich { white-space: normal; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 59 | .rich :global(:is(p, ul, ol, blockquote, h1, h2, h3, h4, h5, h6, table, details)) { margin: 4px 0; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 60 | .rich :global(:first-child) { margin-top: 0; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 61 | .rich :global(:last-child) { margin-bottom: 0; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 62 | .rich :global(:is(ul, ol)) { padding-left: 22px; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 63 | .rich :global(blockquote) { |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 64 | padding: 2px 10px; |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 65 | border-left: 3px solid var(--border); |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 66 | color: var(--muted); |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 67 | } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 68 | .rich :global(:is(h1, h2, h3, h4, h5, h6)) { line-height: 1.3; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 69 | .rich :global(h1) { font-size: 1.4em; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 70 | .rich :global(h2) { font-size: 1.25em; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 71 | .rich :global(:is(h3, h4, h5, h6)) { font-size: 1.1em; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 72 | .rich :global(hr) { border: none; border-top: 1px solid var(--border); margin: 8px 0; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 73 | .rich :global(table) { border-collapse: collapse; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 74 | .rich :global(:is(th, td)) { border: 1px solid var(--border); padding: 3px 8px; text-align: left; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 75 | .rich :global(.spoiler) { |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 76 | border-radius: 4px; |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 77 | background: var(--text); |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 78 | color: transparent; |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 79 | cursor: pointer; |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 80 | } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 81 | .rich :global(.spoiler:is(:hover, :focus)) { background: var(--bg-soft); color: inherit; } |
6d6a4c34bdc1 | atagen | 2026-10-24 06:51 UTC | 82 | .rich :global(.emote) { height: 1.6em; width: auto; vertical-align: middle; } |
df3c0f2b3da4 | atagen | 2026-10-22 13:07 UTC | 83 | </style> |