Commit Graph

69 Commits

Author SHA1 Message Date
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
Chad Curtis 1e232e6a9e Blobbi hatching ceremony: immersive egg-to-blobbi experience with redesigned care UI
Replaces the old onboarding tour with a full hatching ceremony featuring golden aura,
sparkles, typewriter dialog, and fade-to-white reveal. Redesigns the BlobbiPage with
curved arc stats, floating action bubbles, overlay drawer tabs, and responsive layout.
Adds companion pill button, simplified photo modal, and egg animation styles.
Removes the old tour system (FirstHatchTour, tour hooks, tour types).
2026-04-04 16:49:51 -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
Chad Curtis fa34922cce refactor: harden article editor — encryption, mobile UX, deduplication, source toggle
- Encrypt drafts with NIP-44 via NIP-37 (kind 31234) instead of
  plaintext kind 30024
- Fix slug auto-generation overwriting manual edits
- Guard auto-save state setters against unmount
- Deduplicate save logic, load handlers, tag extraction, and types
  via shared ArticleFields/parseArticleEvent helpers
- Replace derived state (wordCount/readingTime) with useMemo
- Mobile UX: sticky toolbar, touch-friendly header image swap,
  adaptive tooltips (pointer:fine only), FAB bottom clearance,
  responsive editor min-height
- Editor placeholder: hide on focus, handle trailing whitespace
- Tighten editor padding and paragraph spacing
- Add raw markdown source toggle (Eye/EyeOff) in toolbar
- Shrink slug/tag fields, consistent sizing
2026-04-02 03:48:10 -05:00
Derek Ross e93c665123 feat: add in-app article editor with Milkdown WYSIWYG
Replace external Inkwell link with a built-in article creation experience.
Uses Milkdown editor with tabbed UI (Write/Details/Drafts) matching the
letters compose pattern, FAB publish button, relay+local draft support,
and kind 30023/30024 publishing.
2026-04-01 14:01:46 -04: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 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 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
Chad Curtis 2329458a84 Fix settings letters section, drawer background/z-index, and top nav scroll hide
- Remove letters section from settings page (accessible from letters page)
- Add background to letter editor drawer panel
- Fix drawer z-index so letter content doesn't bleed through
- Fix compose sheet SubHeaderBar top offset in overlay context
- Hide top bar and sub-header tabs together on scroll down
2026-03-28 00:36:07 -05:00
filemon c054bc7bc7 Merge branch 'main' into feat-blobbi 2026-03-27 01:25:27 -03: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 a2fa2a6b96 Letters: redesign inbox as Wii Mail-style envelope grid with modal detail view 2026-03-26 18:51:45 -05:00
Chad Curtis 628dd47772 Letters: send animation with envelope, wax seal, and Ditto logo 2026-03-26 17:35:31 -05:00
filemon e3412fac46 Merge branch 'main' into feat-blobbi 2026-03-24 12:20:40 -03:00
Chad Curtis 1d9e445d84 Fix arc bugs: revert top arc to upstream, remove top navbar arc, separate bottom nav overhang for harsher curve 2026-03-23 23:11:29 -05:00
Chad Curtis 9ef6f085a0 Harsher arc curves and move bottom nav items up 2026-03-23 22:40:31 -05:00
Lemon 6134786fe9 Add arc overhang clearance to mobile search sheet positioning 2026-03-22 23:39:13 -07:00
Lemon b09c78df92 Cleanup: migrate remaining pages from sticky headers, extract CSS custom properties
- Remove STICKY_HEADER_CLASS + backdrop-blur from TagFeedPage, ListDetailPage,
  RelayPage, and DomainFeedPage to match the arc-based header style
- Migrate ListDetailPage tab bar to SubHeaderBar
- Migrate ThemesPage header to use shared PageHeader component
- Extract --top-bar-height and --bottom-nav-height CSS custom properties in
  index.css, replacing hardcoded 2.5rem/2.75rem in all calc() expressions
