diff options
| author | Adam Soltys <[email protected]> | 2026-09-15 09:27:45 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-15 09:27:45 -0700 |
| commit | c90d0f3c600802b5b4b43959df5fd2d02f78012c (patch) | |
| tree | 0bb36a804eda41415e2d3e871bc6475836f8f99e /src/style.css | |
| parent | feadbb008de9b2fe2332a7f0e190955ae545f07d (diff) | |
| download | coinosv3-c90d0f3c600802b5b4b43959df5fd2d02f78012c.tar.gz coinosv3-c90d0f3c600802b5b4b43959df5fd2d02f78012c.zip | |
Custom emoji in chat: :shortcodes: render as pictures, packs sync with Vector.
A message from Vector says :pika_wave: and carries a NIP-30
["emoji", code, url] tag for it; coinos showed the bare shortcode. Now the
bubble shows the picture (in rooms, DMs, the feed and the public /chat
page), a bubble that is only one to three of them shows them big, and a
:code: reaction chip is a picture too.
Sending: every :code: you type that resolves travels with its tag, so the
other side renders it whether or not they hold the pack. Shortcodes come
from packs you hold (NIP-51 kind 30030 sets) and from what you've seen in
chat, so anyone can answer a :pika_wave: with one. The composer
autocompletes on ":pi" (Tab/Enter takes the first), the reaction picker
lists custom emoji first, and Vector's pack share link renders with an
Add button; a pasted naddr works too.
Packs live on your kind 10030 list — the one Vector reads and writes — so
a pack added in either app appears in both. tools/emoji-test.js drives the
real coinos room headlessly and checks all of the above.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
Diffstat (limited to 'src/style.css')
| -rw-r--r-- | src/style.css | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/style.css b/src/style.css index 4bb7c5b..f969cee 100644 --- a/src/style.css +++ b/src/style.css @@ -1014,3 +1014,32 @@ body::after { .emoji-grid button.on { border-color: var(--accent); } .hub-list { max-height: 360px; overflow-y: auto; } .hub-icon { object-fit: cover; } + +/* custom emoji (NIP-30): an inline picture the height of a capital, sat on + the baseline like the character it stands for */ +.cemoji { display: inline-block; height: 1.4em; width: auto; max-width: 3em; vertical-align: -0.35em; object-fit: contain; } +/* a bubble that is nothing but one to three of them shows them big */ +.chat-bubble.jumbo .cemoji { height: 2.8em; max-width: 5em; vertical-align: middle; } +.chat-react .cemoji { height: 1.25em; vertical-align: -0.3em; } +.emoji-grid .cemoji { height: 28px; max-width: 36px; vertical-align: middle; } +.msg-sheet-emojis .cemoji { height: 22px; vertical-align: middle; } +/* the :shortcode: strip above the composer */ +.emoji-ac { display: flex; flex-wrap: wrap; gap: 4px; } +.emoji-ac:empty { display: none; } +.emoji-ac button { + display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px; font-size: 18px; line-height: 1; + border: 1px solid var(--line); border-radius: 10px; background: var(--paper); +} +.emoji-ac button .small { font-size: 12px; color: var(--muted); } +.emoji-ac .cemoji { height: 22px; vertical-align: middle; } +/* the packs behind the picker, and the add box */ +.emoji-packs { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; } +.emoji-pack { display: inline-flex; align-items: center; gap: 2px; } +.emoji-pack .linklike { padding: 0 2px; font-size: 14px; color: var(--muted); } +/* Vector's pack share link: named, with its Add button */ +.pack-link { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; } +.pack-link .btn-sm { padding: 3px 10px; } +/* a custom emoji whose picture won't load falls back to its :code: alt text; + in the 40px grid cell that text must not spill into the next cell */ +.emoji-grid button { overflow: hidden; } +.emoji-grid .cemoji { font-size: 8px; } |
