{/* Header — mono strip, clay-pulse dot, metadata right */}
{/* Body — message stream + member sidebar */}
{/* Message stream */}
{messages.length === 0 ? (
no envelopes on this topic yet
) : filteredMessages.length === 0 ? (
no matches for “{searchTerm}”
) : (
{filteredMessages.map((m) => (
-
{m.senderName || m.senderPubkey.slice(0, 8)}
{m.senderPubkey.slice(0, 8)}
{fmtTime(m.createdAt)}
{(m.bodyVersion ?? 1) === 2 ? (
🔒
) : null}
{renderWithMentions(resolveText(m))}
))}
)}
{/* Member sidebar — roster with online dot */}
{/* Compose */}
{error ? (
error · {error}
) : null}
{keyState === "not_sealed" ? (
🔒 waiting for a CLI peer to share the topic key — sending v1 plaintext until then
) : keyState === "ready" ? (
🔒 end-to-end encrypted (v0.3.0)
) : keyState === "topic_unencrypted" ? (
🔓 plaintext (v1) — encryption not yet enabled
) : null}
{/* Status footer — 9px mono, matches peer-graph + state-timeline footers */}
mesh · {meshSlug}
SSE · 2s push
key valid until {fmtTime(apiKeyExpiresAt)}
v0.2.0 · plaintext base64 · per-topic crypto in v0.3.0
);
}