Commit Graph

122 Commits

Author SHA1 Message Date
Alex Gleason 4afea98e77 Align bottom bar max-width with content container after card removal 2026-04-01 10:58:46 -05:00
Chad Curtis 6fc5d3ed97 Add 'Show X more replies' for branching threads
When a reply has multiple children, only the first child renders
inline in the thread chain. Remaining siblings are hidden behind
a 'Show N more replies' button placed between the parent and
its inline child. Clicking reveals them as threaded items with
the connector line. Removes bottom border from the expand button
so it flows seamlessly in the thread.
2026-04-01 03:42:13 -05:00
Alex Gleason 77b8498850 npm audix fix 2026-03-31 20:00:22 -05:00
Alex Gleason 922a66835a Fix Nushu script not rendering on Android by bundling Noto Sans Nushu font
Android system fonts don't include glyphs for the Nushu Unicode block
(U+1B170-U+1B2FF), causing the encrypted letter ciphertext to render as
empty boxes. Bundle @fontsource/noto-sans-nushu as a web font so the
glyphs render correctly on all platforms.
2026-03-31 17:44:30 -05:00
Chad Curtis 11ecfb1bcf Render kind 9735 zap receipts and kind 0 profiles in feed and detail pages
- Kind 9735: feed card shows sender, amount (pluralized sat/sats), message; detail page shows activity-style card with ancestor thread; zap rows in InteractionsModal now link to the receipt nevent instead of sender npub, and include eventId on ZapEntry
- Kind 0: feed card renders ProfileCard inline; detail page renders ProfileCard directly with no action header
- CommentContext: add kind 0 (profile) and 9735 (zap) to KIND_LABELS and KIND_ICONS
- NoteCard KIND_HEADER_MAP: add kind 9735 zap header
2026-03-30 23:53:57 -05:00
Alex Gleason a45e649374 Fix infinite re-render crash when dragging profile tabs in edit mode
Remove 'transform' from useLayoutEffect deps in SortableTabChip. During
a drag, useSortable produces a new transform object every frame, which
triggered onActive() -> SubHeaderBar re-render -> new transform ref ->
effect re-fires, causing React error #185 (maximum update depth exceeded).
The active indicator position only needs to update when the active tab
changes, not on every drag frame.
2026-03-30 22:48:31 -05:00
Alex Gleason ec24c4cfae Add zap option to profile 3-dots menu
Move zap functionality into the ProfileMoreMenu so users with a
lightning address can still be zapped. The menu row opens the ZapDialog
after the more menu closes via a hidden trigger ref.
2026-03-30 11:25:03 -05:00
Alex Gleason 94f0c8308d Show all sidebar items to logged-out users and update sidebar order
Stop filtering requiresAuth items from navigation. Pages already render
their own LoginArea when the user is not logged in, so hiding the items
from the sidebar, mobile drawer, and search prevented feature discovery
without providing any benefit.

Also update the default sidebar order: remove bookmarks and profile,
add letters.
2026-03-30 09:56:02 -05:00
Chad Curtis 5288b7a718 Letters: overflow menu, reply button, grid layout, and UX polish
- EnvelopeCard: add ... overflow menu trigger using NoteMoreMenu (no duplicated logic)
- NoteMoreMenu: detect NIP-44 ciphertext by content shape, show 'Encrypted content'
- LetterDetailSheet: reply button (InkPenIcon, primary colors); gift above card; letter centered in viewport; click outside closes
- LettersPage: reply pre-fills sender npub; default stationery falls back to parchment when no custom theme; 2-col mobile / 4-col desktop grid
- NotificationsPage: reply button next to 'View all letters' in letter notifications
- ComposeLetterSheet: auto-focus textarea on open; fix To field overflow on narrow screens
- InkPenIcon: new custom icon replacing PenLine on FAB and reply buttons
2026-03-30 06:21:50 -05:00
Alex Gleason 1988e1b849 Fix duplicate React keys in content settings
Multiple ExtraKindDef entries share the same feedKey (e.g. posts/comments
both use feedIncludePosts) and multiple subKinds share the same showKey
(e.g. both video sub-kinds use showVideos). Using these as React keys
caused 'duplicate key' warnings.

