Commit Graph

4447 Commits

Author SHA1 Message Date
Alex Gleason 43fabe1ac3 Add top padding to theme mockups to restore visual spacing 2026-03-20 01:39:05 -05:00
Alex Gleason 350bb037bf Remove decorative header bar and sidebar strip from ThemePreviewCard and LandingHero mockups 2026-03-20 01:38:28 -05:00
Alex Gleason 71a3836a75 Remove decorative header bar and sidebar strip from ThemeMockup 2026-03-20 01:37:02 -05:00
Alex Gleason b25be7e8e9 Add relay.dreamith.to as a second Ditto relay for search, trending, and streaming queries 2026-03-19 22:25:26 -05:00
Derek Ross 7a9a6edeeb Add CSAE child safety policy page at /safety 2026-03-19 19:43:46 -04:00
Alex Gleason 8ea370067b Add screenshot lightbox modal to Zapstore app events 2026-03-19 18:10:36 -05:00
Alex Gleason c809bf4093 Normalize and validate relay URLs in extractWriteRelays, cap to 5 relays 2026-03-19 18:06:13 -05:00
Alex Gleason 557f29df78 Stop passing react-query signal through useEvent hooks, use AbortSignal.timeout directly 2026-03-19 18:03:20 -05:00
Alex Gleason ab8bf31710 Query Zapstore relay first in useAddrEvent for faster app/release lookups 2026-03-19 18:00:37 -05:00
Alex Gleason a2d5b50fdd Route Zapstore kinds through NostrProvider reqRouter instead of direct relay calls 2026-03-19 17:44:45 -05:00
Alex Gleason bd085ac0a9 Move ZAPSTORE_RELAY constant to appRelays.ts 2026-03-19 17:40:58 -05:00
Alex Gleason 1da093d4bf Use GitFork icon for Source button in Zapstore app card 2026-03-19 17:34:03 -05:00
Alex Gleason a33002ec21 Fix Zapstore link to use correct /apps/ URL format 2026-03-19 17:14:55 -05:00
Alex Gleason bbff34bd76 Add special rendering for Zapstore app events (kind 32267)
Render kind 32267 software application events with app icon, name,
summary, platform badges, screenshots, and action buttons in both
feed (NoteCard) and detail (PostDetailPage) views. Add useAddrEvent
fallback to wss://relay.zapstore.dev for kinds 32267/30063 so app
events are discoverable even when not on the user's relay set.
2026-03-19 17:08:40 -05:00
Alex Gleason 2dbd403f20 Add full-screen rain/snow precipitation effect on country pages
When the weather API reports precipitation for a country, render a
canvas-based particle overlay: animated raindrops for rain/drizzle/
thunderstorm codes, and gently drifting snowflakes for snow codes.
Intensity (light/moderate/heavy) scales particle count and speed.
The overlay is pointer-events-none at z-[100] so it doesn't block
interaction.
2026-03-19 14:54:51 -05:00
Alex Gleason 7f0f25aeb7 Make quoted event tombstones clickable with NIP-19 identifiers
When a quoted event fails to load, the 'this post could not be loaded'
indicator is now clickable, navigating to the event's page. Constructs
nevent1 for regular events and naddr1 for addressable events, including
relay hints and author pubkey when available from the parent event's tags.
2026-03-19 14:34:34 -05:00
Alex Gleason 2e9dc52485 Add current weather display to country pages
Use the free Open-Meteo API to show real-time weather (temperature,
humidity, wind, conditions) on country and subdivision pages. Weather
is fetched based on capital city / major city coordinates and cached
for 15 minutes.
2026-03-19 11:34:26 -05:00
Alex Gleason c1323d5048 Remove LinkFooter from desktop left sidebar to fix duplicate display
The footer links (About, Docs, Privacy, Edit with Shakespeare) were
showing in both the left sidebar and right sidebar on desktop. Remove
from LeftSidebar since it already appears in MobileDrawer for mobile
and in the right sidebars for desktop.

Closes #131
2026-03-19 11:11:39 -05:00
filemon 14644d0cb3 Clean up deprecated tags in migration and republish flows
- Remove incubation_time and start_incubation from coreStateTags in
  buildMigrationTags - these obsolete fields should not be carried
  forward during migration
- Add DEPRECATED_BLOBBI_TAG_NAMES to the exclusion set in buildMigrationTags
  when filtering unknown tags, preventing deprecated tags from being
  preserved in migrated events
