aboutsummaryrefslogtreecommitdiffstats
path: root/src/app.js
Commit message (Collapse)AuthorAgeFilesLines
* Closing the pager (or a picture) lands on the page under it, not wherever ↵Adam Soltys28 hours1-3/+37
| | | | | | | | | | | | | | Back goes The × was a blind history.back(), and the entry under the pager isn't always the feed: the browser's older entries outlive a background reload of the app, and boot merges entries. It took the reader to the wallet, then the chat list. closeLayer still steps Back (so the phone's Back doesn't reopen it), but if Back lands anywhere but the page under the layer, the reader is put on that page and that entry rewritten to it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01KPw21NEpWeTGu6swVASmBt
* Feed wheel: a turn back against the coast hunts, in short steps that grow. ↵Adam Soltys3 days1-17/+43
| | | | | | Flying down the feed and turning the wheel back for the post just passed used to send the page flying the other way (a full notch's coast, 300px) the moment it caught — the reader overshoots again, and hunts by overshooting. Now a reversal against a coast (or one that died within 400 ms) catches the page and takes that notch as a quarter of its travel, over a quick coast (110 ms, not 325); each notch on in the same direction grows the step — 0.35, 0.5, 0.7, 0.85 of a notch — and the sixth is a full push with the usual wind-up, so a few flicks have the wheel flying again. Another turn back while hunting starts the small steps over, and two seconds without a notch ends the hunt: a notch from rest is the push it has always been. Keys, a touch or a grab end it too. tools/feed-wheel-reverse-test.js (short step on reversal, the ramp, the restart, the pause, the just-died coast, the full push from rest); feed-momentum-test still passes. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Feed: a picture opens in the media pager, with the feed's other pictures a ↵Adam Soltys3 days1-2/+5
| | | | | | 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. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Feed wheel: turning the wheel into a page already moving winds the speed up. ↵Adam Soltys3 days1-1/+6
| | | | | | Each notch added the same push whatever the speed, so a sustained turn settled at a stroll (the coast's decay ate what each notch added). Now the push scales with the speed on the page, 1x from rest up to 2.5x at a fast coast, so keeping the wheel turning keeps accelerating; a single notch from rest, the reversal and the trackpad path are as before (feed-momentum + feed-wheel-reverse tests green). Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Lock with fingerprint or face. The padlock's "Protect this device?" now ↵Adam Soltys4 days1-11/+149
| | | | | | | offers a passkey instead of a password, and Settings → Security can turn it on or off. The saved-wallets vault is sealed under a secret only that passkey's PRF produces (behind the phone's fingerprint/face check, the passkey kept by the platform's secure hardware or password manager), so nothing in this browser's storage opens it. Opening the app on a locked device asks for the passkey by itself; a cancel leaves an Unlock button. The prompts that need the vault opened (save, forget, lock a stray wallet) take the passkey too; there's no Change password for a vault that has none; the recovery words remain the way back. The lock passkey has its own PRF salt and a marked user handle, not discoverable where the platform allows — passkey sign-in refuses it rather than derive a stranger's key from it. English + Italian strings. tools/passkey-lock-test.js (Chrome's virtual authenticator with PRF). Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
* Move desktop logo and search into sticky sidebarsAdam Soltys5 days1-8/+14
|
* Footer: the source link and the running commit point at git.coinos.io (cgit) ↵Adam Soltys5 days1-2/+2
| | | | | | | instead of GitHub, where the coinos organisation is suspended. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
* Amounts: no plus sign on money coming in either — the word (Received) and ↵Adam Soltys5 days1-3/+3
| | | | | | | the green say it. History rows, transaction details, the "payment received" screens (wallet, Spending, gifts, boards/onboards) and the till's paid bills. The till's tip choices keep theirs: "+$2" there is what a tip adds to the bill. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
* Amounts: no minus sign on money going out. The word (Sent, Renewal, ↵Adam Soltys5 days1-2/+2
| | | | | | | Exiting…) and the red already say it's a debit — history rows, the transaction details, the sent screens, and on-chain rows (whose negative net printed its own sign). Received keeps its +. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
* Front door: a "Migrate a coinos account" button under the sign-in doors, ↵Adam Soltys6 days1-24/+67
| | | | | | 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]>
* Restart wheel coast timing and respond immediately on reversalAdam Soltys6 days1-3/+12
|
* Feed scrolls faster on a desktop: a wheel notch pushes a quarter further, ↵Adam Soltys6 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 Soltys6 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 Soltys6 days1-0/+97
| | | | | | (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 Soltys6 days1-0/+5
| | | | | | page (shown once a wallet is open, since the shop pays from it) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Keep carousel flick destination through stale scroll-end eventsAdam Soltys6 days1-12/+25
|
* Chip strips drag sideways with a mouse (a drag doesn't click the chip it ↵Adam Soltys6 days1-0/+32
| | | | | | 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]>
* Desktop layout: from 900px the bottom nav is a left rail (your profile first ↵Adam Soltys6 days1-5/+60
| | | | | | 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]>
* A tapped lightning:lnurl (NFC at a till) waits on the paying shell for the ↵Adam Soltys6 days1-17/+25
| | | | | | 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]>
* Max in fiat sends every sat: the figure a Max fill wrote is remembered with ↵Adam Soltys6 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]>
* Max fills the amount in the unit the field shows: in fiat that's money ↵Adam Soltys6 days1-1/+11
| | | | | | 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]>
* Desktop Send focus: a mouse click leaves the Send button focused, and that ↵Adam Soltys7 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 Soltys7 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 Soltys7 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]>
* Setup wizard: a cover behind the avatar — twelve nature covers ↵Adam Soltys7 days1-7/+54
| | | | | | (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]>
* Desktop: the Send amount field takes the cursor as soon as it appears (once; ↵Adam Soltys7 days1-1/+21
| | | | | | never off another field, never on phones) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Swiping to Savings opens its Receive pane (the deposit address, no extra ↵Adam Soltys7 days1-6/+34
| | | | | | tap); Enter on Send picks the top suggestion, and Enter walks amount → review → confirm Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Rebuildable caches move from localStorage to IndexedDB (cache-store.js)Adam Soltys8 days1-1/+8
| | | | | | | | | | | | | | | | | | | | localStorage is ~5M characters per site whatever the device, and a phone had filled it. Profiles, faceless list, reports, follow packs, profile pages, relay lists, the moderation baseline, community directory, link previews, video sizes/probes and search profiles (~3M on that phone) now live in IndexedDB, which shares the site's disk allowance (GBs). cacheStorage keeps localStorage's string API: reads from memory, coalesced write-behind, flushed on hide. Copies migrate on open and are removed once written. Boot waits for it (max 3s) beside the Ark store; caches read at construction re-merge on ready; an early write can't replace the stored copy. A copy an older build writes to localStorage later moves in on first ask. Wallet wipes reach it; private mode stays on localStorage. Read markers, drafts, follows, note threads and sync outboxes stay in localStorage on purpose (cross-tab consistency, early server-rendered seeding). Also asks navigator.storage.persist(). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* README rewritten for today's coinos v3; build switches are COINOS_* (HAL_* ↵Adam Soltys9 days1-8/+3
| | | | | | | still accepted); silent-payment leftovers removed Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01YRC6aKhwAud231ot9FPmhi
* /migrate: a link that opens the coinos.io account moveAdam Soltys10 days1-4/+53
| | | | | | | | Fresh devices reach it through the wizard (in place of the Spending offer); an existing wallet gets the move page on its own once it can mint a payment address, and leaves it straight back to the wallet. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Renewing asks first, and a renewal links to its round's transactionAdam Soltys11 days1-1/+1
| | | | | | | | | | | | | | | | | | | | | - The coins page's Renew button opens a confirmation instead of renewing at once: how many coins, their amount, the fee, and what is left to spend meanwhile — with a red notice when that is nothing (the button selects every coin by default, which is how a user locked their whole balance for an hour on 2026-10-03). It says the coins can't be spent until the round's transaction confirms and that a renewal can't be cancelled; the wallet renews for free near expiry anyway. The inline notice from 328f2db moves into it. - A renewal keeps its round's transaction id as soon as the round has run (before it confirms): the in-progress card on the coins page links to it, and the finished renewal's history row carries it, so its detail shows the id with View/Copy like any on-chain movement. Renewals finished before this change have no id recorded. tools/ark/renew-confirm-ui-test.js, tools/ark/renew-txid-test.js Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01ULQZS9MQa6iAsXnrJUD9Du
* Feed media views: a grid of pictures, videos to flip throughAdam Soltys11 days1-2/+3
| | | | | | | | | | | | | | | | | | | | | | | All / Images / Videos sits under the feed chips (remembered). - Images lays the feed's pictures out as a three-column grid. - Videos opens straight into a full-screen pager: one clip per screen, snapping, the one on screen playing with sound (muted with an Unmute button when the browser refuses), the next a flick or ↓ away. Closing it leaves a grid of the clips. - The pager shows only the media until tapped; a tap shows the author (tap for their profile), the post's words as a caption without the media links (tap to expand), and likes and sats in the bottom right, which also like and zap. - It is a place: Back or Escape closes it. Built outside the morph, so a repaint never restarts a clip; off-screen clips let go of their media. - Near the end of the grid or the pager the feed fetches older posts and new slides are appended. - Toasts now sit above full-screen viewers. tools/feed-media-views-test.js Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01ULQZS9MQa6iAsXnrJUD9Du
* Switching Spending/Savings opens Receive, with that account's addressAdam Soltys12 days1-4/+4
| | | | | | | | It opened the history tab. Any open payment detail still closes with the switch. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Spending settings: Move to Savings opens its form againAdam Soltys12 days1-0/+3
| | | | | | | | | | showSend flipped the wallet's tab to Send but left the screen where it was; from the Spending settings page (where the co-operative exit lives now) the form opened out of sight and the button seemed to do nothing. Opening Send now always means the wallet screen. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Send: a lightning address moves on to the amount by itselfAdam Soltys12 days1-1/+22
| | | | | | | | | | | | | - Pasted with the keyboard (not only the Paste button) it is complete text: it advances at once, as a paste always did through the button. - Typed and then left alone for 0.9s, it is checked quietly (names: our registrar or BIP-353 DNS; zaps: the LNURL-pay endpoint answers) and the form moves on only if something answers. A half-typed domain answers nothing, so it just waits, with no error; finishing it moves on. - tools/send-lnaddr-advance-test.js (live registrar/DNS, [email protected]). Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Send: the recipient field grows to show it all; history steps aside while ↵Adam Soltys12 days1-23/+58
| | | | | | | | | | | | | | | | | | sending - The recipient is a one-line textarea that wraps and grows (rows from the text's length over the field's measured width), so a whole address is in view in the field itself — no second copy in small type below. Enter doesn't break it and pasted line breaks are dropped. Empty, it is as tall as its hint (measured in the hint's own face), so that's whole too. - Past the recipient — the amount, a review, a Lightning/Ark confirmation, a raw tx to broadcast — the history list below the send pane is left out. - tools/send-dest-test.js (390px and 1280px). Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Feed form: relays and an every-post firehose; its Back works; a stronger ↵Adam Soltys12 days1-4/+5
| | | | | | | | | | | | | | | | | | | new-post tint - The new/edit feed form gets a Relays field (read this feed from these relays only) and "Every post on these relays", which saves a firehose feed (optionally curated) named after its relay and hides the people, packs and topics it doesn't need. It used to take a hand-typed /feed/all?r= link. - The form's Back did nothing visible: opening it made no history entry, so Back went to the page behind the feed and left the form up. The editor (and the gear page's Spending/Savings view) are now part of the navigation state. - New-post tint 9% -> 16% green in light mode; dark mode unchanged. - tools/feed-editor-relays-test.js. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Notifications screen links to its settingsAdam Soltys13 days1-0/+2
| | | | | | | | A Settings button beside the Notifications title opens Settings > Notifications (which kinds buzz this device); browser Back returns. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Balance card gear replaces Accounts; Spending's coins live behind itAdam Soltys13 days1-29/+66
| | | | | | | | | | | | | | | | | | | | - The "Accounts" pill on each balance face is now a gear. It opens that face's settings: Spending leads with its coins (renewal, the co-operative move to Savings, unilateral exit), then Security (lock, change password), the recovery phrase, auto-logout; Savings adds its public key. A wallet with no nostr identity also gets sign-in and log-out there, since it has no profile page to hold them. - The exit cost is no longer said under the balance; the Spending settings state it, always, not only when coin chains run deep. - The lone Manage link under the balance is gone (the gear is the way in); warning notices that are about the coins link to the same page. - The Accounts list, Add wallet and Delete all are no longer reached from the wallet (Delete all stays behind profile > Log out > forget). - Tests follow the gear: padlock-ask, lock-wallet and account-access pass again; cooperative-exit-ui clicks the Spending gear. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Shared note links open on the post, with names and facesAdam Soltys13 days1-1/+4
| | | | | | | | | | | | The server renders /nevent1 and /note1 pages with the thread inlined (post, root, replies, kind 0s) and Open Graph tags; the client seeds its thread cache from it and opens the thread on the first paint. Without it, a pending frame holds the screen instead of the front door. Profile lookups ask our relays and the profile indexes at once, streamed, instead of one after the other behind five-second waits. A thread opened straight from a link has no Back button. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Dismiss photos immediately on tap at any zoom levelAdam Soltys13 days1-19/+19
|
* Warm recipient portraits from Send suggestions before selectionAdam Soltys13 days1-0/+4
|
* Add cooperative coin exits and clarify profile, preview and zap controlsAdam Soltys13 days1-2/+2
|
* Clear abandoned payments, reset profile Pay and restore native messaging BackAdam Soltys13 days1-5/+27
|
* The standalone wallet opened from a disk shows its avatars, font and languages.Adam Soltys13 days1-2/+3
| | | | | | | | | | With no files beside it, relative punks/, locales/, nip46.js and jsqr.js looked on the disk. From file:// they now come from v3.coinos.io (images and scripts need no CORS; /locales/ now sends Access-Control-Allow-Origin on the server), and standalone.html carries Public Sans inline. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VP5Ljqk7EYcm5QQAbzDwog
* "Sign into another account" opens on Create new, not the seed import box.Adam Soltys2026-09-301-1/+3
| | | | | Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WMMwWYJkPQxLgfMsY7hWcU
* A picture or video on its way shows a bar with its percentage — shrinking, ↵Adam Soltys2026-09-301-12/+20
| | | | | | | | | | | | | | | | then uploading; the pencil reads "New post". ui.mediaProgress { stage, pct } (a render per whole percent) drawn as a labelled bar under the reply and post composers, instead of only the paperclip turning into a spinner. Upload progress comes from XMLHttpRequest upload events (fetch() has none) in uploadPublicMedia's new onProgress; injected fetchers (tests) keep the fetch path. upload-progress-test: 1.2 MB at 400 KB/s climbs 0→100 in steps. video-compress-test: the bar counts the shrink, then the upload. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
* Videos are shrunk on the phone before upload; nostr.build is the first media ↵Adam Soltys2026-09-301-0/+11
| | | | | | | | | | | | | | | | | | | | | | host. No public Blossom host transcodes (nostr.build's and primal's BUD-05 /media return the same bitrate), so a 15-20 Mbps phone clip stalled on playback. src/video-compress.js re-encodes on the device with WebCodecs via Mediabunny (a lazily loaded chunk, left out of the SW precache and the standalone file): H.264, short edge 720, ~2.5 Mbps, moov first, audio passed through, rotation baked in. Anything short of a clear win uploads the original. A toast counts the shrinking down. Media hosts: blossom.nostr.build first, nostr.download second (it was unreachable for hours); a HEAD probe skips a host that doesn't answer within 5 s instead of waiting out the whole upload timeout. video-compress-test: 1080p 20 Mbps 5 s (landscape and rotated portrait) → 1.6 MB H.264 720p 2.49 Mbps with audio, moov first, in 2-3 s. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
* Composers take pictures from the keyboard: the reply, post and chat fields ↵Adam Soltys2026-09-291-3/+13
| | | | | | | | | | | | | | | | | | | are contenteditable. Android keyboards (Gboard GIFs, stickers) only offer images to fields that accept them, and Chrome says so for contenteditable, never <textarea> — hence the greyed-out GIF key and "This app does not support images here". <coinos-text> (src/rich-text.js) is a contenteditable that acts like a textarea to the code around it (value, selectionStart/End, setSelection- Range, placeholder), keeps text plain, and hands any pasted/dropped/ keyboard picture to onMedia — the paperclip's upload. The morph syncs its value like a field's and leaves its own editing attributes alone. composer-media-test: types like a textarea, strips pasted formatting, a pasted GIF uploads and lands in the reply, still editable after repaint. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
* The coinos logo always goes to the wallet home, from the vtxo page and every ↵Adam Soltys2026-09-291-0/+8
| | | | | | | | | | | other page. goHome cleared a hand-kept list of pages and the vtxo list (arkCoinsPage) wasn't on it — nor a transaction's detail, the hat shop, the till. It now clears every page the history tracks. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp