Commit Graph

4447 Commits

Author SHA1 Message Date
shakespeare.diy 7e55267c86 Move website from profile description to profile fields section
- Remove standalone website link from main profile bio area
- Prepend website as a "Website" field entry in the fields list
- Add inline ProfileFieldInline component for mobile view (xl:hidden)
- Website now appears alongside other profile fields in the sidebar (desktop) and inline below bio (mobile)
- Special rendering for $BTC fields with orange Bitcoin icon and truncated address

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 04:10:11 -06:00
shakespeare.diy d19d80736d Align BTC modal close button with title by matching top/right to p-6 padding
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 04:07:05 -06:00
shakespeare.diy 760ab183b8 Fix BTC modal: align title and X button by moving padding to DialogContent
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 04:06:15 -06:00
shakespeare.diy 1a1e9e015b Remove external link from BTC QR modal title
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 04:05:38 -06:00
shakespeare.diy 1424a8bee6 Fix BTC modal: add pr-10 to title row so external link sits left of close X
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 04:04:48 -06:00
shakespeare.diy 93a484600d Fix BTC modal copy icon clipping: ensure icon never overflows
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 04:03:43 -06:00
shakespeare.diy c5a24653f6 BTC modal: single-line address with copy icon, truncated overflow
- Address and copy icon on one line as a clickable row
- Address truncates with ellipsis, copy icon stays visible
- Whole row is clickable to copy, shows check on success

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 04:02:27 -06:00
shakespeare.diy 288707b0d6 Fix BTC modal layout: stack address and copy button vertically
- Show full address with break-all instead of truncating
- Full-width "Copy address" button below the address
- Prevents the copy button from being clipped by modal overflow

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 04:01:12 -06:00
shakespeare.diy 1e364f7a80 Fix BTC modal overflow, profile follow crash, and genUserName undefined crash
- Add min-w-0 to BTC modal address container to prevent long address from
  breaking the dialog's horizontal overflow
- Guard isFollowing useMemo against undefined followData.pubkeys
- Make genUserName handle undefined seed gracefully (returns 'Anonymous')

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:59:37 -06:00
shakespeare.diy 2f9128068f Add profile tabs, more menu, and follow/unfollow toggle
- Add tabs: Posts (top-level only), Posts & replies, Media, Likes
- Posts tab filters out replies, Media tab filters to posts with images/videos
- Likes tab fetches kind 7 reactions and resolves the liked events
- Add ... more menu with copy pubkey, copy link, view on njump, mute, report
- Follow button checks kind 3 contact list and toggles follow/unfollow
- Unfollow button shows destructive hover state for clarity
- Tabs have sticky positioning with backdrop blur matching feed tabs

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:57:48 -06:00
shakespeare.diy 40ea816f5d Fix media sidebar: link to events, favicon .ico/.svg fallback, fix image rendering
- Media tiles now link to the source event (nevent) instead of opening the raw image
- Favicons try /favicon.ico first, then fall back to /favicon.svg
- Add explicit image-rendering: auto to fix crispy/aliased thumbnails
- Data model now tracks eventId + authorPubkey per media item

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:52:59 -06:00
shakespeare.diy 518c659dc9 Fix media grid spacing, image crispness, and favicon rendering
- Tighten media grid gap from 1.5 to 0.5 for closer tiles
- Remove sizes="96px" hint that was causing pixelated/crispy image rendering
- Switch favicons from Google service to direct /favicon.ico from each domain
- Remove rounded-sm background styling from favicon images

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:50:51 -06:00
shakespeare.diy d8a73007de Refine profile view: rounded media tiles, accent-colored flat streak, favicons on field URLs
- Media grid items now have individual rounded-lg corners with gap spacing
- Images use sizes hint for better quality rendering at small sizes
- Streak indicator: flat style with filled flame icon using theme accent color,
  positioned between username and description, 24h window, kind 1 only