- Add DEPRECATED_BLOBBI_TAG_NAMES filtering to mergeTagsForRepublish so
  deprecated tags are not carried forward when republishing existing events

The deprecated tags (incubation_time, start_incubation, incubation_progress,
egg_status, fees) are now properly excluded from:
1. New events (already handled by buildEggTags)
2. Migrated events (buildMigrationTags)
3. Republished events (mergeTagsForRepublish, mergeBlobbiStateTagsForRepublish)

Legacy parsing still reads these fields for backwards compatibility, but
they are never written to new events.
2026-03-19 13:06:31 -03:00
filemon 4c89a20bbe Fix critical bug: Blobbis disappear after starting incubation
The isValidBlobbiEvent function only accepted 3 states (active, sleeping,
hibernating) but BlobbiState type includes 5 states. When state changed to
'incubating' or 'evolving', events failed validation and were filtered out
by useBlobbisCollection and useBlobbiCompanion hooks.

Added 'incubating' and 'evolving' to the valid states list.
2026-03-19 11:50:45 -03:00
filemon 6a2285ef72 Clean up Blobbi incubation system and enforce consistency
Deprecated tags removed from creation:
- incubation_time: No longer created in buildEggTags or previewToEventTags
- start_incubation: No longer in managed tags
- egg_status: Removed from LEGACY_VISUAL_TAG_NAMES (was duplicated)

These tags are now in DEPRECATED_BLOBBI_TAG_NAMES and stripped on republish.

Visual trait consistency:
- buildEggTags now includes all visual traits (base_color, secondary_color,
  eye_color, pattern, special_mark, size) derived from seed
- VISUAL_TRAIT_TAG_NAMES replaces LEGACY_VISUAL_TAG_NAMES
- Visual traits added to MANAGED_BLOBBI_STATE_TAG_NAMES

Stat safety:
- STAT_MIN = 1 (was 0) to prevent soft-lock
- STAT_MAX = 100
- clampStat now clamps to 1-100 range instead of 0-100
- Recovery is always possible with any healing item

Layout improvements:
- BlobbiPage container: max-w-2xl on mobile, max-w-3xl on desktop
- Reduced side whitespace on mobile (px-2)
- Better breathing room overall

BlobbiCompanion interface:
- incubationTime and startIncubation marked as @deprecated
- DEFAULT_INCUBATION_TIME marked as @deprecated

state_started_at remains the single source of truth for process timing.
2026-03-19 09:55:26 -03:00
filemon 37a791f113 Fix incubation-start flow to properly apply decay and clean obsolete tags
- Apply accumulated decay from last_decay_at to now before state change
- Write decayed stat values into the incubation-start event
- Set last_decay_at = state_started_at = last_interaction for consistency
- Add incubation_progress, egg_status, fees to DEPRECATED_BLOBBI_TAG_NAMES

The incubation-start event now has consistent timestamps:
- created_at: NOW
- state_started_at: NOW
- last_interaction: NOW
- last_decay_at: NOW (was incorrectly preserving old value)
2026-03-19 09:39:03 -03:00
filemon 06f820d355 Refine Blobbi incubation/hatch task system
- Fix Color Moment URL: espy.social -> espy.you
- Improve shape-change task detection: only counts true post-start changes
- Remove duplicate Start Incubation button, integrate into evolve/hatch button
- Extract shared incrementInteractionTaskTags helper for code reuse
- Update floating controls to show incubation action for eggs not yet incubating

The evolve/hatch button now serves as the single entry point:
- Egg (not incubating): Opens incubation dialog
- Egg (incubating): Button hidden, hatch action in HatchTasksPanel
- Baby: Evolves to adult
2026-03-19 09:04:08 -03:00
filemon 3a2571ccc6 Merge branch 'main' into feat-blobbi 2026-03-19 08:08:37 -03:00
Alex Gleason 9f82fb5f46 Show LinkFooter in both desktop and mobile sidebars regardless of login state 2026-03-18 22:33:07 -05:00
Alex Gleason 88088e754d Add LinkFooter component with About, Docs, Privacy, and Shakespeare links 2026-03-18 22:30:24 -05:00
Alex Gleason 962f97fbfc Update tagline to 'Your content. Your vibe. Your rules.' 2026-03-18 21:04:43 -05:00
filemon dd614e6a6a Merge branch 'main' into feat-blobbi 2026-03-18 18:00:55 -03:00
Alex Gleason e3935b7dc6 Replace Messages with Feed in mobile bottom nav
Remove the Messages tab and add a Feed tab (using PlanetIcon) as the
leftmost item in the mobile bottom navigation. Feed highlights when
on /feed or /.
2026-03-18 15:29:33 -05:00
filemon f5595b3477 feat(blobbi): implement hatch task system for egg incubation
Add task-based progression system for hatching Blobbi eggs:

