Commit Graph

12 Commits

Author SHA1 Message Date
shakespeare.diy 0ac0dc0569 DRY: merge VineCard into NoteCard, single component for all event kinds
- NoteCard now handles both kind 1 (text notes) and kind 34236 (vines)
- Extracted NoteBody (text + images) and VineBody (title + video + hashtags)
  as internal sub-components within NoteCard
- Same avatar, header, action buttons (reply, repost, react, zap, more),
  more menu, and reply modal shared across all kinds
- Addressable events (kind 30000+) use naddr encoding for navigation
- Deleted standalone VineCard.tsx — no longer needed
- Updated SearchPage and VinesPage to use NoteCard for everything

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 01:19:39 -06:00
shakespeare.diy beeff37dc6 Add emoji picker for reactions with optimistic count updates
- 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>
2026-02-16 23:23:03 -06:00
shakespeare.diy dd02f2ff27 Render link previews inline where URLs appear in post content
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>
2026-02-16 23:00:58 -06:00
shakespeare.diy 00d5024218 Replace non-media link URLs with rich preview cards
- 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>
2026-02-16 22:58:19 -06:00
shakespeare.diy 8b46ce9692 Fix NIP-05 and display name truncation in NoteCard header
- 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>
2026-02-16 22:53:36 -06:00
shakespeare.diy 7cdbf4a6e6 Add reply compose modal with embedded original post preview
- 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>
2026-02-16 21:35:26 -06:00
shakespeare.diy 3fa066bd46 Add post detail page with replies and reply composer
- Create PostDetailPage with expanded post view showing author info,
  full content, images, stats (reposts, likes, zap amount), full date,
  action buttons, and inline reply composer
- Create useEvent hook for fetching single events by hex ID
- Create useReplies hook for fetching kind:1 replies to an event
- Update NIP19Page to render PostDetailPage for note1/nevent1 identifiers
- Make NoteCard clickable to navigate to post detail via nevent1 URL
- Fix NoteMoreMenu to use React Router navigate instead of window.location.href

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-16 21:24:01 -06:00
shakespeare.diy f181f58425 Show total zap amount (sats) instead of zap count on notes
- useEventStats now sums the `amount` tag (millisatoshis) from kind 9735
  zap receipts and returns `zapAmount` in sats instead of a zap count
- NoteCard displays the total with compact formatting (e.g. 1.2K, 3.5M)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-16 17:53:22 -06:00
shakespeare.diy 03e563d3a5 Remove bookmark button from NoteCard action bar
Bookmark functionality is still accessible via the More menu dialog.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-16 17:52:07 -06:00
shakespeare.diy 6e92ff3468 Add More menu dialog to NoteCard (Ditto-style)
- Created NoteMoreMenu component as a centered dialog with grouped actions:
  - Show Post Details, Copy Link to Post, View on njump.me, Bookmark
  - Mute Conversation, Mention @user
  - Mute @user, Report @user (destructive)
  - Close button
- Added the ⋯ More button back to NoteCard action bar alongside Bookmark
- Menu items show the author's display name dynamically
- Copy Link copies nevent-based URL to clipboard with toast feedback
- Bookmark option in the menu toggles bookmark state via useBookmarks hook

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-16 17:48:48 -06:00
shakespeare.diy 589a60ec89 Replace "More" with Bookmarks page
- Created useBookmarks hook for NIP-51 kind 10003 bookmark list management
  (query, add, remove bookmarks)
- Created BookmarksPage with login prompt, loading skeletons, and empty state
- Replaced "More" nav item with "Bookmarks" in LeftSidebar
- Added bookmark toggle button to NoteCard action bar (replaces three-dot menu)
- Removed /more route from AppRouter
- Bookmarks are stored per NIP-51 as replaceable kind 10003 events

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-16 17:46:37 -06:00
shakespeare.diy 4f1b4800d0 Build Mew: a full-featured kind 1 Nostr client
- Dark theme with purple accent colors matching the reference design
- Three-column layout: left sidebar, main feed, right sidebar
- Left sidebar: Mew logo, search, navigation (Home, Notifications, Search, Vines, Profile, Wallet, Settings, More), compose button, user profile/login
- Main feed: compose box, Follows/Global tabs, live note cards with avatars, author info, NIP-05 verification, relative timestamps, image attachments, and action buttons (reply, repost, like, zap, more)
- Right sidebar: trending hashtags with sparklines, latest accounts, footer
- Full routing: home, profile, notifications, search, hashtags, settings (profile/relays), placeholder pages
- NIP-19 routing with automatic profile redirect
- Custom hooks: useFeed, useTrendingTags, useLatestAccounts, useEventStats
- NoteContent renders mentions, links, and hashtags as clickable elements
- Inter Variable font, skeleton loading states, responsive layout

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-16 17:05:32 -06:00