- Show highlight button when readerContent exists (both nostr articles and external URLs)
- Hide highlight button when browsing app pages like explore, settings, etc.
- Ensures highlighting is available for all readable content but not for navigation pages
- Only display the floating highlight button when currentArticle exists or selectedUrl is a nostr article
- Prevents highlight button from showing on external URLs, videos, or other content types
- Improves UX by showing highlight functionality only where it's relevant
- Fetch marked-as-read articles in useBookmarksData and Explore
- Pass markedAsReadIds through component chain (Bookmarks -> ThreePaneLayout -> BookmarkList)
- Display 100% progress for marked articles in all views (Archive, Bookmarks, Explore)
- Update filter logic to treat marked articles as completed
- Marked articles show green 100% progress bar
- Marked articles only appear in 'completed' or 'all' filters
- Remove reading position tracking from Me.tsx (not needed when all are marked)
- Clean up unused imports and variables
- Add reading position loading to Explore component
- Add reading position loading to useBookmarksData hook
- Display progress bars in Explore tab blog posts
- Display progress bars in Bookmarks large preview view
- Progress shown as colored bar (green for completed, orange for in-progress)
- Only shown for kind:30023 articles with saved reading positions
- Requires syncReadingPosition setting to be enabled
- Bookmark button now visible at top (only hides on scroll down)
- Highlights button hides both at top AND on scroll down
- Separated visibility logic into showBookmarkButton and showHighlightsButton
- Relay status indicator follows bookmark button behavior
- Highlights button now hidden when at the very top of the page
- Tracks scroll position and hides button when scrollY <= 10px
- Bookmark button remains visible as always
- Highlights button appears when scrolling up from below
- Improves UX by reducing visual clutter at page top
- Bookmark button now visible on all pages except settings
- Only hides when scrolling down while reading an article
- Fixes issue where button was hidden on /p/ (profile) and other pages
- Highlights button only shows when viewing article content
- Prevents users from getting stuck without navigation options
- Remove settings parameter from useImageCache and useCacheImageOnLoad hooks as it was never used
- Update all call sites in CardView, CompactView, LargeView, and ReaderHeader
- Remove settings prop from BookmarkItem and its child view components
- Remove settings prop from BookmarkList component
- Update ThreePaneLayout to not pass settings to BookmarkList
This change cascades through the component tree to clean up unused props that were
introduced when we refactored the image caching to use Service Worker instead of
local storage.
- Make AuthorCard clickable to navigate to user profiles
- Add /p/:npub and /p/:npub/writings routes
- Reuse Me component for public profiles with pubkey prop
- Show highlights and writings tabs for any user
- Hide private tabs (reading-list, archive) on public profiles
- Public profiles show only public data (highlights, writings)
- Private data (bookmarks, read articles) only visible on own profile
- Add clickable author card hover styles with indigo border
- Decode npub to pubkey for profile viewing
- DRY: Single Me component serves both /me and /p/:npub routes
- Only show mobile floating buttons when viewing article content
- Hide buttons on settings/explore/me views to avoid UI clutter
- Update conditional rendering logic in ThreePaneLayout
- Convert mobile hamburger and highlights buttons to Tailwind
- Migrate mobile backdrop to Tailwind utilities
- Remove 60+ lines of CSS from app.css and sidebar.css
- Maintain responsive behavior and z-index layering
- Keep dynamic color support for highlight button
- Reduce overall size of indicator on desktop (smaller padding, font sizes)
- On mobile, match size with sidebar toggle buttons (var(--min-touch-target))
- Auto-collapse on mobile (collapsed by default, tap to expand)
- Hide when scrolling down on mobile, show when scrolling up
- Match behavior of other mobile UI controls for consistency
- Update HighlightsPanelCollapsed to accept settings prop
- Apply highlightColorMine to the expand button icon and text
- Pass settings through HighlightsPanel and ThreePaneLayout
- Update floating highlight button (FAB) to use highlightColorMine from settings
- Update mobile highlights button to use highlightColorMine from settings
- Both buttons now reflect the user's chosen 'my highlights' color
- Create reactionService for handling kind:7 and kind:17 reactions
- Add mark as read button at the end of articles (📚 emoji)
- Use kind:7 reaction for nostr-native articles (/a/ paths)
- Use kind:17 reaction for external websites (/r/ paths)
- Pass activeAccount and currentArticle props through component tree
- Add responsive styling for mark as read button
- Button shows loading state while creating reaction
- Only visible when user is logged in
Implements NIP-25 (kind:7 reactions) and NIP-25 (kind:17 website reactions).
Users can now mark articles as read, creating a permanent record on nostr.
- Create Me component to display logged-in user's highlights
- Add /me route to App routing
- Update SidebarHeader to navigate to /me when clicking profile avatar
- Integrate Me page in ThreePaneLayout (same as Settings/Explore)
- Show user profile info and highlight count
- List all highlights created by the user
Clicking the profile picture now takes you to your personal highlights page.
- Remove unused React import from nostrUriResolver
- Add block scoping to switch case statements
- Add react-hooks plugin to eslint config
- Fix exhaustive-deps warnings in components
- Fix DecodeResult type to use ReturnType<typeof decode>
- Update dependency arrays to include all used values
- Add eslint-disable comment for intentional dependency omission
All linting warnings resolved. TypeScript type checking passes.
- Update useScrollDirection to accept elementRef parameter
- Detect scroll on main pane div instead of window
- Create mainPaneRef and attach to scrollable content area
- Fix issue where scroll events weren't detected on mobile
On mobile, content scrolls within .pane.main (overflow-y: auto) not on window.
Now buttons properly hide on scroll down and show on scroll up.
- Add articleTitleResolver service to fetch article titles from relays
- Extract naddr identifiers from markdown content
- Fetch article titles in parallel using relay pool
- Replace naddr references with actual article titles
- Fallback to identifier if title fetch fails
- Update markdown processing to be async for title resolution
- Pass relayPool through component tree to enable resolution
Example: nostr:naddr1... now shows as "My Article Title" instead of "article:identifier"
Improves readability by showing human-friendly article titles in cross-references
- Add useScrollDirection hook for scroll direction detection
- Hide bookmark and highlight buttons when scrolling down
- Show buttons again when scrolling up
- Smooth opacity transitions for better UX
- Only detect scroll when buttons are visible
- Improves mobile reading experience by maximizing content area
- Move refresh button from top bar to end of bookmarks list
- Show relative time of last fetch next to refresh button
- Add 'Explore' button (fa-newspaper icon) to top bar that links to /explore
- Track lastFetchTime in useBookmarksData hook
- Better UX with explore more prominent and refresh less intrusive
- Add imageCacheService with localStorage-based image caching and LRU eviction
- Create useImageCache hook for React components to fetch and cache images
- Integrate image caching with article service to cache cover images on load
- Add image cache settings (enable/disable, size limit) to user settings
- Update ReaderHeader to use cached images for article covers
- Update BookmarkViews (CardView, LargeView) to use cached images
- Add image cache configuration UI in OfflineModeSettings with:
- Toggle to enable/disable image caching
- Slider to set cache size limit (10-200 MB)
- Display current cache stats (size and image count)
- Clear cache button
Images are cached in localStorage for offline viewing, with a configurable
size limit (default 50MB). LRU eviction ensures cache stays within limits.
Make relay indicator icons clickable to trigger manual rebroadcast to all connected relays:
- Click plane icon (local/offline) to rebroadcast to remote relays
- Click server icon to rebroadcast to all relays
- Show spinner while rebroadcasting
- Update icon from plane to server on successful rebroadcast
- Keep plane icon on failure
- Pass relayPool and eventStore through component chain
- Add local state management for highlight updates in HighlightsPanel
- Enhance CSS with scale animation on hover/active
- Create RelayStatusIndicator component with plane icon for local-only mode
- Position indicator in bottom-left corner with amber styling
- Show when only local relays are connected or completely offline
- Hide indicator when remote relays are available (normal operation)
- Add pulsing globe icon animation to indicate checking for connection
- Include hover effects and smooth transitions
- Auto-adjust position when sidebar is collapsed
- Display relay count and clear status messages
- Add published field to ReadableContent interface
- Pass published date from article loader through component chain
- Display formatted publication date in ReaderHeader with calendar icon
- Format date as 'MMMM d, yyyy' using date-fns
- Add relayStatusService to track relay connections with 20-minute history
- Add useRelayStatus hook for polling relay status updates
- Create RelaySettings component to display active and recent relays
- Update Settings and ThreePaneLayout to integrate relay status display
- Shows relay connection status with visual indicators and timestamps
- Add summary field to ReadableContent interface
- Pass summary through ContentPanel to ReaderHeader
- Display summary below title in both overlay and standard layouts
- Style summary with reading font for consistency
- Summary appears in white with shadow in image overlays
- Summary appears in gray (#aaa) in standard headers
- Enhances article preview and reading experience
- Fixed crash when opening bookmark bar
- Removed non-existent Hooks.useRelayPool() call
- Added relayPool prop to SidebarHeader, BookmarkList, and ThreePaneLayout
- Threaded relayPool through component hierarchy from Bookmarks down
- Web bookmark creation now works correctly