<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3.git/src/features/messages.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-17T14:54:35Z</updated>
<entry>
<title>A thread reply is a growing textarea: Enter sends, Shift+Enter breaks the line.</title>
<updated>2026-09-17T14:54:35Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-17T14:54:35Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=8d66d66eaa10041cce1655b7932f694fb7696586'/>
<id>urn:sha1:8d66d66eaa10041cce1655b7932f694fb7696586</id>
<content type='text'>
Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
</content>
</entry>
<entry>
<title>Pay from a profile opens the Send form, not a lingering payment detail.</title>
<updated>2026-09-17T04:27:00Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-17T04:27:00Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=9360ca6806332a9c7e3a2e11f0b973511493c192'/>
<id>urn:sha1:9360ca6806332a9c7e3a2e11f0b973511493c192</id>
<content type='text'>
A tapped history row claims the whole tab area whichever tab is picked,
so jumping to ui.tab = 'send' from a profile's Pay button (or a zap's
form fallback) with a renewal's detail still open showed that detail
instead of the form. showSend() closes any open detail first; the three
feature paths that jump to Send use it.

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 note that wasn't found is asked for again, with the reactor's relay hint.</title>
<updated>2026-09-16T18:25:47Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-16T18:25:47Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=5484c5effa273e96bca69396ead175515aa06352'/>
<id>urn:sha1:5484c5effa273e96bca69396ead175515aa06352</id>
<content type='text'>
A reaction's target was fetched once from our relays, and a miss was
final for the session — so with our own relay down for an evening, a
reply that sat on four relays showed as "no longer on your relays" until
a reload. A missing note is now retried when next wanted (half a minute
on), the reaction's e-tag relay hint rides along, and tapping the row
asks again instead of doing nothing.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
</content>
</entry>
<entry>
<title>Feed: what arrives waits behind the pill; the count bumps; no auto-flush.</title>
<updated>2026-09-16T18:23:54Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-16T18:23:54Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=49caed082a67851fcd5479d1c462b95f1a5d4a7c'/>
<id>urn:sha1:49caed082a67851fcd5479d1c462b95f1a5d4a7c</id>
<content type='text'>
Posts a refresh found slid in a beat after the cached page painted,
moving what you had begun reading, and reaching the top of the page let
waiting posts in with a re-render under a finger on its way to the pill —
the tap landed on the post beneath. Now everything that arrives after the
first paint, the boot catch-up included, waits behind the pill wherever
you are; the pill is a keyed node whose count bumps on each change; and a
tap scrolls to the top before painting so the new posts open under your
eyes. A rebuilt follow list still rebuilds the feed in place.

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 bare @npub in a message resolves to the person's name.</title>
<updated>2026-09-16T05:47:26Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-16T05:47:26Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=398bb77165e3ff454f1401b3c114a976aae5216c'/>
<id>urn:sha1:398bb77165e3ff454f1401b3c114a976aae5216c</id>
<content type='text'>
Vector writes a mention as @npub1… with no nostr: prefix; ours only
resolved the prefixed form, so the raw key sat in the bubble. Bare npubs
and nprofiles, with or without the @, now render as @name and open the
profile, like the prefixed ones. Keys inside URLs are left alone.

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 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>Community reactions carry the target author's p tag, as Concord specifies.</title>
<updated>2026-09-16T05:19:58Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-16T05:19:58Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=12e069fc62bff8715de189aedc777b69d1e56377'/>
<id>urn:sha1:12e069fc62bff8715de189aedc777b69d1e56377</id>
<content type='text'>
A reaction sent from v3 never showed in Vector: its parser requires the
NIP-25 p tag naming the reacted-to message's author (CORD examples §2.3
has e, p and k), and ours sent only e and k. Added.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
</content>
</entry>
<entry>
<title>Cached faces warm from the wallet's own namespace, once its keys are in.</title>
<updated>2026-09-16T04:45:11Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-16T04:45:11Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=3ff00c59bbe350642b23e8b3527b0d07b16bee0e'/>
<id>urn:sha1:3ff00c59bbe350642b23e8b3527b0d07b16bee0e</id>
<content type='text'>
On the phone the profile cache was intact — 150 faces, our own with a
thumbnail — yet an offline boot drew a punk in the header. The header
asks for a face before a silent sign-in has finished resuming, and the
warm-up ran then: it read an empty slot under a keyless namespace and
counted itself done. Online the relays refilled the map and nobody saw
it; offline nothing did. The warm-up now waits for the wallet's keys and
runs again at feature init, from the right namespace.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
</content>
</entry>
<entry>
<title>Offline, the chat shows what it read: messages cache on arrival.</title>
<updated>2026-09-16T04:37:47Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-16T04:37:47Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=88636e5c158c9e390eec25c4471207780857abeb'/>
<id>urn:sha1:88636e5c158c9e390eec25c4471207780857abeb</id>
<content type='text'>
The room cache was written only on our own sends, deletes and
attachments, so a member who only reads had nothing on an offline boot —
"No messages yet" over a room read the day before, and no faces or names
with it. Messages now persist as they arrive (debounced past the backfill
burst), so the last fifty per channel are there without a network. Our
own face never waits its turn for a thumbnail and never gives it up to
the budget, so the header avatar paints offline too.

tools/offline-cache-test.js boots the PWA build, caches a room, reloads
fully offline and checks messages, names and thumbnails are all there.

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 keeps its relay subscriptions alive while the app is on screen.</title>
<updated>2026-09-15T18:56:52Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-15T18:56:52Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=0ebef05d3850d312ec8098584525b22ec1b9a0de'/>
<id>urn:sha1:0ebef05d3850d312ec8098584525b22ec1b9a0de</id>
<content type='text'>
New messages rang in Vector but sat unseen in v3 until a reload. The
resume hook only rebuilds subscriptions after an absence it was told
about; a socket that errors while the page stays visible (a wifi hop, a
laptop lid, a phone freezing the tab without the away timer noticing,
another tab clearing that timer first) is dropped from the nostr-tools
pool with every subscription it carried, and nothing dials it again.

A watchdog now runs whenever the app is on screen: on focus, on becoming
visible, and every ten seconds between. It asks the pool whether each
relay the inbox and the rooms listen on still holds a live socket (a dial
hung past 20s counts as dead, and a relay that closed a subscription on us
counts too) and rebuilds the lot when one is missing, dropping a stuck
relay first so the rebuild dials afresh. Rebuilds retry on a growing
backoff while a relay keeps refusing. tools/chat-watchdog-test.js errors
every socket under an open room and checks the recovery.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
</content>
</entry>
</feed>
