356 Commits

Author SHA1 Message Date
Chad Curtis ceb442ebf1 Merge remote-tracking branch 'origin/main' into fix/remote-signer-ux-improvements
# Conflicts:
#	src/hooks/useCurrentUser.ts
#	src/index.css
2026-03-28 07:47:26 -05:00
Chad Curtis e1348f782e refactor: deduplicate theme dark/light detection into colorUtils
Extract getBackgroundThemeMode() and getBackgroundHex() into colorUtils.ts,
replacing duplicated CSS variable reading and luminance calculations in
EmojiPicker, main.tsx status bar, and TweetEmbed. Also fixes TweetEmbed
incorrectly treating custom themes as always light.
2026-03-28 06:27:21 -05:00
Chad Curtis e38f57f823 Merge branch 'fix/hashtag-query-eq' into 'main'
Fixing query case variants for tag feed parity with search

See merge request soapbox-pub/ditto!111
2026-03-28 10:57:46 +00:00
Chad Curtis f3b9eb9f73 Merge branch 'fix/disable-notifications' into 'main'
Fix notification preferences not filtering based on settings

See merge request soapbox-pub/ditto!93
2026-03-28 10:55:25 +00:00
Chad Curtis 6dd29c571f refactor: extract useInfiniteScroll hook and deduplicateEvents utility
Consolidate duplicated infinite-scroll boilerplate (auto-fetch page 2,
IntersectionObserver, scroll trigger) into a shared useInfiniteScroll
hook, and extract the flatten+dedup pattern into deduplicateEvents.

Also migrate BadgesPage and ThemesPage to use useFeedTab for
consistent tab persistence across all feed pages.
2026-03-28 05:31:49 -05:00
Lemon 9d8a30f678 Add badge awards push notification template and pref key mapping 2026-03-28 00:13:21 -07:00
Lemon 8551852c9d Add badges and letters kinds to shared notificationKinds helper 2026-03-28 00:00:20 -07:00
Lemon 0ad655d1cf Fix notification preferences not filtering push notifications or unread dot
Disabled notification types (e.g. reactions) still triggered push
notifications and showed the unread dot indicator, even though the
notification tab correctly filtered them out.

Three root causes fixed:
- useHasUnreadNotifications now uses getEnabledNotificationKinds to
  only query for enabled types, preventing phantom unread dots
- NotificationSettings now syncs type preference changes to the
  nostr-push server via updateSubscription (is_active toggle)
- Native Android poller now receives enabled kinds from the JS layer
  and uses them in the relay filter instead of hardcoded kinds
2026-03-27 23:58:31 -07:00
Alex Gleason a48ac48202 Trim Sentry bundle by tree-shaking unused replay/feedback/canvas modules
Use named imports in the dynamic import of @sentry/react so the bundler
can drop re-exported modules we never reference (replay 207K, feedback 67K,
replay-canvas 25K). Also set defaultIntegrations: undefined to prevent
Sentry from pulling those modules at runtime.

Sentry chunk: 431K → 128K (-70%).
2026-03-28 00:00:21 -05:00
Alex Gleason dce3d5b411 Merge branch 'feat-blobbi' into 'main'
Blobbi: add core pet system, interactions, missions, etc

See merge request soapbox-pub/ditto!104
2026-03-28 01:23:11 +00:00
Mary Kate Fain b59eeeca81 Show theme description on 'updated their theme' (kind 16767) posts
Kind 16767 events previously hardcoded description to undefined, so the
theme description never appeared on 'updated their theme' posts in the
feed or detail view.

Three changes:
- buildActiveThemeTags now accepts and includes a description tag, so
  future kind 16767 events carry the description directly
- setActiveTheme accepts description to thread it through publishing
- ThemeContent extracts the description tag from kind 16767 events, and
  for older events without one, falls back to querying the source theme
  definition via the a-tag reference
2026-03-27 17:09:08 -05:00
Alex Gleason da27054a9b Fix file downloads and URL opening on Capacitor iOS
The <a download> and <a target="_blank"> patterns don't work in
WKWebView. Add downloadTextFile() and openUrl() utilities in
src/lib/downloadFile.ts that use @capacitor/filesystem and
@capacitor/share on native platforms, falling back to standard
browser behavior on web.

Update all call sites: onboarding key download (InitialSyncGate,
SignupDialog), image lightbox buttons (ImageGallery, ProfilePage).

