<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3.git/src/style.css, 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-13T06:17:39Z</updated>
<entry>
<title>Media pager: up and down go from post to post, left and right along a post's pictures. Adam: swipes and arrows up/down should go to the next post's media, left/right to the next within a post. The pager is now posts stacked top to bottom, each a row of its pictures or clips side by side — a quoted post's join the post that quotes it — with dots along the top when a post has more than one, saying how many and which. Up and down (swipe, arrows, j/k, Page) move a post at a time and land on a post where its row was left; left and right (swipe, arrows, h/l) move within the post and stop at its ends. A post's pictures all load as it comes near (those along its row too); a clip's head start goes to the next post's (where its row rests), the next along this one, and the post after next, at half; the look-ahead (the feed paging on, the media crawl) counts posts. Pictures pan sideways as well as up and down at 1×. Tests find the slide on screen by where it sits (the pager's children are posts now); feed-picture-pager walks right within a post, down past one with none, back up to where a post was left, left to its first, and a sideways swipe next to a swipe up; quote-pager walks the quoting post's row (its own picture, then the quote's).</title>
<updated>2026-10-13T06:17:39Z</updated>
<author>
<name>Adam Soltys</name>
<email>asoltys@gmail.com</email>
</author>
<published>2026-10-13T06:17:39Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=8f80948eb174a273f3b1dea963bb91745bcf323b'/>
<id>urn:sha1:8f80948eb174a273f3b1dea963bb91745bcf323b</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01KPw21NEpWeTGu6swVASmBt
</content>
</entry>
<entry>
<title>Feed video: fewer "To exit full screen" notices, and a YouTube clip takes one tap. Adam: Chrome's "v3.coinos.io – To exit full screen, drag from the top and touch the back button" shows every time, and a YouTube clip needs its own small full-screen icon. The notice is Chrome's, put up whenever a page goes full screen; a page can't turn it off, so the app goes full screen less. In the installed app (display-mode standalone, or opened from an android-app:// referrer) there is no address bar and the pager already fills the window, so it no longer goes full screen: a wide clip asks the screen to turn without it, and only if that's refused (the browser may allow turning only in full screen) goes full screen — the notice then, but the clip on its side; the screen is let go past that clip, or on closing. A browser tab goes full screen as before. A feed clip's own control bar loses its full-screen button (controlslist=nofullscreen): a tap on the clip is the way, into the pager. YouTube: the player's taps never reach the page, so a layer over a playing clip's picture takes them, leaving YouTube's control bar along the bottom to YouTube; one tap on it — or on the still — plays with sound and takes the clip's box full screen, turned on its side (unMute + playVideo through the iframe API for a player autoplaying muted); full screen the layer steps aside, so all of YouTube's controls are there. YouTube can only fill the screen through Chrome's full screen, so its notice still shows there. tools/fullscreen-notice-test.js (installed app: no full screen, the screen turned and let go, the fallback when turning is refused; no full-screen button on feed clips); tools/youtube-tap-test.js (YouTube stood in for: autoplaying muted, a tap on the control bar stays YouTube's, one tap full screen with unMute and playVideo, the layer aside full screen and back after; with Data Saver, the still to full screen with sound); video-unmute-test stubs ui for its slice of videoNode.</title>
<updated>2026-10-13T05:29:09Z</updated>
<author>
<name>Adam Soltys</name>
<email>asoltys@gmail.com</email>
</author>
<published>2026-10-13T05:29:09Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=c423cf3b79b088e542709267002b7db27b1a83ff'/>
<id>urn:sha1:c423cf3b79b088e542709267002b7db27b1a83ff</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01KPw21NEpWeTGu6swVASmBt
</content>
</entry>
<entry>
<title>Media pager: past the last slide, a "fetching the next video" screen — and the next one, when it comes, is moved onto. Adam reached the last clip before the next was in, and a swipe only nudged the clip and sprang back. Now the pager ends in a screen of its own: a ring sweeping round, three sparks orbiting the other way, the play mark (a picture mark in a pictures pager) breathing in the middle, and "Fetching the next video…" (or "Fetching more pictures…") with a sheen running through it, all still under prefers-reduced-motion. Landing there stops the clip left behind and asks for more at once (the feed pages on; the media grid's pager crawls); slides that arrive go in above it, and one arriving while the reader waits is moved onto and plays. With nothing older to be had (the feed at its end, or the media index), it says "That's everything for now" and goes still. The scroller no longer anchors (overflow-anchor: none), so a slide put in above the screen doesn't hold the screen in view. Strings in all 20 languages. tools/pager-tail-test.js (relays that take 3 s for anything older: the screen at the end, the clip behind stopped, the next clip moved onto and playing, the end saying that's everything, Escape onto the last clip's post); feed-pager-ahead and feed-media-views count slides without it.</title>
<updated>2026-10-13T05:19:47Z</updated>
<author>
<name>Adam Soltys</name>
<email>asoltys@gmail.com</email>
</author>
<published>2026-10-13T05:19:47Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=6488a0a687144e217f71ab1c7a768613b0f17e58'/>
<id>urn:sha1:6488a0a687144e217f71ab1c7a768613b0f17e58</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01KPw21NEpWeTGu6swVASmBt
</content>
</entry>
<entry>
<title>Media pager: the seek bar sits clear of the phone's gesture strip. Adam's screenshot: the bar ran along the very bottom edge of the screen, under Android's own gesture handle — a drag there is the system's (home, recents), and it was placed by env(safe-area-inset-bottom), which is 0 here (the page doesn't ask for viewport-fit=cover, and the gesture strip is never reported as a safe area anyway). It now sits 32px up from the bottom (plus any safe-area inset) and 16px in from each side, where an edge drag is the back gesture; the post's details stand above it, and its line has rounded ends. feed-video-pager-test checks the bar's place (32px up, 16px in) and that the author, caption and counts clear it; SHOT=path saves a picture of the pager with the details up.</title>
<updated>2026-10-13T04:55:16Z</updated>
<author>
<name>Adam Soltys</name>
<email>asoltys@gmail.com</email>
</author>
<published>2026-10-13T04:55:16Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=028dd56084b5a07bbff6d37e5f760ad344d58060'/>
<id>urn:sha1:028dd56084b5a07bbff6d37e5f760ad344d58060</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01KPw21NEpWeTGu6swVASmBt
</content>
</entry>
<entry>
<title>Feed: a clip opens in the media pager, full screen, with the feed's other clips a swipe away and a seek bar to drag. Adam full-screened a video in the feed and swiped up for the next one, and nothing moved: a tap on a feed clip handed it to the player's own full screen (video.requestFullscreen), where every touch is the player's and there is no next. Now, as pictures do since 6eda018, the tap opens the media pager on that clip over the feed's clips in the feed's order (every shape, not only the tall ones the Videos view flips through), carrying on from where it was. What the player's full screen gave is kept: the pager puts the page itself full screen (the tap's own gesture), and a wide clip locks the screen to landscape — for that clip; past it the screen follows the phone. Each clip in the pager (the media grid's too) gets its own seek bar, a thin line along the bottom that thickens with the details up; dragging it scrubs with the time shown, and the drag is never the pager's swipe or tap. A tap pauses the clip and shows the post's details, the × and the bar; another plays on. Leaving full screen another way (Back on Android, Escape) leaves the pager in the same step; × or Escape after moving on lands the feed on the post last watched. Threads, profiles and chats keep the player's full screen. tools/feed-video-pager-test.js (open, resume, landscape lock and release, seek drag, tap pause/play, swipe and arrows, Escape onto the post, exit full screen); video-tap-test now checks the feed opens the pager and runs its native full-screen checks in a thread. tools/puppeteer.js takes CHROME=/path for a machine without /usr/bin/google-chrome. feed-media-views-test's range-less probe check fails on HEAD before this too.</title>
<updated>2026-10-13T04:04:32Z</updated>
<author>
<name>Adam Soltys</name>
<email>asoltys@gmail.com</email>
</author>
<published>2026-10-13T04:04:32Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=b01ec800019bc0ac74926a4366f045b71bd7c29b'/>
<id>urn:sha1:b01ec800019bc0ac74926a4366f045b71bd7c29b</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01KPw21NEpWeTGu6swVASmBt
</content>
</entry>
<entry>
<title>Feed: a picture opens in the media pager, with the feed's other pictures a swipe away. Tapping a picture in a feed row used to open it alone (the lightbox); it now opens the media grid's pager on that picture, over the feed's pictures in the feed's own order — every picture of a post before the next post's (a repost's inner post, the feed's moderation) — so a swipe up or down, or any arrow key (up/down as before, now left/right too), steps to the next or previous one. A tap on the picture that opened it still closes it, as a full-screen picture always has; once the reader has moved on, the first tap shows the post's details and actions, and the next (or Escape, or the ×) closes the pager with the feed landed on that post (glideToPost, once the pop has brought the feed back). The pager's pictures pinch to zoom (attachZoom, now exported, without its wheel — the wheel is the pager's; at 1× one finger is the pager's swipe). Pictures in threads, profiles and chats still open alone. tools/feed-picture-pager-test.js; image-tap-test and lightbox-scroll-test accept the pager as the full-screen picture.</title>
<updated>2026-10-12T05:47:47Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-12T05:47:47Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=6eda01863920ae45d56a65563a7f956a429fced8'/>
<id>urn:sha1:6eda01863920ae45d56a65563a7f956a429fced8</id>
<content type='text'>
Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Messages: attach and GIF inside the field, as in the post composer. The DM and room composer still had them as buttons in its row — Adam's long DM to yorgos sat squeezed between a clip, GIF and Send. They now sit at the right of the field's last line (the field keeps room on that side, less with GIF alone), leaving the row as field + Send.</title>
<updated>2026-10-11T15:46:47Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-11T15:46:47Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=491904e04fe3d69aa6b417c266aa8b550ffa0534'/>
<id>urn:sha1:491904e04fe3d69aa6b417c266aa8b550ffa0534</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
</content>
</entry>
<entry>
<title>Composers: attach and GIF sit in the field's corner. The post composer's row had grown to Post · 📎 · GIF · Preview · Cancel; the reply box's likewise. The paperclip and GIF button are now small borderless tools inside the text field, bottom right (the field keeps room under its text so nothing runs beneath them), and the row under it is only what you do with the post: Post, Preview, Cancel (Preview, Cancel, Reply in a thread). Tests find the tools in .compose-box.</title>
<updated>2026-10-10T15:28:53Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-10T15:28:53Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=42c0ef9c6391285d76825bdf0d29371cd6ebf500'/>
<id>urn:sha1:42c0ef9c6391285d76825bdf0d29371cd6ebf500</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
</content>
</entry>
<entry>
<title>Feed: reposts. Amethyst showed Zapstore's repost of LWB's "Tankful" post in Adam's follows; we showed nothing — a feed asked only for posts (kinds 1, 1068). A feed of people now asks for their reposts too (NIP-18 kind 6; topic and firehose asks stay posts-only), and a repost shows as the note itself, under "🔁 &lt;name&gt; reposted" — its reactions, zaps, ⋯ and thread are the note's. Only reposts that carry the note and whose copy checks out (kind 1/1068, the id the e tag names, a valid signature); a muted author's note stays out. A note shows once: as itself, or under the first repost of it to arrive, counting rows still warming at the door. Media grids skip reposts. tools/feed-repost-test.js</title>
<updated>2026-10-10T14:45:07Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-10T14:45:07Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=9abd654e8ef57de59a4f4bd5cbfbba560ed7e523'/>
<id>urn:sha1:9abd654e8ef57de59a4f4bd5cbfbba560ed7e523</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
</content>
</entry>
<entry>
<title>GIF search, from nostr.build's GIF index (gifs.nostr.build). A GIF button in the post composer and in every chat composer (DMs, groups, communities) opens a picker: "GIFs from nostr.build" (linked, as their terms require), starter chips (gm, lol, yes, wow, …; the first runs on open), a search field (debounced 250 ms, no one-letter searches, one shared request per normalised query, never aborted, 429/403/503 answered in words), and a masonry grid whose tiles play the small H.264 copy only while near the screen, over the lqip blur, falling back to the animated preview (stills under reduced motion). A pick puts the original URL in a post — published with a NIP-92 imeta (m, dim, size, alt) — or, in a chat, sends it at once after whatever was typed. Media URLs not on gifs.nostr.build are dropped. Browser calls carry no headers: production needs v3.coinos.io registered in the nostr.build dashboard (localhost works as their shared dev client). tools/gif-picker-test.js runs against the live API.</title>
<updated>2026-10-10T14:35:16Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-10T14:35:16Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=79b09acc3c4c471fb29bb8d6994c26e849b90bb9'/>
<id>urn:sha1:79b09acc3c4c471fb29bb8d6994c26e849b90bb9</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
</content>
</entry>
</feed>
