Commit Graph

2491 Commits

Author SHA1 Message Date
Chad Curtis e951a3b00a Fix key download on Android: save to Documents instead of share sheet 2026-03-28 21:47:47 -05:00
Chad Curtis 62b5aab753 Disable DM handler background processing 2026-03-28 21:34:06 -05:00
Alex Gleason 7b307ffe22 Replace window.open() calls with Capacitor-aware openUrl()
window.open() and target="_blank" silently fail inside WKWebView on
iOS. Replace all programmatic window.open() calls with the openUrl()
utility from src/lib/downloadFile.ts, which uses the native share sheet
on Capacitor and falls back to window.open() on web.

Fixed in: ZapDialog, TasksPanel, HatchTasksPanel, PullRequestCard,
CustomNipCard, GitRepoCard, PatchCard.

The middle-click handler in useOpenPost is left as-is since middle-click
is a web-only interaction with no equivalent on mobile.
2026-03-28 21:25:58 -05:00
Mary Kate Fain 5ae233ff62 Add dedicated photo upload flow for NIP-68 kind 20 events
Enable the floating compose button on the photos page with a camera
icon. Clicking it opens a new PhotoComposeModal with image upload,
title, caption, alt text, and content warning support. Publishes
kind 20 picture events per the NIP-68 specification.
2026-03-28 16:30:21 -05:00
Mary Kate 19400a78e5 Merge branch 'fix/profile-tab-form-reset' into 'main'
Fix custom profile tab form retaining fields from previous tab

Closes #196

See merge request soapbox-pub/ditto!134
2026-03-28 21:08:25 +00:00
Mary Kate Fain 497d6979d0 Fix custom profile tab form retaining fields from previous tab
The ProfileTabEditModal reset form state inside a handleOpenChange
callback, but Radix Dialog does not fire onOpenChange when opened
programmatically via the `open` prop. This meant that when a parent
component set `open={true}` (e.g. after clicking 'Add custom tab'),
the reset logic never ran and the form kept stale values from the
last edit session.

Replace the handleOpenChange reset with a useEffect that triggers
whenever `open` transitions to true, ensuring the form always
initializes from the current `tab` prop (or clean defaults for a
new tab).

Closes #196
2026-03-28 16:01:17 -05:00
Mary Kate Fain 74b84eb5ac Fix badge notifications not being clickable
Wrap badge cards in BadgeAwardNotification and BadgeAwardNotificationGroup
with Link components that navigate to the badge detail page via naddr1
encoded URLs. Both single and grouped badge notifications now link to
the badge definition page when clicked.

Closes #201
2026-03-28 13:38:11 -05:00
Mary Kate bfc864cc7c Merge branch 'rename-vines-to-divines' into 'main'
Rename "Vines" to "Divines" in all user-facing strings

Closes #194

See merge request soapbox-pub/ditto!132
2026-03-28 18:12:28 +00: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
Mary Kate 503fed5fdb Merge branch 'changelog-footer-link' into 'main'
Add changelog link to footer section

Closes #203

See merge request soapbox-pub/ditto!131
2026-03-28 17:57:31 +00:00
Mary Kate Fain 32cb3eeba3 Add changelog link to footer section
Closes #203
2026-03-28 12:51:42 -05:00
Mary Kate 7e49e85495 Merge branch 'fix/geocache-treasure-terminology' into 'main'
Fix inconsistent use of 'geocache' vs 'treasures' terminology

Closes #198

See merge request soapbox-pub/ditto!130
2026-03-28 17:49:44 +00:00
Mary Kate Fain c3d7984d7a Fix inconsistent use of 'geocache' vs 'treasures' terminology
Closes https://gitlab.com/soapbox-pub/ditto/-/work_items/198
2026-03-28 12:44:28 -05:00
Mary Kate Fain 83c1e9aa6c Fix double line under profile tabs in edit mode
Replace the flat h-1 indicator bar in SortableTabChip with the
SubHeaderBar arc-based active indicator, matching how TabButton works.
The flat bar was overlapping the ArcBackground border stroke, creating
a visible double line when editing profile tabs.
2026-03-28 12:29:38 -05:00
Chad Curtis 8a6cb02dc0 Convert blobbi audio from MP3 to M4A (AAC-LC 32kbps mono), enable R8 shrinking
Replace 36 MB of MP3 files with 4.6 MB of M4A (AAC-LC) files encoded
at 32kbps mono. M4A is required for iOS/Safari compatibility in
Capacitor's WKWebView.

