Commit Graph

18 Commits

Author SHA1 Message Date
Alex Gleason 6569478fc4 Remove implementation notes from avatar shape NIP section 2026-03-13 20:48:03 -05:00
Alex Gleason 91b96984cb Make NIP.md implementation notes platform-generic (web, iOS, Android) 2026-03-13 20:47:38 -05:00
Alex Gleason 196f3dd64e Update NIP.md: shape field is emoji-only, remove predefined shape references 2026-03-13 20:47:07 -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 9e03579d0f Fix heart shape: use polygon approximation instead of path() which requires pixel coordinates
clip-path: path() uses pixel coordinates, making a 0-1 normalized path
invisible. Replaced with a parametric heart curve sampled into a 50-point
polygon using percentage coordinates, consistent with all other shapes.
2026-03-13 17:29:03 -05:00
Alex Gleason 61ea5ff1fe Add heart shape and document kind 0 shape extension in NIP.md
- Add 'heart' as the 8th avatar shape using SVG path() clip-path with cubic beziers
- Document the kind 0 'shape' metadata extension in NIP.md with all 8 defined values,
  client behavior rules, and forward-compatibility guidance
2026-03-13 17:25:50 -05:00
Alex Gleason 9ea8788b92 Replace kind 16769 SavedFeedFilters with standard NIP-01 filters and variable tags
The proprietary SavedFeedFilters JSON schema in kind 16769 tab events was
non-interoperable. Replace it with standard NIP-01 filter objects that any
Nostr client can execute, plus a variable system (var tags) for dynamic
values like follow lists.

- Tab filters are now standard NIP-01 filters with optional NIP-50 search
- Variables ($name) in filters are resolved via var tags that extract tag
  values from referenced events (e.g. follow list pubkeys from kind 3)
- $me is the only runtime variable (profile owner's pubkey)
- Variables in arrays are expanded in-place (spliced)
- Add useResolveTabFilter hook for variable resolution with caching
- Update all consumers: ProfilePage, Feed, SearchPage, ContentSettings
- Remove SavedFeedFilters type entirely in favor of TabFilter
2026-03-06 01:28:09 -06:00
Chad Curtis 134236636a Profile tabs: kind 16769 Nostr event, manager modal, + dropdown, wider save button
Kind 16769 (profile tabs):
- src/lib/profileTabsEvent.ts: encode/decode kind 16769 — tab tags are
  ['tab', label, filtersJSON], no UUIDs, label is the stable key
- useProfileTabs: queries kind 16769 with authors filter (secure)
- usePublishProfileTabs: publishes kind 16769, invalidates cache
- useProfileSupplementary: now fetches kind 16769 alongside kind 3 and
  10001 in a single relay round-trip, seeds profile-tabs query cache
- NIP.md: documents kind 16769 schema

ProfileTabEditModal:
- Save button is now full-width with a Check icon (Cancel below)
- hideFrom + hideSort props on SavedFeedFiltersEditor used here — author
  is the profile owner implicitly, sort is irrelevant for profile tabs

ProfileTabsManagerModal:
- dnd-kit drag-to-reorder sortable list of custom tabs
- Per-row edit (pencil) and remove (trash) buttons
- Add custom tab button at the bottom
- Single Save button publishes the full updated list

ProfilePage tab bar (own profile):
- Custom tabs read from kind 16769 via useProfileTabs
- + button opens a DropdownMenu: core tabs listed as already-added
  (dimmed with checkmarks), Add custom tab at the bottom
- SlidersHorizontal pencil at end of row opens the manager modal
  (only shown when custom tabs exist)
- Per-tab onEdit pencil removed — manager handles all editing
- ProfileTab type aliased to CoreProfileTab to avoid collision with
  CustomProfileTab from profileTabsEvent
2026-03-05 22:53:44 -06:00
Alex Gleason c0c65047fa Update NIP.md kind numbers: 33891 -> 36767, 11667 -> 16767 2026-02-26 17:31:05 -06:00
Alex Gleason b5a59ac9a6 Remove 'contain' background mode from NIP.md and codebase, keep only cover and tile 2026-02-26 15:22:35 -06:00
Alex Gleason bc4cc80581 Simplify theme fonts to a single font (remove heading/body roles)
Reduce font complexity from two-role (title/body) to a single font
that applies globally to all text. Updates NIP.md f tag format from
["f", family, role, url] to ["f", family, url], removes ThemeFonts
wrapper in favor of a single ThemeFont on ThemeConfig.font, and
simplifies FontPicker to a single dropdown.
2026-02-26 14:57:41 -06:00
Alex Gleason 51304a3a7c Add font (f) and background (bg) tags to theme event spec
Replace the u tag with a richer bg tag using imeta-style key-value
pairs (url, mode, m required; dim, blurhash optional). Add f tag for
font declarations (family, role, and font file URL required). Both
tags are documented in a shared definitions section for kind 33891
and kind 11667.
2026-02-26 14:26:08 -06:00
Alex Gleason 14dcb8ce81 Add optional u tag for background image to both theme kinds 2026-02-26 12:45:05 -06:00
Alex Gleason ed8a1d59b5 Remove description and t tags from kind 33891 2026-02-26 12:40:15 -06:00
Alex Gleason 9d0efe76a3 Update kind 33891 to use c tags for hex colors instead of content JSON
Align theme definition event with kind 11667 by replacing the HSL
color token JSON in the content field with c tags using 6-digit hex
color codes and required markers (primary, text, background).
2026-02-26 12:39:19 -06:00
Alex Gleason 2c3260760a Update kind 11667 to use c tags for hex colors instead of content JSON
Replace the HSL color tokens in the content field with c tags using
6-digit hex color codes and required markers (primary, text, background).
Remove the a tag for theme attribution. Add optional title tag.
2026-02-26 12:35:56 -06:00
Mary Kate Fain 096096f685 Replace kind 30203 with new multi-theme NIP: kind 33891 (definitions) + kind 11667 (active profile theme)
- Theme definitions are addressable (multiple per user, each with title/description)
- Active profile theme is replaceable (one per user, copies tokens from source)
- Updated all hooks, components, and feed integration for new kinds
- Theme builder preview now shows accent color on streak flame, banner gradient, and repost action
2026-02-25 15:23:18 -06:00
Mary Kate Fain bac31a5b6d Add profile theme sharing: publish kind 30203, scoped themes on profiles, feed cards, and content settings 2026-02-25 13:49:55 -06:00