- Profile field URLs now show Google favicon next to each link with graceful fallback

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:48:07 -06:00
shakespeare.diy 8de69a21af Add profile enhancements: zap button, posting streak, media sidebar, profile fields with $BTC QR code
- Add Zap button to profile header (visible for other users with lightning address)
- Add posting streak counter with flame icon (36h window, caps at 99+)
- Create ProfileRightSidebar with Media grid and Profile Fields sections
- Handle $BTC profile field with copiable address, QR code modal, and mempool.space link
- Regular profile fields render as labels with linked URLs
- MainLayout now accepts optional custom right sidebar prop

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:43:48 -06:00
shakespeare.diy ad8181754e Remove sticky header bar from profile page
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:36:46 -06:00
shakespeare.diy 457f4f27b4 Add bottom padding to "Vibed with Shakespeare" footer to align with left sidebar username height
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:35:46 -06:00
shakespeare.diy 1a8577bd6e Pause videos when scrolled out of view
Add IntersectionObserver to both VideoPlayer (used in note cards) and
VineMedia (used in vine feed cards) to automatically pause playback
when less than 25% of the video container is visible in the viewport.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:33:08 -06:00
shakespeare.diy 5c916947b9 Brighten destructive color on dark and black themes for better readability
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:31:17 -06:00
shakespeare.diy 6db6d9c337 Align theme dropdown menu to the right
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:30:04 -06:00
shakespeare.diy 09c5f88af1 Fix theme selector: add "Theme" label, fix hover clipping, open menu upward
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:29:23 -06:00
shakespeare.diy fb84bc8101 Switch to follows tab after login
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:28:12 -06:00
shakespeare.diy d7a98f61b8 Fix Home icon in mobile bottom nav: remove fill, use stroke highlight like other icons
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:27:33 -06:00
shakespeare.diy a058f098fc Bump mobile banner text to 13px
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:26:37 -06:00
shakespeare.diy 06315d8d55 Make "Follow accounts you care about" text smaller on mobile
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:26:07 -06:00
shakespeare.diy 7c1914eab4 Hide sign up button on mobile top bar when signed out; add "Join" label to FAB
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:25:36 -06:00
shakespeare.diy edea0eb013 Revert to 5babdf6: Defer sidebar queries until feed loads and sidebar is visible
This reverts the codebase back to the state at commit 5babdf6.

Reverted 2 commit(s):
- 64e1273: Race relays on first EOSE with grace timer for remaining
- cf193ab: Route reads to a single relay (round-robin) for fast EOSE resolution

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:21:19 -06:00
shakespeare.diy 64e1273458 Race relays on first EOSE with grace timer for remaining
Replace the round-robin single-relay approach with proper racing:
- Queries are sent to ALL read relays simultaneously
- First relay to return EOSE starts a 1.5s grace timer
- Remaining relays that respond within the grace window have their
  events merged into the result set
- If all relays finish before the timer, returns immediately
- Events are deduplicated via NSet (handles replaceable events correctly)
- Publishing and req() still delegate to the pool unchanged

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:20:52 -06:00
shakespeare.diy cf193abfd9 Route reads to a single relay (round-robin) for fast EOSE resolution
Previously reqRouter sent every query to all 3 read relays, meaning
NPool.query() had to wait for all relays to coordinate before resolving.
The slowest relay dictated the feed speed.

Now reads go to one relay at a time, rotating round-robin across the
configured read relays. Each query resolves as soon as that single relay
sends EOSE — no waiting on the other two. Publishing still fans out to
all write relays.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:18:33 -06:00
shakespeare.diy 5babdf6fa0 Defer sidebar queries until feed loads and sidebar is visible
- Add `enabled` parameter to `useTrendingTags` and `useLatestAccounts` hooks
- RightSidebar now detects xl breakpoint visibility with matchMedia
- Sidebar queries only fire after the feed finishes its initial fetch
- On smaller screens where the sidebar is hidden, queries are skipped entirely
- Gives the feed full relay bandwidth priority on page load

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:16:04 -06:00
shakespeare.diy d5f61e1ff8 Switch feed to infinite scroll with 30 events per page
- Rewrite useFeed to use useInfiniteQuery with timestamp-based pagination
- Reduce page size from 60/40 to 30 for both follows and global tabs
- Add intersection observer sentinel in Feed component for auto-loading
- Deduplicate feed items across pages
- Show spinner while fetching next page

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 03:05:55 -06:00
shakespeare.diy a830b4a1e8 Fix feed/vine skeletons to match NoteCard layout; skeleton-load profile names and avatars
- Feed NoteCardSkeleton: restructured to match NoteCard's avatar + stacked
  name/handle header with full-width content below (was incorrectly nested)
- VinesPage VineSkeleton: restructured to match vine card layout with
  header, title, video placeholder, hashtags, and actions
- SearchPage PostSkeleton: aligned with Feed skeleton for consistency
- NoteCard: show skeleton for avatar and name while useAuthor is loading,
  resolves to real data or fallback when relay responds/gives up
- RepostHeader: skeleton for reposter name while author loads
- ReplyContext: skeleton for reply-to name while author loads
- PostDetailPage: skeleton for author row in both main post and parent note
- EmbeddedNote: skeleton for author row in embedded note card
- EmbeddedNaddr: skeleton for author row in embedded naddr card

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:58:22 -06:00
shakespeare.diy 3ea786f3e8 Default to follows tab when logged in, filter out future-dated posts
- Feed.tsx: initialize activeTab to 'follows' when user is logged in, 'global' otherwise
- useFeed.ts: filter out events with created_at > now in both follows and global feeds, including embedded repost content and fetched originals

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:51:03 -06:00
shakespeare.diy 2e4513aab5 Video controls: volume next to play, primary accent progress bar, Expand icon
- Moved volume toggle to the right of the play/pause button
- Progress bar fill and scrub dot now use bg-primary accent color
- Replaced Maximize icon with Expand (lucide) for fullscreen button

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:47:44 -06:00
shakespeare.diy 1f61f7583f Custom video controls matching design: play/pause, seek bar, time, volume, fullscreen
Created a reusable VideoPlayer component with custom controls:
- Big centered play button overlay before first play
- Bottom control bar with gradient background that auto-hides during playback
- Play/pause toggle, seek bar with hover scrub dot, current/total time display
- Volume mute toggle and fullscreen button
- Controls reappear on mouse move and auto-hide after 2.5s
- Used in both NoteCard and PostDetailPage

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:46:10 -06:00
shakespeare.diy d63f431064 Use native browser video controls instead of custom play/pause overlay
Replaced custom play/pause overlay on note videos with native HTML5
video controls (play, pause, volume, progress, timestamp, fullscreen).

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:44:20 -06:00
shakespeare.diy e519f282f3 Render video embeds in kind 1 notes with play/pause overlay
- Extract video URLs (.mp4, .webm, .mov) from note content
- Parse all imeta tags into a URL-keyed map to get thumbnails for videos
- NoteCard renders videos with the same play/pause UI as vine events,
  using imeta thumbnail as the poster image
