Commit Graph

1813 Commits

Author SHA1 Message Date
Mary Kate Fain f0efbf683d refactor: merge community badge feed into Badge Shop as tabs
Badge Shop (/shop) now has 3 tabs following the ThemesPage pattern:
- Shop: admin badge grid with categories, search, prices (unchanged)
- Follows: NoteCard feed of badge events from followed users
- Global: NoteCard feed of all badge events

The standalone BadgesFeedPage is deleted — its content now lives as
the Follows/Global tabs inside the Shop page.

- Add useBadgeFeed hook (modeled on useThemeFeed) for infinite scroll
- Remove 'badges' sidebar item, keep 'shop' and 'achievements'
- Add 'badges' → 'shop' sidebar ID migration so existing users
  who had Badges in their sidebar seamlessly get Badge Shop instead
- Redirect /badges → /shop for backward compatibility
- Add quick-action links to Create Badge and My Badges on Shop tab
2026-03-20 23:16:55 -05:00
Mary Kate Fain e0a5702374 refactor: query achievements from admin instead of hardcoding
Achievements are now queried as kind 30009 badge definitions from the
admin pubkey with t:achievement tag, grouped by category t-tags.
Removed the static achievementCatalog.ts - the admin publishes all
achievement badges to relays and the client discovers them dynamically.
2026-03-20 22:55:32 -05:00
Mary Kate Fain bf646b557e feat: implement comprehensive badge & achievement system (NIP-58)
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.
2026-03-20 22:51:01 -05:00
Alex Gleason 23e55ffff7 Consolidate IndexedDB into a single 'ditto' database with multiple stores
Replace three separate per-hostname databases (nostr-nip05-cache-*,
nostr-profile-cache-*, nostr-dm-store-*) with one shared 'ditto'
database containing three object stores: nip05, profiles, messages.

A single db.ts module manages the connection and upgrade logic, and
caches the promise so only one connection is created per page lifetime.
2026-03-20 21:59:48 -05:00
Alex Gleason d9e943d03c Add kind 0 profile IndexedDB cache to eliminate author loading skeletons
Profile events (kind 0) are now persisted in IndexedDB and hydrated into
memory before React renders. useAuthor seeds TanStack Query with
initialData from the cache so names, avatars, and metadata render
instantly on repeat visits instead of showing skeletons.

Cache writes happen from three sites: useAuthor (single profile fetch),
useAuthors (batch fetch), and useFeed (community feed metadata prefetch).
Only newer events overwrite older ones to prevent out-of-order downgrades.

Staleness tiers match NIP-05: < 5 min fresh, 5 min - 7 d background
refetch, > 7 d expired (skeleton until fresh data arrives).
2026-03-20 21:52:48 -05:00
Alex Gleason ddd9bb06f4 Add staleness tiers to NIP-05 cache: fresh / background recheck / expired
Cached entries now follow three tiers based on age:
- < 1 hour: fresh, rendered instantly with no network request
- 1 hour – 7 days: rendered instantly, background refetch updates cache
- > 7 days: discarded, shows skeleton until fresh verification completes
2026-03-20 21:11:03 -05:00
Alex Gleason 318f8fcc8a Add NIP-05 IndexedDB cache to eliminate loading skeletons on repeat visits
Successful NIP-05 resolutions are now persisted in IndexedDB with a
lastVerified timestamp. On subsequent page loads the cache is hydrated
into memory before React renders, so TanStack Query receives initialData
and skips the pending state entirely — verified NIP-05 names appear
instantly instead of showing a skeleton placeholder.

Failed lookups are not persisted. Stale entries are evicted when the
domain responds but the identifier is no longer present.
2026-03-20 21:01:39 -05:00
Alex Gleason d0f458f985 Go back to using Shakespeare's corsProxy (we don't even use it in Ditto yet) 2026-03-20 19:14:13 -05:00
Alex Gleason d92be3e341 Swap out default favicon and link-preview APIs 2026-03-20 16:23:50 -05:00
Alex Gleason 8a6b524e85 Update default corsProxy 2026-03-20 16:09:18 -05:00
Alex Gleason a9449bd009 Fix jumpy home feed: layout shifts, background refetches, and pre-filtering
- Add min-height placeholder to InlineImage to prevent layout shifts when
  images load from 0px to natural height
- Remove 60s refetchInterval from useFeed that caused all pages to re-sort
  in the background, triggering full feed re-renders
- Pre-filter deprecated/hidden events at Feed level (shouldHideFeedEvent)
  instead of returning null inside NoteCard after hooks have already run