Enable R8 minification and resource shrinking in the Android release
build to further reduce APK size. Add ProGuard rules to keep Capacitor
and OkHttp classes.
2026-03-28 11:35:49 -05:00
Alex Gleason 91237c252c Sanitize Blobbi SVG output with DOMPurify before DOM injection
Add defense-in-depth sanitization at the output boundary of the Blobbi
SVG rendering pipeline. The upstream pipeline validates user inputs
(normalizeHexColor, instanceId regex), but 3000+ lines of regex-based
SVG string manipulation feed directly into dangerouslySetInnerHTML with
no structural guarantee that the output is safe.

sanitizeBlobbiSvg() uses DOMPurify with an allowlist tuned for the
Blobbi pipeline (gradients, clip paths, animations, @keyframes) while
blocking scripts, event handlers, foreignObject, href, and other
dangerous constructs.
2026-03-28 11:33:10 -05:00
Chad Curtis 9056b43696 Highlight flushed posts, fix new-posts pill positioning, fix desktop tab gap
- 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
2026-03-28 10:12:11 -05:00
Chad Curtis cdf54e9eff Fix 'new posts' button on search page not loading posts
The button only called window.scrollTo() and relied on the scroll event
listener to auto-flush the stream buffer. This failed when smooth
scrolling didn't fire reliable scroll events (especially on mobile/
Capacitor WebView). Now explicitly calls flushStreamBuffer() on click.
2026-03-28 09:51:30 -05:00
Chad Curtis 7a49e9646c Bypass nudge for encrypt and decrypt, remove phase-transition toast
Encrypt and decrypt operations now call the signer directly without
nudge/timeout/retry wrapping. The sign operation already provides
the user-facing nudge when approval is needed, so the encrypt nudge
was redundant noise. Phase-transition toast and related constants
removed as dead code.
2026-03-28 09:43:43 -05:00
Chad Curtis 2189f5e7c4 Fix MobileTopBar double-opacity: remove bg from header, use dedicated safe-area fill
The header had bg-background/85 plus the ArcBackground SVG fill-background/85
stacking to ~98% opacity. Now the safe-area padding zone gets a single-layer
bg-background/85 fill div (same pattern as pinned SubHeaderBar), and the
ArcBackground provides the only fill for the content area.
2026-03-28 09:39:09 -05:00
Chad Curtis 2822b4c159 Remove decrypt nudge, fix pinned tab safe area fill
- Decrypt operations now bypass signerWithNudge entirely (no nudge toast)
- Pinned SubHeaderBar safe area uses a separate fill div matching
  MobileTopBar's bg-background/85, avoiding double-opacity stacking
  with the ArcBackground SVG below
2026-03-28 09:37:28 -05:00
Chad Curtis 3dd2591709 Fix pinned tab arc, signer toast spam, new-posts pill position, toast swipe
- Pinned SubHeaderBar uses safe-area-inset-top (top offset) instead of
  safe-area-top (padding) so the arc stays flush with the tab content
- Throttle signer nudge toasts (8s cooldown) to prevent rapid-fire storm
  when relay connection is unstable
- New posts pill fades out when nav hides instead of translating, avoiding
  it floating in the safe area zone
- Signer toasts use finite duration (120s) so Radix swipe-to-dismiss works
- Lower toast swipe threshold from 50px to 30px for easier dismissal
2026-03-28 09:32:08 -05:00
Chad Curtis ab2145ffe9 Fix mobile UX: sticky safe area, page padding, stream buffering, media CW
- SubHeaderBar pinned mode adds safe-area-top padding when nav is hidden
- Increase signer nudge delay to 10s for decrypt ops (reduces false triggers on Amber)
- Add arc overhang spacer to Search, Notifications, and Profile pages
- Add PageHeader to Search page for consistent top-level layout
- Buffer streamed posts when user is scrolled down to prevent scroll jumps
- Show 'N new posts' pill that tracks SubHeaderBar position and nav state
- MediaCollage respects NIP-36 content warnings (blur/hide/show policy)
- Normalize main element classes across Profile and Notifications pages
2026-03-28 09:16:00 -05:00
Chad Curtis 586e103161 Merge branch 'fix/zap-primal-users' into 'main'
Fixing zap Primal users without error

See merge request soapbox-pub/ditto!110
2026-03-28 12:55:40 +00:00
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 e6a2bdc65f Clean up nsec paste guard toast wording for clarity 2026-03-28 07:37:59 -05:00
Chad Curtis c9205adbab Merge branch 'fix/nsec-paste-guard' into 'main'
feat: block nsec private key paste with warning

See merge request soapbox-pub/ditto!101
2026-03-28 12:37:28 +00:00
Chad Curtis 29d56daab3 fix: relay page arc header with inline NIP-11 info panel
- Use PageHeader + SubHeaderBar arc format matching other feed pages
- Add arc overhang spacer for consistent feed padding
- Move NIP-11 relay info into an inline expanding panel (maxHeight transition)
- Info toggle button in PageHeader top-right corner
- Accept string | undefined in useRelayInfo hook signature
- Register useLayoutOptions({ hasSubHeader: true }) for mobile nav
2026-03-28 07:28:32 -05:00
Chad Curtis 4d7ac5e619 Merge branch 'feat/relay-info' into 'main'
Adding NIP-11 relay information on network settings page