- PostDetailPage also renders videos with the same player
- Videos are already stripped from NoteContent text by the MEDIA_URL_REGEX

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:42:11 -06:00
shakespeare.diy 49917ec1a0 Preserve newlines between text and naddr URL in note content
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>
2026-02-17 02:34:50 -06:00
shakespeare.diy 7ca3587e1d Preserve original URL for naddr embeds and implement naddr detail page
- 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>
2026-02-17 02:33:06 -06:00
shakespeare.diy b81aa6f2c8 Render naddr1 URLs as embedded Nostr events instead of broken link previews
- 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>
2026-02-17 02:30:17 -06:00
shakespeare.diy 507a3430e1 Use consistent mr-1 spacing for repost and reply context labels
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:26:06 -06:00
shakespeare.diy 81c9249a18 Tighten spacing between username and "reposted" text
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:24:49 -06:00
shakespeare.diy 04ecbe7e4f Align repost header indent with reply context (ml-14)
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:24:01 -06:00
shakespeare.diy a3033b6b90 Include kind 6 reposts in the follows feed
- Updated useFeed hook to query kinds [1, 6] for the follows tab
- Reposts are resolved from embedded content JSON or fetched by event ID
- Added FeedItem type with repostedBy and sortTimestamp fields
- Deduplication prefers direct posts over reposts of the same event
- NoteCard now shows a "reposted by" header with the reposter's name
- Feed renders repost items with unique keys

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:22:46 -06:00
shakespeare.diy 98e2cb4578 Match right border to right sidebar visibility (xl breakpoint)
Changed `lg:border-r` to `xl:border-r` on the main content area across
all 12 pages so the right border only appears when the right sidebar is
visible (at xl/1280px+).

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:19:37 -06:00
shakespeare.diy 402d726836 Hide right sidebar below xl breakpoint (1280px)
The right sidebar was showing at lg (1024px) which made the three-column
layout too cramped. Changed from `hidden lg:flex` to `hidden xl:flex` so
the sidebar only appears when there's enough horizontal space.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:18:35 -06:00
shakespeare.diy 896252144e Show parent event on post detail page for replies
When viewing a reply's post detail page, the event being replied to
is now rendered above the main post with a thread connector line.

- Added getParentEventId() helper that extracts the parent event ID
  from e-tags following NIP-10 conventions (marked and positional)
- Added ParentNote component with avatar, author info, content preview,
  and a vertical thread connector line linking parent to child
- Parent note is clickable and navigates to its own post detail page
- Includes skeleton loading state while parent event is being fetched

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:16:27 -06:00
shakespeare.diy 5ad24f07cb Redesign notifications page with rich rendering
- Add All/Mentions tab bar with underline indicator
- Like notifications: show heart icon + actor name + original post with full content, images, link previews, and action buttons
- Repost notifications: show repost icon + actor name + original post
- Zap notifications: show zap icon + actor name + amount + original post
- Mention notifications: show @ icon + actor name + full note card with avatar, nip05, reply context, content, and action buttons
- Fetch referenced events for likes/reposts/zaps to show the original post
- Include reply, repost, react, zap, and more action buttons on all notification posts
- Skeleton loading states matching the new layout

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:12:12 -06:00
shakespeare.diy c051c1afd0 Restyle interaction buttons: left-aligned with gap spacing, show user's emoji or heart
- Changed action buttons from justify-between to gap-6 left-aligned layout
- Updated count text to text-sm tabular-nums for consistent sizing
- Simplified ReactionButton: shows user's own emoji if reacted, heart icon otherwise
- Removed unused reactionEmojis/showEmojis props from ReactionButton

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:07:07 -06:00
shakespeare.diy 8323f86db7 Stack author name and handle vertically in NoteCard header
Display name on first line (bold), @handle · timestamp on second
line (muted), matching the Ditto-style two-line author layout.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:04:51 -06:00
shakespeare.diy 27972c4e27 Remove left margin gap on all NoteCard content
Restructure NoteCard so avatar+name is a header row, and all
content (text, images, videos, action buttons) renders at full
card width below it — no more indentation from the avatar column.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-02-17 02:03:44 -06:00