Commit Graph

4447 Commits

Author SHA1 Message Date
Mary Kate Fain 9b93881663 Merge remote-tracking branch 'origin/main' into fix/toast-swipe
# Conflicts:
#	src/components/ui/toast.tsx
#	src/components/ui/toaster.tsx
2026-03-27 19:14:08 -05:00
Mary Kate 21df47eccb Merge branch 'fix/compose-preview-overflow' into 'main'
Fix compose preview overflow not being scrollable in modal

Closes #179

See merge request soapbox-pub/ditto!126
2026-03-28 00:07:25 +00:00
filemon 1d87315426 Adjust eyebrow position higher for owli and froggi forms 2026-03-27 21:01:17 -03:00
filemon 4db0e8870d Fix clipPath ID collision causing eyes to disappear with multiple Blobbis 2026-03-27 20:54:06 -03:00
Mary Kate Fain 310993d57c Fix compose preview overflow not being scrollable in modal 2026-03-27 18:51:14 -05: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
filemon deb59b314b Fix adult eye layering by excluding EyeBase gradients from eye white detection
The isEyeWhiteElement function was incorrectly matching colored eye rim gradients
like froggiEyeBase3D (green frog eye bulge) because it matched any gradient with
'Eye' in the name. This caused the eyelid to be placed behind the eye base layer,
making only the eyelid visible.

Now the detection:
- EXCLUDES EyeBase patterns (colored eye rims)
- INCLUDES EyeWhite patterns (actual white of eye)
- INCLUDES generic Eye gradients without 'Base' (baby Blobbi, etc.)
2026-03-27 20:25:32 -03:00
filemon 4c75d4f559 Add missing form-specific color customizers for adult Blobbi SVGs
Complete the color mapping system by adding customizers for:
- breezy: body, inner, veins, arms, legs, floating leaves
- bloomi: all 6 petals with color variations, center, pollen
- cacti: body, arms (pot keeps original red)
- cloudi: body, highlights, raindrops
- crysti: body, inner (facets keep colorful nature)
- owli: body, ears, wings (beak keeps yellow/orange)

Pandi intentionally excluded as it's a panda with black/white coloring by design.
2026-03-27 20:17:26 -03:00
Mary Kate Fain c5bc900212 Use kind-specific labels in notification action text instead of generic 'post'
Notifications now say 'reacted to your badge', 'reposted your theme',
'commented on your nsite', etc. instead of always saying 'your post'
or 'your note'. Uses the referenced event's kind to look up a
human-readable noun from a comprehensive kind-to-label map.
2026-03-27 18:14:18 -05:00
filemon 8bd2bca879 Add form-specific color customizers for adult Blobbi SVGs
Implement comprehensive gradient replacement for each adult form to ensure
Blobbi custom colors are properly applied to all visual elements (body, ears,
tail, arms, legs, petals, etc.) while preserving 3D shading gradients.

Forms with full color mapping: catti, droppi, flammi, froggi, leafy, mushie,
rocky, rosey, starri. Forms owli/pandi keep original colors by design.
2026-03-27 20:12:01 -03:00
Mary Kate Fain 9901635008 Add zap button to badge detail view action bar
The BadgeDetailContent action bar had reactions, reposts, and comments
but was missing the zap button that NoteCard renders for the same
events in the feed.
2026-03-27 17:52:52 -05:00
Mary Kate Fain 1f5ce2546c Add emoji picker and shortcode autocomplete to zap comment box
Extract shared useInsertText hook to DRY up the duplicated text
insertion logic across ComposeBox, DMChatArea, and ZapDialog.
Add EmojiPicker (GUI) and EmojiShortcodeAutocomplete (:shortcode
typing) to the zap comment textarea, and also add shortcode
autocomplete to the DM chat input which was previously missing it.

Closes #176
2026-03-27 17:46:16 -05: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
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
Mary Kate Fain d4a928b682 Show full theme description on post detail page
On the feed, theme descriptions are truncated to a single line. On the
post detail page, the full description is now displayed so users can
read long descriptions that don't fit in the thumbnail card.