Document Capacitor compatibility constraints in AGENTS.md.
2026-03-27 16:42:36 -05:00
filemon 0d8b320f31 Implement improved Blobbi care streak system with day-based tracking
Add new streak tags to kind 31124 events:
- care_streak: Consecutive days of care (starts at 1, resets to 1 if 2+ days missed)
- care_streak_last_at: Unix timestamp of last streak update
- care_streak_last_day: Local calendar day (YYYY-MM-DD) of last update

Streak validation rules:
- Initialize to 1 on first activity
- Increment when activity occurs on the next local day
- Same-day activity does not increment (at most once per day)
- Missing 2+ days resets streak to 1

Files added:
- blobbi-streak.ts: Centralized streak calculation logic
- useBlobbiCareActivity.ts: Hook for registering care activity

Streak integration points:
- Blobbi page entry (automatic check-in)
- Direct actions (play_music, sing)
- Inventory item use
- Stage transitions (hatch, evolve)
- Rest action (sleep/wake)
- Companion item use (outside BlobbiPage)
2026-03-27 17:01:35 -03:00
filemon 6ab05471b2 Migrate Blobbonaut profile from kind 31125 to 11125 with auto-onboarding
- Change KIND_BLOBBONAUT_PROFILE constant from 31125 to 11125
- Add KIND_BLOBBONAUT_PROFILE_LEGACY (31125) for migration support
- Add BLOBBONAUT_PROFILE_KINDS array to query both kinds
- Update useBlobbonautProfile to prefer 11125 over 31125
- Add needsKindMigration flag for legacy profile detection
- Extend useBlobbonautProfileNormalization to auto-migrate legacy kinds
- Refactor onboarding to auto-create profile using kind 0 name
- Remove manual name entry step from onboarding flow
- Delete unused BlobbiProfileOnboarding component
- Update all documentation comments to reference kind 11125
2026-03-27 16:27:26 -03:00
Mary Kate Fain f82adab05d Fix: add letter (kind 8211) notifications
Letters were completely absent from the notification pipeline — users had
to visit the Letters page to discover incoming letters. This integrates
kind 8211 into every layer of the notification system:

- useNotifications: query, grouping, and referenced-event exclusion
- useHasUnreadNotifications: unread dot indicator
- NotificationsPage: LetterNotification component with link to /letters
- NotificationSettings: toggleable Letters row
- notificationTemplates: web push template
- Android NotificationRelayService + NostrPoller: native push support
- EncryptedSettings + schema: letters preference field

Closes #188
2026-03-27 14:15:50 -05:00
filemon 1291a0e932 Fix: ensure t and client tags are removed from Blobbi events
The previous commit removed these tags from event building functions, but
the tag validation/repair system in blobbi-tag-schema.ts was re-adding them:

1. BLOBBI_TAG_SCHEMA had 't' marked as required:true with defaultValue:'blobbi'
2. RECOVERABLE_SYSTEM_TAGS had both 't' and 'client' with default values
3. DEPRECATED_TAG_SCHEMA did not include 't' or 'client'

Fixed by:
- Removing 't' and 'client' from BLOBBI_TAG_SCHEMA (no longer required)
- Removing 't' and 'client' from RECOVERABLE_SYSTEM_TAGS
- Adding 't' and 'client' to DEPRECATED_TAG_SCHEMA

Now the validateAndRepairBlobbiTags function will properly filter out
these tags during any republish/migration/update flow.
2026-03-27 15:58:44 -03:00
filemon a2d40c5cbf Remove Blobbi shape system and clean up t/client tags
- Remove BLOBBI_TOPIC_TAG and BLOBBI_CLIENT_TAG from event building
- Add t and client to DEPRECATED_BLOBBI_TAG_NAMES for migration cleanup
- Update validation functions to not require t tag
- Delete blobbiShapes.ts and BlobbiShapePicker.tsx entirely
- Simplify avatarShape.ts to only support emoji shapes
- Remove blobbi_shape task from useEvolveTasks
- Remove change_shape task from useHatchTasks
- Remove change_shape mission from daily-missions
- Clean up ProfileCard shape picker to only show emoji picker

The app's useNostrPublish hook already adds client tags automatically,
making the explicit client tag redundant. Old events with these tags
will have them stripped on next save.
2026-03-27 15:54:20 -03:00
filemon c054bc7bc7 Merge branch 'main' into feat-blobbi 2026-03-27 01:25:27 -03:00
Chad Curtis 51fffc0ae1 Merge branch 'envelope-inbox' into 'main'
Add Letters inbox page with full letter composing from lief