- Stabilize author info skeleton/loaded height with consistent min-h-[42px]
  to prevent cascading layout recalculations
2026-03-20 13:56:26 -05:00
Alex Gleason c7d7ac3c7c Swap followers and following order on profile pages 2026-03-20 04:18:27 -05:00
Alex Gleason b1f81016a4 Add followers count and paginated followers list to profile page
Display NIP-85 follower count next to the existing following count on
profiles. Clicking the count opens a paginated modal that fetches
followers via kind:3 #p queries with infinite scroll.
2026-03-20 04:10:39 -05:00
Alex Gleason d65a4d81cc Merge branch 'feat/profile-field-weather' into 'main'
feat/profile-field-weather

See merge request soapbox-pub/ditto!86
2026-03-20 07:58:00 +00:00
Alex Gleason 43fabe1ac3 Add top padding to theme mockups to restore visual spacing 2026-03-20 01:39:05 -05:00
Alex Gleason 350bb037bf Remove decorative header bar and sidebar strip from ThemePreviewCard and LandingHero mockups 2026-03-20 01:38:28 -05:00
Alex Gleason 71a3836a75 Remove decorative header bar and sidebar strip from ThemeMockup 2026-03-20 01:37:02 -05:00
Alex Gleason b25be7e8e9 Add relay.dreamith.to as a second Ditto relay for search, trending, and streaming queries 2026-03-19 22:25:26 -05:00
Derek Ross 7a9a6edeeb Add CSAE child safety policy page at /safety 2026-03-19 19:43:46 -04:00
Alex Gleason 8ea370067b Add screenshot lightbox modal to Zapstore app events 2026-03-19 18:10:36 -05:00
Alex Gleason c809bf4093 Normalize and validate relay URLs in extractWriteRelays, cap to 5 relays 2026-03-19 18:06:13 -05:00
Alex Gleason 557f29df78 Stop passing react-query signal through useEvent hooks, use AbortSignal.timeout directly 2026-03-19 18:03:20 -05:00
Alex Gleason ab8bf31710 Query Zapstore relay first in useAddrEvent for faster app/release lookups 2026-03-19 18:00:37 -05:00
Alex Gleason a2d5b50fdd Route Zapstore kinds through NostrProvider reqRouter instead of direct relay calls 2026-03-19 17:44:45 -05:00
Alex Gleason bd085ac0a9 Move ZAPSTORE_RELAY constant to appRelays.ts 2026-03-19 17:40:58 -05:00
Alex Gleason 1da093d4bf Use GitFork icon for Source button in Zapstore app card 2026-03-19 17:34:03 -05:00
Alex Gleason a33002ec21 Fix Zapstore link to use correct /apps/ URL format 2026-03-19 17:14:55 -05:00
Alex Gleason bbff34bd76 Add special rendering for Zapstore app events (kind 32267)
Render kind 32267 software application events with app icon, name,
summary, platform badges, screenshots, and action buttons in both
feed (NoteCard) and detail (PostDetailPage) views. Add useAddrEvent
fallback to wss://relay.zapstore.dev for kinds 32267/30063 so app
events are discoverable even when not on the user's relay set.
2026-03-19 17:08:40 -05:00
Alex Gleason 2dbd403f20 Add full-screen rain/snow precipitation effect on country pages
When the weather API reports precipitation for a country, render a
canvas-based particle overlay: animated raindrops for rain/drizzle/
thunderstorm codes, and gently drifting snowflakes for snow codes.
Intensity (light/moderate/heavy) scales particle count and speed.
The overlay is pointer-events-none at z-[100] so it doesn't block
interaction.
2026-03-19 14:54:51 -05:00
Alex Gleason 7f0f25aeb7 Make quoted event tombstones clickable with NIP-19 identifiers
When a quoted event fails to load, the 'this post could not be loaded'
indicator is now clickable, navigating to the event's page. Constructs
nevent1 for regular events and naddr1 for addressable events, including
relay hints and author pubkey when available from the parent event's tags.
2026-03-19 14:34:34 -05:00
Alex Gleason 2e9dc52485 Add current weather display to country pages
Use the free Open-Meteo API to show real-time weather (temperature,
humidity, wind, conditions) on country and subdivision pages. Weather
is fetched based on capital city / major city coordinates and cached
for 15 minutes.
2026-03-19 11:34:26 -05:00
Alex Gleason c1323d5048 Remove LinkFooter from desktop left sidebar to fix duplicate display
The footer links (About, Docs, Privacy, Edit with Shakespeare) were
showing in both the left sidebar and right sidebar on desktop. Remove
from LeftSidebar since it already appears in MobileDrawer for mobile
and in the right sidebars for desktop.