Closes #124
2026-03-27 16:52:20 -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 8fe8525b06 Merge branch 'main' of gitlab.com:soapbox-pub/ditto 2026-03-27 15:40:40 -05:00
Mary Kate 9169cd5d1f Merge branch 'fix/letter-notifications' into 'main'
Fix: add letter (kind 8211) notifications

Closes #188

See merge request soapbox-pub/ditto!118
2026-03-27 20:30:42 +00:00
filemon 97748dfd34 Remove page entry from streak triggers - only real interactions count
Streak now only updates from actual care interactions:
- Direct actions (play_music, sing)
- Inventory item use (feed, clean, treat, etc.)
- Stage transitions (hatch, evolve)
- Rest action (sleep/wake toggle)

Page visits and app opens no longer count toward streak.
2026-03-27 17:08:27 -03: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
Alex Gleason 32b0cef65d Change toast swipe direction from right to up for mobile dismissal 2026-03-27 14:57:51 -05:00
Mary Kate Fain abcb51c0e2 Show badge thumbnail preview in badge award notifications
Closes #186. Badge award notifications now display a visual preview
card with the badge image, name, and description for both single and
grouped badge notifications.
2026-03-27 14:44:33 -05:00
Mary Kate Fain 8d02645e26 Enhance letter notification with envelope card preview
Show the sender's profile pic via the EnvelopeCard component (the same
Wii-Mail-inspired envelope tile used in the letters inbox). The card
auto-decrypts to display stationery colors and the sender's avatar as a
wax seal. Clicking the envelope navigates to /letters.
2026-03-27 14:31:05 -05: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
Alex Gleason 17954e0504 Fix badges page showing infinite skeleton when logged out
The useBadgeFeed hook required a logged-in user before enabling the query,
causing the follows tab to show loading skeletons forever when logged out.
Now fetches the Team Soapbox follow pack (kind 39089) and uses its members
as the authors filter, giving logged-out users a curated badge feed.
2026-03-27 13:15:44 -05:00
filemon 2e5e6c9ad3 feat: add 'hungry' emotion for Blobbi
New emotion that conveys low energy + wanting food:
- Watery eyes (like sad) but WITHOUT blue water fill - longing, not crying
- Worried/sad eyebrows for that wanting/longing look
- Droopy mouth - less curved than sad frown, softer and more tired
- Small drool drop from corner of mouth with subtle wobble animation
- Fork & knife icon above head (subtle, 65% opacity)

Also adds new config types:
- DroolConfig: drool drop effect
- FoodIconConfig: utensils/plate icon above head
- DroopyMouthConfig: weak/tired frown with adjustable width and curve
2026-03-27 12:56:45 -03:00
filemon c1e9143483 fix: add missing pupil colors for adult Blobbi eye detection
Added #1e1b4b (dark indigo) for starri/crysti and #0891b2 (cyan) for
droppi to the PUPIL_COLORS array. Without these colors, the eye
animation system couldn't detect pupils in these adult forms, causing
eyes to not render properly (only showing eyelids).
2026-03-27 12:25:59 -03:00
filemon 774f7d2dbe Add sparkles around Blobbi and create excited variation B
Sparkles:
- Move sparkles from around eyes to around entire Blobbi body
- 11 sparkles distributed around the perimeter (top, sides, bottom)
- Subtle fade/twinkle animation with staggered timing
- Soft opacity (0.7 max) for gentle effect

Excited variations:
- Excited A (original): star eyes + big smile
- Excited B (new): star eyes + round 'O' mouth (like curious)
- Both include sparkles around the Blobbi
- Added excitedB to emotion tester panel for comparison
2026-03-27 12:16:25 -03:00
filemon de9eab1e4e Finalize emotion visual tweaks
Sleepy closed-eye lines:
- Increase curve depth (0.5x radius) to match eye curvature
- Position slightly lower (0.75x radius offset)
- Disappear immediately at 63% (as eyes start opening)

Excited star eyes:
- Reduce star scale from 1.4 to 0.9 for cuter look
- Insert stars INTO blobbi-eye groups so they track with eye movement
- Stars now follow mouse cursor like normal pupils