- Extend BlobbiState with 'incubating' and 'evolving' states
- Add task tracking fields to BlobbiCompanion interface
- Create useStartIncubation hook to begin incubation process
- Create useHatchTasks hook to compute task progress from Nostr events
- Add HatchTasksPanel UI component showing 5 hatch tasks:
  - Create Theme (kind 36767)
  - Color Moment (kind 3367)
  - Change Avatar Shape (kind 0 with shape change)
  - Create Post with required prefix/hashtags
  - 7 Blobbi interactions
- Add BlobbiPostModal with enforced content requirements
- Add StartIncubationDialog confirmation dialog
- Auto-increment interaction counter in action hooks
- Gate hatch button visibility based on task completion
2026-03-18 16:44:38 -03:00
Alex Gleason 464279b2e6 feat: add custom font upload to theme editor FontPicker
Allow users to upload their own .woff2/.woff/.ttf/.otf font files via
Blossom, which are immediately applied and stored with the theme. The
uploaded font URL is preserved when publishing themes to Nostr (via the
existing f tag in the theme event schema).
2026-03-18 13:01:07 -05:00
filemon e9c34df51e fix(blobbi): show aggregated stat preview in inventory use dialog
The inventory modal's use confirmation dialog was showing simple
multiplication (effect * quantity) instead of the actual clamped
values that would be applied.

Now it simulates the sequential application of effects, clamping
at each step, to show the true total effect that will be applied
when confirming. This matches the behavior of the action modal's
confirmation dialog.
2026-03-18 11:34:25 -03:00
filemon 82b9964a61 feat(blobbi): improve item usage UX with quantity selector and inventory actions
- Add quantity selector to item usage modal (feed/play/clean/medicine)
  - Users can now use multiple items at once
  - Effects are applied sequentially with proper clamping at each step
  - Shows estimated total effect preview

- Add 'Use' button to inventory modal
  - Items can now be used directly from inventory
  - Reuses same logic as normal item usage flow
  - Opens confirmation dialog with quantity selector

- Add stage-based item blocking in inventory
  - Eggs cannot use food or toys (shown disabled with reason)
  - Shell Repair Kit only usable by eggs (blocked for baby/adult)
  - Blocked items remain visible but cannot be used

- Shell Repair Kit visibility in medicine modal
  - Only appears for eggs, hidden for other stages

- Make shop modal narrower (max-w-4xl to max-w-2xl)

- Add centralized item usability logic (canUseItemForStage)
  - Single source of truth for item/stage restrictions
  - Exported from actions module for reuse
2026-03-18 11:24:07 -03:00
filemon a0cb5cc307 Merge branch 'main' into feat-blobbi 2026-03-18 10:51:45 -03:00
filemon 0b26ef51a2 feat: add pot to Rosey shape 2026-03-18 10:50:44 -03:00
filemon da3cc5f997 fix: apply shape mask to hover/edit overlay in ProfileCard
The hover overlay was showing as a full rectangle instead of respecting
the Blobbi shape mask. This happened because the overlay was using the
sync getAvatarMaskUrl() which returns empty for Blobbi shapes (they now
render asynchronously as PNG).

Changed ProfileCard to:
- Use getAvatarMaskUrlAsync() for the overlay mask
- Load mask URL via useEffect with proper cleanup
- Apply the same mask to the hover overlay as the avatar itself

Now the hover/edit darkening effect respects the actual avatar shape,
only appearing inside the visible silhouette.
2026-03-18 10:44:28 -03: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 80067a212c fix: inject fill/stroke attributes directly into SVG elements for mask rendering
The previous approach using <style> tags with CSS selectors inside SVG data URLs
didn't work reliably when the SVG was used as a CSS mask-image. Some browsers
don't process CSS inside SVG data URLs correctly.

This fix:
- Adds injectWhiteFillStroke() function to directly inject fill="white" and
  stroke="white" attributes into each SVG shape element
- Properly handles elements with transform attributes (the root cause of
  droppi, flammi, leafy, mushie, owli, rocky, rosey failing)