Use def.id (always unique) for ContentTypeRow keys and sub.feedKey
(unique per sub-kind) for SubKindRow keys.
2026-03-29 17:29:45 -05:00
Alex Gleason d3a418b5ee Remove redundant header from profile badges feed card
Remove the 'Name's Badges (N badges)' header line from ProfileBadgesContent
to reduce visual clutter. The badge grid and NoteCard's KIND_HEADER_MAP
already provide sufficient context.
2026-03-29 14:18:37 -05:00
Chad Curtis 6bf630bb40 Fix delete post dialog freezing feed on desktop
Move the delete confirmation AlertDialog out of NoteMoreMenuContent
(where it was nested inside the more-menu Dialog) and into the parent
NoteMoreMenu component. The nested Radix dialogs caused overlapping
overlays and focus traps that left the page uninteractable after
confirming deletion. Now follows the same close-then-open pattern used
by Report, Mention, AddToList, and EventJson dialogs.
2026-03-29 06:16:23 -05:00
Lemon 9ffab3d2dd Fix double-tap reaction not showing emoji on the post
The double-click handler was setting the user-reaction query cache to a
plain string instead of a ResolvedEmoji object. RenderResolvedEmoji
expects { content: '❤️' }, not just '❤️'.
2026-03-28 23:07:21 -07:00
Mary Kate Fain 6c067a3ae6 Rename "Vines" to "Divines" in all user-facing strings
Update sidebar label, page title, feed empty states, search filter
labels, notification kind nouns, comment context labels, and
documentation to use "Divines" instead of "Vines".

Closes #194
2026-03-28 13:05:08 -05:00
Alex Gleason dc3fe02767 Upgrade Radix UI packages to fix infinite render loop with React 19
@radix-ui/react-popper 1.2.4 had a useEffect with no dependency array
that called setState (onAnchorChange) on every render, causing an
infinite loop. Fixed in 1.2.8 by tracking the previous anchor value
in a ref and only calling setState when it changes.

Upgraded all Radix packages that depend on react-popper:
- react-tooltip 1.2.4 -> 1.2.8
- react-popover 1.1.11 -> 1.1.15
- react-dropdown-menu 2.1.12 -> 2.1.16
- react-context-menu 2.2.12 -> 2.2.16
- react-hover-card 1.1.11 -> 1.1.15
- react-select 2.2.2 -> 2.2.6
- react-menubar 1.1.12 -> 1.1.16
- react-navigation-menu 1.2.10 -> 1.2.14
2026-03-28 02:29:17 -05:00
Alex Gleason c613a7aedd npm audit fix 2026-03-28 00:30:35 -05:00
Alex Gleason d4d502f418 Loosen engines constraint to node >=22 2026-03-28 00:30:14 -05:00
Alex Gleason 7f37f16c7b Upgrade React from 18.3 to 19.2
- Upgrade react, react-dom to ^19.2.4 and @types/react, @types/react-dom to v19
- Upgrade @nostrify/react to 0.4.0 (peer deps fix for React 19)
- Upgrade vaul to 1.1.2 and react-day-picker to 9.14.0 for React 19 compatibility
- Fix useRef() calls to pass explicit initial values (required in React 19)
- Update RefObject types to include null (React 19 type change)
- Rewrite Calendar component for react-day-picker v9 classNames API
- Add npm overrides for @emoji-mart/react (only remaining React 18 holdout)
2026-03-28 00:29:37 -05:00
Alex Gleason c257e61fa7 Add bundle analyzer (rollup-plugin-visualizer) to the build 2026-03-27 20:26: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 872d319220 Fix compose modal closing when dismissing emoji picker on mobile
Prevent the compose modal from being accidentally dismissed when the user
taps the emoji/GIF picker overlay to close it.  On mobile this was very
easy to trigger, causing the draft to be lost.