Excited sparkles:
- Add 4 animated sparkles around each eye
- Small 4-pointed star shapes that twinkle
- Staggered animations (0.3s delay between each)
- Positioned at orbit around the eyes
2026-03-27 12:07:27 -03:00
filemon 9b1925d6de Refine excited, sleepy, and adoring emotions
Excited eyes:
- Keep white eye circle visible behind the star
- Only hide pupils (.blobbi-eye), not entire blink group

Sleepy animation:
- Update to use new clip-path blink system
- Add SMIL animations to clip-path rects for eye closing
- Remove old scaleY CSS animation
- Eyes now close with natural eyelid-down effect

Adoring eyes:
- Add includeWaterFill option to PupilModification
- Adoring uses watery highlights but no blue fill
- Sad retains the blue watery semicircle
2026-03-27 12:02:24 -03:00
filemon a6ad1bdcdb Refine blink animation and eyelid system
Blink behavior:
- Change from scaleY to clip-path mask approach
- Eye keeps original size, visible area cropped from top to bottom
- Creates natural eyelid-closing effect revealing eyelid layer behind
- Add clipPath definitions and animate rect Y/height

Eyelid color:
- Reduce darken amount from 15% to 8%
- Subtle contrast that reads as eyelid, not shadow

Sleepy closed-eye lines:
- Lower position by 70% of eye radius
- Aligns with final closed eye position in clip-path system
2026-03-27 11:53:25 -03:00
filemon f9c8bbc4cc Add eyelid background layer and update excited emotion with star eyes
Eyelid layer:
- Add blobbi-eyelid ellipse behind each eye white
- Derive color from base body color (darkened by 15%)
- Pass baseColor to addEyeAnimation from visual components
- Ready for future blink animation integration

Excited emotion:
- Replace eyes with 5-pointed golden stars
- Add big smile (30% wider, 40% deeper curve)
- Hide normal eyes when stars are active
- Clean, readable across baby and adult variants
2026-03-27 11:44:30 -03:00
filemon 3634440c8b Update excited emotion and add adoring emotion
- excited: use normal eyes, keep animated eyebrows, use curious round mouth
- adoring: watery eyes (like sad), no eyebrows, curious round mouth
- Add adoring to emotion tester panel
2026-03-27 11:37:18 -03:00
Chad Curtis 488ce5750d Hide top nav on scroll and unify top padding across pages
- MobileTopBar: changed from sticky to fixed positioning with scroll-hide
  transform animation (mirrors bottom nav behavior via useScrollDirection)
- MainLayout: replaced -mt-mobile-bar overlap trick with pt-mobile-bar
  padding since the top bar is now fixed; added data-nav-hidden attribute
  to drive CSS transitions on sticky sub-headers
- SubHeaderBar/top-mobile-bar: sticky top offset transitions to 0 when
  the top bar hides, keeping sub-headers flush with the viewport top
- NotificationsPage, ProfilePage: added arc overhang spacer after
  SubHeaderBar to match Feed's spacing
2026-03-27 02:07:12 -05:00
filemon c963673a19 feat(blobbi): add dizzy, excited, mischievous emotions with animated effects
- Add dizzy emotion with rotating spiral eyes (counter-clockwise)
- Add excited emotion with watery eyes, bouncing sad-style eyebrows, and smile
- Add mischievous emotion with bouncing angry-style eyebrows and small smug smile
- Wrap eyebrows in groups to preserve rotation while CSS animates translateY
- Add new emotions to DEV emotion panel for testing
2026-03-27 02:17:49 -03:00
Chad Curtis 93bc669f24 Lazy-load hls.js in VideoPlayer to reduce main bundle by ~500KB 2026-03-26 23:33:09 -05:00
filemon 0602c1b59d refine(blobbi): adjust sleepy animation timing and transitions
Three targeted refinements to sleepy emotion:

1. Mouth transition simplified:
   - Now goes directly: smile → U-shaped → smile
   - Removed intermediate flat line phase
   - Smoother, more natural transition

2. Eyes fully hidden when closed:
   - Changed scaleY from 0.05 to 0 when fully closed
   - Original eye completely disappears
   - Only curved closed-eye line visible during sleep

