aboutsummaryrefslogtreecommitdiffstats
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* Translation: posts in another language are shown in yours — "Translated ↵Adam Soltys12 days5-6/+196
| | | | | | | from Spanish · Show original" under the words, automatic by default for posts the language guess calls foreign (Settings → Nostr → Translation switches it off and leaves a Translate link instead), and ⋯ → Translate for any post. The browser's on-device Translator does it when the language pair is already installed (desktop Chrome); otherwise the registrar's new POST /translate (names/translate.js): a cached, 4-at-a-time front for a LibreTranslate container on cs (names/compose-libretranslate.yml, v1.9.6, 32 languages; none for sw/mr/ta/te, so those readers get no offer). Links, nostr: mentions, :emoji:, #tags and long codes are never sent to the model — only the prose between them, batched in one call (src/translate-split.js, shared). Translations are remembered (coinos-translations, 300). tools/translate-test.js Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
* Accounts: switching no longer leaks the previous identity's notifications ↵Adam Soltys12 days1-8/+39
| | | | | | | and DMs into the next. A notifications query (up to 5 s on the relays) or a wrap mid-decrypt that was still out at the switch landed in the NEW account's list and was saved there under its key — a throwaway account showed adam's zaps, reactions and conversations for good. A session counter bumped in stop() is checked after every await on both paths; notifications only take events p-tagging this identity, and an incoming DM must come from or name it. Healing: notification caches saved before this (no notifsV 2) are dropped once and refetched; a cached DM thread holding a row from someone who is neither us nor the peer is swept. tools/account-switch-leak-test.js (fails on the old code: the reaction and the thread both leak) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
* Dark mode: your own chat bubbles are a gray (#343a44, light text) instead of ↵Adam Soltys12 days1-0/+3
| | | | | | | the white accent, which glared among the dark bubbles. Android 1.12 (code 13): the TWA no longer names a navigation-bar colour — the helper library always passed one (white when the manifest named none), and Chrome 154's Custom Tab window paints that bar white anyway while the buttons follow the colour asked for, so the colour extras are stripped from the launch intent (both schemes) and the bar is left to the browser and the system. Untested on a device yet; not published. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
* Posts: edit and delete your own. The ⋯ menu on your post gains Edit (a ↵Adam Soltys12 days3-8/+166
| | | | | | | kind 1010 edit beside the original — the draft NIP-41 Amethyst reads and writes; the feed, thread and quote cards show the newest text with "· edited") and Delete (a NIP-09 kind 5, after a confirmation). Edits and deletions are asked for in the same REQ as each post's tallies and its live subscription, and count only when signed by the post's own author; they're remembered between sessions (postEdits cache) so a deleted post never flashes back from a cached feed. A post signed by the wallet key before a login was linked is still signed by that key. A deleted thread root keeps its place as "deleted by its author". relay.coinos.io now accepts kind 1010. tools/post-edit-test.js Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
* DMs: a linked nostr login whose signer hadn't resumed yet (a reload before ↵Adam Soltys12 days2-11/+48
| | | | | | | the bunker reconnected, a session just dropped) counted as "every key is here", so each wrap sealed to the login npub was tried on the wallet key alone, given up after ~40 s and logged as opened — never asked for again (a phone kept 9 of 186 messages). Since b06bbb4 the check only passes with no login or a live signer that decrypts (or Amber); a drain without one waits for the signer instead of re-running the wallet key, and the slow retry is rescheduled in finally so an early return can't end it. "All promises were rejected" (every relay refused the bunker request) and "not open anymore" count as try-later, not "not ours". Heal v2 re-opens every wrap the relays still hold, marked done only once nothing it re-opened is still waiting for the signer Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MgAFLnkF7KrdhuyCLMNgtL
* Profiles: the Following / Followers counts no longer flash a dash before ↵Adam Soltys12 days2-1/+5
| | | | | | | they load — the number's place is held by an invisible stand-in and the real count fades in over it Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MgAFLnkF7KrdhuyCLMNgtL
* Feeds: Everything and Follows + lists are no longer built-in chips; any ↵Adam Soltys12 days2-22/+53
| | | | | | | custom feed can be one. The editor gains "Everyone on my lists and packs" (the people of all your other feeds and packs, read fresh each time the feed opens) and "Posts from anyone on hashtags I follow" (your topic feeds' tags and your kind-10015 interests, OR'd in beside the feed's people, or the whole feed when it has no people). The editor reads a feed as saved, never expanded, so the lists don't get copied into it Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MgAFLnkF7KrdhuyCLMNgtL
* Feed: the "new posts" pill only ever takes you up. It counts the new posts ↵Adam Soltys12 days1-20/+57
| | | | | | | you haven't scrolled up to yet (going up to one, or past it, takes it and everything below it off), and the tap glides to the nearest of them above the post at the top of your screen — reading one newer than the oldest, you were sent back down to the oldest. A new post peeking in at the top edge still counts as above you. The count updates as you scroll up, and the notice clears when none are left (this replaces the at-the-top check) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MgAFLnkF7KrdhuyCLMNgtL
* Notifications: a reply, mention or reaction your follows reported is left ↵Adam Soltys12 days1-2/+6
| | | | | | | off the list and the unread count, as a muted one is — the thread folds that post behind who flagged it, so the tap landed on a fold instead of the reply it promised. Checked at render time, so reports that load later (or a report taken back) apply to what was kept Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MgAFLnkF7KrdhuyCLMNgtL
* Chat: a one-tap ⚡ beside every bubble from someone else, in communities ↵Adam Soltys12 days2-5/+30
| | | | | | and DMs, vertically centred on the bubble — tap zaps the default amount (the strike starts at the bolt), hold sets the amount, without opening the message sheet first. Own messages, visitors and wallets that can't zap get none; Marmot groups have no zap yet and are left alone Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Ark: a Lightning payment's HTLC vtxo is never a coin to spend. The reconcile ↵Adam Soltys12 days1-3/+33
| | | | | | pass held an in-flight action's inputs but not its HTLC outputs, so between two quick zaps it took the first zap's HTLC coin for an unheld 'pending' orphan, the server called it unspent, and it came back 'spendable' — the second zap chose it as its input and the server refused the policy ("not spendable as a round, offboard or arkoor input (policy: server-htlc-send-v1)"). HTLC outputs are now held with their action, _free() refuses any non-pubkey coin whatever its state (records learn their policy from their bytes), and a pass heals HTLC coins an earlier pass freed Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Front door: a "Migrate a coinos account" button under the sign-in doors, ↵Adam Soltys12 days3-25/+77
| | | | | | opening a page that says a wallet and its twelve words come first (Create, or the sign-in doors), and /migrate on a device without a wallet opens on that page instead of an unexplained welcome; while a move is queued the recovery-phrase step offers no Later. Spending step: an account whose custom name the registrar handed back (a wallet a sign-in restored) leaves the wizard instead of being shown a claim form it could only retype its own name into — claiming it again "succeeded" onto the same page; the claim form also waits behind "Getting things ready…" until the registrar lookups settle Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Feed images: the column copy and the grid tile are decoded, resized and ↵Adam Soltys12 days2-37/+105
| | | | | | WebP-encoded in a worker, one picture at a time, instead of on the page thread between scroll frames (a profile of the live feed showed 1.8 s of convertToBlob there, in tasks up to 383 ms). A picture that hangs or crashes the worker is given up and the worker restarts for the next; three in a row and originals paint for the session, as they do wherever workers can't run Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Restart wheel coast timing and respond immediately on reversalAdam Soltys12 days1-3/+12
|
* Post composer: Preview and Cancel stand as tall as Post and the attach ↵Adam Soltys12 days2-1/+4
| | | | | | button, in the same type Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Change username: a name this wallet's key claimed before a login identity ↵Adam Soltys12 days1-0/+11
| | | | | | was attached no longer reads as taken — the identity-signed claim is refused, so retry signed by the wallet key that owns the record Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Reuse feed overscan to reduce rendering during scroll coastsAdam Soltys12 days1-6/+15
|
* Feed scrolls faster on a desktop: a wheel notch pushes a quarter further, ↵Adam Soltys12 days1-3/+3
| | | | | | and a grab-and-flick throws twice as hard with a higher top speed Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Grab-and-flick no longer opens the post: a flick that starts a little ↵Adam Soltys12 days1-8/+13
| | | | | | sideways still scrolls (only a clearly sideways drag selects text), and any press that moved eats the click Chrome still fires. A wheel push at the very top of the page no longer dies on its first frame (a frame stamp older than the push read as a step up) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Desktop feed scrolls like a phone: a mouse-wheel notch coasts and slows ↵Adam Soltys12 days2-0/+99
| | | | | | (quick turns stack, a reverse turn brakes, trackpads left alone), and a mouse can grab the feed and flick it (a sideways drag still selects text, a drag doesn't click what it started on) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Footer: "Show your support" beside How it works opens the hat shop from any ↵Adam Soltys12 days3-0/+8
| | | | | | page (shown once a wallet is open, since the shop pays from it) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Profile public key: solid border instead of dashed, a copy icon beside the ↵Adam Soltys12 days2-2/+10
| | | | | | key, and a slightly larger font (13px) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Keep carousel flick destination through stale scroll-end eventsAdam Soltys12 days1-12/+25
|
* The built-in community's fallback name is Coinos, matching its new ↵Adam Soltys12 days1-1/+1
| | | | | | owner-signed metadata (edition v3), so the public /chat page and a client that hasn't folded the control plane yet agree Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Asset paths are site-absolute: relative ones resolved against a deep page ↵Adam Soltys12 days1-2/+4
| | | | | | (/feed/…, /nevent1…) and fetched the app's HTML, which broke the coinos community's logo (and would have broken the QR decoder, signer module and language packs there). Dev server serves the app icons. The live Concord delivery test is gone: it posted "delivery test" messages into the real coinos #general Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Chip strips drag sideways with a mouse (a drag doesn't click the chip it ↵Adam Soltys12 days2-0/+40
| | | | | | started on) and show a thin scrollbar on mouse devices, so the feed chips that run past the card are reachable on desktop Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Amethyst's feed model: an Everything feed (your follows, everyone on your ↵Adam Soltys12 days3-8/+67
| | | | | | lists and packs, and posts from anyone on a hashtag you follow: your topic feeds' tags and your NIP-51 interests, kind 10015) and a Follows + lists feed beside Following, built from your feeds and offered once there's something to add. Long names in search results end in an ellipsis instead of running off the card Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Desktop layout: from 900px the bottom nav is a left rail (your profile first ↵Adam Soltys12 days3-12/+141
| | | | | | with a bigger face and name, Settings last) beside a 600px page column, and from 1220px the wallet (balance, Receive/Send, latest payments) rides in a right column; search is a full field in the header there. Floaters re-centred on the page column, open chats still fill the window, phones unchanged Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Auto-pay budgets on offer are round money when fiat is the unit on screen ↵Adam Soltys12 days1-1/+9
| | | | | | ($1, $5, $10, $100 in the user's currency, kept as sats at today's rate) instead of 1k/5k/10k/100k sats shown as odd fiat figures Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A tapped lightning:lnurl (NFC at a till) waits on the paying shell for the ↵Adam Soltys12 days2-17/+28
| | | | | | feature that pays it instead of sitting as raw text in the recipient field; Paste and Scan stay one line tall as a long address grows the field Co-Authored-By: Claude Opus 5.5 <[email protected]>
* POS terminals ring up in the owner's currency: the app sends its currency ↵Adam Soltys12 days1-1/+4
| | | | | | when minting a terminal token (it sent none, so every terminal priced sales in USD and a $0.03 sale paid out as $0.04 CAD), and a new token retunes the terminals already paired to that name Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Max in fiat sends every sat: the figure a Max fill wrote is remembered with ↵Adam Soltys12 days1-5/+16
| | | | | | its exact sats, so the cent-rounded amount no longer parses back a few sats short and strands them. Anything typed parses as typed Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The 'Coins renew in ~N days for X. Manage' line under the Spending balance ↵Adam Soltys12 days1-29/+3
| | | | | | is gone: the card's gear opens the coins page, which carries the renewal schedule and fees Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Max fills the amount in the unit the field shows: in fiat that's money ↵Adam Soltys12 days4-8/+18
| | | | | | floored to the cent (so it never parses back above the maximum), not a BTC figure under a CAD label. One ctx.amountField helper for the ark send/LN Max, the gift Max and fixed-amount zap/BOLT 12 fills Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Prefetch visible post threads after a bounded reading dwellAdam Soltys13 days2-6/+80
|
* Coins in another device's renewal are busy here too: the renewal sliver ↵Adam Soltys13 days2-38/+74
| | | | | | names its inputs, and ArkManager._free / freeCoins exclude coins an in-flight remote renewal holds from balance (counted pending), send/LN/offboard/exit selection, auto-renew, the backstop and the coins page (greyed with the round). Freed the moment that renewal reads finished, failed or lapsed Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Renewals show on every device: the sync snapshot carries each device's own ↵Adam Soltys13 days2-2/+59
| | | | | | renewals as display-only slivers (step, amounts, fee, round txid; no signing material), merged into remoteRenewals furthest-step-wins, never as actions; the coins page lists another device's renewal in progress with its round transaction until it finishes there or a 'Renewed' row syncs (two-day cap) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A renewal refused for 'insufficient refresh fee' re-reads the server's fee ↵Adam Soltys13 days1-1/+33
| | | | | | schedule and re-prices instead of resubmitting the same underpaying set on every sync; if the new fee leaves under 330 sats (or the price didn't change) it fails and frees the coins. Backstop registration re-reads the schedule on the same refusal Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Renewal page shows the server's flat renewal fee: the schedule reads '0.2% + ↵Adam Soltys13 days2-4/+12
| | | | | | 300 sats' and '300 sats' instead of 'free' when the ASP charges a base fee, and the description says automatic renewals wait for the cheapest bracket rather than a free one Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A finished renewal adopted twice no longer shows 'Renewal in progress' ↵Adam Soltys13 days1-1/+32
| | | | | | forever: once its done action is pruned, a re-read round breadcrumb adopted it again as a rescue at step 'issued', whose spent inputs had lost their bytes, so every sync threw. A round counts as claimed when its 'Renewed' movement or its fresh coins are already in the wallet; the breadcrumb and rescueParticipation skip it, and a stuck issued action retires without a row Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Savings scan looks 20 addresses past the last used one (BIP-44 gap limit) ↵Adam Soltys13 days1-35/+40
| | | | | | instead of stopping at the first unused address, so a seed restored from another wallet shows coins sitting past a gap; the window of 20 is probed in parallel, the empty look-ahead tail isn't kept, and the next fresh address is one past the highest used (never a hole another wallet left) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* No speaker pop on opening the app: the zap sound decodes in an ↵Adam Soltys13 days1-25/+35
| | | | | | | OfflineAudioContext and makes its real AudioContext on the first tap (one made at load ran at once in the installed app, re-opening the phone's audio output on every open/refocus), suspended again after the sound and when the app is hidden Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCGjEEMD23CweKrefbTDJp
* Gentler on relays: a relay that says rate-limited (CLOSED/OK/NOTICE) gets no ↵Adam Soltys13 days2-12/+148
| | | | | | | one-shot reads for 30 s, doubling to 10 min; zap/reply tallies flush at most every 2 s in one REQ (two filters) and the live #e sub swaps at most every 10 s; quoted-note lookups batch per relay over 150 ms — scrolling a 300-follow feed went from ~21 to ~8.5 REQs per 10 s on the busiest relay, primal's "too many concurrent REQs" from 19 to 0 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCGjEEMD23CweKrefbTDJp
* Feed videos before they play: the picture fills the box with only the play ↵Adam Soltys13 days2-7/+38
| | | | | | button and size (no seek bar or sound button until playing); hovering the cover no longer paints it over with the app's button grey; upright phone clips (stored sideways with a quarter-turn matrix) paint upright, v1 size caches dropped; a clip the probe found HEVC switches to the copy before fetching the original Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Videos: posters for clips that came without one, and an H.264 copy for a ↵Adam Soltys13 days3-9/+69
| | | | | | clip this browser can't picture (an iPhone's HEVC on Chrome for Linux played sound over black) — vmedia container on cs (bun + ffmpeg, /vmedia/), switch on zero-width metadata or an HEVC header from the probe, a line saying why if the copy fails too Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Desktop Send focus: a mouse click leaves the Send button focused, and that ↵Adam Soltys14 days1-9/+12
| | | | | | blocked the recipient field — only a field you're typing in is protected now (test opens Send with a real click) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Wizard cover: an upload icon (arrow out of a tray) instead of the camera emojiAdam Soltys14 days1-1/+2
| | | | Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Desktop: Send opens with the cursor in the recipient field (once per visit, ↵Adam Soltys14 days1-13/+19
| | | | | | never off another field, never on phones); the amount field still takes it once a recipient resolves Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Call the protocol by its name: 'Marmot (MLS)' in the group-type picker and ↵Adam Soltys14 days1-4/+4
| | | | | | the send-by menu (White Noise is one app that speaks it); a zap on something no relay has says it may be a private message instead of claiming the post vanished Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Setup wizard: a cover behind the avatar — twelve nature covers ↵Adam Soltys14 days3-8/+72
| | | | | | (self-hosted, Unsplash) cycled with arrows or a swipe, or upload your own; untouched, each pubkey gets its own default, published as the kind-0 banner beside the punk Co-Authored-By: Claude Opus 5.5 <[email protected]>