See merge request soapbox-pub/ditto!106
2026-03-28 12:11:44 +00:00
Chad Curtis fb3686fef4 Merge branch 'fix/embedded-note-link-preview' into 'main'
Show link preview cards in quoted posts

See merge request soapbox-pub/ditto!107
2026-03-28 12:05:15 +00:00
Chad Curtis fd90f90cbb Restore client-side reply count seeding with correct nip85-event-stats cache key 2026-03-28 06:59:01 -05:00
Chad Curtis b6cee104b9 Filter Mentions tab by literal nostr: URI mentions in content 2026-03-28 06:49:19 -05:00
Chad Curtis 5c6df95734 Fix review issues: remove duplicate subscription, fix zapAmount regression, remove dead cache seeding 2026-03-28 06:40:58 -05:00
Chad Curtis 8941aca968 Merge branch 'main' of gitlab.com:soapbox-pub/ditto into fix/notifications-136
# Conflicts:
#	src/hooks/useHasUnreadNotifications.ts
#	src/hooks/useTrending.ts
#	src/pages/NotificationsPage.tsx
2026-03-28 06:32:45 -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 530c0681d0 Merge branch 'main' of gitlab.com:soapbox-pub/ditto into fix/emoji-picker-autofocus
# Conflicts:
#	src/components/EmojiPicker.tsx
2026-03-28 06:01: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 e1fa43c9f0 fix: add arc overhang spacer to BadgesPage to match other feeds 2026-03-28 05:48:07 -05:00
Chad Curtis ccb0d9ec71 fix: add background to PageSkeleton so it matches feed appearance 2026-03-28 05:46:41 -05:00
Chad Curtis eca4a5ba77 fix: PageHeader padding, opacity, and BooksPage search bar overlap
- Equal vertical padding (py-4) on PageHeader for balanced spacing
- Add bg-background/85 to PageHeader to match SubHeaderBar opacity
- Add top padding to BookSearchBar so it clears the arc overhang
2026-03-28 05:39:48 -05: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
Chad Curtis 28f1e2b517 Merge branch 'main' of gitlab.com:soapbox-pub/ditto into fix/feed-header-ordering 2026-03-28 05:14:26 -05:00
Chad Curtis 21374b2cb4 Make vines desktop immersive like mobile, with floating tab bar and back button 2026-03-28 05:13:21 -05:00
Chad Curtis ada87468cc Merge branch 'main' of gitlab.com:soapbox-pub/ditto into fix/feed-header-ordering
# Conflicts:
#	src/pages/BadgesPage.tsx
2026-03-28 05:00:19 -05:00
Chad Curtis aa257b34ec Fix bottom nav flashing during vine swipe transitions
Remove the activeVinePlaying reset on index change. The old card's
onPlayingChange is already undefined after re-render, and the new
card's autoplay fires onPlay directly, so the state stays consistent
through transitions without a brief false→true flash.
2026-03-28 04:43:52 -05:00
Chad Curtis c48e6c7123 Add safe area insets to vine card overlay UI
Offset the bottom info strip, action sidebar, and mute button by
env(safe-area-inset-bottom) so they clear the home indicator on
notch/island devices. Applied to both the live UI and loading
skeleton.
2026-03-28 04:43:14 -05:00
Chad Curtis 827bc4b836 Show bottom nav when vine is paused, hide during playback
Lift playing state from VineCard to VinesFeedPage via onPlayingChange
callback. hideBottomNav is now driven by whether the active vine is
playing, so users can navigate when paused. Reset playing state on
swipe so the nav briefly appears while the next vine loads. Remove
noArcs so the bottom nav renders with its normal arc appearance.
2026-03-28 04:41:40 -05:00
Chad Curtis c7d115f873 Make vines page fully immersive on mobile
Hide the mobile top bar and bottom nav entirely on the vines page,
replacing them with a floating TikTok-style tab bar that overlays
directly on the video. The menu button (hamburger) is embedded in
the floating bar so users can still access navigation.

- Add hideTopBar and hideBottomNav layout options
- Add DrawerContext so pages can open the mobile drawer directly
- Move floating tab bar outside the scroll container to fix
  IntersectionObserver index tracking (autoplay on next video)
- Simplify vine-slide-height CSS to use full 100dvh
2026-03-28 04:36:41 -05:00
Alex Gleason 45c585a27d fix: add Vines feed section header with info link to divine.video
Fixes #154
2026-03-28 04:20:30 -05:00