Commit Graph

65 Commits

Author SHA1 Message Date
mkfain f413d29fa1 Remove duplicate close X in mobile hamburger menu
The mobile nav drawer in TopNav has its own X button inside the panel
header, but SheetContent was also rendering the shadcn primitive close
button just outside the panel — two X buttons for the same sheet.

Add an opt-in `hideClose` prop to SheetContent and set it on the
TopNav drawer. Other Sheet consumers (MobileDrawer, etc.) keep the
default built-in close.
2026-05-17 20:30:45 -05:00
Alex Gleason 740fc1c63c Merge ditto/main into agora
Pulls in 387 commits from ditto/main while preserving Agora-specific
features. Where the two codebases diverged on the same concept, kept
the Agora side per project direction.

Kept Agora-specific:
- SparkWallet stack (over Ditto's nostr-derived Bitcoin wallet)
- Communities (NIP-72 + chat + members), Messages, Organizers,
  Actions, Verified, Appearance settings
- DMProviderWrapper, country/organizer moderation in NoteMoreMenu
- 'Agora' branding, pub.agora.app bundle ID, version 2.8.0
- Built-in theme system (src/themes.ts) only

Rejected from Ditto:
- All Blobbi virtual pet code (80+ files, route, provider, sidebar,
  kind labels, feed setting, NIP.md entries, CSS animations)
- Custom theme events (kinds 36767/16767) — ThemesPage, ThemeContent,
  active profile themes, theme snapshot recovery
- On-chain zaps (kind 8333) and the entire Bitcoin wallet implementation
  (useBitcoinWallet, bitcoin-signers, BitcoinContentHeader,
  bitcoinjs-lib / @bitcoinerlab/secp256k1 / ecpair / tiny-secp256k1)
- ZapSuccessScreen (depended on dropped bitcoin lib)

Pulled in from Ditto:
- .agents/skills/* (12 new specialized skills, slim AGENTS.md)
- @nostrify bumps to 0.52 / 0.6 / 0.37
- New routes/pages: Music, Podcasts, Videos, Vines, Wikipedia, Books,
  Bluesky, Archive, AIChat, Trends, Webxdc, Highlights, Decks, Emojis,
  Development, Treasures, Colors, Packs
- Birdstar feed integration (kinds 2473, 12473, 30621)
- Wikipedia/Wikidata/Scryfall lookup in ExternalContentPage
- release-notes CI job + extract-release-notes.mjs script
- nsite:// URI handling in feed/sidebar
- iOS fastlane setup
- src/lib/avatarShape.ts + Avatar shape prop (kept for new Music/People
  components that depend on it)

Preserved Agora's ABSOLUTE 'NEVER COMMIT' rule at the top of AGENTS.md
and dropped Ditto's contradicting 'Commit at the end of every task'
section.

Validation: npm run test passes (tsc, eslint, 40/40 vitest, vite build).
2026-05-13 18:35:03 -05:00
lemon c798e2a53e Refine community member UI 2026-05-11 22:20:50 -07:00
lemon 1873823b4c Portal tooltip overlays above sidebars 2026-05-11 11:12:13 -07:00
sam e12716722a remove shape stuff 2026-05-11 14:49:11 +07:00
Alex Gleason cc702027b0 Add native haptic feedback to all key interactions
Install @capacitor/haptics and add a centralized haptics utility
(src/lib/haptics.ts) that uses the native taptic engine on iOS/Android
and falls back to navigator.vibrate() on web.

Haptics added to:
- Switch component (covers 36+ toggle switches app-wide)
- PullToRefresh threshold (covers 15+ pages)
- MobileBottomNav tab taps
- ReactionButton (like/unlike, double-click heart)
- RepostMenu (repost/undo repost)
- ZapDialog button press + payment success (NWC and WebLN)
- FollowButton and ProfilePage follow toggle
- ComposeBox (post, voice message, and poll publish success)
- NoteMoreMenu (bookmark, pin, mute)
- VinesFeedPage reaction and repost buttons
- ProfileReactionButton and ExternalReactionButton
- NoteCard share button
- BlobbiRoomShell swipe navigation

Replaces raw navigator.vibrate() calls in GameControls and
SendAnimation with the new cross-platform haptics utility, fixing
haptic feedback on iOS where the Vibration API is not available.
2026-04-14 11:06:18 -05:00
Alex Gleason 357ba7d8c8 fix: migrate to SystemBars API for Android 16+ safe area inset support
Android 16 (API 36) enforces edge-to-edge rendering unconditionally,
breaking @capacitor/status-bar's setOverlaysWebView and setBackgroundColor.
Additionally, a Chromium bug (<140) causes env(safe-area-inset-*) to report
0 in some Android WebViews.

- Replace @capacitor/status-bar with SystemBars from @capacitor/core 8+
- Enable insetsHandling: 'css' in capacitor.config.ts so the SystemBars
  plugin injects --safe-area-inset-* CSS variables on Android
- Update all safe area CSS utilities and inline styles to use
  var(--safe-area-inset-*, env(safe-area-inset-*, 0px)) fallback pattern
- Remove @capacitor/status-bar dependency (no longer needed)
2026-04-11 14:47:15 -05:00
Alex Gleason 126dce1dfc Surface account deletion as 'Delete Account' for App Store compliance
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.
2026-04-10 16:44:35 -05:00
Chad Curtis 0c29506402 Fix all 50 ESLint warnings by extracting non-component exports and adding missing deps
- Extract utility functions from component files into dedicated modules
  to fix react-refresh/only-export-components warnings:
  - parseBadgeDefinition -> src/lib/parseBadgeDefinition.ts
  - parseProfileBadges -> src/lib/parseProfileBadges.ts
  - getColors, paletteToTheme -> src/lib/colorMomentUtils.ts
  - parseDimToAspectRatio, eventToMediaItem -> src/lib/mediaUtils.ts
  - isAudioUrl, isImageUrl, isVideoUrl -> src/lib/mediaTypeDetection.ts
  - buildKindOptions, parseSelectedKinds -> src/lib/feedFilterUtils.ts
  - useVideoThumbnail -> src/hooks/useVideoThumbnail.ts
  - useEnvelopeDimensions -> src/hooks/useEnvelopeDimensions.ts
  - usePortalContainer -> src/hooks/usePortalContainer.ts
  - useAudioPlayer -> src/contexts/audioPlayerContextDef.ts
  - SubHeaderBar context/hooks -> src/components/SubHeaderBarContext.ts
  - EmotionDev hooks -> src/blobbi/dev/useEmotionDev.ts
  - BlobbiActions context def -> BlobbiActionsContextDef.ts

- Remove export from internal-only functions (useEventComments,
  parseEmojiPack, useScrollCarets, formatEffectSummary, getSortedEffectEntries)

- Fix react-hooks/exhaustive-deps warnings by adding missing dependencies
  to useEffect/useCallback/useMemo hooks across 14 files

- Fix logical expression dependency warnings by wrapping conditional
  values (tasks, pubkeys, authorPubkeys) in useMemo

- Move module-level constants (CORE_TAB_IDS, CORE_TAB_LABELS,
  DEFAULT_TAB_LABELS) out of ProfilePage component body

- Reorder usePushNotifications hooks so syncPreferences is defined
  before enable to fix block-scoped variable error
2026-04-05 11:57:31 -05:00
Chad Curtis 42832b72e3 Revert dialog fly-up on mobile keyboard open
The keyboard-aware repositioning of dialogs was too aggressive and broken.
Removes the CSS rule, dialog-keyboard-aware class, and global keyboard
detector mount. The useKeyboardVisible hook is preserved for ArticleEditor.
2026-04-02 18:20:56 -05:00
Chad Curtis ad604eae68 Improve dialog UX on mobile: rounded corners, button spacing, keyboard awareness
- Add rounded-xl to Dialog and AlertDialog (was sm:rounded-lg only)
- Add consistent gap-2 to footer buttons on mobile (was no gap)
- Use w-[calc(100%-2rem)] for mobile side margins
- Push dialogs to top of viewport only when keyboard is visible via
  .keyboard-visible class on <html>, toggled by useKeyboardVisible
- Mount useKeyboardVisible globally in MainLayout so the class is
  always available for CSS-only consumers
2026-04-02 05:10:07 -05:00
Alex Gleason 02231ea1f9 Fix avatar shape flash by computing mask URL synchronously
The Avatar component was initializing maskUrl as '' and loading it in a
useEffect. Since hasCustomShape was true immediately, rounded-full was
removed on the first render, but the mask wasn't applied until after the
effect fired — causing a visible square flash for one frame.

getAvatarMaskUrl is already synchronous (renders emoji to canvas, caches
the data-URL), so compute it inline during render instead of deferring
to an effect. The mask is now applied on the very first paint.
2026-03-29 17:47:57 -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 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
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 12d578ff57 Improve bundle chunking: lazy-load emoji picker, markdown, and remove runtime tailwind config
- Hardcode md breakpoint in useIsMobile and toaster to eliminate runtime
  import of tailwind.config (was pulling in tailwindcss, postcss-selector-parser,
  and plugin code ~100KB)
- Lazy-load EmojiPicker in ComposeBox (emoji-mart + data ~500KB deferred)
- Dynamic import webxdcMeta.ts (smol-toml + fflate only loaded for .xdc uploads)
- Lazy-load ArticleContent, PullRequestCard, CustomNipCard in NoteCard and
  PostDetailPage (react-markdown + unified pipeline ~147KB deferred)
- Consolidate 60+ lucide-react icon micro-chunks into a single chunk via
  manualChunks, reducing HTTP request overhead
- ReplyComposeModal chunk: 808KB -> 296KB (-63%)
- JS file count: 226 -> 181 (-45 files)
2026-03-27 23:44:20 -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
Lemon 7bfab65042 Fix toast swipe direction to match entry direction on mobile
On mobile, toasts enter from the top but previously could only be swiped
right to dismiss. Now swipe direction is responsive: swipe up on mobile
(top-positioned), swipe right on desktop (bottom-right positioned). Exit
animations also match the swipe direction at each breakpoint.
2026-03-27 15:13:43 -07: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 e3412fac46 Merge branch 'main' into feat-blobbi 2026-03-24 12:20:40 -03:00
Lemon 6e9c971dd0 Extend drawer background image into the vertical arc
Moves the arc from the generic Sheet component into MobileDrawer
so it can inherit the theme background image. Uses clip-path
ellipse on an HTML div instead of SVG fill, with the same
bg-background/70 overlay applied when a background image is set.
2026-03-22 23:33:06 -07:00
Lemon cf8e60aaa1 Make drawer arc more dramatic and match sidebar background
Increases the arc width from 20px to 36px with a deeper curve,
and changes fill from background/80 to solid background to
match the drawer's actual background color.
2026-03-22 23:33:06 -07:00
Lemon 893a7dfb8a Add vertical semi-ellipse arc to left-side drawer edge
Removes the flat right border from the left sheet variant and
adds an SVG arc that curves outward along the right edge,
matching the curved styling used on the horizontal nav bars.
2026-03-22 23:33:06 -07:00
Lemon a90191ac61 Add decorative semi-ellipse arc to right edge of mobile drawer
Replaces the flat right border with an SVG arc that curves
outward along the full height of the drawer, matching the
curved design language used on the nav bars.
2026-03-22 23:33:06 -07:00
DanConwayDev b4d3c4833c feat: remote signer UX improvements for Amber/NIP-46 users on Android
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.
2026-03-20 17:22:37 +00:00
filemon 96356eb804 fix: render Blobbi masks to PNG via canvas for reliable CSS mask-image
CSS mask-image with SVG data URLs doesn't work reliably for complex SVGs
with transforms in some browsers. The picker preview works because it renders
inline SVG directly, but the avatar mask-image was failing for shapes like
droppi, flammi, leafy, mushie, owli, rocky, and rosey.

Changes:
- Rewrite getBlobbiMaskUrl() to render SVG to canvas and export PNG
- Use Blob URL for SVG loading (more reliable than data URL)
- Add async mask generation with proper caching and deduplication
- Update Avatar component to load masks asynchronously via useEffect
- Add getAvatarMaskUrlAsync() for async mask URL retrieval

The picker preview continues to use inline SVG (which works fine),
while the avatar mask now uses rasterized PNG (which works everywhere).
2026-03-18 10:36:27 -03:00
filemon d962d7952b fix: remove hardcoded white stroke from catti tail and fix avatar mask updates
1. Remove stroke="white" from catti shape - let the styling apply colors
2. Fix Avatar component to properly update mask when shape changes:
   - Compute maskUrl outside useMemo so it's always fresh
   - Use maskUrl directly in dependencies instead of shape string
   - This ensures the mask updates immediately when selecting a new shape
2026-03-18 10:21:39 -03:00
filemon a7c29c4a85 feat: add Blobbi shapes as avatar masks
New feature allowing users to select Blobbi character silhouettes as
avatar masks, in addition to existing emoji shapes.

New files:
- src/lib/blobbiShapes.ts: Shape definitions with SVG paths for all
  Blobbi forms (egg, baby, 16 adults)
- src/components/BlobbiShapePicker.tsx: Grid picker with category tabs

Changes:
- Extended avatarShape.ts to support 'blobbi:' prefixed shape values
- Added getAvatarMaskUrl() unified function for both shape types
- Updated Avatar component to render Blobbi masks
- Added tabbed UI in ProfileCard (Emoji/Blobbi tabs)
- Renamed emojiAvatarBorderStyle to shapedAvatarBorderStyle

Shape format: 'blobbi:<id>' (e.g., 'blobbi:baby', 'blobbi:catti')
Stored in kind-0 metadata as 'shape' property, same as emojis.

Available shapes:
- Egg (simple egg silhouette)
- Baby Blobbi (water droplet)
- Adults: catti, owli, froggi, droppi, flammi, crysti, cloudi,
  mushie, starri, pandi, cacti, breezy, leafy, rocky, rosey, bloomi
2026-03-17 12:32:46 -03:00
Alex Gleason 10bb16abfb Clean up avatar shape code: remove magic strings, type casts, and inconsistencies
- avatar.tsx: consolidate to single isEmojiShape boolean, fix AvatarFallback using same logic as Avatar
- avatarShape.ts: accept NostrMetadata directly in getAvatarShape (no cast needed)
- Remove 'as Record<string, unknown>' casts from all ~50 call sites
- Replace 'circle' magic string with empty string in form defaults and parseShape
- Use isValidAvatarShape instead of string comparison in save logic
- ProfileCard: extract IIFE overlay style into useMemo, use isEmojiShape throughout
2026-03-13 21:14:03 -05:00
Alex Gleason b661e9be9b Remove predefined shape dead code: delete AvatarShapePicker, UserAvatar, and geometric shape utilities 2026-03-13 20:57:09 -05:00
Alex Gleason 55e8075542 Support emoji as avatar shape: use any emoji as a mask over the avatar
Extend the kind-0 'shape' field to accept any emoji string in addition to
the predefined geometric shapes (circle, triangle, hexagon, star, etc.).
When an emoji is chosen, its native OS glyph is rendered onto a canvas,
the alpha channel extracted as a PNG mask, and applied via CSS mask-image.

Implementation:
- Widen AvatarShape type to accept emoji strings alongside predefined names
- isEmoji() detects any short non-ASCII string (avoids fragile Unicode regex)
- getEmojiMaskUrl() renders emoji at 512px, crops to tight bounding box
  (with alpha threshold to ignore shadows/glows), squares the crop, scales
  to 256px output, converts to white+alpha mask PNG. Cached per emoji.
- Avatar component applies mask-image for emoji, clip-path for geometric
- ProfileCard uses ring-4 instead of border-4 for emoji shapes to avoid
  mask/content misalignment (border is inside the element; ring is outside)
- AvatarShapePicker adds emoji-mart picker in a popover
- Form schemas use z.string() to accommodate both predefined and emoji values
- NIP.md documents emoji shape support
2026-03-13 20:27:14 -05:00
Alex Gleason 0781b1a87c Merge origin/main and re-apply avatar shape changes to conflicted files 2026-03-13 17:23:30 -05:00
Alex Gleason 3b79b384e5 Add avatar shapes: users can set a shape (circle, triangle, hexagon, star, etc.) for their avatar via kind 0 metadata
- New 'shape' property on kind 0 profile metadata with 7 predefined shapes:
  circle, triangle, inverted-triangle, hexagon, star, inverted-star, hexagram
- Avatar component updated with clip-path support for non-circle shapes
- Visual shape picker added to both EditProfileForm and ProfileSettings
- Shape applied across all 49 avatar render sites in the app
- New UserAvatar wrapper component for future simplified avatar rendering
- Unknown shape values gracefully fall back to circle (forward compatible)
2026-03-13 16:14:40 -05:00
Lemon 7e19a7f773 New Theme Modal Mobile Fixes 2026-03-13 20:33:23 +00:00
Mary Kate Fain b60b2c131f Add help tips to more UI surfaces and fix search filter dropdown z-index
- Add 'How do I report harmful content?' help tip to Muted Content and Sensitive Content sections
- Add 'For You page' help tip to Home Feed settings header
- Move wallet help tip from NWC section to Wallet page header
- Add 'What are zaps?' help tip to Zap dialog title
- Add 'Mastodon/Bluesky comparison' help tip to Platform filter in search
- Fix Select dropdown z-index (250->270) so dropdowns render above filter popover (260)
2026-03-07 20:14:17 -06:00
Mary Kate Fain b045fb53b9 Fix color pickers and font selector rendering behind theme edit dialog 2026-03-07 16:57:31 -06:00
Alex Gleason 60e3ead6ed Merge branch 'main' of gitlab.com:soapbox-pub/ditto 2026-03-07 11:52:48 -06:00
Alex Gleason bed84c6285 Fix iOS Safari auto-zoom on input focus by ensuring 16px minimum font size on mobile 2026-03-07 11:42:54 -06:00
Lemon 5a0bc346b7 fix: make emoji/GIF picker dialog dismiss on iOS tap-outside
- Raised dialog z-index from z-[150] to z-[250] so the overlay sits above
  CommentsSheet's backdrop (z-[200]) and receives touch events
- Removed stopPropagation from DialogOverlay/DialogContent onClick handlers
  which was preventing Radix DismissableLayer's deferred click listener from
  reaching document on iOS Safari

On iOS touch, Radix registers a one-time click listener on document after
pointerdown. The stopPropagation was intercepting that click before it could
reach document, so the dismiss callback never fired. Z-index stacking now
handles isolation between the dialog and the CommentsSheet backdrop.
2026-03-06 23:16:30 -08:00
Lemon 54c4d7e47c Fix GIF picker scroll inside dialogs by portaling into modal container
Radix Dialog's RemoveScroll blocks wheel events on elements outside the
Dialog's DOM tree. The GIF picker Popover was portaling to document.body,
placing it outside the RemoveScroll boundary. Trackpad scrolling was
blocked while scrollbar dragging still worked.

Added PortalContainerContext so PopoverContent can portal into the modal
element instead of document.body when rendered inside a dialog/modal.
2026-03-06 23:16:30 -08:00
Mary Kate Fain ff3d99f205 Fix search filter dropdown z-index rendering behind popover
SelectContent used z-50 while PopoverContent used z-[200]. Both are
portaled to the body, so when a Select inside a Popover is opened,
the Select dropdown rendered behind the Popover panel. Raised
SelectContent to z-[250] so it always appears above popovers.

Closes #55
2026-03-04 23:56:04 -06:00
Derek Ross 3eaee4d560 fix: emoji/gif picker hidden behind modal dialogs
Bump z-index from z-50 to z-[200] on PopoverContent, TooltipContent,
and DropdownMenuContent so they render above dialog overlays (z-[150]).
2026-03-03 11:20:09 -05:00
Chad Curtis e82c4642c9 Portal HoverCardContent to document body so it escapes overflow-hidden containers 2026-03-03 05:42:08 -06:00
Chad Curtis 64c9936014 fix vine comments and toast visibility
- ComposeBox: invalidate the correct 'event-comments' cache key after
  posting a NIP-22 comment so CommentsSheet refreshes immediately
- toast: raise z-index to 300 so it renders above the CommentsSheet
  backdrop blur (which sits at z-200)
2026-03-03 00:45:31 -06:00
Chad Curtis 771b3df9d8 fix lightbox: stable image keys prevent reload, dialog z-index above lightbox, media tab auto-open 2026-03-02 23:56:06 -06:00
Alex Gleason dd2f7af3d3 Don't put black overlay over color picker items 2026-02-26 16:22:39 -06:00
Alex Gleason 1a17a3a068 Show pencil icon on color swatches always, not just on hover 2026-02-26 11:59:13 -06:00
Alex Gleason 970c0119b1 Replace hint text with pencil overlay on color swatches for intuitive editability 2026-02-26 11:53:59 -06:00
Alex Gleason 1c8761440c Improve theme color editor discoverability with circle swatches and hint text 2026-02-26 11:51:15 -06:00
Chad Curtis 01e190476b fix: theme page mobile layout, remove white from quick theme toggle, use SwatchBook icon for theme nav item 2026-02-26 06:02:39 -06:00