5019 Commits

Author SHA1 Message Date
Chad Curtis 4c7d059b0b Add Start a campaign button to middle home CTA
Place a 'Start a campaign' button next to the centered 'Browse all'
CTA in the middle of the campaigns home page, stacking on mobile.
2026-06-02 08:51:38 -05:00
Chad Curtis eae5e1c3a7 Always show Explore campaigns button on home page
Remove the !loggedIn gate that hid the 'Explore campaigns' CTA from
logged-in users. The campaigns home page shouldn't gate this button
behind login state.
2026-06-02 08:46:45 -05:00
Chad Curtis e7c488af63 Add Zapstore app download nudge
Prompt mobile-web visitors to install the native Android app from
Zapstore. Shows a card at the bottom of the home feed and a link in
the account switcher menu. Both are hidden inside the native app
(Capacitor.isNativePlatform) and on desktop (sm:hidden for the banner).

Adds nav.getApp and feed.getApp.* strings across all locales.
2026-06-02 08:40:58 -05:00
lemon 4153792e54 Add missing Why Agora translations 2026-06-02 04:29:26 -07:00
lemon c731256efb Preserve Latin display font for balances 2026-06-02 04:18:04 -07:00
lemon 702d374a06 Sync lockfile version 2026-06-02 04:10:04 -07:00
lemon b174152566 Fix stale language switching 2026-06-02 04:09:44 -07:00
Chad Curtis 6a5c426648 release: v2.8.8 v2.8.8 2026-06-02 04:57:32 -05:00
Chad Curtis f8547668b2 Replace old Ditto splash icon with Agora double-bolt
The Android 12 splash vector (splash_icon_vector.xml) and the legacy
splash PNGs still showed the old Ditto cat / single-bolt logo. Replace
the splash vector with the current double-bolt glyph from logo.svg and
regenerate splash_icon.png and all port/land splash PNGs as the white
double-bolt on the dark splash background.
2026-06-02 04:56:53 -05:00
Chad Curtis 49049f98e7 Fix squashed app icon: render logo SVG with preserved aspect ratio
The 720x880 logo.svg was force-rendered into a 512x512 square, stretching
the bolt horizontally. Render height-bounded (aspect-preserving) instead
and let the centered composite handle fit. Regenerate all Android, iOS,
and web/PWA/Zapstore icons.
2026-06-02 04:53:57 -05:00
Chad Curtis 048878b699 fix zapstore info v3 2026-06-02 04:52:25 -05:00
Chad Curtis 476a3856ec release: v2.8.7 v2.8.7 2026-06-02 04:34:48 -05:00
Chad Curtis d69cfa0862 fix zapstore info v2 2026-06-02 04:32:59 -05:00
Chad Curtis a5cc9c5163 Break walletHeroNote onto two lines 2026-06-02 04:24:57 -05:00
Chad Curtis 42ac269a56 release: v2.8.6 v2.8.6 2026-06-02 04:24:53 -05:00
Chad Curtis caa8e70703 fix zapstore info 2026-06-02 04:19:11 -05:00
Chad Curtis 8f53e3e53b Regenerate app icons as white double-bolt on orange circle
The Android launcher icons and adaptive foreground were the old icon
(orange-circle single bolt / stale Ditto vector), and generate-icons.sh
still sourced the purple Ditto branding. Rewrite the generator to use
the current logo.svg double-bolt glyph in white on the brand orange
(#e9673f) circle, and regenerate:
- Android legacy + adaptive launcher icons (all densities)
- adaptive icon background color -> #e9673f
- iOS AppIcon
- web/PWA/Zapstore icons (logo.png, icon-192, icon-512, apple-touch-icon)

Also remove the unused stale adaptive foreground vector so it can't
shadow the regenerated foreground PNG.
2026-06-02 04:17:23 -05:00
Chad Curtis 5d4d0825c6 Remove "no payout setup" from wallet hero note copy 2026-06-02 04:10:33 -05:00
Chad Curtis b9b7351361 release: v2.8.5 v2.8.5 2026-06-02 03:40:31 -05:00
Chad Curtis 6dcae6385a ci: use uniform PKCS12 password for signing keystore
packageRelease failed with 'Given final block not properly padded'
because the migrated PKCS12 entry was protected with the store password,
not the key password Gradle read from key.properties. Write the PKCS12
with a single uniform password ($KEY_PASSWORD) for store and entry, and
point both storePassword and keyPassword at it.
2026-06-02 03:39:54 -05:00
Chad Curtis 13386bf0fd release: v2.8.4 v2.8.4 2026-06-02 03:29:34 -05:00
Chad Curtis 2ae2a3da18 android: add R8 keep rules for barcode-scanner Gson references
R8 release minification failed on a missing com.google.gson.annotations
.SerializedName referenced by the OutSystems barcode plugin. Suppress the
Gson missing-class warning, keep annotations, and keep the plugin's model
classes so serialized fields survive shrinking.
2026-06-02 03:28:48 -05:00
Chad Curtis 1c06e070cd release: v2.8.3 v2.8.3 2026-06-02 03:22:02 -05:00
Chad Curtis f0c3ff1a80 android: raise minSdk to 26 for barcode-scanner plugin
@capacitor/barcode-scanner v3 pulls in ionbarcode-android:2.0.1, which
declares minSdk 26. The inherited Ditto minSdk of 24 fails the manifest
merger. Raise the floor to 26 (Android 8.0) as the merger recommends.
2026-06-02 03:21:22 -05:00
Chad Curtis 13a0bb3e3a release: v2.8.2 v2.8.2 2026-06-02 03:09:16 -05:00
Chad Curtis 646ed9777f ci: pass alias key password to keytool keystore migration
The build-apk JKS->PKCS12 migration only supplied the store password,
so keytool prompted for the upload key's distinct password on the
non-interactive runner and failed with 'Too many failures - try later'.
Pass -srckeypass/-destkeypass ($KEY_PASSWORD) to match key.properties.
2026-06-02 03:07:04 -05:00
Chad Curtis 437613641a release: v2.8.1 v2.8.1 2026-06-02 03:02:12 -05:00
Chad Curtis d0836328a4 qrcode: stop fixed pixel styles overflowing the container
The qrcode library hard-codes inline width/height pixel styles on the
canvas, overriding the Tailwind sizing classes (h-auto w-full) callers
pass in. On viewports narrower than the QR's intrinsic size this made
the code spill outside its rounded box — visible on the campaign
details donate panel. Remove the inline styles after rendering so the
caller's className controls the responsive size.
2026-06-02 02:02:58 -05:00
Chad Curtis 123f53e7a6 campaigns: carry public/private framing into custom wallet mode
Switching to a custom (manual-entry) wallet used to drop the friendly
accept picker entirely, leaving two unlabeled-purpose address inputs.
Restore the hand-holding: add an intro line restating the field-driven
model (public address, private code, or both) and label each input
with its meaning. The public/on-chain input is marked with a Bitcoin
icon and a 'Public. Anyone can see these donations.' caption; the
silent-payment input with an EyeOff icon and a privacy caption. Both
inputs keep the Wallet leading icon. Updates all 16 locales.
2026-06-02 01:59:44 -05:00
Chad Curtis 977fd000ea campaigns: make the donation-accept picker friendlier
Replace the three terse jargon pills (Accept All / Public Only /
Private Only, captioned with 'on-chain' and 'silent payment') with a
vertical stack of selectable option cards. Each card has a friendly
icon, a plain-language title, and a one-sentence reassurance written
for an anxious first-time creator, with the SP-dependent options
clearly disabled when the login can't support them.

Also softens the wallet hero card: drop the linked-icon trio for a
simple campaign-to-wallet arrow, and rewrite the copy without the
key/posts technical aside or em dashes. Updates all 16 locales.
2026-06-02 01:59:44 -05:00
Chad Curtis 5132141aa2 campaigns: give the wallet step a hero coupling card
Redesign the 'My wallet' branch of the campaign wizard's donation
destination step. Replace the plain identity+balance row with a
primary-tinted hero card modelled on the onboarding 'Save your key'
surface: a linked-icon trio (campaign -> key -> wallet) explains that
donations land in the creator's own Agora wallet unlocked by the same
key that signs their posts, with the avatar+live-balance chip
confirming the exact destination and a ShieldCheck reassurance line
below.
2026-06-02 01:59:44 -05:00
Chad Curtis b6dc57eb85 Merge branch 'feat/send-MAX' into 'main'
Feat/send max

See merge request soapbox-pub/agora!40
2026-06-02 06:36:55 +00:00
Chad Curtis 016a7b4a7d Constrain event detail pages to max-w-3xl
Both PostDetailShell (Nostr event details) and ExternalContentPage
(NIP-73 external content like bitcoin:tx) rendered their <main> with no
max-width under the wide layout, stretching edge-to-edge on large
screens. Add w-full max-w-3xl mx-auto to match the narrow-layout column
width used elsewhere.
2026-06-02 01:30:55 -05:00
mkfain 7ae63883e9 campaigns: surface 'Add to list' in the detail-page three-dots menu 2026-06-02 00:28:08 +02:00
mkfain d4cf4ba0d8 campaigns: collapse curated lists strip after first 5 pills 2026-06-02 00:28:08 +02:00
Chad Curtis 399dc53395 Merge branch 'remove-pin' into 'main'
Remove redundant campaign location pin icons

See merge request soapbox-pub/agora!39
2026-06-01 22:26:29 +00:00
filemon 699e505fb5 Merge remote-tracking branch 'origin/main' into remove-pin
# Conflicts:
#	src/components/CampaignCard.tsx
2026-06-02 00:23:07 +02:00
lemon 20839f4de3 wallet: match silent inputs without prevout index 2026-06-01 15:18:13 -07:00
lemon 4e9da2d168 wallet: prune rediscovered spent silent outputs 2026-06-01 15:18:13 -07:00
lemon 32b477bd01 wallet: refresh history after pruning silent inputs 2026-06-01 15:18:13 -07:00
lemon 564459e12d wallet: disable send button when balance is unspendable 2026-06-01 15:18:13 -07:00
lemon c97d0723a6 wallet: add max send option 2026-06-01 15:18:12 -07:00
filemon 53da626461 Remove redundant campaign location pin icons
Regression-of: ba2c541c
2026-06-02 00:13:35 +02:00
Chad Curtis c79699ca71 campaigns: remove deadline from events and form
Drop the optional `deadline` tag from kind 33863 campaigns. Removes the
date input and validation from the create/edit form, the deadline chips
on the card, detail, and inline-preview surfaces, and the derived
"ended" state that disabled donations after the deadline. Cleans up the
associated locale keys and NIP.md documentation.
2026-06-01 17:03:30 -05:00
Alex Gleason e58c031a85 Merge branch 'main' of gitlab.com:soapbox-pub/agora 2026-06-01 23:17:58 +02:00
Alex Gleason bc80dba826 home: fan out single-relay queries to fix load waterfall
The home page serialized its first paint behind relay.ditto.pub:
useCampaignLists queried that one relay via nostr.relay(DITTO_RELAY)
(awaited, up to an 8s timeout) and every hero campaign was gated on
its result, so a slow ditto.pub stalled the whole page. Connection
sharing made it worse — pooled queries multiplexed onto the same
stalled socket.

Switch the home-critical moderation/list/discovery hooks from
single-relay nostr.relay(DITTO_RELAY) calls to the parallel pooled
nostr.query() fan-out:

- useCampaignLists: authors:[curator] filter enforces trust; relay
  pin was unnecessary and headed the waterfall.
- useCampaignModeration: authors:[moderators] filter enforces trust.
- useFeaturedOrganizations: per-author filters enforce curation.
- useDiscoverCommunities: global discovery — fan-out broadens coverage.

useDashboardCounts stays pinned: NIP-45 COUNT is a single-relay
primitive and isn't mergeable across relays, and it's off the home
critical path.

Regression-of: 3d825aef
2026-06-01 23:16:45 +02:00
Chad Curtis 611f97488e home: drop label-based hidden filter from the WLC hero row
The home page hero row is already a moderator-curated kind-30003 list,
so re-filtering its members through the agora.moderation hide axis was
redundant: a campaign that shouldn't appear simply shouldn't be on the
list. The hidden-filter only mattered in the narrow window where a
listed campaign also carried a moderator hidden label, and it cost an
extra limit:2000 kind-1985 query to DITTO_RELAY on every landing-page
load for that edge case.

Render the curated list verbatim, in list order. Label-based hidden
moderation still lives on /campaigns and every other surface; only the
home hero row stops consulting it.
2026-06-01 16:04:22 -05:00
Alex Gleason a948725245 home: stop fetching kind 1985 moderation labels
The home page (CampaignsPage) called useCampaignModeration() solely to
drop hidden campaigns from the WLC hero row, which fired a kind 1985
label query (limit 2000) on every initial load just to check ≤6
curated coords. Remove the dependency: the hero row now only reorders
to the moderator-curated list order. Hidden-campaign moderation already
lives entirely on /campaigns, so the home page no longer needs it.
2026-06-01 22:51:19 +02:00
mkfain dde9865284 campaigns: drop duplicate arrow from browseAll button label
The 'Browse all campaigns' Link on the home page renders an <ArrowRight>
lucide icon next to t('campaigns.home.browseAll'), but the translated
string itself ended in '→' (or '←' for RTL locales), so the button
displayed two arrows. Strip the literal arrow from all 16 locale files
and let the icon do the visual work — it already handles RTL via
rtl:rotate-180 in CampaignsPage.tsx.
2026-06-01 22:41:06 +02:00
Chad Curtis 3d825aef04 campaigns: hardcode moderators, gate lists on a single curator
The home page used to serialize two single-relay round-trips before any
campaign card could render: useCampaignModerators fetched the Team Soapbox
follow pack (kind 39089), and useCampaignLists waited on it to apply an
authors: gate. Each could stall up to an 8s EOSE timeout against the app
relay.

Both lookups are now eliminated from the critical path:

- CAMPAIGN_MODERATORS in agoraDefaults.ts is a hardcoded snapshot of the
  pack's p tags. useCampaignModerators serves it synchronously (no
  queryFn network call), keeping its useQuery return shape so all ~15
  consumers work unchanged. The roster changes rarely; update the array
  and re-cut a release when it does.

- Lists are an editorial surface curated by one identity (MK Fain / Team
  Soapbox), not the whole moderator pack. useCampaignLists now pins
  authors: to LIST_CURATOR_PUBKEY and no longer depends on the moderator
  query at all. The multi-author allowlist remains for labels only
  (approve/hide), where any pack member is trusted.

Regression-of: be1fadfc
2026-06-01 15:36:08 -05:00