Add onInteractOutside and onEscapeKeyDown handlers to the compose modal's
DialogContent that detect when a nested dialog (emoji picker) is open and
prevent the dismiss event from propagating to the parent modal.
2026-03-27 18:31:58 -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
Alex Gleason 3c54cd27fe Fix package-lock name 2026-03-27 15:41:39 -05:00
filemon c054bc7bc7 Merge branch 'main' into feat-blobbi 2026-03-27 01:25:27 -03:00
Alex Gleason c46e7b98e0 npm audit fix 2026-03-26 23:22:21 -05:00
Alex Gleason 58a5c470bd release: v2.1.0 2026-03-26 23:14:03 -05: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
Alex Gleason cbbb576b26 Add release system with semver versioning, changelog, and release skill
- Switch from CalVer (date+SHA) to semantic versioning starting at v2.0.0
- Create release skill (.agents/skills/release/) with full AI-guided release workflow
- Add CHANGELOG.md with initial 2.0.0 entry
- Update CI tag regex to match semver tags (v2.0.0 instead of v2026.03.24-sha)
- Extract changelog content into GitLab release descriptions
- Update Android versionName to 2.0.0 in build.gradle
- Update iOS MARKETING_VERSION to 2.0.0 in pbxproj
- Expose VERSION (semver) and BUILD_DATE (ISO 8601) as build-time constants
- Display version and build date in Settings page footer
- Remove npm release script (releases are now done via the AI skill)
2026-03-26 21:15:35 -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 264358c223 Upgrade @nostrify/nostrify 0.50.5 -> 0.51.0 and @nostrify/react 0.3.0 -> 0.3.1
Includes NRelay1 AUTH fix for correct NIP-42 challenge handling.
2026-03-25 01:37:07 -05:00
filemon 6a7c037ea8 feat(blobbi): implement real item use system for companion falling items
- Add BlobbiActionsContext to bridge companion UI with item use functionality
- Create useCompanionItemUse hook with category-to-action mapping (food→feed, toy→play, etc.)
- Update HangingItems with async onItemUse callback and success/failure handling
- Wire BlobbiCompanionLayer to use context-provided item actions
- Provide BlobbiActionsProvider in BlobbiPage so items actually update stats
- Items only disappear after successful use, stay on screen if use fails
2026-03-24 21:57:56 -03:00
filemon 2414441efa Merge branch 'main' into feat-blobbi 2026-03-24 21:32:47 -03:00
Alex Gleason 0666278a58 refactor: use @nostrify/react@0.3.0 for client-initiated NIP-46
Replace inline nostrconnect:// protocol logic with NLogin.fromNostrConnect(),
generateNostrConnectParams(), and generateNostrConnectURI() from upstream
@nostrify/react. Removes ~130 lines of code that is now in the library.
2026-03-24 16:21:00 -05:00
filemon e3412fac46 Merge branch 'main' into feat-blobbi 2026-03-24 12:20:40 -03:00
Chad Curtis 9ef6f085a0 Harsher arc curves and move bottom nav items up 2026-03-23 22:40:31 -05:00
Alex Gleason ca1b055dad Add iOS platform support with Capacitor and remote build script
- Add @capacitor/ios dependency and iOS Capacitor platform
- Configure capacitor.config.ts with iOS settings (scheme, background color, content inset)
- Add scripts/build-ios.sh for building iOS over SSH on Mac Mini (orcus.lan)
- Script supports simulator, device, archive, and open-in-Xcode modes
2026-03-23 20:27:13 -05:00
filemon 974cdcccc9 Merge branch 'main' into feat-blobbi 2026-03-23 10:58:25 -03:00
Dirk Rost c58c2f52a0 Revert NIP-46 workaround, bump @nostrify/react to 0.2.31 2026-03-22 23:27:46 +00:00
Alex Gleason 98b254e296 Upgrade @nostrify/nostrify to 0.50.5 and @nostrify/react to 0.2.30 2026-03-21 20:35:01 -05:00
filemon b51535bfa0 feat(blobbi): implement Blobbi Photo (Polaroid) feature
Add the ability to take polaroid-style photos of Blobbis and share them:

