When disableEmbeds is true, image-embed tokens now return null instead of
rendering the raw URL as a link. This fixes the triple-dot (more menu)
preview showing bare blossom/image URLs instead of clean post text.
- Images now render inline via NoteContent at the position of their URL
rather than collected into a gallery block below the text
- Clicking an inline image opens a full lightbox with navigation across
all images in the post; lightbox index is tracked by position so
duplicate URLs open at the correct index
- Removed separate ImageGallery/extractImages from NoteCard,
PostDetailPage, and ComposeBox to prevent double-rendering
- Added disableEmbeds to NoteMoreMenu clamped preview to avoid block
embeds inside a line-clamp-3 container
- Fixed hasPreviewableContent in ComposeBox to detect image-only posts
so the Preview tab appears correctly
- Removed mp3/ogg/wav/pdf from MEDIA_URL_REGEX suppression list; those
URLs now render as clickable links instead of being silently dropped
- Added avif to IMAGE_URL_REGEX; added cursor-pointer to InlineImage
The cache-peek approach always returned npub because the cache was empty
at render time. Replace it with a proper hook that calls useNip05Verify,
relying on TanStack Query's deduplication to avoid redundant requests.
Also fix the dot separator in NoteCard to hide when NIP-05 is unverified,
and refactor ProfileSearchDropdown to pass the verified URL through
onClick rather than recomputing it in an event handler.
- Add overflow-hidden to NoteCard article elements in both normal and
threaded layouts to clip content that exceeds card width
- Add overflow-hidden to NoteContent root div to prevent link preview
cards and embedded content from pushing beyond container bounds
- Strip .xdc URLs in EmbeddedNote content preview (was missing from
the media URL regex, causing raw long URLs to render in quote embeds)
- Add overflow-hidden to EmbedContentPreview paragraph for defense
against long unbreakable strings
- Use disableEmbeds on NoteContent inside ReplyComposeModal's embedded
post preview so URLs render as plain links instead of full preview
cards that overflow the clamped container
- Add attachment indicator chips to EmbeddedNote (images, videos, apps,
links) so stripped media URLs still have a visible presence
URLs like https://following.party/naddr1... were having all surrounding
whitespace removed because naddr-embed tokens from URLs were treated as
block-level elements. Only bare naddr1 identifiers (without a URL) should
strip surrounding whitespace; URL-sourced ones are inline and need their
spacing preserved.
Mentions now trigger the Edit/Preview toggle. Compose preview uses
NoteContent directly for link previews and embeds instead of rendering
them separately, matching how real notes display. LinkPreview falls back
to a domain+favicon card when OEmbed data is unavailable. Added
disableEmbeds prop to NoteContent for future use.
- Create useWebxdc hook bridging the Webxdc API with Nostr kind 4079 state updates
- Create WebxdcEmbed component with launch-on-click UX for sandboxed iframe rendering
- Update ComposeBox to accept .xdc files and generate imeta tags with webxdc UUID
- Update NoteCard and PostDetailPage to detect and render webxdc attachments
- Skip .xdc URLs in NoteContent to avoid rendering them as raw links
Add emojify/EmojifiedText utilities that replace :shortcode: patterns with
inline images using emoji tags from kind 0 and kind 1 events. Applied to
display names across NoteCard, PostDetailPage, ProfilePage, ProfileHoverCard,
InteractionsModal, NotificationsPage, and NoteContent @mentions. Also
emojifies about/bio text in ProfilePage and ProfileHoverCard.
Remove string-level truncation from getDisplayName to avoid breaking
shortcodes mid-pattern (CSS truncate handles visual overflow). Use
em-relative sizing and align-text-bottom for proper inline alignment.
- Show link preview cards for URLs that end a line, not just standalone
URLs; only suppress previews for URLs followed by more text on the
same line
- Show skeleton placeholders on notifications page until the query has
completed at least once instead of flashing 'No notifications yet'
- Add skeleton loading for author rows in notification cards while
profile data loads
- Replace inline image <a> tags with ImageGallery component so clicking
images opens the lightbox with navigation
- Match notification tab height/weight to feed tabs on mobile while
preserving original desktop styling
- Add true optimistic updates for reactions and reposts via setQueryData
instead of only invalidating queries after publish
- Track user's own reaction per event and display their emoji in place of
the Heart icon across feed, post details, and notifications
- Strip whitespace around block embeds and skipped media URLs to eliminate
blank lines caused by whitespace-pre-wrap
- Only render link preview cards for standalone URLs; inline URLs in
sentences render as plain clickable links
- Remove border-b separators and use fixed-height object-cover on preview
images to eliminate gaps
- Tighten padding on EmbeddedNote and EmbeddedNaddr cards
- Use fixed-height object-cover for ImageGallery grid images
- Unify RepostMenu to use Popover on all screen sizes instead of Drawer
on mobile
- Domain feed page at /timeline/:domain fetches .well-known/nostr.json and queries events from domain users
- NIP-05 domains are clickable in usernames throughout the app (Nip05Badge, NoteCard, PostDetailPage, etc.)
- @_@domain.com renders as @domain.com (underscore prefix hidden)
- Profile hover cards on avatars, usernames, and mentions across all components
- Clicking avatar/banner on profile page opens image in gallery lightbox with safe-area support
- NIP-05 verified users get clean profile URLs (e.g. /user@domain.com) instead of /npub1...
- NIP19Page unified dispatcher handles NIP-19, NIP-05, and profile routing at /:param
- Removed /u/:npub and /d/:domain routes in favor of root-level routing
- CORS proxy fallback for NIP-05 resolution on non-CORS-compliant servers
- Mobile top bar logo links to home
- Safe area fixes for gallery lightbox, mobile drawer, and sheet close button
- Show multiple reply authors like "Replying to @chad and @alex"
- Display up to 2 authors, with "and X others" for more
- Enlarge emojis when they're the only content (text-5xl)
- Detect emoji-only content (max 12 emoji chars)
- Update ReplyContext to accept array of pubkeys
- Extract all non-mention p tags for reply context
- Matches Ditto's reply author display behavior
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Strip trailing punctuation from URLs (.,;:!?)]) that are likely not part of the URL
- Fixes issue where (https://example.com) was parsed incorrectly
- Preserve newlines and formatting after embedded content
- Only collapse excessive whitespace (3+ newlines) instead of removing all whitespace
- Maintains proper text flow after link previews and embedded events
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Preserve one newline after naddr-embed tokens when present
- Prevents text from flowing directly after URL without spacing
- Embedded event now properly displays with preserved formatting
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Removed lookahead that was preventing matches in certain contexts
- NIP-19 identifiers now render as mentions regardless of surrounding characters
- Maintains single @ display by consuming optional @ prefix
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Updated regex to optionally match @ before NIP-19 identifiers
- Removed word boundary requirement to allow mentions in quotes
- Mentions now render correctly with single @ symbol in all contexts
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
Add e.stopPropagation() to hashtag, nostr-link, and mention Links
inside NoteContent so clicks don't bubble up to the parent card's
onClick handler that navigates to the post detail page.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
The content parser regex only matched nostr:-prefixed identifiers like
`nostr:naddr1...`. Bare identifiers like `naddr1...` were rendered as
plain text. Added a \b word-boundary alternation to also match bare
npub1, note1, nprofile1, nevent1, and naddr1 identifiers, so they
render as proper embeds/mentions/links.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Fix NoteContent fallback that incorrectly rendered raw media URLs as
plain text when the entire content was a media URL. The parser would
skip media URLs (handled by parent as embeds), but when all tokens
were skipped, the empty-result fallback re-added the full content
as text. Now tracks whether any regex matches occurred to distinguish
"no matches at all" from "all matches were skipped media URLs".
- Restructure PostDetailSkeleton to match the actual PostDetailContent
layout: proper article/replies separation (fixes double padding on
reply skeletons), image placeholder, rounded action button circles,
and -mx-4 action bar matching the real component.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
The whitespace collapsing logic was stripping newlines before naddr-embed
tokens that have a URL, causing text and the URL to smash together.
Now only pure block embeds (no URL) trim preceding whitespace.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- NoteContent now shows the original URL as a clickable link above the
embedded naddr card when the naddr was extracted from a regular URL
- Replaced "Addressable event view coming soon" placeholder in NIP19Page
with a full AddrDetailPage that shows hero image, author, title,
description, image gallery, metadata fields, and tags
- AddrDetailPage extracts metadata from both event tags and JSON content
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Added useAddrEvent hook for fetching addressable events by kind+pubkey+d-tag
- Created EmbeddedNaddr component that displays title, description, image, and author
from addressable events (extracting metadata from tags and JSON content)
- Updated NoteContent to detect naddr1 identifiers in regular URLs (e.g.
bitpopart.com/art/naddr1...) and render them as Nostr embeds
- Added naddr1 to the nostr: URI regex so nostr:naddr1... is also handled
- Added naddr-embed token type with proper whitespace collapsing
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Create EmbeddedNote component with avatar, author name, timestamp,
truncated content preview, and optional image thumbnail
- Update NoteContent tokenizer to detect note1 and nevent1 references
and render them as embedded cards instead of plain text links
- Collapse whitespace around embedded note cards like link previews
- Clicking an embedded card navigates to the full post detail page
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
Spacing:
- Reduce link preview margins from my-2 to mt-1.5 mb-0.5
- Collapse whitespace on text tokens adjacent to block-level tokens
(link-preview, youtube-embed) so newlines from the original content
don't stack with the card's own spacing
- Filter out empty text tokens after trimming
Bot headers:
- Send proper User-Agent header ("Mew/1.0 Link Preview Bot") when
fetching OG data so dynamic sites (SPAs, Twitter, etc.) return
server-rendered HTML with OG meta tags instead of a JS shell
- Accept application/xhtml+xml in addition to text/html
YouTube embeds:
- Detect YouTube URLs (youtube.com/watch, youtu.be, /embed/, /shorts/)
and extract video ID
- New YouTubeEmbed component renders a privacy-enhanced iframe player
(youtube-nocookie.com) with proper 16:9 aspect ratio
- YouTube links render as playable inline embeds instead of OG cards
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
Move LinkPreview rendering from a fixed position below the post into
NoteContent itself, so previews appear exactly where the URL was in
the original text.
- Rewrite NoteContent to use a token-based architecture: useMemo
produces typed tokens (text, link-preview, mention, nostr-link,
hashtag), then the render phase maps tokens to components
- Non-media URLs produce a `link-preview` token that renders an
inline <LinkPreview> card at that position in the content flow
- Remove separate LinkPreview blocks from NoteCard and PostDetailPage
since previews are now handled by NoteContent
- Remove unused extractPreviewUrl helper from useLinkPreview hook
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Add useLinkPreview hook that fetches Open Graph metadata (title,
description, image, favicon, site name) via CORS proxy with 1hr
stale time caching
- Add extractPreviewUrl helper to find the first non-media URL in
note content
- Add LinkPreview component with a polished card UI showing OG image,
title, description, domain favicon, and external link indicator
- Strip all URLs (both media and non-media) from NoteContent inline
text — media URLs are rendered as image embeds, non-media URLs are
rendered as LinkPreview cards
- Integrate LinkPreview into NoteCard and PostDetailPage between
image attachments and action buttons
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
Image URLs (jpg, jpeg, png, gif, webp, svg) are already rendered as
embedded image previews by NoteCard and PostDetailPage. This change
removes them from the inline text content to avoid duplication.
Also trims leading/trailing whitespace left behind after stripping
image URLs from the edges of content.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>