- Document MobileDrawer DRAWER_BG_WIDTH constant (300px + 36px arc overhang)
- Remove unused STICKY_HEADER_CLASS import from ProfilePage
2026-03-22 23:35:56 -07:00
Lemon c452170242 Extend AI chat background behind bottom nav to prevent double opacity
Change ai-chat-height to span full viewport minus only the top bar,
with padding-bottom for the bottom nav. The bg-secondary/50 background
now extends behind the bottom nav arc, eliminating the opacity seam.
2026-03-22 23:33:06 -07:00
Lemon 0baab2521c Reduce mobile bottom nav height from h-14 (56px) to h-11 (44px)
Update all CSS utilities referencing bottom nav height (bottom-fab,
bottom-mobile-nav, pb-overscroll, ai-chat-height, livestream-height,
vine-slide-height) from 3.5rem to 2.75rem.
2026-03-22 23:33:06 -07:00
Lemon 87092f0cad Reduce mobile top bar height from h-12 (48px) to h-10 (40px)
Update all CSS utilities that reference the top bar height (top-mobile-bar,
-mt-mobile-bar, ai-chat-height, livestream-height, vine-slide-height) from
3rem to 2.5rem. Scale logo from 28px to 24px to fit.
2026-03-22 23:33:06 -07:00
Lemon 4441342bff Scope content area negative margin to mobile viewport only
Wraps the -mt-mobile-bar styles in a max-width: 899px media
query so the negative margin and padding only apply when the
mobile top bar is visible. Desktop layout is unaffected.
2026-03-22 23:33:06 -07:00
Lemon ed018ba9ec Extend content area behind header for consistent opacity
Removes the fixed backing layer approach. Instead, pulls the
content area up behind the mobile header with a negative margin
and compensating padding. The content's bg-background/85 now
extends behind the header at all scroll positions, giving the
same double-opacity look as the tab bar without any stacking
issues.
2026-03-22 23:33:06 -07:00
filemon 24aa80840c Merge branch 'main' into feat-blobbi 2026-03-21 19:24:47 -03:00
Alex Gleason d0ef3e2575 Add dramatic NIP-62 Request to Vanish display (kind 62)
Implement a visually striking display for kind 62 vanish events with
animated caution stripes, glitch effects, and a grand exit aesthetic.
Since the user has nuked their account, the npub is shown instead of
profile info. Supports both compact feed cards and full detail view
with comments and sharing.
2026-03-20 23:17:25 -05: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 c17883bdb8 feat: add natural blinking system for Blobbi eyes
- Random blink intervals between 2-5 seconds for organic feel
- Blink animation: fast close (~80ms), pause (~100ms), slower open (~120ms)
- 20% chance for double blinks (extra polish)
- Uses scaleY transform combined with mouse tracking translate
- Easing functions: ease-in for close, ease-out for open
- Disabled when Blobbi is sleeping
- No CSS transitions - all animation via RAF for instant response
2026-03-17 11:42:40 -03:00
filemon 0b90b0206b fix: eliminate eye tracking lag with direct SVG transforms
- Remove CSS transitions from .blobbi-eye class (root cause of delay)
- Use SVG transform attribute instead of style.transform for reliable repaints
- Cache eye element references after mount with automatic refresh on SVG changes
- Hook now manages DOM directly without onUpdate callback
- Simplified visual components to just pass containerRef
2026-03-17 11:34:58 -03:00
filemon 4feb051177 fix: rewrite eye animation system for proper SVG transforms and mouse tracking
Root cause: The original implementation had two critical issues:
1. Grouping algorithm assumed highlights immediately followed pupils in SVG,
   but SVGs have all pupils first, then all highlights (proximity-based fix)
2. CSS transforms weren't working on SVG <g> elements without transform-box

Fixes:
- Rewrite pupil/highlight detection to use proximity-based grouping (15px radius)
- Add transform-box: fill-box and transform-origin: center inline styles
- Replace CSS keyframe animation with JavaScript-controlled transforms

New features:
- Natural idle behavior with random movement and pauses
- Mouse tracking when cursor is within 200px radius
- Smooth transitions between idle and tracking states
- Different delays for left/right eyes for organic feel

Implementation:
- useBlobbiEyes hook manages animation state and mouse tracking
- addEyeAnimation wraps pupil+highlight elements in <g class="blobbi-eye">
- Visual components apply transforms via DOM refs in useEffect
- CSS provides transition timing (.3s idle, .1s tracking)
2026-03-17 09:47:39 -03:00
filemon 27bce0d334 feat: add subtle eye movement animation for Blobbi baby and adult visuals
Add eye animation utility that:
- Detects pupil and highlight elements via gradient patterns and dark fills
- Wraps pupil+highlight elements in animated <g> groups
- Applies CSS keyframe animation for gentle wandering eye movement
- Uses different delays for left/right eyes for natural feel
- Only animates when awake (skips sleeping state)

Integrates animation into both BlobbiBabyVisual and BlobbiAdultVisual
components for a more lifelike appearance.
2026-03-16 21:23:24 -03:00
filemon d59ba03cc6 fix: sing reaction only starts when recording begins, adjust animation timing
- Add onRecordingStart/onRecordingStop callbacks to InlineSingCard
- Move singing reaction trigger from card open to actual recording start
- Reduce sing bounce animation movement (6px → 3px for baby, 4px → 2px for egg)
- Slow down sing bounce animation (0.4s → 0.5s for baby, 0.5s → 0.6s for egg)
- Change Record button label to Sing
2026-03-16 19:29:50 -03:00
filemon 04112110f7 polish: faster music animation timing and fix egg centering with music notes 2026-03-16 19:22:40 -03:00
filemon d835cb5e6a feat: add floating music notes and tune animation timing for Blobbi reactions 2026-03-16 19:10:20 -03:00
filemon 6e5a6b5d91 feat: reusable music/dance reaction system for all Blobbi stages
BREAKING: Egg no longer sways by default when animated=true.
Sway animation now requires explicit reaction state.