See merge request soapbox-pub/ditto!117
2026-03-27 03:59:48 +00:00
Chad Curtis 403946bac5 Use mailbox icon from lief for Letters page and sidebar 2026-03-26 22:43:11 -05:00
Alex Gleason cc59035c62 Redesign changelog page with parsed structured entries
Parse Keep a Changelog markdown into structured data and render
version cards with colored category badges instead of raw markdown.
2026-03-26 21:57:49 -05:00
Chad Curtis 7a8fbe3ee5 Fix review items 6-10: use default relays, lazy-load fonts, paginate letters, cap SVG size, fix exhaustive-deps 2026-03-26 21:32:18 -05:00
Chad Curtis 848ac15ef0 Fix CI: remove unused prop, centralize color helpers, extract constants, memoize Sets, move @types/dompurify to devDeps 2026-03-26 19:45:51 -05:00
Chad Curtis ae1f97eb08 Letters: bigger wax seals, adaptive text, inline labels, font loading, SVG sticker fix 2026-03-26 19:17:58 -05:00
Chad Curtis 865fabce98 Add Letters inbox page with full letter composing from lief
- Port letter protocol (kind 8211, NIP-44 encrypted) from lief
- LettersPage at /letters with inbox and sent tabs
- ComposeLetterSheet with full stationery, font, frame, sticker, drawing support
- LetterCard with expand-to-read animation and deletion
- LetterPreferencesSection stored in encrypted settings (NIP-78)
- /settings/letters route for letter preferences
- Letters added to sidebar nav
- All letter lib utilities: letterTypes, letterUtils, colorUtils extensions, sanitizeSvg, svgDrawing
- StationeryBackground, StationeryPicker, FramePicker, StickerPicker, DrawingCanvas all ported
2026-03-26 16:11:29 -05:00
Alex Gleason 143b383a62 Remove /messages route and navigation entry 2026-03-26 10:18:22 -05:00
Alex Gleason 7511578bf2 Merge branch 'main' of gitlab.com:soapbox-pub/ditto 2026-03-25 20:11:00 -05:00
Alex Gleason d09629c100 Add standalone repost event views and separate quotes count display
- Render kind 6/16 repost events as standalone viewable cards (similar to
  kind 7 reactions): compact activity-style card showing repost icon, author
  avatar, author name, 'reposted' label, and timestamp
- Support both normal and threaded layouts for repost events in NoteCard
- Add repost detail view in PostDetailPage with full action buttons (reply,
  repost, react, share, more) and ancestor thread pointing to reposted event
- Register kind 6/16 in all kind label registries: CommentContext KIND_ICONS,
  extraKinds KIND_SPECIFIC_LABELS/ICONS, and shellTitleForKind
- Separate quotes count from reposts in action buttons: reposts button now
  shows only repost count, new Quote button shows quote count separately
