Once an organization publishes its verifier statement on /organizations,
show an interactive walkthrough demonstrating how to verify a campaign:
a looping three-step animation on a mock campaign card where a cursor opens
the three-dots menu and selects 'Verify this campaign'. Step list is
clickable to scrub; motion is gated behind prefers-reduced-motion.
The About page (and `HelpFAQSection`) shipped extensive `dark:` overrides
in 76597ae7 and b05ded03, but they never fired in the in-app theme
toggle because tailwind.config.ts left `darkMode` unset. Tailwind
defaults to `media`, so `dark:bg-...` and `dark:text-...` utilities
only respect the OS `prefers-color-scheme` — not the `.dark` class
that `useTheme` writes to <html> when the user picks a dark theme
inside Agora.
Setting `darkMode: 'class'` wires every `dark:` utility in the
codebase (About page, HelpFAQSection, alert variants, chart, et al.)
to the in-app theme toggle. The About page now actually goes dark in
dark mode.
Regression-of: 76597ae7
- Switch the hook headline to Bebas Neue (font-display family) at heavier
size with a synthetic webkit-text-stroke fatten, italic, uppercase, and
tight leading so 'Connecting activists to / unstoppable funding.' reads
as a single editorial statement.
- Force the orange highlight onto its own line via <br>; tune left/right
padding and inner text offset so the U sits flush with 'Connecting'
above while the box extends past the word as a flourish.
- Fix two horizontal slashes across the world map caused by
antimeridian-crossing rings (Russia, Antarctica): detect any longitude
step > 180° and close+restart the SVG subpath instead of drawing the
connecting line.
- Drop the 2008-era left-edge darkening gradient and the bottom
vignette behind the map.
- Dim the central radial brand-orange glow (~half alpha).
- Tighten the arc-flow dash period and pixel size.
The @samthomson/nostr-messaging library opens fresh NRelay1 sockets per
participant per relay outside the shared NPool, fanning out to every
conversation partner's NIP-65 + NIP-17 inbox relays plus all
discoveryRelays in hybrid mode. In practice this drives connection counts
to several hundred relays per session.
Rather than band-aid the fan-out, drop the feature entirely and point
users to White Noise for end-to-end encrypted Nostr chat.
- Replace /messages with a 'Install White Noise' CTA card (route kept)
- Delete MessagingSettingsPage, DMProviderWrapper, messaging-intro.png
- Remove DMProvider wrapper and PROTOCOL_MODE config from App.tsx
- Drop messaging config from AppConfig, AppConfigSchema,
EncryptedSettingsSchema, EncryptedSettings, and the NostrSync /
useInitialSync sync paths
- Remove messages sidebar entry, default sidebarOrder slot, and
SettingsPage messaging card
- Uninstall @samthomson/nostr-messaging and drop its tailwind content
glob and vitest deps.inline entry
- Update copy in PrivacyPolicy, AdvancedSettings delete-account warning,
ProfileSettings nsec warning, RequestToVanishDialog deletion checklist,
MainLayout comment, and NIP.md
- Leave kind 4 rendering (EncryptedMessageContent) intact so DM events
authored elsewhere still display in feeds and quote embeds
Previously, a successful send from the Zap dialog auto-closed and surfaced a
toast. That undersold what just happened — the user sent Bitcoin. Now both
rails (on-chain + Lightning) flip the dialog over to a dedicated success
screen with an animated check, amount, recipient card, rail indicator, and
(for on-chain) a "View transaction" link to mempool.space. The dialog
auto-dismisses after six seconds if the user walks away.
Wikipedia/Wikimedia Commons hosts editorially-curated, mostly Xeno-
Canto-sourced recordings on bird species articles. Surface them on
Ditto's /i/ page whenever the article exposes one: an emerald play
button sits inline with the article title, looping the song on
click and swapping its play triangle for an animated equaliser to
indicate active playback. When a recording is present, the footer
row gains a second link crediting the recordist and license and
pointing at the Commons file-description page for verification.
Adapted from Birdstar's BirdInfoDialog / useBirdSound / useWikipedia
Sound hooks; the iNaturalist fallback from the original is dropped
per request — Ditto only uses Wikipedia/Commons.
Add a 'Delete Account' pill button to the bottom of the Settings
page (Guideline 5.1.1v). Rename the Danger Zone heading in Advanced
Settings to match. Simplify the deletion dialog to a single screen:
plain-language warning, list of what gets deleted, type DELETE to
confirm, and Cancel/Delete buttons. Always broadcasts to all relays.
The underlying NIP-62 mechanism and components that render vanish
events to other users are unchanged.
- Switch autocomplete dropdowns from absolute to fixed positioning so they
aren't clipped by ancestor overflow containers (e.g. the compose modal's
overflow-y-auto wrapper)
- Add viewport-relative coordinate calculation using getBoundingClientRect
- Add flip logic to show dropdown above cursor when near viewport bottom
- Dismiss dropdown on scroll/resize since fixed position doesn't track
- Add font-emoji utility class to force emoji presentation for native
Unicode characters (star, fire, etc.) that may render as text glyphs
- Apply same fixes to MentionAutocomplete for consistency
Closes#216
Both Current Focus and Daily Bounties sections are now collapsible
via Radix Collapsible, defaulting to open. Section headers stay
visible when collapsed and show summary info at a glance:
- Current Focus: Hatch/Evolve badge + progress count (e.g. 2 / 5)
- Daily Bounties: coin progress + green dot for claimable count
A subtle animated chevron rotates on toggle. The collapsible
animation uses new collapsible-down/up keyframes added to the
Tailwind config (mirrors the existing accordion pattern but uses
--radix-collapsible-content-height).
Settings row stays non-collapsible to keep it simple.
- New posts flushed from the stream buffer now briefly highlight with a
primary-tinted fade animation so users can see what appeared
- New-posts pill uses responsive CSS (new-posts-pill utility) so it sits
correctly below the SubHeaderBar on both mobile and desktop
- SubHeaderBar desktop padding moved inside the inner wrapper so the arc
background extends to the viewport edge, eliminating the gap above tabs
Replace the link-preview-style layout (full-width image + text below) with
a centered badge showcase: the image is displayed at badge size (112px)
with name and description centered beneath it, and a slow-rotating conic
gradient spotlight behind it for a grand presentation feel.
Add full badge system with achievements, shop, creation, and management:
- 11 new hooks for badge queries, mutations, and DVM claims
- 4 new pages: Achievements, Badge Shop, Badge Create, Badge Manage
- 4 new shared components: BadgeShowcaseGrid, BadgeThumbnail, BadgeTierPill, AwardBadgeDialog
- Badge showcase on ProfileCard and ProfileHoverCard
- Badge award notifications (kind 8) in notification feed
- Enhanced BadgeDetailContent with accept/award/buy actions
- Achievement catalog (73 achievements across 8 categories)
- Shop category system with admin-issued badge support
- Sidebar items for Achievements and Badge Shop
- CSS animations for badge glow and confetti effects
Built entirely on standard NIP-58 (kinds 30009, 8, 30008) with
NIP-90 DVM for achievement verification and NIP-57 zaps for shop.
Amber users on Android who manually approve events must switch from Ditto to
Amber to approve, then switch back. Backgrounding Ditto can freeze its
WebSocket, causing the NIP-46 response to be silently dropped — leaving the
operation hanging with no feedback and no way out. Users with Amber
notifications working correctly are unaffected, as approving via notification
does not background Ditto.
Even with auto-approve enabled, kinds outside Amber's default whitelist
require manual approval. Ditto uses several of these regularly: kind 1059
(NIP-17 gift-wrap DMs), 1111 (comments), 1311 (live chat), 31925 (RSVPs),
24242 (Blossom file upload auth), and 30078 (app settings).
This introduces signerWithNudge, a NostrSigner wrapper with the following
behaviour:
Nudge toast after 4 seconds
If a signing or encryption op is still pending after 4 s, a persistent toast
appears naming what is being approved (e.g. 'Approve file upload auth'), with
a human-readable label derived from the event kind.
Android 'Approve in signer' button
On Android the nudge toast includes an 'Approve in signer' button that opens
Amber via the nostrsigner: URI scheme, keeping the WebSocket alive. After
tapping, the button becomes a spinner and a Cancel button appears.
Automatic retry on foreground resume
When Ditto returns to the foreground after being backgrounded, it
automatically retries the pending NIP-46 request (up to 2 times) and shows a
brief 'Checking for signer response' toast.
Hard 45-second timeout
Operations with no response within 45 s are rejected with a clear error.
Cancel / Skip
The nudge toast has a Skip link throughout. After tapping 'Approve in signer'
it becomes a full Cancel button.
Multi-phase encrypt-then-sign
Saving app settings (kind 30078) and mute lists (kind 10000) require a nip44
encrypt followed immediately by a signEvent. When the encrypt nudge was shown,
a phase-transition toast tells the user a second approval is coming. The check
is kind-specific to avoid false positives.
Success feedback
A brief 'Approved' toast confirms the outcome when the nudge was shown.
Relay connectivity check
At nudge time, if the bunker relay WebSocket is not OPEN the toast warns
'Signer relay unreachable' instead of prompting for an approval that cannot
be delivered.
Accessibility
Toast buttons meet the 44 px touch target minimum. Text size and contrast
were increased for readability on small screens.
The sidebar now either shows fully (280px with labels, search, user
info) or is completely replaced by the mobile UI. The icon-only 72px
strip is eliminated — below 900px the mobile top bar, bottom nav,
drawer, and FAB take over entirely.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
The mobile layout now activates the moment the left sidebar would need
to shrink — at 688px (72px sidebar + 600px feed + padding). Added a
custom `sidebar` Tailwind screen breakpoint and replaced all `md:`
references that control the sidebar/mobile toggle with `sidebar:`.
This ensures the bottom nav, top bar, drawer, FAB, and full-width feed
kick in precisely when the sidebar can no longer fit alongside the feed.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>