aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/messages.js
Commit message (Collapse)AuthorAgeFilesLines
...
* Message box: no scrollbar until the text outgrows itAdam Soltys13 days1-1/+8
| | | | | | | | | growComposer sized the border-box field to scrollHeight, two pixels short of its own content (the border), so even an empty box overflowed and showed a scrollbar. Count the border, and scroll only at the height cap. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Bigger new-posts pill that swipes awayAdam Soltys13 days1-2/+59
| | | | | | | | | | The pill is thumb-sized now (16px, 12/24 padding) and rides above the Post button on a phone. Drag it sideways or down and let go: it flies off and stays away until more posts arrive than it was showing. A short drag springs back and is not a tap. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Tall videos fill the column with no side bars, up to the screen's heightAdam Soltys13 days1-3/+3
| | | | | Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
* Videos in posts span the column instead of a narrow strip at the leftAdam Soltys13 days1-3/+4
| | | | | | | | | A tall clip was 360px high at most (profile, thread) or sized to its own width (feed), leaving most of the post blank. Now every inline video is the column's width, up to three quarters of the screen tall, letterboxed. 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-33/+60
| | | | | | | | | | | | 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]>
* New posts go in above the first post at the top of the feedAdam Soltys13 days1-4/+28
| | | | | | | | | | | Arrivals used to wait behind the pill whenever the feed header was on screen. They now go in above the first post with that post held where it is, so the page grows upward and can be scrolled to before tapping the pill. While the composer or another header field is in use they still wait. The pill clears only when the reader scrolls up to the newest post, not on the hold's own downward correction. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Ask each open outbox relay about everyone who writes thereAdam Soltys13 days1-1/+6
| | | | | | | | | The planner picked relays to cover each followed author once, so an author was read on a single relay even when several of their write relays were open in the same plan. Fishcake's posts on damus and primal never showed because he was assigned to nos.lol alone. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Use a two-tone paper and green pen icon for new postsAdam Soltys13 days1-1/+2
|
* Warm recipient portraits from Send suggestions before selectionAdam Soltys13 days1-6/+42
|
* Add cooperative coin exits and clarify profile, preview and zap controlsAdam Soltys13 days1-18/+25
|
* Clear abandoned payments, reset profile Pay and restore native messaging BackAdam Soltys13 days1-7/+10
|
* Stream ready feed posts without waiting for catch-up batchesAdam Soltys14 days1-62/+96
|
* Zaps and reactions get their own notification switches.Adam Soltys14 days1-1/+4
| | | | | | | | | | | | The notifier now watches kind-7 reactions p-tagged at the user (opt-in by an explicit flag, so older apps that can't word them stay quiet) and sends zap receipts as 'zap' to apps that report the category, 'payment' to older ones. Coinos zap receipts carry their amount into the push. The service worker names the reactor when it knows them and stays quiet for a muted one. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VP5Ljqk7EYcm5QQAbzDwog
* Each post's reply button shows how many replies it has.Adam Soltys14 days1-2/+34
| | | | | | | | | | Replies (kind 1 and NIP-22 comments) are asked in their own batched #e request beside the likes/zaps one and counted under every post of the conversation they name; quotes ('mention') aren't replies, muted authors aren't counted, and a sent reply counts at once. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VP5Ljqk7EYcm5QQAbzDwog
* The Back button under a post returns to the feed where the reader left it, ↵Adam Soltys14 days1-2/+5
| | | | | | | | | | not its top. It now walks history like the system Back (whose popstate restores the scroll place); the profile page's Back does the same. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VP5Ljqk7EYcm5QQAbzDwog
* Serve a shared snapshot for the public feedAdam Soltys14 days1-10/+49
| | | | Build the default Popular feed once on the server and let browsers verify and paint its signed events before slow media finishes. Keep custom relays, pagination, filtering, and relay fallback on their existing paths.\n\nAdd stale-while-refresh persistence, service-worker bypass, development integration, and unit/browser coverage.
* A profile shows all of someone's posts, not just the two primal still holds.Adam Soltys14 days1-14/+34
| | | | | | | | | | | The phone had written off relay.coinos.io, nos.lol and damus after a network blip, so only primal answered. Home relays are now skipped for a minute at most and forgiven on resume/online; failures while hidden or offline don't count. Profiles also ask history-keeping relays, merge answers instead of replacing the page, and re-ask on reopen. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VP5Ljqk7EYcm5QQAbzDwog
* A video in the feed paints at its own shape, not a 16:9 frame with black ↵Adam Soltys2026-10-011-2/+74
| | | | | | | | | | | | | | | bands beside a portrait clip. The shape comes from the post's imeta dim when it gives one (Amethyst, Primal and others publish it), else from the clip's metadata fetched while the row warms (3 s cap), and is remembered on the device. The box is as wide as the column, never taller than 75vh; an unknown shape keeps 16:9. tools/feed-video-aspect-test.js: 3:4 and 16:9 clips measured ahead, a 9:16 one shaped by imeta alone (its file served too late to probe), a broken one. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WMMwWYJkPQxLgfMsY7hWcU
* Switching feeds paints posts at once instead of a spinner while the relays ↵Adam Soltys2026-09-301-2/+39
| | | | | | | | | | | | | | | | | | | answer. The disk cache held four feeds, so with more chips than that (or one never opened here) a switch opened on nothing. Now: - up to twelve feeds on disk: the four read last keep a page of 30, the rest 5 seed posts (same 256 KB budget); - once the feed on screen settles, every other feed with nothing on disk has its first posts fetched ahead, one small request each, every 15 min; - a feed with nothing on disk borrows matching posts (its people, its topics) that open feeds already hold. tools/feed-switch-seed-test.js: with 8 s relays, a fetched-ahead feed and a never-opened topic feed both paint rows at once (fails on the old code). Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WMMwWYJkPQxLgfMsY7hWcU
* Merge remote-tracking branch 'cs/prod'Adam Soltys2026-09-301-152/+794
|\
| * "Post" floats at the feed's bottom right instead of sitting in the header.Adam Soltys2026-09-301-6/+12
| | | | | | | | | | | | | | | | | | | | A pill with the pencil and "Post", fixed above the bottom nav inside the page column, wherever the reader is in the feed; the tap scrolls to the top, opens the composer and focuses it. Hidden while the composer is open (it has its own Post button) and for visitors. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * A picture or video on its way shows a bar with its percentage — shrinking, ↵Adam Soltys2026-09-301-2/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
| * Topic feeds go back as far as the relays remember, instead of "all caught ↵Adam Soltys2026-09-301-5/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | up" after a handful. #gardenstr: 5 posts across damus/primal/nos.lol/ours (they prune), 774 once archive-keeping relays are asked too (ditto, nostr.mom, oxtr, nostrplebs, nostr21, offchain) — topic feeds now read those. And a page whose posts were all filtered out (replies, muted, spam) no longer ends the feed: paging goes on from the oldest event the relays returned, up to three asks per scroll. The quoted-note wide net gains ditto/nostrplebs/nostr21. topic-depth-test (/feed/t/gardenstr): 9 posts then "caught up" before, 73+ and still going after. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * From someone's timeline, ‹ goes back to their profile and the Feed tab is ↵Adam Soltys2026-09-301-2/+10
| | | | | | | | | | | | | | | | | | | | | | | | your own feed again. The Feed tab reopened whichever feed was last on — the session timeline — and ‹ on it went to the chat list, so there was no way back to your own feed. The tab now opens the last of your own feeds; ‹ on a feed opened from somewhere (a timeline, a #tag, a pack link) steps back in history. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * NIP-22 comments (kind 1111): shown in threads, sent when replying to a poll, ↵Adam Soltys2026-09-291-9/+53
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | article or comment, and in notifications. Kind 1111 is the reply format for everything that isn't a kind 1 note: uppercase E/A + K + P name the root, lowercase e/a + k + p the parent. Threads now also ask for comments naming the root (#E, and #A for an addressable root like an article), place each under its parent, and draw them as posts. A reply to anything but a kind 1 note goes out as a 1111 with the root's scope and the parent's tags (copied from the comment when the root isn't loaded); replies to kind 1 notes stay kind 1. Comments that answer you show in Notifications. comments-test (a real article with 4 comments; events caught at the socket, nothing published): comments listed, reply to the article and to a comment tagged per NIP-22. 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-11/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
| * Quoted notes are found on more relays and never show as a bare "view note"; ↵Adam Soltys2026-09-291-17/+48
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Back from a post keeps the feed's place. - findNote: the reference's hints, its author's NIP-65 relays and ours, plus a wide net of big public relays, all at once, first answer wins. A real quote (SuiGenerisJohn → 0c5e0f08…) sat only on nostr.mom, named by neither the nevent nor its author's relay list. - A feed row whose quote isn't in yet shows the quote card with "Fetching note…" / "Couldn't find that note" instead of a link; the card replaces it once found. - Opening a post remembers the scroll position like opening a profile does; Back restores it instead of landing at the top of the feed. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * A face still being looked up shows its punk after a second at most; a ↵Adam Soltys2026-09-291-13/+29
| | | | | | | | | | | | | | | | | | | | | | | | picture found later replaces it. The quiet loading circle is capped at 1 s per face (a timer repaints when it runs out); one miss is enough to remember someone as faceless; and a room's warm-up adds members whose messages arrived after it first ran, instead of reusing a warm-up that covered only the early history. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * Someone with no profile picture paints as their punk from the first frame ↵Adam Soltys2026-09-291-4/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | after a reload, not a blank circle that turns into one. Faceless answers were never persisted (they'd evict real faces from the 150-row profile blob), so every reload re-asked and showed the loading circle until the relays said "nothing". A small pubkey->time list now remembers them: no kind 0 on two asks running (a cold relay isn't enough), or a kind 0 naming nothing; finding a face takes them off it. room-faces-test --refresh: reload inside the coinos room, faces keyed by author — 2 changed (wait→punk) before, 0 after. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * A community opens with its members' faces, not a beat of punks.Adam Soltys2026-09-291-2/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | Faces (profile, then the picture decoded) are warmed when the pointer is over or presses a room's row, and while the chat list sits there; the tap waits for them, 1.5 s at most, before the room replaces the list. A face still loading in a room is the quiet circle, not a punk. room-faces-test (fresh wallet, real coinos community): 57 faces flipped punk → picture before, 0 after. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * Confirm discarding substantial post draftsAdam Soltys2026-09-291-1/+25
| |
| * Discard canceled post draftsAdam Soltys2026-09-291-12/+38
| |
| * Fix public media uploads and feed tab navigationAdam Soltys2026-09-291-5/+9
| |
| * Cache notification note content locallyAdam Soltys2026-09-291-4/+69
| |
| * "Save feed" on someone's timeline adds it to your feeds at once, instead of ↵Adam Soltys2026-09-281-17/+55
| | | | | | | | | | | | | | | | | | | | | | | | | | an editor listing every person they follow. The editor copied their whole follow list into the form, one row each — long enough to freeze the browser. A saved timeline now keeps only the person (of: pk); their follow list is read from the relays when it is opened, so it stays small in sync and follows who they follow. Its ⋯ offers Delete rather than Edit, and list pickers leave it out. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * Someone's timeline gets a labelled feed chip instead of a blank black pill.Adam Soltys2026-09-281-1/+3
| | | | | | | | | | Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * Polls (NIP-88): options with each one's share of the vote, votable from the ↵Adam Soltys2026-09-281-13/+119
| | | | | | | | | | | | | | | | | | | | | | | | | | | | feed and the thread. A kind 1068 poll showed as "an event this app doesn't show". Now its options are rows with the vote share behind them (kind 1018 votes, each person's latest counts, single/multiple choice, endsAt honored); a tap votes, marked as yours at once. A quoted poll is pictured in its card. Feeds and profiles list polls alongside notes, and a thread's root is looked up by id with any kind, so replies to a poll find it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * A thread that starts from a poll (or any non-kind-1 post) is cached too, so ↵Adam Soltys2026-09-281-1/+1
| | | | | | | | | | | | | | | | | | | | | | a reload paints its replies at once. The thread store accepted only kind 1 and silently skipped saving a thread rooted in a kind 1068 poll — every refresh then waited on the relays behind a spinner. Also guard the profile Back listener for window-less tests. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * A face tapped in the feed opens that person's profile at its top; Back ↵Adam Soltys2026-09-281-0/+14
| | | | | | | | | | | | | | | | | | | | returns to the same place in the feed. The profile kept the feed's scroll offset, so the reader landed deep in the person's posts — which read as a thread opening. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * A quoted note that was slow to arrive turns into its card instead of staying ↵Adam Soltys2026-09-281-4/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a "view note" link. A feed row keeps its first look, and a quote that missed the readiness gate froze as a link — with nothing asking for the note again. The frozen row now keeps asking (the existing 30s retry) and takes the card once the note and its own avatar/pictures are warm. quote-card-test: reach the feed through the bottom nav, seed the author's profile, and --slow drops the first ask for the quote to cover this. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
| * A reloaded thread paints whole, quoted posts included, with no spinner.Adam Soltys2026-09-281-1/+19
| | | | | | | | | | | | | | | | | | 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]>
| * New posts: the pill lands on the oldest one, and each wears a tint until ↵Adam Soltys2026-09-281-6/+77
| | | | | | | | | | | | | | | | | | | | | | 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]>
| * The chat list shows four conversations and four communities, the rest behind ↵Adam Soltys2026-09-281-7/+14
| | | | | | | | | | | | Show all. Co-Authored-By: Claude Opus 5.5 <[email protected]>
| * The bottom nav spans the window; the chat list is just conversations.Adam Soltys2026-09-281-41/+9
| | | | | | | | | | | | | | | | | | 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]>
| * The bottom nav rides every page: Feed, Messages, Notifications, Wallet.Adam Soltys2026-09-281-14/+33
| | | | | | | | | | | | | | | | | | 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]>
| * Keep feed navigation visible and add a wallet shortcutAdam Soltys2026-09-281-4/+6
| |
| * Add scrolling feed navigation for home, messages and notificationsAdam Soltys2026-09-281-1/+26
| |
| * Enlarge post text and use full width below author headersAdam Soltys2026-09-281-4/+4
| |
* | Encrypted chat pictures get blossom.yakihonne.com as a third host; a small ↵Adam Soltys2026-09-301-2/+3
|/ | | | | | | | | | | | file stops at two copies. Benchmarked 18 public Blossom hosts: only ditto, nostr.download and yakihonne take opaque (application/octet-stream) blobs, which is what an encrypted attachment is. ditto is fastest; yakihonne is slow, so it is reached only when one of the first two fails. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WMMwWYJkPQxLgfMsY7hWcU
* Merge remote-tracking branch 'prod/prod' into merge-tmpAdam Soltys2026-09-281-6/+11
|\