aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
Commit message (Collapse)AuthorAgeFilesLines
* Console: NWC chatter behind a debug switch; dead relays remembered longer ↵Adam Soltys2026-09-261-17/+18
| | | | | | | | | | | | | | | | | | 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
* Profile: the action row's labels never break inside a button; a button wraps ↵Adam Soltys2026-09-261-1/+1
| | | | | | | | | whole. The list button made four across, and ⚡ Pay folded onto two lines. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
* Thread: Cancel and Reply share one size, the toolbar's button height.Adam Soltys2026-09-261-1/+1
| | | | | Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
* Thread: the reply box continues the note's highlight, one panel at the ↵Adam Soltys2026-09-261-6/+19
| | | | | | | | | | | | note's width. The box sat inset beneath the focused note's grey highlight as a separate field. It now shares the highlight: same width and background, the note's bottom corners squared off and the box carrying them, the field inside a quiet hairline. Under the root (no highlight) it is a soft panel of its own. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
* Thread: the reply box appears on Reply, full width, with its tools on a row ↵Adam Soltys2026-09-261-7/+18
| | | | | | | | | | | | | | | | | beneath. A thread opened to read came with an empty field under its first post. The box now appears under the note whose Reply was tapped (or while a draft is pending), folds away once the reply is sent or Cancel is tapped, and takes Amethyst's shape: the field across the full width, attach and preview on a row beneath it with Cancel and Reply at the right. Tests: thread-reply's helper follows the new shape and expects the box to fold after sending; compose-preview and feed-list tap Reply before expecting a box (the thread card carries .thread-card as the marker). Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
* Feed: the new-posts pill glides up to the top instead of cutting there.Adam Soltys2026-09-261-1/+14
| | | | | | | | | An instant scrollTo read as a page refresh. A long way down, most of the distance is closed in one step (so the glide is short and passes rows the window has mounted), then the last two screens roll by; reduced-motion keeps the cut. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Notifications: the faces the page will paint are warmed before it opens.Adam Soltys2026-09-261-1/+16
| | | | | | | | | | | | | | | | The list was already cached locally and refreshed from the chat home, but each row only asked for its author's profile when painted, so the page opened as quiet circles filling in one by one. Now the actors' names are fetched in one batch and each picture decoded into a thumbnail the moment the list is read from disk or grows — which the chat home does before the page is ever opened. Test: notif-faces (stub relay answers the kind-0 batch; the pictures are fetched and cached from the chat home; every row has its face on the first frame). Note for tests: serve /verify-worker.js from dist, or every relay answer waits four seconds for the inline fallback. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Feed: only the rows near the viewport are in the DOM, however far you scroll.Adam Soltys2026-09-261-9/+95
| | | | | | | | | | | | | | | | | | A long scroll left hundreds of rows mounted, and every repaint (a zap count, a profile landing, the thirty-second sync) rebuilt and diffed all of them — the slowdown deep in the feed. Rows beyond two and a half screens either side of the viewport are now replaced by a spacer at their measured height, so the page keeps its length (scrollbar, Back, arrival anchoring behave as before) while a repaint touches a few dozen rows. After svelte-virtual-list: measure after paint, estimate unmeasured rows at the running average, hold the reader's row still when a measurement corrects an estimate. Applies to the profile notes list too. Tests: feed-window-dom (120 posts, 27,800px page, 12–24 rows mounted, anchor held, spacers both sides); feed-live looks at the top after scrolling up; the moderation test's stub relay no longer lets real posts in. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Feed: cached posts paint at once, never a spinner over them; the chat home ↵Adam Soltys2026-09-251-5/+14
| | | | | | | | | | | | | | prefetches the feed. The boot gate hid everything, cached posts included, until the opening page's faces and pictures had decoded — seconds of spinner on a feed we already held. Cached rows now paint immediately as they are and take their prepared presentation once the warm-up lands (the container carries data-booting meanwhile). The relay fetch starts at once instead of after the warm-up; arrivals still wait at the door. Opening the chat home warms and refreshes the current feed, so the Feed tap opens on the latest posts. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Prefetch a smaller feed and bound its local cacheAdam Soltys2026-09-241-24/+70
|
* Coins page: a renewal in flight keeps the whole page; a renewal you asked ↵Adam Soltys2026-09-241-18/+55
| | | | | | | | | | | | | | | | for is in history. Tapping Renew marked the coins pending and the page, finding nothing spendable, collapsed to a single "Pending: N sats" line — no table, no exit explainer. Coins in a round now stay in the table (greyed, tagged renewing), with a card saying where the round is (queued, in a round waiting for a confirmation, finishing). The page no longer closes on Renew. History: a manual renewal shows as "Renewing · in progress" while the round runs, and as "Renewed" after, even when it was free (automatic free renewals stay out of history, as before). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
* Send: the form is cleared the moment a payment goes through, not only when ↵Adam Soltys2026-09-241-0/+5
| | | | | | | | | its card is tapped. Leaving the sent card by a tab or Back kept the recipient and amount in the form, so the next send opened already filled in. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Preserve restored thread state across rapid refreshesAdam Soltys2026-09-241-1/+17
|
* Paint cached thread counts and header hat on refreshAdam Soltys2026-09-242-9/+38
|
* Keep thread avatars and viewport stable on refreshAdam Soltys2026-09-241-5/+52
|
* Videos play by themselves, muted, while on screen — with an Unmute button; ↵Adam Soltys2026-09-231-28/+99
| | | | | | | | | | | | | | | | | | | YouTube too. An inline video starts as it scrolls into view (muted, the only way a browser lets a page start one), pauses as it leaves, and a corner button turns the sound on; the native controls' own mute keeps the button honest. A YouTube box loads its player muted once in view (enablejsapi, so the same button can unmute it over the iframe API) and pauses out of view; a tap on the poster still means sound. One IntersectionObserver watches every player. Data Saver keeps tap-to-play. Tests adapted to the feed's new admission rule (a row waits for its author's face and pictures): the markdown and post-actions tests seed the poster's profile and serve their pictures locally; a picture that cannot be decoded is now a link, by design. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Feed: threads cached locally, posts never inserted under the reader, rows ↵Adam Soltys2026-09-231-183/+249
| | | | | | | | | | | | | | | | | | | | | | | | | | | | keep their first look. Work by Codex, wrapped up and verified here. Threads: a viewed conversation is persisted (thread-cache.js, up to 12 threads / 160 events), so a refresh or a cached note link shows the root and ancestors at once instead of the selected reply and a spinner; relays are re-asked in the background and an empty answer keeps the cache. Feed window (feed-window.js): arrivals are merged without inserting between visible rows — a gap fill under the reader's eyes waits until that part of the feed is offscreen, prepends anchor the reading position, the notice counts what went in above, and only its tap goes to the top. Older pages are prepared a few screens ahead; a page's pictures and faces are decoded before it is shown. Rows keep the presentation they were admitted with (feedPaint): background profile and quote refreshes no longer rewrite text or swap faces mid-read; media dimensions are known before paint. Thumbnails queue instead of being dropped past the first three. Tests: thread-cache, feed-window, feed-stability; feed-live updated for the new arrival rules (the notice counts up while you read). Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Always offer coin management for a Spending balanceAdam Soltys2026-09-231-7/+14
|
* Moderation: the whole mute list everywhere, follows' reports fold posts, ↵Adam Soltys2026-09-231-34/+331
| | | | | | | | | | | | | | | | | | | | | | strangers' spam hidden. Mutes were only applied when the feed merged and painted. One predicate (hiddenWhy / hiddenPk) now gates the feed, thread replies, notifications, the who-reacted panel and counts, quote cards, rooms, the DM list and the DM push. The list itself is read in full — people, words, hashtags, whole threads, and the nip44 private half — and edited through one publish path (mute thread and hidden words from the ⋯ menu and a Settings → Nostr card). Reports (NIP-56) from the people you follow are read from their outbox relays every half hour; a post or author they flagged is folded behind who said so, with Show. Report… in the ⋯ menu publishes a kind 1984 and hides the post for you. Amethyst's stranger rules: a post of 60+ characters repeated under another id is a duplicate and five duplicates hide the author for the session; more than ten hashtags hides the post. Both switchable in Settings. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Social: NIP-51 lists as feeds, posts and people in the address bar, the ⋯ ↵Adam Soltys2026-09-231-19/+291
| | | | | | | | | | | | | | | | | | | | | | menu on every screen. Lists: a feed of hand-picked people is published under your key as a kind-30000 follow set (title, p tags, t tags), so Coracle, Nostria and friends show it; your existing follow sets from other clients turn up as feeds (relay copy wins when newer; private nip44 members read and followed, never rewritten). "Keep as a nostr list" in the editor; unticking sends a NIP-09 deletion and the feed stays. "Add to a list" from a profile or a post's ⋯; someone's lists show on their profile and open as feeds (a kind-30000 naddr works as a pack too). Links: a thread puts its nevent in the address bar, a profile its npub — copy, share, reload; Copy link / Share in the ⋯ sheet. Boot-time renders after a reload share one history slot, so Back goes to the screen before. Fix: the ⋯ sheet and the reaction picker were only drawn by the feed and notification views, so the button did nothing on a thread or a profile. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Server comparison: drop the closed-app renewal row.Adam Soltys2026-09-221-3/+0
| | | | | Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Server comparison: the closed-app renewal row says "not verified there" for ↵Adam Soltys2026-09-221-1/+3
| | | | | | | Second, not "no". Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Payment detail: the unit is the tap-to-toggle tag; tests enter through the ↵Adam Soltys2026-09-221-2/+2
| | | | | | | wizard's import line. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Communities: Leave lives in the room header, not the invite panel.Adam Soltys2026-09-221-9/+9
| | | | | Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Ark: receives waiting with another server are claimed; notifications belong ↵Adam Soltys2026-09-222-3/+45
| | | | | | | | | | | | | to the identity. Once per session the wallet visits every other Ark server it holds state with — its own manager, a receive rescan, a sync to claim — and says what arrived and where; the coins wait there until a switch back. The stored notification list remembers which identity fetched it, so another identity on the same wallet starts empty instead of reading the previous one's. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Send: a bitcoin: URI with ark= pays over Ark on the same server, on-chain ↵Adam Soltys2026-09-221-0/+18
| | | | | | | | | | | | with a note otherwise. Noah and Second's other wallets share BIP-21 URIs carrying an ark= address. Same server as ours: the send goes over Ark with the URI's amount (your own address routes to boarding). A different server: the on-chain address is used and a toast says why. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Ark server card: a side-by-side comparison of the servers, from their own ↵Adam Soltys2026-09-221-1/+54
| | | | | | | published info. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Ark server is a setting again; an address on another server falls back to ↵Adam Soltys2026-09-222-4/+76
| | | | | | | | | | | | | | | | | | | Lightning. Settings → Advanced → Ark server: coinos, Second (ark.second.tech) or a custom server, per network — the stored choice is honoured on mainnet again. Ark state is kept per server, so switching hides but never loses coins; the card says what the current server holds and asks before letting go. After a switch the reusable address, the nostr advert and the payment name's ark= instruction follow the new server. Sends between servers can't be arkoor, so an Ark address that names a different server (its first bytes hash the server key) is treated as no Ark address at all in the pay ladder — a coinos name or npub then goes over Lightning by itself — and a pasted one is refused with the reason. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* POS token card: the terminal is flashed at coinos.io/flash.Adam Soltys2026-09-211-1/+1
| | | | | Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Settings: the terminal's cards (POS tokens, tap-to-pay link) move to Point ↵Adam Soltys2026-09-211-8/+10
| | | | | | | of sale; the show/hide toggle is gone. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Threads: replies as a tree, your own first under the note they answer.Adam Soltys2026-09-211-1/+26
| | | | | Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Settings: a Point of sale page of its own; Network folds into Advanced.Adam Soltys2026-09-211-2/+2
| | | | | | | | Six tiles still: Wallet, Payments, Point of sale, Nostr, Notifications, Advanced. The network and explorer cards sit at the top of Advanced. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Threads: climb to the real root, and look for it on the right relays.Adam Soltys2026-09-211-8/+39
| | | | | | | | | | | | | A client that tags only the note it answered leaves the root unnamed, so the note it replied to was taken as the root and the thread opened with its first post missing (a reply at the top wearing a "reply" badge). The loader now climbs: when the note it resolved as the root is itself a reply, it fetches that note's root and re-roots the thread, a few hops at most. The root is also looked for on the participants' relays and the e tags' relay hints, not just the reply author's. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Starter feeds: #gardenstr only until a Bitcoin follow pack is chosen.Adam Soltys2026-09-211-5/+4
| | | | | Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* New identities start with something to read: Adam and coinos followed, a ↵Adam Soltys2026-09-212-0/+63
| | | | | | | | | | | | | | | Bitcoin feed, and #gardenstr. A wallet the wizard made from fresh words, or a sign-in that found no wallet on its identity, gets one kind-3 update following the two coinos accounts (a sign-in identity only if it follows nobody yet), plus two starter feeds. The Bitcoin feed has a follow-pack slot (STARTER_BITCOIN_PACK) and reads the #bitcoin topic until a pack is chosen; #gardenstr shows what a topic feed is. Once per identity. The feed test now runs through the real first run, reading the words off the screen. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Send: a Lightning payment while Savings is showing asks before it pays from ↵Adam Soltys2026-09-211-0/+41
| | | | | | | | | | | | | | | Spending. Every Lightning payment passes through the Ark flow, whichever balance is on screen, and the review's "from your Spending balance" line was easy to miss. With Savings selected the flow now stops at an ask first: switch to Spending and continue, move Savings into Spending first (the existing board panel — an on-chain step, so a fresh invoice afterwards), or cancel. Pasted invoices, Lightning addresses and LNURL all pass through; autopay (a trusted, budgeted code) never asks. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Spending card: the Manage link shows whenever there are coins, warning or not.Adam Soltys2026-09-211-4/+9
| | | | | Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Spending coins: Manage opens on the first tap.Adam Soltys2026-09-211-7/+13
| | | | | | | | | | | The notice reads the persisted Ark state; the page read the live manager, which is null for the first seconds after boot — so a tap before it had connected found no coins and closed itself. The page now reads the same state, dials the manager meanwhile, and keeps Renew and Exit now disabled until it is there. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Spending coins: the unilateral exit section sits below renewal.Adam Soltys2026-09-211-5/+5
| | | | | Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Spending coins: "Unilateral exit", with an Exit now button behind a ↵Adam Soltys2026-09-211-1/+29
| | | | | | | | | | | | confirmation. The confirmation shows the coin count, the amount, the estimated mining fees (paid from Savings as the exit unrolls) and what Savings holds for them, refuses when Savings can't carry the fees, and says the funds only land once the timelocks run out and that an exit can't be stopped. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* First run: a new wallet is offered a Spending account before the home ↵Adam Soltys2026-09-211-0/+3
| | | | | | | | | | | | | screen, Not now one tap away. The wizard's spend step (claim a name, get a payment address) now follows the seed screen and the sign-in backup screen, wherever Spending can be set up (Ark-capable network with the names registrar, a signing account). Not now lands on Savings like before. namesAvailable answers 'yes'/'no' rather than a boolean, which featureHook would read as no answer. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Seed words read down each column; the Google central is a parameter with a ↵Adam Soltys2026-09-212-3/+12
| | | | | | | | | | | | | | door to the previous one. Word grids flow down a column then the next, with the row count from the word count — on a phone the first column is 1–6, the way a hand copies a list. pomegranate.js takes the central as an option (CENTRALS.coinos is auth.coinos.io, now deployed; the default stays auth.njump.me until its Google client is live), and the sign-in card grows a "previous server" line once the default moves, so accounts made under njump keep working. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Ark: the renewal notices and the Spending coins screen speak in sats, ↵Adam Soltys2026-09-211-8/+8
| | | | | | | whatever the display unit. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Point of sale: the sats sit under a fiat total, so a payer's wallet and the ↵Adam Soltys2026-09-211-1/+6
| | | | | | | counter agree by eye. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Point of sale: a sale the till never saw settle is adopted from the wallet's ↵Adam Soltys2026-09-211-0/+18
| | | | | | | own record. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Point of sale: a paid sale opens its payment detail, which now says bill and ↵Adam Soltys2026-09-212-1/+29
| | | | | | | | | | | | tip. The row finds the ln-receive movement by the invoice it recorded and opens the same detail screen the history page shows; the detail asks features for more (arkMoveDetailExtra) and the till adds Bills, Tips (with the percentage) and the note. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Point of sale: in a currency the pad works like a till — digits shift in ↵Adam Soltys2026-09-211-2/+12
| | | | | | | | | | from the right. 5 is 0.05, 277 is 2.77, 5588 is 55.88; backspace shifts out; the "." key becomes "00". Sats are whole numbers and type plainly. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Point of sale: /pos, a per-device till mode, an on-screen pad — and off ↵Adam Soltys2026-09-213-15/+42
| | | | | | | | | | | | | | | the Receive tab. v3.coinos.io/pos opens the point of sale once a wallet is up (claimed at boot before any feature reads the path), so the till can be bookmarked or put on a home screen. Settings → Payments gains "Start in point of sale on this device" (localStorage, not synced: the till, not every phone the owner carries). The amount and the custom tip get a 3×4 pad that edits the same field a keyboard or a paste would. The button under the payment address on Receive is gone. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Point of sale: the total on the tip screen reads at a glance.Adam Soltys2026-09-211-1/+1
| | | | | Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Point of sale: the tip screen shows an invoice error, and both screens say ↵Adam Soltys2026-09-211-3/+7
| | | | | | when the invoice is being made. Co-Authored-By: Claude Fable 5.1 <[email protected]>