<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3.git/src/features/messages.js, branch master</title>
<subtitle>coinos v3 — bitcoin, Ark, Lightning and nostr wallet (web + Android)</subtitle>
<id>https://git.coinos.io/coinosv3.git/atom?h=master</id>
<link rel='self' href='https://git.coinos.io/coinosv3.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/'/>
<updated>2026-10-15T06:39:33Z</updated>
<entry>
<title>Group chats: White Noise's own :marmot: and :wn: draw as pictures. White Noise sends its two built-in emoji as bare shortcodes — no NIP-30 tag, no picture — so a :marmot: reaction in the community showed as text (Adam; the phone's group log: kind 7, content ":marmot:", an e tag and nothing else). Their artwork is published in the app's repository (builtin_emoji_marmot.png, builtin_emoji_wn.png); emojiUrl now resolves those two codes to it through our picture proxy (serverPic, a 72px tile cached on vmedia for a week, as any picture in a post), not bundled: the app is AGPL and this one MIT. Learned packs and tags still come first.</title>
<updated>2026-10-15T06:39:33Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-15T06:39:33Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=664d6b632f8221c8154a912323a9669a40f4d5af'/>
<id>urn:sha1:664d6b632f8221c8154a912323a9669a40f4d5af</id>
<content type='text'>
Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
</content>
</entry>
<entry>
<title>Share eager media pager loading across feed, profile, and grid</title>
<updated>2026-10-15T06:38:07Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-15T06:38:07Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=c0f1f1de0c7dca3d35cc19bb3e18487666c3ba5c'/>
<id>urn:sha1:c0f1f1de0c7dca3d35cc19bb3e18487666c3ba5c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Group invitations go to one device of yours, by your choice; group reactions learn their emoji pictures. Max added Adam to the 155-member White Noise community and no device showed it: a Marmot inviter picks ONE of a person's published KeyPackages, the Welcome lands on that device alone, and nothing said which (it was the phone's — and the phone, signing through a bunker, couldn't open a 218 KB Welcome until relay.coinos.io's maxEventSize went from 256 KB to 1 MB: the NIP-46 decrypt request carrying it was over the cap). Settings → Nostr gains "Group invitations" (groupDevicesCard): this device's standing, the account's other invitation keys on the relays (by app and date), and "Invite this device only" — a kind 5 naming each other key (NIP-09 `a` for the addressable 30443s, `e` for an old 443) and a fresh key of this device (marmot-client devices/onlyHere). A device whose key was retired by another sees the deletion, newer than its key, when it next checks (checkRetired, a few times a day, before any republish or the card) and stops putting one back, until "only here" is pressed on it in turn. And a group's reactions and messages now teach the app a :code:'s picture from their NIP-30 tag (noteEmoji on the group paths), the way feed reactions do: a :marmot: reaction in the community showed as text. tools/wn-only-device-test.js (the card lists three other keys newest first; the deletion names the two slots and all three events and not ours; the card then shows no others; a retirement by another device is honoured and taken back).</title>
<updated>2026-10-15T06:32:33Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-15T06:32:33Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=14de2121fa1c806048689010cf85d4f65b6e28c1'/>
<id>urn:sha1:14de2121fa1c806048689010cf85d4f65b6e28c1</id>
<content type='text'>
Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
</content>
</entry>
<entry>
<title>Count posts rather than images in media pager</title>
<updated>2026-10-15T06:29:40Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-15T06:29:40Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=c5d42cd305f2f96e84a7526fef1cffcc6aeaac02'/>
<id>urn:sha1:c5d42cd305f2f96e84a7526fef1cffcc6aeaac02</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Loop media pager through loaded posts and show position</title>
<updated>2026-10-15T06:21:55Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-15T06:21:55Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=686309a584a8e7a13091cb194e42aa09e2aec5d5'/>
<id>urn:sha1:686309a584a8e7a13091cb194e42aa09e2aec5d5</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Profile pages: a picture of theirs opens in the pager, over their timeline's pictures. Tapped on someone's profile page, a picture opened alone in the lightbox (the pager ran only over the feed), so there was nothing to swipe to (Adam). Now the page a row is on says what the pager runs over (pageRowOf, pagerSource): the feed, or this person's timeline — their posts' pictures (and clips) in the timeline's order, nobody else's, more fetched as the reader nears the end (loadOlderNotes, the way the feed pages on); the tap rules are the feed's, and closing after moving on lands the profile on that post (landOnPost judges the page by what is on screen, since a refetch replaces the timeline's cache entry). The profile screen syncs the pager as the feed does. tools/profile-pager-test.js (her pictures only and in order, the end past her last, Escape lands on the post, a tap on the opening picture closes).</title>
<updated>2026-10-15T06:01:38Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-15T06:01:38Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=63d43428468bb5dc336006bc345769b071905204'/>
<id>urn:sha1:63d43428468bb5dc336006bc345769b071905204</id>
<content type='text'>
Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
</content>
</entry>
<entry>
<title>Media pager: the slide meant stays on screen through a resize, from the first moment. The pager's resize handler re-showed pager.cur, which the slide observer sets a frame after the pager opens — so a resize in that first frame (the page going full screen for the pager, as the player's full-screen button does: a taller window, the address bar gone) had nothing to re-show, and the pager was left to the browser's re-snap. Now the slide meant is an anchor: the start slide the moment the pager opens, then each slide arrived at; a resize re-shows it (or the tail, when the reader is waiting there), and an arrival the observer reports at a size other than the one the pager last laid out at is taken as the resize's doing, not the reader's: the anchor goes back instead. Hardening: Adam's full-screen button on a clip 23 posts down showed another post's still, which a headless run of the same path (a user-gesture requestFullscreen on the feed clip) and tools/pager-resize-test.js (the window grows as the pager opens, shrinks and grows again, changes shape) did not reproduce; the recorder on his tab is for the next time.</title>
<updated>2026-10-15T05:35:27Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-15T05:35:27Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=1f2ad6bcf369f17f8710a078293b31e7584e6bba'/>
<id>urn:sha1:1f2ad6bcf369f17f8710a078293b31e7584e6bba</id>
<content type='text'>
Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
</content>
</entry>
<entry>
<title>Media pager: a spin of the wheel flies past the posts and lands snapped on one. A notch was a step, and a breath between steps meant a flick of the wheel moved two or three pictures at most (Adam). Now each notch adds a post to go — the third and later notches of a quick run (within 400 ms) add two, so a flick is a few posts and a spin a dozen — and the pager glides through them with the pictures passing (pagerFly: a longer glide, 100 ms + 110 per screen, eased out), landing snapped on the last. The posts passed are not arrived at: the slide observer stands down while flying (no clip starts, nothing marked seen, no counts asked), and the landing arrives (pager.arrive, the observer's old body). A notch back against a flight catches it on the post it is passing and steps back from there; a touch or a key catches it too (pagerGlide now takes a duration and an onDone that pagerHold fires on interruption, with the snap restored). A notch from rest is the single quick step it was; sideways notches and trackpad runs step as before. tools/pager-wheel-test.js: a spin of five flies eight posts on and lands snapped (gliding mid-way), the spin back, a notch against the flight. feed-video-pager-test's two failures are on HEAD before this.</title>
<updated>2026-10-15T05:21:25Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-15T05:21:25Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=ebc59e50cf86e8edfab21a5be9063e5d5eeab07b'/>
<id>urn:sha1:ebc59e50cf86e8edfab21a5be9063e5d5eeab07b</id>
<content type='text'>
Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
</content>
</entry>
<entry>
<title>Media pager with a mouse: the wheel pages, ctrl+wheel zooms, arrows for the pointer. Adam reached for the scroll wheel in the pager on his laptop and nothing useful happened: a notch scrolled the snap container a hundred pixels and the glide's snap put it straight back (a headless probe of the live pager: scrollTop stays 0), so the arrow keys were the only desktop way through. Now a wheel notch is a step — down the next post, up the one before, a sideways notch (a trackpad's, or shift+wheel) along the post's pictures — with a 220 ms breath between steps so a spin of the wheel is a step or two, not five; a trackpad's run of small deltas is one step per run (its first 40 px, the rest until a pause is spent). Ctrl+wheel zooms the picture at the cursor, which is also what a trackpad's pinch arrives as in Chrome (attachZoom's new wheel: 'ctrl' mode, 0.004 per unit); while zoomed the plain wheel pans it, and at 1× it is the pager's again. And where there is a pointer to hover with (hover: hover and pointer: fine), arrows: up and down at the right edge, left and right when the post has a picture that way (has-left/has-right, set as the slide on screen changes), faint until the pointer is over the pager. The keys, the wheel and the arrows share one step (pagerStep). No mouse drag-flick: discrete steps suit a pager. tools/pager-wheel-test.js (CDP mouseWheel is always a 120-unit notch to Chrome, so a trackpad run is dispatched page-side; headless has no hovering pointer, so one is given with --blink-settings); feed-picture-pager and image-zoom tests pass.</title>
<updated>2026-10-15T05:04:35Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-15T05:04:35Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=0355c21254d6d452fd4afbec28db3e124bc1d61a'/>
<id>urn:sha1:0355c21254d6d452fd4afbec28db3e124bc1d61a</id>
<content type='text'>
Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
</content>
</entry>
<entry>
<title>Notifications: a row from someone your follows reported is folded, not dropped. A reply Amethyst showed was missing from Adam's phone (2026-10-14, Johnny's reply to d558ba5d): the row was in the stored list, but two of his follows had filed kind 1984 person reports ("spam") on Johnny, which meets the two-follows bar, and the page filtered every one of Johnny's rows out without a trace — the feed and a thread fold such a post with who flagged it and a Show, the Notifications page simply lost it. Now the page keeps the row and folds it (notifFoldRow): the face, name and what they did, "Reported by mar, Rich" (up to three names, else how many), the time, and Show — which reveals it here and, being the same id, in its thread. Mutes and spam still drop the row; the unread count still leaves flagged rows out. Opening the page also syncs your follows' reports (syncReports, throttled), which only the feed and chat home did. tools/notif-report-fold-test.js.</title>
<updated>2026-10-15T04:48:02Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-15T04:48:02Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=c8b7eff398c5a6120434c9a362c3e20edd2d662e'/>
<id>urn:sha1:c8b7eff398c5a6120434c9a362c3e20edd2d662e</id>
<content type='text'>
Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
</content>
</entry>
</feed>