- Quote button on detail page opens InteractionsModal on the quotes tab
- Quote count sourced from useEventInteractions for accurate counts
  (NIP-85 doesn't provide quote_cnt)
2026-03-25 18:40:58 -05:00
Alex Gleason c9e447ff13 Add title font support for profile display name
Implement the title font feature across the full stack:

- Type system: Add titleFont to ThemeConfig, ThemePreset, ThemeDefinition,
  ActiveProfileTheme interfaces and Zod schema
- Event encoding: Update f-tag build/parse to emit role markers (body/title)
  with backward-compatible parsing of legacy roleless tags
- Font loading: Add loadAndApplyTitleFont with --title-font-family CSS var
- UI: Add Title Font picker to theme builder dialog and profile theme editor,
  with configurable label prop on FontPicker
- Profile rendering: Apply --title-font-family to the display name h2
- Data flow: Thread titleFont through ThemeSelector snapshots, theme
  presets, publish/update, NostrSync, ThemeContent, and diff detection
2026-03-25 13:37:29 -05:00
Alex Gleason a921e640cc Add copyable Nostr clone URI to git repo cards
Port NostrURI module from Shakespeare to generate nostr:// clone URIs
from kind 30617 event data (pubkey, d-tag, relays). Display the Nostr
clone URI in GitRepoCard as the sole clone URL, replacing the previous
HTTPS clone URL. Also use the nostr:// URI for Shakespeare clone links.
2026-03-25 12:55:09 -05:00
Alex Gleason 8143d8b9ac Add Zapstore apps (32267) to development feed kinds 2026-03-24 21:51:58 -05:00
Alex Gleason 4fecb7b32e Show globe icon for nsites in embed cards instead of parent category code icon
Add KIND_SPECIFIC_ICONS override map in extraKinds.ts so kinds in
extraFeedKinds arrays get their own icon instead of inheriting the
parent def's icon. Nsites (15128/35128) now show Globe, patches
show GitPullRequestArrow, etc.
2026-03-24 20:59:03 -05:00
Alex Gleason a8cb7240bf Use specific kind labels in embed cards instead of parent category name
Add getKindLabel() to extraKinds.ts as the canonical resolver for
per-kind labels. Kinds in extraFeedKinds (like nsites 15128/35128)
now show 'nsite' instead of the parent category 'development'.
2026-03-24 20:57:20 -05:00
Alex Gleason 221aa03362 Add nsite deployment support to development feed
Display kind 15128 (root site) and 35128 (named site) events as
deployment cards in the development feed with a link to view the
site via the nosto.re gateway.
2026-03-24 20:11:29 -05:00
Alex Gleason dac2bf6bb0 Fix nav search to use word-boundary matching and remove path display
Change search to only match from the start of words, so 'arch' matches
'Archive' but not 'Search'. Remove the pathname text from nav item results.
2026-03-24 19:49:21 -05:00
Alex Gleason 292fe289f7 Add sidebar nav items to autocomplete search results
Allow users to search for sidebar navigation pages (e.g. Notifications,
Settings, Bookmarks) in both the desktop and mobile search autocomplete.
Results appear as instant local matches above profile/identifier results.
2026-03-24 19:47:21 -05:00
filemon e3412fac46 Merge branch 'main' into feat-blobbi 2026-03-24 12:20:40 -03:00
Sergey B. 25bfe4f0fa fix: query case variants for tag feed parity with search 2026-03-24 17:13:33 +03:00
Alex Gleason 4c1576f704 Add Bluesky to sidebar navigation and update icon to Simple Icons SVG 2026-03-23 22:18:10 -05:00
filemon aa2d724a13 Merge branch 'main' into feat-blobbi 2026-03-23 20:10:15 -03:00
Alex Gleason a1b2c23e46 Merge origin/main into feat/curves 2026-03-23 15:31:05 -05:00
filemon 163712471c Improve Blobbi UI mobile responsiveness and add compact coin formatting
- Add formatCompactNumber utility for compact coin display (1.2K, 15.4K, 1.2M)
- Fix BlobbiActionInventoryModal (medicine items) layout for mobile
- Fix BlobbiBottomBar to prevent overflow on narrow screens
- Fix BlobbiInventoryModal item cards for mobile
- Fix BlobbiMissionsModal horizontal scroll and layout issues
- Fix DailyMissionsPanel and TasksPanel for mobile
- Fix BlobbiShopModal and related dialogs for mobile
- Apply compact number formatting to all coin displays
2026-03-23 17:07:16 -03:00
Alex Gleason 894f692dea Display rich Wikipedia article content on /i/ pages instead of generic link preview
Detect Wikipedia URLs and render a custom WikipediaArticleHeader with hero
image, article title, Wikidata description, expandable extract, and a
Read on Wikipedia footer link. Also uses the Wikipedia API for accurate
page titles in the header bar and SEO metadata, and navigates back to
/wikipedia on the back button.
2026-03-23 13:31:40 -05:00
Alex Gleason 4dd1ceb9b4 Add custom Wikipedia icon, use it in page header, card fallbacks, and sidebar 2026-03-23 13:23:22 -05:00
Alex Gleason daf3a38c21 Add /wikipedia page with dynamic featured content from Wikipedia's API 2026-03-23 12:59:33 -05:00
filemon 974cdcccc9 Merge branch 'main' into feat-blobbi 2026-03-23 10:58:25 -03:00
Lemon 2b8b7a1750 Cleanup: remove dead code, hoist styles, adopt PageHeader across remaining pages 2026-03-22 23:36:40 -07:00
Alex Gleason 6d71fcaa45 Move image quality setting to Network Settings page
Remove the inline toggle from the post composer toolbar and add
imageQuality to AppConfig instead. The setting now lives in
Settings > Network under 'Image Uploads' with a Compressed/Original
pill toggle, persisted to localStorage like other app settings.
2026-03-23 00:44:30 -05:00
Alex Gleason 9e26446d7b Pick smallest format (JPEG vs PNG) when resizing images
Instead of always converting to JPEG, encode both JPEG and PNG in
parallel and keep whichever is smaller. Skip re-encoding entirely
when the image already fits within the dimension limit.
2026-03-23 00:32:13 -05:00
Alex Gleason fbf8c328f6 Merge branch 'main' of gitlab.com:soapbox-pub/ditto 2026-03-23 00:22:12 -05:00