aboutsummaryrefslogtreecommitdiffstats
path: root/src/i18n.js
Commit message (Collapse)AuthorAgeFilesLines
* Feed: the foot says when older posts are loading, and when there are none left.Adam Soltys2026-09-271-0/+2
| | | | | Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
* Renewal: a submitted round the server has forgotten is repaired, not asked ↵Adam Soltys2026-09-261-0/+1
| | | | | | | | | | | | | | | | | | | | | | about forever. Adam's wallet carried a refresh action from August 31 in step 'submitted' whose unlock hash the server never ran: the round went through under a later submission (another hash), the inputs were spent by it and the 5,233-sat output reached the wallet through the mailbox — but the original action kept asking RoundParticipationStatus on every sync for four weeks, and since this week's coins page shows renewals in flight, it showed up as "in progress" with the raw gRPC error underneath. On "not found" the manager now checks the inputs: all spent means the round ran under another submission and the record is retired (failed, superseded — no history row, no card); none spent means the server dropped it before a round ran, so it is submitted again; a mix goes through the existing input repair. The coins page never prints a server error string; a failed check reads as "the wallet keeps trying". Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
* Coins page: a renewal in flight keeps the whole page; a renewal you asked ↵Adam Soltys2026-09-241-0/+10
| | | | | | | | | | | | | | | | 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]>
* Videos play by themselves, muted, while on screen — with an Unmute button; ↵Adam Soltys2026-09-231-0/+2
| | | | | | | | | | | | | | | | | | | 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]>
* Moderation: the whole mute list everywhere, follows' reports fold posts, ↵Adam Soltys2026-09-231-0/+30
| | | | | | | | | | | | | | | | | | | | | | 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-0/+11
| | | | | | | | | | | | | | | | | | | | | | 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-4/+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-0/+1
| | | | | | | Second, not "no". 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-0/+1
| | | | | 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-221-0/+1
| | | | | | | | | | | | | 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/+1
| | | | | | | | | | | | 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-0/+23
| | | | | | | 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-221-0/+9
| | | | | | | | | | | | | | | | | | | 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 tiles: a receipt icon for Point of sale; Advanced's line fits on ↵Adam Soltys2026-09-211-1/+1
| | | | | | | one row. 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-1/+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
* Send: a Lightning payment while Savings is showing asks before it pays from ↵Adam Soltys2026-09-211-0/+5
| | | | | | | | | | | | | | | 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 coins: "Unilateral exit", with an Exit now button behind a ↵Adam Soltys2026-09-211-3/+12
| | | | | | | | | | | | 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
* Seed words read down each column; the Google central is a parameter with a ↵Adam Soltys2026-09-211-0/+1
| | | | | | | | | | | | | | 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
* First run: "Create a new wallet" shows the twelve words at once.Adam Soltys2026-09-211-0/+2
| | | | | | | | | | | | No create/import tabs and no Generate button inside the wizard: the words appear the moment the button is tapped. Underneath, "Have an existing seed or entropy to import?" swaps to the import pane (which has its own entropy door), and "Create a new wallet instead" swaps back with fresh words. The create/import card elsewhere (adding an account) keeps its tabs. Tests that entered through the old tab go through the new line. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* Front door: the divider is just "or" — every door below makes an account too.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: a paid sale opens its payment detail, which now says bill and ↵Adam Soltys2026-09-211-0/+2
| | | | | | | | | | | | 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: /pos, a per-device till mode, an on-screen pad — and off ↵Adam Soltys2026-09-211-0/+3
| | | | | | | | | | | | | | | 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 tip screen shows an invoice error, and both screens say ↵Adam Soltys2026-09-211-0/+1
| | | | | | when the invoice is being made. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Point of sale: a bill, an optional tip prompt, one invoice, and a ledger ↵Adam Soltys2026-09-211-0/+30
| | | | | | | | | | | | | | | | | | that keeps tips apart. A new deferred feature (src/features/pos.js): type the amount in the display unit, optionally a note, Charge. With the tip prompt on, the customer sees the bill and picks a percentage (configurable, default 10/15/20), their own figure, or no tip; one Lightning invoice is made for the total through the Ark feature's receive (new hooks arkLnInvoice/arkLnWatch/arkLnUnwatch/ arkLnCancel wrap createLnInvoice and pollArkLn). Paid, expired and cancelled sales are recorded with the bill and the tip as separate figures, and the fiat rate at the time; the amount screen shows today's bills, tips and total. Doors: Settings → Payments card, and a button under the payment address on Receive (a receiveExtras hook the names pane renders). Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Settings → Nostr: make coinos the browser's handler for web+nostr: and ↵Adam Soltys2026-09-201-0/+6
| | | | | | | | | | bitcoin: links. njump's "Your default web app" is a web+nostr: link: it opens whichever site registered that scheme. A card offers to register this app (the browser asks), and ?u= now accepts the web+nostr: form. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Feeds: follow packs from following.space (NIP-51 kind 39089) as a feed's people.Adam Soltys2026-09-201-0/+5
| | | | | | | | | | | A feed can name packs as well as people: the pack's current members are its authors, read from the pack event itself and cached on disk, refreshed hourly when a feed using it is opened — so a curator's change reaches the feed by itself. The editor takes a pasted following.space link or naddr, or searches packs by title (NIP-50 on relay.nostr.band). parseNostrRef learned naddr. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Messages: every saved feed is a row on the home list, under Following.Adam Soltys2026-09-201-0/+3
| | | | Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Feeds: Following is one of many; topics from search and #tags; the bolt is ↵Adam Soltys2026-09-201-1/+18
| | | | | | | | | | | | | | | | | | | | | | | | amber only for your own zap. Custom feeds live in the synced messages state — a name, everyone you follow and/or hand-picked people, and topics (hashtags, any of them; with people set as well, only their posts on those topics — the way a nostr filter composes authors and #t). Each feed keeps its own notes, clock and disk cache; a chips row under the feed title switches between them and + opens the editor (people are added through the same search the Send form uses). A word in the header search is a topic too: 'Posts on this topic' opens a session feed for it, as does a #tag in any post body — Save feed keeps it. Topic-only feeds read the big public relays as well as ours, since a hashtag has no author whose outbox we could follow. The zap icon used to go amber once anyone had zapped a post; now only when you have, like the heart. tools/feed-custom-test.js drives the editor, the relay filter, a tagged post landing, the #tag link, reload persistence and delete. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Zaps: the sound can be switched off — from the held bolt or Settings → ↵Adam Soltys2026-09-191-0/+1
| | | | | | | | | | Nostr. A prefs flag (zapSound, absent = on) synced with the zap amount. The strike and the tally are unchanged; only the clip stays quiet, and the clip chunk is not even fetched while it's off. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Zaps: tap again while one flies, hold the bolt to change the amount.Adam Soltys2026-09-191-1/+3
| | | | | | | | | | | | | | | | A pending zap no longer refuses the next tap: the optimistic tally keeps one entry per zap and matches each report and receipt to the oldest it can describe, so two default-amount zaps stack, settle and hand over to their receipts one at a time. Instant post zaps run off the send screen's zap slot, so a second tap can't evict the one still resolving, and send action ids are unique within a millisecond. Holding ⚡ (500ms) opens the amount screen in an edit mode — Save alone, or Save and zap this note — from the action bar and the chat chips alike; the press's timer lives on the element so a background repaint mid-press can't turn a lifted finger into a hold. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Zaps: the sound, the sender, and one action bar for every post.Adam Soltys2026-09-181-0/+2
| | | | | | | | | | | | | | | | | | Tap feedback: a bolt strike, the amount popping off the button, the post trembling, and the zap.mp3 clip. The clip is 62KB of base64 and messages.js is boot code, so it is its own chunk, fetched once a zappable post is on screen and played inside the tap once loaded; the standalone build inlines it. Ark zap receipts are signed by the wallet key, which has no profile: they now carry the login identity as the sender (NIP-57's P tag), readers prefer it, and our own older receipts read as us. The action bar is the same six slots on every post: the zap button and the who-reacted chevron are always there (inert until they have something to do), so the first zap no longer reflows the row, and you can zap your own posts and messages. Community rows centre their unread dot off the edge. Also in here: reactions with custom emoji, reply-composer focus under the tapped post, profile fetch retry, and Lightning zap failures that say so. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Feed: what arrives waits behind the pill; the count bumps; no auto-flush.Adam Soltys2026-09-161-0/+2
| | | | | | | | | | | | | | Posts a refresh found slid in a beat after the cached page painted, moving what you had begun reading, and reaching the top of the page let waiting posts in with a re-render under a finger on its way to the pill — the tap landed on the post beneath. Now everything that arrives after the first paint, the boot catch-up included, waits behind the pill wherever you are; the pill is a keyed node whose count bumps on each change; and a tap scrolls to the top before painting so the new posts open under your eyes. A rebuilt follow list still rebuilds the feed in place. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
* Gift detail links the coin behind the gift, and the claim once claimed.Adam Soltys2026-09-151-0/+2
| | | | | | | | | | | An unclaimed on-chain gift has no transaction of its own yet — its funding transaction is presigned and only broadcast when someone claims. The coin it's locked against is on-chain from the start, so the detail page now links that outpoint's transaction on the block explorer, and the claim transaction once it exists. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
* Renewal copy: automatic when free and near expiry; early renewal insures the ↵Adam Soltys2026-09-151-1/+1
| | | | | | | uncooperative exit. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
* Renewal fee copy: how close the coin is to expiry.Adam Soltys2026-09-151-1/+1
| | | | | Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
* Coins page: renewal is automatic, and the copy says so first.Adam Soltys2026-09-151-3/+3
| | | | | | | | | | | | | | The renewal card opened with how to renew and mentioned only at the end that the wallet does it by itself, which read as an invitation to renew by hand. It now leads with the automatic, free renewal before expiry, then says renewing early is only for someone who would rather not count on the coinos server, with the round cadence taken from the server's own info (two minutes now, not the hour the old text claimed). The "past its expiry" footnote under the table is gone. Stale translations of the rewritten strings fall back to English. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
* Spending coins as a headed table instead of chip rows.Adam Soltys2026-09-151-4/+5
| | | | | | | | | | | Every row repeated "expiry", "exit cost", "renewal cost" as pills. The labels now sit once in a header row over right-aligned tabular figures; the table's wrapper scrolls sideways on a screen too narrow for it (the page never does), and it fits a 390px phone without scrolling. A tap anywhere on a row toggles it. A sub-satoshi renewal share reads "< 1 sat". Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
* A tiny coin's renewal chip says "under 1 sat", not "1 sat".Adam Soltys2026-09-151-1/+2
| | | | | | | | | | | | | The server prices a renewal on all the coins together: ppm accumulates sub-satoshi across every input and rounds up once. The per-coin chip rounded each coin's share up on its own, so nine 1-sat coins each showed "renewal cost 1 sat" under a total of 4 sats — as if the page were skipping them. The chip now shows the coin's real share: "under 1 sat" for a sub-satoshi one, rounded otherwise, and its tooltip says how the fee is priced. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
* A pack link in chat adds the pack in place; coinos has its own share link.Adam Soltys2026-09-151-0/+1
| | | | | | | | | | | | | | | | | | Tapping "Emoji pack" on a phone opened Vector: the chip was an outbound link to vectorapp.io, a domain the Vector app owns. The chip is now a button — one tap adds the pack right here, nothing leaves coinos. Packs also get a coinos share link, v3.coinos.io/emojis/pack/<naddr> (copy it from the picker's pack row). The Android app already claims every v3.coinos.io path, so on a phone that link opens coinos, which adds the pack once the wallet is open. Pack links from any host render as the chip; the naddr's kind is what's checked. Pack changes now save at once (learned shortcodes stay coalesced) — a remove followed straight away by a navigation was lost to the debounce. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
* Custom emoji in chat: :shortcodes: render as pictures, packs sync with Vector.Adam Soltys2026-09-151-0/+8
| | | | | | | | | | | | | | | | | | | | | | | A message from Vector says :pika_wave: and carries a NIP-30 ["emoji", code, url] tag for it; coinos showed the bare shortcode. Now the bubble shows the picture (in rooms, DMs, the feed and the public /chat page), a bubble that is only one to three of them shows them big, and a :code: reaction chip is a picture too. Sending: every :code: you type that resolves travels with its tag, so the other side renders it whether or not they hold the pack. Shortcodes come from packs you hold (NIP-51 kind 30030 sets) and from what you've seen in chat, so anyone can answer a :pika_wave: with one. The composer autocompletes on ":pi" (Tab/Enter takes the first), the reaction picker lists custom emoji first, and Vector's pack share link renders with an Add button; a pasted naddr works too. Packs live on your kind 10030 list — the one Vector reads and writes — so a pack added in either app appears in both. tools/emoji-test.js drives the real coinos room headlessly and checks all of the above. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z
* An @handle in a bio or post opens the people search for that name.Adam Soltys2026-09-151-0/+1
| | | | | | | | A bare @name carries no key, so nothing can resolve it for certain — but it can be a tap that opens the search with the name filled in. The @ inside an email or nip05 is left alone, as is anything inside a URL. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Join suggests communities from the Vector Hub, searchable, beside the paste box.Adam Soltys2026-09-141-1/+6
| | | | | | | | | | | The Join panel used to be one empty box asking for a link nobody had. It now lists the Vector Hub's public communities under it — icon, name, member count, category, description, sorted by size, marked when you're already in one — fetched on demand and kept for the session. The same box takes a link or filters the list; a tapped suggestion previews exactly like a pasted invite, since every listing is a CORD-05 link. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Invite links open in Vector, communities sync across Concord clients, and ↵Adam Soltys2026-09-141-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | any emoji can be a reaction. Vector's bundle parser has no default for a channel's key and epoch, so a coinos invite — which sent only id and name — failed its whole JSON parse and the link did nothing there. Every channel entry now carries key and epoch (a public channel's key is the community_root at the base epoch, CORD-05 §1), and bundles minted before this are re-signed at the same coordinate once per device, so links already shared start working. Concord clients now keep their Community List as kind 33302 fragments (CORD-02 §8): addressable per index, NIP-44 to self, 32-byte values as unpadded base64url, embedded join material without its community_id, seed omitted when it equals current. coinos read and wrote only the retired single-event 13302 on its own two relays, so a community joined in Vector under the same key never appeared here. The fragmented list is now read from our relays, the stock CORD set and every held community's relays, merged, and written back in the same shape; the home view re-syncs after a minute and a live subscription brings a fresh write straight in. 13302 stays for older coinos devices. The reaction row keeps its quick emojis, recents first, and a + opens a searchable picker of a few hundred more — eyes included. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* A picture can be sent to a channel or a DM, encrypted, and read by Vector.Adam Soltys2026-09-141-0/+4
| | | | | | | | | | | | | | | The composer grows a paper clip. A picked file is encrypted under a fresh AES-GCM key and 16-byte nonce, the ciphertext uploaded to a public Blossom host that takes anonymous blobs (blossom.ditto.pub, then nostr.download as a fallback copy), and the pointer posted the way Vector posts it: a kind-9 with empty content and a NIP-92 imeta tag carrying url, mime, key, nonce, both hashes, size and dimensions. In a DM it is a NIP-17 kind-15 file message with the same fields as flat tags and the url as content, wrapped to the peer and to ourselves. Kind-15 file messages are now accepted on receive too, rendered like any attachment, and previewed as a photo in the thread list. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* A picture sent to a channel shows up as a picture, not an empty bubble.Adam Soltys2026-09-141-0/+1
| | | | | | | | | | | | | Vector attaches files as NIP-92 imeta tags: the blob is encrypted with a one-off AES-GCM key before it reaches Blossom, and the tag carries the url, mime, key, nonce, plaintext sha256 and dimensions. Such a message has no text, so the bubble rendered blank. The blob is now fetched (fallback hosts too), decrypted in the browser, checked against the hash, and shown from an object URL — a grey box its shape while it loads, tap to view full size, other file types as a download by name. The same tags render in DMs. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* Logging out leaves one identity, not everyone on the device.Adam Soltys2026-09-141-0/+4
| | | | | | | | | | | | With several identities signed in, the profile's Log out now signs out only the current one: its accounts leave the session, directory, cache and vault, the others stay put, and the next identity takes the screen. The confirmation names who is leaving and says whether they can sign straight back in (a nostr login) or need their recovery phrase (a bare seed). Logging out of every account is a second, explicit button. Alone on the device, Log out is unchanged. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* A knight's helm, for one small knight.Adam Soltys2026-09-141-0/+1
| | | | | | | | | | A gifted hat that covers the whole face — its own square drawing over the avatar rather than perched on it: steel great helm, cross slit, breathing holes, a red plume. Never sold; the registrar's gift endpoint knows it beside the beta hard hat. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01QYJfZ4A1TDCEY4Foq3CApR
* A reply or a mention on nostr can buzz your phone.Adam Soltys2026-09-141-0/+1
| | | | | | | | | | | | | The push notifier now watches kind 1 for the user's pubkey beside DMs and zap receipts, and pushes who, what, and an excerpt. The worker shows "New reply to your post" or "You were mentioned" with the text, and a tap lands in the Notifications list — as ?open=notifs when a window has to be opened, or as a worker message when one already is. It has its own switch, "Replies and mentions on nostr", in Settings → Notifications, on by default like payments and DMs. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01QYJfZ4A1TDCEY4Foq3CApR
* A zap on a chat message shows the message, not "Fetching note…" forever.Adam Soltys2026-09-141-0/+1
| | | | | | | | | | | | A receipt for a zap on a chat message or a DM e-tags the rumor's id, which no relay has ever held as an event — so the row fetched it by id and waited forever. The rooms and threads we hold are searched first: the row shows the message's text and a tap opens that room or thread. A post the relays really don't have says so instead of spinning. And a coinos zap's own receipt beside the LNURL server's is one row, not two. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01QYJfZ4A1TDCEY4Foq3CApR