Look up the content type's icon from CONTENT_KIND_ICONS (same icons
used in the sidebar) and display it in both the label row and as the
fallback thumbnail placeholder.
When viewing a kind 1111 comment that replies to an addressable event
like a vine (34236), music, or article, the detail page now shows a
rich preview banner with thumbnail, kind label, title, and author —
matching the existing pattern for URL, profile, and community previews.
Works generically for all addressable event kinds by looking up the
kind label from EXTRA_KINDS and extracting thumbnails from image/imeta
tags.
Closes#75
The profile page effect cleanup was restoring the background using a
stale previousBgCss value captured when the effect first ran, before
'Copy Theme' was clicked. Now the cleanup always rebuilds background
CSS from ownThemeRef.current (like colors already do), so it reflects
any theme changes made while on the profile page.
Closes#71
Portal the popover into the DialogContent element using
PortalContainerProvider so Radix pointer-event blocking
doesn't prevent the dropdown from opening.
Closes#68
Rename 'Search query' to 'Filter by Word' and 'Kinds' to 'Content Kinds'
for clarity. Reorder fields to: Tab name, Content Kinds, Filter by Word,
Authors — placing the higher-order Kind filter before the word filter.
Closes#68
Country feeds (iso3166) are social feeds and should display in
reverse-chronological order. URL and ISBN comment threads keep
the existing oldest-first conversation order.
Closes#64
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.
- Add kind 1111 to the Nostr REQ filter in NotificationRelayService
- Add case 1111 to kindToAction() in NostrPoller with the same context-aware
label logic: 'replied to your comment' when k=1111, 'commented on your post' otherwise
When a kind 1111 comment's parent is another comment (k tag = '1111'), show
'Replying to @user' with a link to the parent comment instead of the generic
'Commenting on [root]' label that always pointed to the thread root.
- Include kind 1111 in all three notification query filters (useNotifications, useHasUnreadNotifications, useNativeNotifications)
- Add CommentNotification component with context-aware action label: 'replied to your comment' when parent kind is 1111, otherwise 'commented on your post'
- Add 'New comment' title for native/browser push notifications
- Include kind 1111 in the Mentions tab filter alongside kind 1
- 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.
The picker was positioned relative to the trigger button via a Popover,
which felt awkward especially on smaller screens or inside other modals.
Now renders as a centered Dialog with a backdrop for a more traditional
modal experience.
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.
- /lists now redirects to /settings/lists
- UserListsPage redesigned to match the settings sub-page pattern (back arrow to /settings, collapsible section, IntroImage)
- Lists added as an entry in the SettingsPage menu
- Removed Lists from sidebar nav (it was requiresAuth and felt out of place)
- Add NIP-51 Follow Sets management (useUserLists, UserListsPage at /lists)
- Add Follow Packs support (useFollowPacks) for curated people lists
- Add FeedEditModal for creating/editing home feed tabs with author scope,
kind picker, and list/pack author population
- Add AddToListDialog accessible from the note more-menu
- Unify home feed tab resolution with profile tabs via useResolveTabFilter,
supporting $follows variable expansion
- Wire People filter in Search and FeedEditModal with list/pack picker
- Extract shared ScopeToggle, ListPackPicker, parseSelectedKinds primitives
into SavedFeedFiltersEditor to eliminate duplication across three call sites
- Cache savedFeeds in AppConfig for instant tab render on load
- Strip orphaned profile-destination entries from encrypted settings on read
Blossom servers return content-addressed URLs (/<sha256>) that may omit
the file extension. After upload, extract the extension from the source
filename and append it to the URL if not already present. This helps
clients infer the media type from the URL alone.
Core tabs (Posts, Media, Likes, Wall, etc.) were published with empty
filter stubs, making the event uninterpretable by other clients. Now
each core tab carries a proper NIP-01 filter with the actual pubkey
interpolated (e.g. Wall: {kinds:[1111], #A:["0:<pubkey>:"]}).
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
Simplify the ProfileTabEditModal to only show Search Query, Author Scope
(Me/Contacts/Global), and a multi-select Kind picker with checkboxes and
chips. Remove Media, Platform, and Language fields that were not useful
for profile tabs.
Extract parseKindFilter utility to handle comma-separated kind values
across all consumers (Feed, ProfilePage, SearchPage).