Closes #131
2026-03-19 11:11:39 -05:00
Alex Gleason 9f82fb5f46 Show LinkFooter in both desktop and mobile sidebars regardless of login state 2026-03-18 22:33:07 -05:00
Alex Gleason 88088e754d Add LinkFooter component with About, Docs, Privacy, and Shakespeare links 2026-03-18 22:30:24 -05:00
Alex Gleason 962f97fbfc Update tagline to 'Your content. Your vibe. Your rules.' 2026-03-18 21:04:43 -05:00
Alex Gleason e3935b7dc6 Replace Messages with Feed in mobile bottom nav
Remove the Messages tab and add a Feed tab (using PlanetIcon) as the
leftmost item in the mobile bottom navigation. Feed highlights when
on /feed or /.
2026-03-18 15:29:33 -05:00
Alex Gleason 464279b2e6 feat: add custom font upload to theme editor FontPicker
Allow users to upload their own .woff2/.woff/.ttf/.otf font files via
Blossom, which are immediately applied and stored with the theme. The
uploaded font URL is preserved when publishing themes to Nostr (via the
existing f tag in the theme event schema).
2026-03-18 13:01:07 -05:00
Chad Curtis 176813dce0 feat: support multi-photo upload in media picker
Add the  attribute to the file input in ComposeBox and update
the onChange handler to iterate over all selected files, uploading each
one via handleFileUpload, enabling users to select and attach multiple
files at once.
2026-03-18 05:55:41 -05:00
Chad Curtis 39fee6aa5d Filter notifications for reactions/reposts/zaps on posts user didn't author 2026-03-18 05:36:10 -05:00
Chad Curtis a7b142b5e5 Filter reactions/reposts on posts the user didn't author from notifications 2026-03-18 05:31:26 -05:00
Chad Curtis 018fad1a2e Fix color moments text overlay, add geohash pill and geotag feed support
- Fix color moments rendering long text as emoji overlay; only render
  single emoji (≤2 code points) as palette overlay
- Replace MapPin with ChestIcon on geocache name
- Add geohash pill badge to geocache type/size row, linking to /g/ route
- Truncate geohash display to 5 characters
- Add /g/:geohash route with GeotagPage backed by shared TagFeedPage
- DRY up HashtagPage and GeotagPage into shared TagFeedPage component
- Extend useInterests to support g tags for geohash following
- Add geotag feed tabs to home feed with MapPin icon
2026-03-18 04:00:25 -05:00
Alex Gleason aea730a949 Redesign Request to Vanish as a multi-step wizard
Break the dialog into 3 focused steps (Scope, Details, Confirm)
with animated progress indicators, dramatic destructive color
treatment, custom scope selection cards, and a centered final
confirmation with type-to-confirm input.
2026-03-18 03:20:55 -05:00
Alex Gleason f861641aa1 Add NIP-62 Request to Vanish support
Implement kind 62 event publishing to allow users to request
permanent deletion of their data from relays. Includes global
(ALL_RELAYS) and targeted (specific relays) modes with a
multi-step confirmation dialog in Advanced Settings.
2026-03-18 03:06:24 -05:00
Alex Gleason 573c680d2f Add privacy policy link to Help page 2026-03-18 01:16:36 -05:00
Alex Gleason 9010dba583 Add privacy policy page with route and sidebar link 2026-03-18 01:13:04 -05:00
Dirk Rost 9309308a4e Merge branch 'fix/iOS-accessibility' into 'main'
fix: prevent iOS Safari auto-zoom on input focus

See merge request soapbox-pub/ditto!84
2026-03-17 19:55:18 +00:00
Dirk Rost cd1620c76e Merge branch 'feat/poll-compose' into 'main'
Add poll creation to compose toolbar and polls page FAB

See merge request soapbox-pub/ditto!85
2026-03-17 19:55:18 +00:00
Lemon f91a37914c fix: prevent iOS Safari auto-zoom on input focus 2026-03-17 19:55:18 +00:00
Chad Curtis f1c15b64a2 Add poll creation to compose toolbar and polls page FAB 2026-03-17 19:55:18 +00:00
Mary Kate c3a4d8be57 Fix sticky tabs not scrolling to top on click or switch 2026-03-17 19:46:44 +00:00