| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
| |
The thread cache kept the replies but not the posts quoted inside them, so
every reload showed "Fetching note…" until a relay answered. Quotes (of any
kind — the one that showed it was a poll) are now saved with the thread and
restored before the first paint.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
you've seen it.
The new-posts pill used to glide to the top of the feed; now it stops at
the oldest post that came in, right above where you were reading, so you
read on upward. Posts that arrive while you read are tinted until they've
been in view about two seconds, then fade to the plain page (like Amethyst).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
flickers.
The panel was swapped for fresh nodes on every background render, which
dropped :hover each time. Now it's one node for the page's life and its
rows are rebuilt only when the results change.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
that looks like any zap.
No warning and no gift wording: when a person has no Ark address and no
Lightning address, the ordinary amount + Zap form sends a gift locked to
their nostr key and DMs it; the receipt screen is the usual Zapped!, with
the link and code only if the DM couldn't be delivered. One-tap post zaps
take the same path instead of failing. The Lightning button appears only
for someone who has a Lightning address, and an Ark advert for another
network no longer stops the lookup short of Lightning.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
Show all.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
Feed and Notifications leave the chat list (the nav reaches both; the bell
carries the notifications dot now). On a wide screen the bar runs edge to
edge with its buttons over the page column; quiet muted tabs, a pill for the
current one. Feed gets a newspaper icon instead of a house.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
It now shows across the signed-in app and a visitor's public pages (never
over sign-in, onboarding or the lock prompt), marks the current page, and
carries the unread dot. Home is renamed Feed, and the Messages button leaves
the header.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
|
| | |
|
| | |
|
| | |
|
| |\ |
|
| | | |
|
| |/
|
|
|
|
|
|
|
|
|
| |
pencil for a new post.
Save feed, Relays, Share and New post sat in the title row and wrapped on a
phone. Share, Relays and Save or Edit now live in the feed's ⋯ sheet, and
New post is a pencil; the title has the width.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
| |
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
| |
The settings screen replaces the page, and the page came back at its top;
the scroll position is remembered on opening and put back on Save, Save
and zap, and Back. The feed's windowing mounts the rows for that place.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
however its box is rebuilt.
Pinning the box only protected it from a patch in place. A repaint that
pairs children differently, the window unmounting the row and mounting it
again, or a quoted note loading all rebuilt the player muted with the
button back; the URL is remembered now, and a rebuilt box starts loud with
no button. Muting again from the player's own control forgets it.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
| |
feed-snapshot hunks.
Same cause as aad978d (a shared working tree); same fix: messages.js in
master is the last clean version plus this commit's own three changes
(the sound button leaving once unmuted, the list action under the profile
row). The working tree keeps the in-progress edits for their author.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
sound is on; the list action moves under the profile row.
The pill was at the top of the window, a stretch for a thumb. An unmuted
video kept a Mute button the player's own controls already provide, and in
a quoted note the box could be rebuilt muted; unmuting now pins the box and
removes the button. The ☰ on the profile's action row wrapped onto a line
of its own; it is now "Add to a list" beside "Their timeline".
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
colour follows the app's.
One dark colour for both bars gave white navigation icons over a light page
under gesture navigation. The wrapper (1.9, versionCode 10) now uses the
page background in light mode and the dark theme colour in dark mode, for
the status bar and the navigation bar alike. The page updates its
theme-color meta when its own theme is applied, so a PWA's status bar and
the wrapper's follow the same switch.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
unfinished feed-snapshot work.
Commit 40bec6c carried, beside its own change, an import of src/popular-feed.js
(not in git) and the /api/feed snapshot path from a concurrent worktree edit,
so every deploy since has failed at the build step. This restores messages.js
to that commit's own change on top of the last clean version; the working
tree keeps the in-progress edits for their author to commit whole.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
| |
and their own Back pops one.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
| |
not takeovers.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
| |
client said it is (NIP-31 alt), not as raw content dressed as a post.
A chess game (kind 64) reached through a reaction to it painted its PGN as
a reply. Now it reads "♟ Daily chess game #11: …".
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
| |
A coin past its expiry and under the 330-sat floor can be renewed by
nobody and exited by nobody; the home page said "the server can still
renew it" in red over 21 sats. Now a muted line points at Manage, where
the coin's row offers Forget: held as spent, quietly, so it stops
counting and stops warning. Larger expired coins keep the warning.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
| |
is a nostr account.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
/feed opened before the wallet no longer doubles Popular.
A refresh at the created step with an input past its expiry (only the
server's backstop can renew it now), or whose fee leaves less than the
330-sat floor (a 21-sat coin with a 150-sat fee sat "in progress" for
days), is failed quietly and its inputs go back to spendable.
/feed read before the wallet restored made a visitor's session copy of
Popular beside the built-in one; the wallet's arrival now folds it away.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
| |
The thumbnail maker fetches each face once to shrink it; a host that serves
pictures without CORS headers (primal's blossom, cdn.nostrcheck.me, most
personal sites) refuses the bytes and the browser prints a red line per
face while the <img> paints fine. The host is now remembered for a week
after a second quick refusal and not asked about every new face.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
public header has Search and Sign in.
Reading is free. A tap on an action without a wallet opens a sheet with the
sign-in doors (Google, passkey, Nostr), Create a new wallet, and Not now;
the missing-identity path lands there too instead of a toast, and zapping
is never offered to a visitor as if it could go through. The header on a
public page (a feed, a profile, a thread) carries Search and Sign in. The
page is remembered, so a sign-in lands back on it.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
to, in your language, with the machine posts gone.
A brand-new post has no reactions yet (of 73 fresh English posts on the
four relays, one had two), so Popular starts from the other end: the latest
reactions, reposts and zaps, counted per post by distinct people, then the
posts two or more people touched. Older pages walk the reactions back in
time; new ones arrive by a two-minute poll. At the door, JSON and other
machine output are dropped, and so is anything not in the reader's language
(script first, then a vote of function words among the Latin-script
languages the app speaks; unknown passes). The raw firehose stays at
/feed/all. A language selector sits under every feed, and changing it
rebuilds the curated ones.
A tall video scrolled past used to let go of its media at once and collapse,
shifting the page under a thumb; it now waits a moment and holds its height
until the clip is back. A tap on a full-screen picture closes it.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
with no web of trust borrows coinos's.
Each relay in a feed's list is a select over popular relays that answer a
bare "everything" query, with Other… for one typed in; the firehose reads
coinos, damus, nos.lol and primal by default. A relay chosen by hand or
named in a link is tried even if it had been marked sick, which had made a
hand-picked nos.lol fetch nothing.
A visitor, or a wallet that follows fewer than five people, has no follows
whose flags could fold anything, so the public feeds showed the relays raw.
They now get the moderation the coinos account gets: its follows' reports
(and, for visitors, its mute list), read every few hours and kept on the
device. A wallet's own follows and flags always come first.
The new-posts pill: the generic button press moved it half its width to
the right (its centring transform was replaced), so the tap never landed,
and the generic hover painted it light over light text.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
from relays of your choosing.
Plain /feed is the firehose: every post relay.coinos.io carries, no filter.
It sits beside Following as a built-in chip for wallets and opens as a
session feed for a visitor.
A feed's relay list is independent of what it asks for. The Relays button
in the header opens a panel to add to or take from the list; empty means
the usual choice (each author's outbox, the wide relays for a topic, the
coinos relay for the firehose). The list rides in the URL as ?r=…, on every
kind of feed, so a shared link reads where you read.
A feed state dropped while its fetch was still out used to swallow the
answers meant for its replacement; a relay change showed nothing.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
/feed/<npub> is the timeline that person sees: their follow list, read from
the relays, as a feed. /feed/<naddr> is a follow pack or a follow set,
/feed/t/<tag> a topic, and /feed?p=…&t=…&pack=…&name=… any mix. A visitor
gets the feed over the front door, can open a post's thread and come back;
the composer, chips and editing stay with a wallet. Every feed has a Share
button (the built-in Following shares as your own timeline), a profile page
has "Their timeline", and Back/Forward walk through feeds by id.
Public pages used to miss their repaint: the scheduler only painted the
wallet screen, so a visitor's feed filled up invisibly.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
| |
A plain link becomes an Open Graph card: picture, title, a line, the site.
The registrar fetches the page on the reader's behalf (names/preview.js,
GET /preview?url=): only public hosts, at most half a megabyte of HTML,
cached a day. The client warms the card with the rest of the post so the row
arrives whole, keeps a few hundred cards across sessions, and leaves a page
with nothing to say as a bare link. Pictures and YouTube keep their boxes.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
| |
The recipient box keeps the name, with their face beside it and "Sent
instantly, no fee."; the review names them too. The ark1… the name resolved
to is plumbing, and read as gibberish to anyone new to this.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
screen no longer shadows a restored wallet; stop() no longer throws.
Reconcile now asks the server about a 'pending' coin no live action or
standing renewal order holds: spendable again, or gone. Thirty zap-sized
coins another device had already spent counted in a balance for weeks.
A nav saved by a page with no wallet (the start screen) was restored over a
wallet that had since been saved to the device, painting the start page.
messages.stop() referenced feedAt, which no longer exists, so the rest of the
teardown never ran on an account switch.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
| |
One variable-weight woff2 each for upright and italic (41 KB + 45 KB, OFL),
shipped with the build and precached by the service worker; the system stack
paints first and stays when the file never arrives.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
| |
Every English string, the translations, the README and the messages the code
shows people now break with a full stop, a colon or a comma instead. Only
console logs and the "—" placeholder for an empty cell keep the dash.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
| |
padlock moves from the header to this page.
The identity chip used to put the npub in the URL and leave the list on
screen (the profile only paints over the wallet screen). Lock/Unlock now sits
with the other device-wide actions (log out, clear); the padlock tests reach it
through the Accounts page and lose their stale "Wallets" button.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
read off the clipboard or pasted.
Closes #7. A "Sign in with Amber" door on Android opens nostrsigner: intents for
get_public_key, sign_event and nip44 encrypt/decrypt, with a waiting card that
reads the clipboard when the tab returns (or takes a paste). Requests queue one
at a time — a sign-in fires the backup, relay list and follows together — and
each answer is checked for its type so a stale clipboard is never mistaken for
one. An interactive signer is not asked to decrypt DMs or private lists that
arrive on their own; each trip through Amber is a deliberate one.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
| |
never counts.
One follow's mis-tapped "impersonation" on fiatjaf's key was folding his
entire timeline. A flag on a specific post from one follow still folds
that post.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
| |
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
| |
buffering the whole clip.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
| |
may be pruned).
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
about forever.
Adam's wallet carried a refresh action from August 31 in step 'submitted'
whose unlock hash the server never ran: the round went through under a
later submission (another hash), the inputs were spent by it and the
5,233-sat output reached the wallet through the mailbox — but the original
action kept asking RoundParticipationStatus on every sync for four weeks,
and since this week's coins page shows renewals in flight, it showed up as
"in progress" with the raw gRPC error underneath.
On "not found" the manager now checks the inputs: all spent means the
round ran under another submission and the record is retired (failed,
superseded — no history row, no card); none spent means the server
dropped it before a round ran, so it is submitted again; a mix goes
through the existing input repair. The coins page never prints a server
error string; a failed check reads as "the wallet keeps trying".
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Every render builds a fresh tree to diff against the live one, and a media
element starts downloading the moment its src is set, even off the
document: a sixteen-second feed scroll built 204 <video> and 1,416 <img>
elements whose loads the morph then threw away — 375 cancelled video
range requests, and full re-downloads from hosts that send no cache
headers. h() now puts the source on data-lazy-src and it becomes src only
once the node is in the page (render promotes it; a MutationObserver covers
nodes appended by hand); the morph treats the two as one attribute.
The thumbnail maker fetched every original with cache: 'reload' (38 MB in
one scroll); the face was just painted from that URL, so the cache serves.
holdScroll now recovers an anchor row that a large insert above pushed out
of the window, from the height cache. Tests: the YouTube test accepts the
in-view players autoplay loads; the stability test watches the notice for
the catch-up, since the new rows land inside the window's spacer.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
nothing.
With stale nodes still in front, every kept row's position was off by the
stale count and each one was pulled out and re-inserted — a remove and an
add per row per repaint. The feed's window evicting rows at the top did
this to every mounted row on every scroll step; a moved <video> leaves the
document and comes back, restarting its loading (one clip was fetched 61
times in 40 seconds), and images were refetched. Measured with a
MutationObserver on the live tab: 160 of 179 row additions during a
20-second scroll were the same key going out and back in.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A CPU profile of a 44 s scroll on Adam's tab: 21 of 27 busy seconds in
loadFeatureState — every read parsed the multi-megabyte messages blob from
localStorage and re-hashed the seed for its key, and the mute/spam checks
read it for every row on every repaint. Now the cache key is hashed once
per identity, the messages state is parsed once per tick (a write refreshes
the copy; the copy is dropped on account switch), and the profile blob
stays parsed in memory and is written back once per burst instead of being
parsed and re-serialized for each of thirty profiles landing mid-scroll.
Videos preload metadata only: a window of autoplaying players was
streaming 20 MB during the same scroll.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
and dropped from the pool.
`coinosDebug(true)` in the console (or ?debug=1) turns the nwc: listener
logs back on; they are off by default. Warnings and errors stay.
The red WebSocket lines were the pool's own reconnect loop redialling relays
from other people's relay lists that have been dead for weeks — the sick
list only stopped NEW dials, for ten minutes, and forgot on reload. A dead
relay is now dropped from the pool (no reconnect loop), skipped twice as
long each time it fails (up to a day), keyed by normalized URL, and the
verdict survives a reload. A relay the pool has failed to reconnect to
three times counts as dead.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
|