- Updated CTA text to "Follow accounts you care about on Mew"
- Reinforces brand identity in the call-to-action
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Reduced padding from py-6 to py-3 for more compact design
- Horizontal layout instead of vertical stacking
- Better CTA copy: "Follow accounts you care about"
- Smaller button size (sm) and simpler "Join" text
- Keeps gradient background but with better proportions
- More balanced and less overwhelming
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Center-aligned design for better visual balance
- Gradient background (primary/5 to primary/10) for subtle depth
- Larger, more prominent "Join Mew" button with shadow effects
- Engaging copy: "Join to unlock your personalized feed ✨"
- Increased padding and spacing for breathing room
- More visually appealing and less boring design
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Change to "Join Mew to follow accounts & personalize your feed"
- Add emphasis with bold "Join Mew" in foreground color
- Use medium font weight for better visual hierarchy
- Make Join button smaller (sm size) for better balance
- More engaging and visually distinct CTA
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Changed "Join Mew to personalize your feed and connect with others" to "Join to personalize your feed"
- More concise and direct call-to-action
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Show Follow/Global tabs only when user is logged in
- Display CTA banner with Join button when logged out
- CTA message: "Join Mew to personalize your feed and connect with others"
- Join button triggers login dialog in Feed component
- Added LoginDialog and SignupDialog to Feed component
- Improves UX with clear call-to-action instead of empty tab bar
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Import useCurrentUser hook to check login status
- Conditionally render tabs only when user is logged in
- Change default tab to 'global' for logged-out users
- Improves UX by showing only relevant UI elements based on auth state
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Added onSignupClick prop to LoginDialog interface
- Added "New here? Create account" link in LoginDialog
- Link appears after extension login button (if available) or with other options
- Matches borkstr's login dialog pattern for better UX
- Users can easily switch between login and signup flows
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Changed Join button onClick handler to open LoginDialog instead of SignupDialog
- Follows the same pattern as borkstr project where Join opens the login modal
- Users can still access signup through the login modal's "More Options" section
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Moved early return to after all hooks to comply with Rules of Hooks
- Changed handleLogout to async/await pattern for better error handling
- Prevents "Rendered more hooks than during the previous render" error
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Simplified code to inline filters in className
- Light theme: dark grey filter
- Pink theme: dark pink filter with medium brightness
- Dark/Black themes: no filter (original logo)
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Light theme: neutral dark grey filter (no color tint)
- Pink theme: vibrant dark pink filter with high saturation
- Improved contrast and readability on light backgrounds
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Apply dark blue-purple filter for light theme to make logo readable
- Apply dark pink filter for pink theme to match theme and improve visibility
- Replace opacity with color filters for better contrast
- Logo remains unfiltered in dark and black themes
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Show current theme name and icon in dropdown trigger button
- Fix light theme not working (update class removal from 'mew' to 'dark')
- Remove opacity from logo in pink theme (keep full visibility)
- Logo now only uses opacity in light theme (70%)
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Use opacity (60% pink, 70% light) for MewLogo instead of color filters
- Change Mew theme icon to Cat, Black theme icon to Moon
- Convert theme selector to proper dropdown menu with chevron indicator
- Add DropdownMenuLabel and separator for better UX
- Maintain theme icons: Cat (Mew), Sun (Light), Moon (Black), Heart (Pink)
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Rename "mew" theme to "dark" (Mew=dark, Light=light remain)
- Make pink theme more vibrant with increased saturation and adjusted hues
- Convert theme selector to dropdown menu with icons (Moon, Sun, Zap, Heart)
- Add CSS filters to MewLogo for pink and light themes with smooth transitions
- Keep Black and Pink themes as requested
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
Add showEmojis prop to ReactionButton (default false). The emoji
indicators next to the count now only render when showEmojis is
true, which is only passed from PostDetailPage.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
The optimistic +1 delta was stacking on top of the refetched stats
(which already included the new reaction), causing the count to
jump by 2. Now we reset the delta to 0 on success so only the
real server count is displayed.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Create ReactionButton component with Popover-based emoji picker
- Clicking the reaction button opens the full emoji picker (EmojiPicker)
- Selecting an emoji publishes a NIP-25 kind 7 reaction event with proper e/p/k tags
- Optimistically increments the reaction count and shows the user's chosen emoji
- Reverts optimistic update on publish failure
- Invalidates event-stats and event-interactions queries on success
- Replace static heart/like buttons in NoteCard and PostDetailPage with ReactionButton
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
Parse nostr:npub1… and nostr:nprofile1… references within embedded note
card text and render them as clickable @username mentions (resolving the
display name via useAuthor), matching the style used in NoteContent.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
Embedded note cards now strip out nostr:nevent1... and nostr:note1...
references from the content preview text, preventing recursive embedding
and keeping the preview clean.
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>
- Cap display name to max 40% width so it doesn't get crushed by long NIP-05 addresses
- Make NIP-05 span properly truncate with min-w-0 instead of pushing the layout
- Timestamp and separator remain fixed (shrink-0) so they're always visible
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
Unreliable metric since it only reflects the limited number of posts fetched, not the user's actual total.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Removed the Calendar icon and "Joined Nostr" text from profile info
- Added truncate to NIP-05 address to prevent overflow
- Added min-w-0 and truncate to website URL to prevent container breakout
- Made link icon shrink-0 to prevent it from being squished by long URLs
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Scrollbars are hidden by default (transparent thumb and track)
- Thin 6px scrollbar appears with 25% opacity on container hover
- Thumb brightens to 40% on direct hover for feedback
- Works across both webkit and Firefox (scrollbar-width/scrollbar-color)
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Use flex items-center on the input wrapper instead of absolute
top-1/2 -translate-y-1/2 hacks for proper icon centering
- Remove focus-visible ring and ring-offset on search input
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Create useSearchProfiles hook that queries wss://relay.ditto.pub
with NIP-50 search filter for kind 0 (profile) events
- Create ProfileSearchDropdown component with debounced input,
keyboard navigation, and animated dropdown of matching profiles
- Update SearchPage to use the new profile autocomplete
- Update LeftSidebar search bar to use the profile autocomplete
- Selecting a profile navigates to their npub profile page
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Removed the border-top from the footer
- Changed aside from lg:block to lg:flex flex-col for flex layout
- Added mt-auto to push footer to the bottom, mirroring the left
sidebar's profile position
- Right-aligned the text with text-right
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
The query already had limit: 5 at the relay level, but relays may
return more results than requested. Added .slice(0, 5) after sorting
to guarantee only the 5 most recent accounts are shown.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
Added z-10 to the Feed tab bar so note content scrolls behind
it instead of overlapping on top.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Added logo.png to public folder
- Added favicon and apple-touch-icon link tags to index.html
- Updated manifest.webmanifest with icon references
- Updated MewLogo component to render the PNG image instead of SVG
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
ReplyComposeModal now handles both cases: when an event is passed it's a
reply (shows embedded post preview), when no event is passed it's a new
post. FloatingComposeButton reuses ReplyComposeModal instead of having
its own duplicate dialog.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
Updated ReplyComposeModal, FloatingComposeButton, and InteractionsModal
to place the title on the left and the dismiss X button on the right,
matching the standard dialog layout pattern.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Created useEventInteractions hook that fetches kind 6 (reposts),
kind 7 (reactions), and kind 9735 (zap receipts) for a given event ID
- Created InteractionsModal component with three tabs:
- Reposts: shows who reposted with avatar, name, and timestamp
- Reactions: groups reactions by emoji, showing each user under the
emoji header with counts
- Zaps: shows who zapped with amount badges (sorted by largest first),
zap messages, and a total sats summary at top
- Stats row text (e.g. "2 Reposts", "1 👍", "500 sats") is now clickable
and opens the modal to the relevant tab
- Action buttons (Repost, Reactions, Zaps) in the post detail view also
open the modal to their respective tabs
- All user rows link to the user's profile page
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Created ReplyComposeModal component that shows the original post embedded
in a compact card above the compose area, matching the reference design
- Updated ComposeBox to accept replyTo, forceExpanded, and hideAvatar props
- ComposeBox now generates proper NIP-10 reply tags (root/reply markers,
p tags for thread participants)
- Wired reply buttons in NoteCard and PostDetailPage to open the modal
- Reply success invalidates both feed and replies query caches
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Map "+" and empty reactions to 👍 emoji so they appear in the stats row
- Remove border-top from stats row and date-only row to match Ditto
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>