Keep the fast pooled first render, but merge each read relay's DM backfill
into the visible inbox as soon as that relay finishes instead of waiting for
all relays. Track per-relay sent/received cursors so older pagination cannot
skip dense relay history because another relay returned older sparse events.
Timed-out or failed relays are kept retryable instead of being marked
exhausted, while successful relay cursors unlock deterministic pagination.
Backfilled events still dedupe by id and update latest previews/sort order.
Use the shared pooled query for the initial messages page so the inbox keeps
Ditto-style fast first paint with the provider's short eoseTimeout. Page 0 is
marked pending backfill, then a background effect queries each configured read
relay individually, merges those slower results into the same infinite-query
cache entry, and unlocks older-page pagination after backfill completes.
Also update conversation merging so a backfilled newer event updates the row's
latest preview and sort order.
The inbox query went through the shared pool, whose eoseTimeout resolves as
soon as the first relay sends EOSE (+300ms). DMs held only by slower relays
were dropped, so each hard refresh returned a different, incomplete set of
conversations. Fan the kind-4 query out to each configured read relay
individually (Promise.allSettled, bounded by the existing 8s cap) and merge
deduped by event id, so every relay contributes its full set.
The inbox query key now carries the read-relay list; update the send-message
optimistic cache writes to match ['direct-messages', pubkey] by prefix so the
append still lands.
handleMute awaited addMute's relay round-trip (fetch fresh kind 10000 +
publish) before hiding the conversation, leaving the muted thread visible
for a few seconds. Hide the peer optimistically the moment the user
confirms; the relay-backed mute list still reconciles on reload.
Adds a 'New message' button to the conversation list (and the empty-pane
prompt) that opens a fresh compose pane in the right column instead of a
modal. The pane has a 'To:' field that drives debounced profile search via
useSearchProfiles (name / NIP-05 / npub / nprofile), rendering suggestions
inline beneath the field — no popover. Arrow-key navigation + Enter select a
recipient; choosing one opens the normal thread (existing conversation or a
fresh blank thread). Adds the supporting locale strings across all locales.
bottom-full anchored the bubble above the avatar block's top edge, which
margin-collapses up into the banner, pushing the bubble off the visible
area. Position it with a top offset within the same coordinate space the
original used, lowered so its tail rests at the banner's bottom edge.
- Anchor the NIP-38 status bubble to the bottom edge of the banner so it
no longer overlaps the follow/donate action buttons.
- Drop the founder/verified footer badges from the profile Agora tab so its
campaign cards render identically to the campaigns page CampaignCard.
- Recolor the 'raised' stat from text-orange-500 to text-primary to match
bio/profile hyperlink coloring.
The back arrow used top-5 on a size-9 padded button, sitting lower than
the X close button (top-4, size-5 icon). Move it to left-2 top-2 so its
icon center lines up with the X on the opposite side.
Overhaul AuthDialog's login step:
- Add translation keys for every previously-hardcoded string (titles,
buttons, placeholders, status labels, validation/errors) across all
sixteen locales.
- The secret-key form is no longer collapsible — it's always open and is
the first option, followed by 'Log in with extension', then a
text-with-arrow link to the remote-signer step.
- Move the key-file upload icon onto the same row as the nsec input
(instead of beside the submit button); submit button is now full-width
below.
- Surface extension-login errors as a destructive toast rather than
writing them into the nsec input's inline error.
- Replace the centered 'Back' text buttons with a back arrow in the
top-left of the dialog header.
Also correct AGENTS.md's i18n section: the project ships fifteen
non-English locales (hi, id, sw, tr, zh-Hant were missing from the list).
Logged-in users change language via Settings, so the top-nav globe now
appears only when logged out (matching the search icon). On the homepage
hero, replace the 'Explore campaigns' button with 'Verify campaigns' and
order it before 'How it works'. Drop the now-unused exploreCampaigns
locale key across all locales.
Add /sponsors, a landing-style page for companies that want to partner
with the platform. Lays out the three ways to get involved: an
unrestricted gift to the Agora Seed Fund (BTC or USD), a matching pool
for an individual campaign, a featured campaign, or a curated list of
campaigns (e.g. political prisoners or women's sovereignty in Africa),
and promoting Agora donations to a customer base as a philanthropic
initiative.
Modeled on AboutPage's section recipe (dark hero, alternating section
backgrounds, hand-rolled cards) and routed under the wide
FundraiserLayout above the /:nip19 catch-all. Adds a Sponsors link to
the site footer. English copy only for now; other locales fall back to
English until the copy settles.