Changes:
- Remove default egg sway from animated prop in EggGraphic
- Add reaction prop to EggGraphic, BlobbiEggVisual, BlobbiBabyVisual, BlobbiStageVisual
- Add EggReactionState, BabyReactionState, BlobbiReaction types
- Wire blobbiReaction state from BlobbiPage to BlobbiStageVisual
- Add animate-blobbi-sway and animate-blobbi-bounce CSS animations
- Add animate-egg-bounce for singing reaction on eggs

Reaction states:
- idle: no animation (default)
- listening: gentle sway (music playing)
- swaying: gentle sway
- singing: bouncy animation (sing action active)
- happy: gentle sway

Trigger behavior:
- Play Music: listening reaction when audio plays
- Sing: singing reaction when card opens
- Close activity: returns to idle
2026-03-16 18:48:57 -03:00
Alex Gleason 0305a53116 Reduce bottom overscroll padding from 50vh to 10vh 2026-03-16 00:03:36 -05:00
Alex Gleason d7461e0488 Add bottom overscroll padding to center column for visual comfort and bottom bar clearance 2026-03-15 23:17:15 -05:00
Alex Gleason 71f9a6c354 Expand vine slides to fill screen when bottom nav hides on scroll
The vine-slide-height CSS class statically subtracted 3.5rem for the
bottom nav. Added a vine-slide-height-expanded class without that
subtraction, toggled by scroll direction so the video fills the full
viewport when the bottom nav slides away.
2026-03-14 01:18:08 -05:00
Alex Gleason 59311e6b2c Restore mobile bottom nav with scroll-to-hide behavior
Bring back the mobile bottom navigation bar with Home, Notifications, and
Search buttons. The nav slides out of view when scrolling down and reappears
on upward scroll, keeping the viewport uncluttered while reading. Search
retains the popover account search sheet for fast profile lookup without
navigating away. Updated CSS height calculations for full-screen pages
(AI chat, vines, livestream) and FAB positioning to account for the nav.
2026-03-13 22:47:17 -05:00
Alex Gleason 885425ec34 Add landing hero for logged-out homepage with theme showcase and trending tags
Replace the plain 'Join' CTA banner with an engaging first-impression
experience: logo + tagline, interactive theme swatches that transform
the page on click, and a trending hashtags strip — all above the
existing hot feed. Staggered fade-in animations add polish.
2026-03-07 13:58:39 -06:00
Alex Gleason 2e6d328335 Remove mobile bottom navigation bar
Delete MobileBottomNav component and all related code including the
noBottomSpacer layout option, bottom nav height spacer, and CSS
calculations that accounted for the bottom nav height.
2026-03-07 11:57:17 -06:00
Chad Curtis 7aaa3e2587 Add interactive profile editor with live card, image crop, and onboarding integration 2026-03-03 07:31:06 -06:00
Chad Curtis b200d5a84d fix: account for safe-area-inset-bottom in live stream chat height on PWA/APK 2026-03-03 05:51:02 -06:00
Chad Curtis efed412495 Fix AI chat height on desktop by using CSS class instead of inline style 2026-03-02 01:33:58 -06:00
Chad Curtis ede8aa28e0 fix(vines): correct mobile height for safe-area-inset and preload adjacent videos
- Add .vine-slide-height CSS utility that subtracts env(safe-area-inset-top/bottom) so slides don't bleed under the bottom nav on PWA/APK with home indicator
- Replace all hardcoded calc(100dvh-9.5rem) vine heights with the new utility
- Preload active video with 'auto', adjacent (±1) with 'metadata', and far-away cards with 'none' to speed up video playback on swipe without wasting mobile bandwidth
2026-03-01 13:28:01 -06:00
Chad Curtis 51e84ffa8f Add blinking eye icon to color moment Set as theme button
Replaces the SwatchBook icon with a small circular eye (using the palette
colors for iris/pupil ring) that blinks using espy's eyelid-blink animation
when tapped. The eyelid fills with the palette's midpoint color and carries
the EyeClosed lash icon at its edge, matching the interaction pattern from
espy's color picker.
2026-02-28 16:26:38 -06:00
Chad Curtis 5e826b0395 Magic sigil: hidden easter egg under settings, unlocks magic mouse on click 2026-02-28 04:07:44 -06:00
Alex Gleason 3e686d90d8 Style share-theme dialog with the user's custom theme colors 2026-02-26 19:08:08 -06:00
Alex Gleason 29a9a0f36c Merge branch 'add-custom-theme-editor-ui' 2026-02-26 02:28:23 -06:00
Chad Curtis 787676e014 Fix FAB safe-area offset on Android and generate video preview thumbnails via canvas 2026-02-25 21:44:43 -06:00