<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3.git/src/public-chat.js, branch fdroid-v1.7</title>
<subtitle>coinos v3 — bitcoin, Ark, Lightning and nostr wallet (web + Android)</subtitle>
<id>https://git.coinos.io/coinosv3.git/atom?h=fdroid-v1.7</id>
<link rel='self' href='https://git.coinos.io/coinosv3.git/atom?h=fdroid-v1.7'/>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/'/>
<updated>2026-09-16T05:39:05Z</updated>
<entry>
<title>A changed reaction stays changed: the fold keeps the newest, not the last to arrive.</title>
<updated>2026-09-16T05:39:05Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-16T05:39:05Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=3d706acd1edccb5c4eb0f781b52b3d302bdafa2b'/>
<id>urn:sha1:3d706acd1edccb5c4eb0f781b52b3d302bdafa2b</id>
<content type='text'>
One reaction per author was folded as "last one in wins". A reload's
backfill hands reactions back in relay order, so a flame swapped for
confetti came back as the flame. Rooms, DMs and the public page now keep
the newest by the rumor's own clock, and an optimistic send stamps its
time so an older one arriving afterwards stays out.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
</content>
</entry>
<entry>
<title>A reply's quoted line shows its custom emoji as pictures.</title>
<updated>2026-09-15T16:33:36Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-15T16:33:36Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=8f3ef61e4fbaf8c7cf586ed1280fd8f4bdc624ae'/>
<id>urn:sha1:8f3ef61e4fbaf8c7cf586ed1280fd8f4bdc624ae</id>
<content type='text'>
The quote above a reply bubble, the composer's reply bar, and the same
on the public /chat page rendered the raw :shortcode:. They now run the
one-line snippet through the same NIP-30 tokenizer, cutting on text so a
shortcode is never sliced in half.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
</content>
</entry>
<entry>
<title>Custom emoji in chat: :shortcodes: render as pictures, packs sync with Vector.</title>
<updated>2026-09-15T16:27:45Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-15T16:27:45Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=c90d0f3c600802b5b4b43959df5fd2d02f78012c'/>
<id>urn:sha1:c90d0f3c600802b5b4b43959df5fd2d02f78012c</id>
<content type='text'>
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 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
</content>
</entry>
<entry>
<title>Chat reactions render inside the bubble (Telegram-style), not floating below it.</title>
<updated>2026-09-07T02:48:19Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-07T02:48:19Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=ad496c0fb53706f221241dd48440c68d3333937d'/>
<id>urn:sha1:ad496c0fb53706f221241dd48440c68d3333937d</id>
<content type='text'>
Reactions were a sibling of the bubble (a separate row under it), so they hung outside the message. Moved the reaction pills inside .chat-bubble, tucked under the text, across all three renderers: community channel messages, DMs, and the read-only public /chat page. The pill background and the "your reaction" highlight border now derive from the bubble's own text colour (color-mix on currentColor), so they read correctly on both the plain bubble and the accent "me" bubble. Tapping a pill stops propagation so it toggles the reaction without also opening the message action sheet.

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01MGzU12QrAA4G6BYGzGVdXz
</content>
</entry>
<entry>
<title>Telegram-style message action sheet + replies in community chat. Tapping any bubble opens a centered sheet: a quick row of the six reaction emojis (your current one highlighted; picking fires immediately) above Reply / Copy / Delete (delete on own messages only) — replacing the hover-only 🙂 picker, which was invisible on the phones that need it most. Links, images and the hover × keep their own clicks, and a desktop text-selection drag never pops the sheet over the copy. REPLIES are new: Reply arms a composer bar showing who/what you're answering (× to cancel, cleared on channel/room switch), the sent kind-9 e-tags the quoted message, and rows carrying an e-tag render the quoted context above their text — author + one-line snippet, silent when the original is deleted or not held. The public /chat page renders the same quotes. Verified against the built stylesheet: 300px sheet, six even emoji buttons, quote ellipsizes, circular cancel button</title>
<updated>2026-09-04T16:26:00Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-04T16:26:00Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=d92dfd42e7b01fd2a4806175136d10872474ca5c'/>
<id>urn:sha1:d92dfd42e7b01fd2a4806175136d10872474ca5c</id>
<content type='text'>
Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01MGzU12QrAA4G6BYGzGVdXz
</content>
</entry>
<entry>
<title>Chat renders links and sends emoji reactions. Links: community bubbles and DM bubbles now run through noteBody (URLs → anchors, image URLs inline, npub mentions clickable, all content kept as text nodes — nothing from a relay reaches innerHTML); the public /chat page gets its own linkedBody (same splitter, nostr refs stay dim stubs since there are no profile screens there). Reactions: a 🙂 opener on every bubble (rides the edge like the delete ×, steps left on own rows) unfolds a six-emoji picker; tapping an existing chip joins that vote, your own reaction is highlighted, and picking a different emoji replaces it (kind-7 rumor on the channel stream, one per author, fold keeps the latest — inbound rendering already existed, this adds the sending half). Optimistic like sendMessage: the chip lands instantly and is rolled back to whatever stood before if signing/wrapping fails</title>
<updated>2026-09-04T16:07:52Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-04T16:07:52Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=e43e6dade447bf8ce5150323719937e28ebabe74'/>
<id>urn:sha1:e43e6dade447bf8ce5150323719937e28ebabe74</id>
<content type='text'>
Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01MGzU12QrAA4G6BYGzGVdXz
</content>
</entry>
<entry>
<title>Public read-only coinos community chat at /chat — a share-anywhere link that shows the live chat history to anyone, logged in or not, with a "Sign in to chat" button ("Open coinos" when the device already has an account). No server-side decoder needed: the community's join material was already public by construction (baked into the client bundle — every coinos user is meant to be a member), so the page derives the stream keys and decrypts wraps client-side exactly like the app's Chat tab, worker-offloaded with the same sliced fallback. Renders messages + edits + deletes + reactions and honors the folded control state's ban list; presence/typing/guestbook deliberately omitted. Profiles come from ONE batched kind-0 query per burst (a REQ per author tripped relay concurrency limits). Plumbing: the join material moved to src/community.js (shared with messages.js so they can never drift), /chat is excluded from the single-segment profile deep-link (which was eating the path and rewriting the URL before the route ran), and app renders stand down in public-chat mode so a feature-init render can't paint onboarding over the page. Verified headless against the live relays: 59 messages decrypt, ban-fold applies, names resolve</title>
<updated>2026-09-04T15:55:45Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-04T15:55:45Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=a6851ae954d819b116aae6b19b175525f1488928'/>
<id>urn:sha1:a6851ae954d819b116aae6b19b175525f1488928</id>
<content type='text'>
Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01MGzU12QrAA4G6BYGzGVdXz
</content>
</entry>
</feed>