3. Zzz appears from the beginning:
   - Starts at 0% with opacity 0
   - Fades in softly: 10% → 0.2, 20% → 0.4
   - Full opacity by 35% (during sleep)
   - Creates 'getting sleepy' feel from the start
2026-03-27 01:33:04 -03:00
filemon d8a81879b1 feat(blobbi): redesign sleepy emotion as micro-sleep animation
Complete rewrite of sleepy emotion to be a 'micro-sleep' cycle:

Eye Animation:
- Slow eye closing over ~3 seconds (not partial blinks)
- Eyes fully close with scaleY near 0
- Curved closed-eye lines appear when eyes shut (like eyelids)
- Wake-up includes quick right-left glance before settling

Mouth Animation:
- Smile → flat line → small round mouth (while falling asleep)
- Small round mouth holds during sleep
- Reverses back: round → flat → smile (while waking)
- Uses SMIL path animation for smooth morphing

Sleep State:
- Zzz text appears above head during sleep
- Zzz fades in/out and floats upward
- Sleep holds for ~1 second before waking

Full 8-second cycle timeline:
- 0-10%: Awake, normal smile
- 10-35%: Getting sleepy, eyes closing, mouth flattening
- 35-50%: Eyes closed, mouth becomes round
- 50-62%: Asleep (hold with Zzz)
- 62-75%: Waking, eyes opening
- 75-90%: Quick right-left glance
- 90-100%: Return to normal, cycle repeats
2026-03-27 01:27:46 -03:00
filemon c054bc7bc7 Merge branch 'main' into feat-blobbi 2026-03-27 01:25:27 -03:00
filemon daf35f6e41 feat(blobbi): add curious asymmetric eyebrow and sleepy animation
Curious emotion:
- Right eyebrow now raised slightly more than left for questioning look
- Added per-eye override support in EyebrowConfig (leftEyeOverride/rightEyeOverride)

Sleepy emotion:
- Implemented 3-stage tired blink animation cycle:
  1. Small blink (~25% closed)
  2. Medium blink (~55% closed)
  3. Heavy blink (~80% closed)
- Mouth animates from smile → flat → smile in sync with blinks
- Uses CSS keyframe animation for smooth, slow transitions
- 8-second cycle duration for natural tired feel
- Added SleepyAnimationConfig type for configuration
2026-03-27 01:17:05 -03:00
Chad Curtis aecddf6fb5 Fix drawing canvas 'done' button clipped by drawer max-height 2026-03-26 23:13:42 -05:00
filemon d947a951ad feat(blobbi): add curious/surprised emotions and adjust baby eyebrows
- Add 'curious' emotion: small round mouth, soft curved eyebrows
- Add 'surprised' emotion: larger round mouth, raised curved eyebrows
- Add round mouth generation (replaces default mouth like sad/angry)
- Add curved eyebrow support via new 'curve' config option
- Move baby eyebrows slightly farther from eyes (-2px offset)
- Add variant parameter to applyEmotion for baby/adult differences
- Add both new emotions to DEV emotion panel
2026-03-27 01:00:01 -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
filemon 273cf1094d fix(blobbi): fix sad eye highlights and add angry body animation
- Fix invalid SVG generated by sad highlight injection regex
- Refactor water fill to insert inside blink groups (below pupil, above eye white)
- Add anger-rise body effect that animates red color from bottom to top
- Uses clipPath to constrain effect to body shape
2026-03-27 00:51:32 -03:00
Chad Curtis 403946bac5 Use mailbox icon from lief for Letters page and sidebar 2026-03-26 22:43:11 -05:00
filemon c907779b3c Fix sad eye highlight injection with robust parsing and debug logs
- Replace fragile regex with index-based string manipulation
- Find opening tag first, then locate closing tag by position
- Add DEV-only debug logging for eye detection and injection
- Log whether blobbi-eye groups are found and matched
- Log eye positions and water fill generation
- Should fix sad highlights not appearing in blobbi-eye groups
2026-03-27 00:35:24 -03:00
Alex Gleason 5fed2f4182 Add pre-release indicator to settings version footer 2026-03-26 22:28:18 -05:00