- Preserves fill="none" for stroke-only elements (like catti's tail)
- Works reliably across all browsers since it uses SVG attributes, not CSS
2026-03-18 10:28:08 -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 ae4847ce50 fix: use SVG data URL directly for Blobbi mask instead of canvas rendering
The previous implementation tried to render SVG to canvas synchronously,
but Image loading is asynchronous, causing getBlobbiMaskUrl() to return
empty string and avatars to fall back to squares.

CSS mask-image supports SVG data URLs directly, so we now skip the
canvas conversion entirely. This is simpler, more reliable, and works
synchronously.

- Remove renderSvgToMaskUrl() and drawImageToCanvas() functions
- Simplify getBlobbiMaskUrlAsync() to just wrap sync version
2026-03-18 10:15:45 -03:00
filemon a07a2de786 fix: scope Blobbi shape colors and increase preview size
- Use fill/stroke attributes on <g> instead of global CSS to prevent color leakage
- Reduce grid columns from 5 to 4 for larger shape previews
- Reduce inner padding from inset-1 to inset-0.5 for bigger shapes
2026-03-18 10:09:08 -03:00
filemon 96ce34c7f1 refactor: use raw SVG markup for Blobbi shapes instead of single path
- Change BlobbiShape type from 'path: string' to 'svg: string'
- Store original SVG body markup preserving circles, ellipses, rects, paths, transforms, and strokes
- Update getBlobbiMaskUrl() to render SVG string via Image element instead of Path2D
- Add getBlobbiMaskUrlAsync() for guaranteed async loading
- Add getBlobbiShapeSvg() helper to get complete SVG markup with custom fill
- Update BlobbiShapePicker to render multi-element SVG with dangerouslySetInnerHTML
- Shapes now visually match original SVG files exactly (e.g., catti tail is stroke-based)
2026-03-18 09:50:13 -03:00
filemon c6fa1acf66 refactor: improve Blobbi shape picker UI and update character silhouettes
- Add tight viewBox computation for better shape visibility in picker
- Change grid layout to 5 columns for larger, more prominent shapes
- Remove shape name labels for cleaner picker interface
- Rename 'Blobbi' tab to 'Blobbids' in avatar picker dialog
- Update all adult Blobbi SVGs with refined designs
- Redesign shape paths with detailed silhouettes including limbs and accessories
- Add pot to Leafy, adjust Pandi arms, remove shadows from Rocky
2026-03-18 09:44:23 -03:00
Chad Curtis 176813dce0 feat: support multi-photo upload in media picker
Add the  attribute to the file input in ComposeBox and update
the onChange handler to iterate over all selected files, uploading each
one via handleFileUpload, enabling users to select and attach multiple
files at once.
2026-03-18 05:55:41 -05:00
Chad Curtis 39fee6aa5d Filter notifications for reactions/reposts/zaps on posts user didn't author 2026-03-18 05:36:10 -05:00
Chad Curtis a7b142b5e5 Filter reactions/reposts on posts the user didn't author from notifications 2026-03-18 05:31:26 -05:00
Chad Curtis 018fad1a2e Fix color moments text overlay, add geohash pill and geotag feed support
- Fix color moments rendering long text as emoji overlay; only render
  single emoji (≤2 code points) as palette overlay
- Replace MapPin with ChestIcon on geocache name
- Add geohash pill badge to geocache type/size row, linking to /g/ route
- Truncate geohash display to 5 characters
- Add /g/:geohash route with GeotagPage backed by shared TagFeedPage
- DRY up HashtagPage and GeotagPage into shared TagFeedPage component
- Extend useInterests to support g tags for geohash following
- Add geotag feed tabs to home feed with MapPin icon
2026-03-18 04:00:25 -05:00
Alex Gleason aea730a949 Redesign Request to Vanish as a multi-step wizard
Break the dialog into 3 focused steps (Scope, Details, Confirm)
with animated progress indicators, dramatic destructive color
treatment, custom scope selection cards, and a centered final
confirmation with type-to-confirm input.
2026-03-18 03:20:55 -05:00
Alex Gleason f861641aa1 Add NIP-62 Request to Vanish support
Implement kind 62 event publishing to allow users to request
permanent deletion of their data from relays. Includes global
(ALL_RELAYS) and targeted (specific relays) modes with a
multi-step confirmation dialog in Advanced Settings.
2026-03-18 03:06:24 -05:00
Alex Gleason 573c680d2f Add privacy policy link to Help page 2026-03-18 01:16:36 -05:00