- Add lookMode prop to Blobbi rendering system:
  - 'follow-pointer': Eyes track mouse cursor (default, existing behavior)
  - 'forward': Eyes look straight ahead (for photos/export)
  - Updated useBlobbiEyes, BlobbiBabyVisual, BlobbiAdultVisual, BlobbiStageVisual

- Create BlobbiPolaroidCard component:
  - Classic polaroid-style frame with white background and shadow
  - Soft gradient background for photo area
  - Caption area with Blobbi name, stage, and date
  - Fixed dimensions (320x400) for consistent export
  - Built with HTML+CSS (not canvas) for easy customization

- Create BlobbiPhotoModal component:
  - Opens from 'Take a Photo' button on BlobbiPage
  - Shows polaroid preview with Blobbi looking forward
  - Download button: exports as PNG using html-to-image
  - Post button: uploads to Blossom and creates kind 1 note
  - Clean, minimal UI focused on the photo

- Wire up to BlobbiPage:
  - Photo modal state and handler
  - Connected to floating 'Take a Photo' action button

Dependencies:
- Added html-to-image for DOM-to-PNG conversion
2026-03-21 20:29:03 -03:00
filemon ffab9d3aaa feat(blobbi): add dev-only instant stage transition button
- Add 'Dev Hatch' button for eggs (bypasses incubation tasks)
- Add 'Dev Evolve' button for babies (bypasses evolution tasks)
- Button only appears in dev mode (import.meta.env.DEV)
- Uses dashed amber border style to clearly indicate dev-only
- Reuses existing onHatch/onEvolve callbacks
- No button shown for adults (no further transitions)
2026-03-20 18:15:30 -03:00
Alex Gleason b28f6f1336 npm audit fix 2026-03-20 04:15:49 -05:00
Alex Gleason 8ea370067b Add screenshot lightbox modal to Zapstore app events 2026-03-19 18:10:36 -05:00
Mary Kate c3a4d8be57 Fix sticky tabs not scrolling to top on click or switch 2026-03-17 19:46:44 +00:00
Alex Gleason 9dbf364f37 feat: generate sitemap.xml at build time via PUBLIC_URL env var
Add a Vite plugin that writes a sitemap.xml containing all static
routes to the build output. Enabled by setting the PUBLIC_URL
environment variable (e.g. PUBLIC_URL=https://ditto.pub) in .env
or the shell. When PUBLIC_URL is not set, no sitemap is generated.

Also fix a pre-existing LSP type error caused by importing Plugin
from 'vite' while defineConfig came from 'vitest/config' (which
bundles a different vite version). Now both come from 'vite'.
Add explicit 'import process' for node:process.
2026-03-16 15:22:23 -05:00
Chad Curtis 7034c54bbb Fix zapstore publish version by injecting tag into zapstore.yaml 2026-03-16 03:34:50 -05:00
Alex Gleason 80a2d3d846 Remove 'View on njump.me' from profile dropdown menu 2026-03-15 04:33:14 -05:00
Chad Curtis b76bf7b198 Condense notifications and add per-type notification preferences
- Group reactions, reposts, and zaps on the same post into a single condensed
  row with stacked actor avatars (up to 5 + overflow count); single-actor
  interactions use the original compact layout
- Deduplicate actors by pubkey within groups
- Sum zap totals across all actors in a zap group
- Add notificationPreferences per-type settings (reactions, reposts, zaps,
  mentions, comments, onlyFollowing) to EncryptedSettings and Zod schema
- Per-type kind toggles and onlyFollowing applied at relay query level (kinds
  array + authors filter), not client-side; query key includes kindsKey and
  authorsKey so preference changes trigger a fresh fetch
- Default push notifications to enabled
- Notification settings UI matches ContentSettings exactly: section headers
  with accent underline, p-4 wrapper, broken border rows (border-b on outer
  wrapper div), sub-section labels, w-[52px] switch column, KindBadges
- Add 'Only from people I follow' toggle under Filter sub-section
- Filter and push notification prefs also respected in useNativeNotifications
  web push subscription via stable ref
2026-03-14 19:06:31 -05:00