Commit Graph

220 Commits

Author SHA1 Message Date
Gigi
41fb51c357 feat: stream highlights progressively as they arrive from relays 2025-10-05 22:42:39 +01:00
Gigi
647cf1caf7 feat: update default highlight colors to orange for friends and purple for nostrverse 2025-10-05 22:34:54 +01:00
Gigi
c407663c2b fix(settings): make startup preference checkboxes checked by default and remove redundant text 2025-10-05 22:26:04 +01:00
Gigi
ba34e51803 fix(bookmarks): ensure both panels start collapsed on initial load regardless of saved settings 2025-10-05 22:24:32 +01:00
Gigi
518c6d9714 feat(settings): set default font size to middle option (18px) 2025-10-05 22:19:51 +01:00
Gigi
5f7aab90a7 feat(settings): align color pickers and labels for better visual layout 2025-10-05 22:18:55 +01:00
Gigi
6d41d95627 feat(highlights): update default colors to yellow, orange, purple 2025-10-05 22:17:39 +01:00
Gigi
9aea1f9a70 feat(settings): enhance preview with longer text and three-level highlights 2025-10-05 22:16:20 +01:00
Gigi
8594b733ef style(settings): remove 'Color' from highlight setting labels 2025-10-05 22:15:35 +01:00
Gigi
be42203944 remove(settings): remove legacy highlight color setting 2025-10-05 22:15:08 +01:00
Gigi
c51c1810c4 feat(settings): set Source Serif 4 as default reading font 2025-10-05 22:14:47 +01:00
Gigi
6bbc5eb1fc docs(settings): clarify that both panels default to collapsed state 2025-10-05 22:14:01 +01:00
Gigi
ff5c974557 style(icons): change user icon to fa-user-circle in sidebar header 2025-10-05 22:13:21 +01:00
Gigi
61bc64ea26 feat(auth): make user icon clickable to trigger login when logged out 2025-10-05 22:13:01 +01:00
Gigi
73da428cd7 remove(highlights): remove 'Show context' functionality from highlight items 2025-10-05 22:12:41 +01:00
Gigi
ce2ccd54b3 fix(lint): resolve all linting and TypeScript errors 2025-10-05 22:12:07 +01:00
Gigi
4f8bc0c641 style(bookmarks): move view mode controls to bottom of bookmarks sidebar 2025-10-05 22:11:14 +01:00
Gigi
d6edddc572 style(bookmarks): right-align all buttons except collapse button in sidebar header 2025-10-05 22:10:09 +01:00
Gigi
6e0a88fbd9 style(bookmarks): reorder sidebar header buttons to collapse, refresh, settings, avatar, login/logout 2025-10-05 22:07:48 +01:00
Gigi
5e788b0026 style(highlights): move collapse button to far right of highlights header 2025-10-05 22:04:01 +01:00
Gigi
256540bf60 feat(bookmarks): add loading state to bookmark list with spinner 2025-10-05 22:03:12 +01:00
Gigi
e710391962 style(ui): replace all loading text with spinners per fontawesome rule 2025-10-05 22:02:01 +01:00
Gigi
aac4adeda6 feat(bookmarks): add refresh button to sidebar header with loading state 2025-10-05 22:00:18 +01:00
Gigi
6088dcc395 style(highlights): show only external-link icon for source (no label) 2025-10-05 21:57:57 +01:00
Gigi
f2422e9601 feat(highlights): color sidebar highlight items by level (mine/friends/nostrverse) 2025-10-05 21:54:02 +01:00
Gigi
d3ad08dd61 refactor(reader): extract ReaderHeader to keep ContentPanel concise (<210 lines) 2025-10-05 21:46:31 +01:00
Gigi
d148433fcc fix(content): render markdown immediately while computing highlights; prevent initial login refresh from overwriting article highlights 2025-10-05 21:45:47 +01:00
Gigi
8d7b853e75 fix: ensure highlights always render on markdown content
- Add logic to wait for HTML conversion when highlights need to be applied
- Prevent rendering plain markdown when highlights are pending
- Show ReactMarkdown fallback only when no highlights need to be applied
- Fixes default article highlights not showing
2025-10-05 21:15:30 +01:00
Gigi
cdbb920a5f fix: resolve linter errors
- Add missing useMemo import to Bookmarks component
- Remove unused NostrEvent import from contactService
- All ESLint checks passing
- All TypeScript type checks passing
2025-10-05 21:13:39 +01:00
Gigi
cc311c7dc4 fix: classify highlights before passing to ContentPanel
- Add classifiedHighlights memo in Bookmarks to ensure highlights have level property
- Pass classified highlights to ContentPanel so color-coded rendering works
- Reduce reader border-radius from 12px to 8px to reduce visual separation
- Fixes highlights not showing with proper colors on default article
2025-10-05 20:26:03 +01:00
Gigi
0fe1085457 feat: always show friends and user highlight buttons
- Show friends and user highlight buttons regardless of login status
- Disable buttons when user is not logged in (instead of hiding them)
- Add helpful tooltips indicating login is required
- Add disabled state styling with reduced opacity and not-allowed cursor
2025-10-05 20:18:06 +01:00
Gigi
65e7709c63 fix: remove Highlights title and count from panel, fix markdown rendering
- Remove 'Highlights' text and count number to save space in panel
- Fix markdown rendering fallback to always show content when finalHtml is not ready
- Simplify render logic by removing highlight count condition that prevented content display
2025-10-05 20:17:23 +01:00
Gigi
17b5ffd96e feat: implement three-level highlight system
- Add three highlight levels: nostrverse (all), friends (followed), and mine (user's own)
- Create contactService to fetch user's follow list from kind 3 events
- Add three configurable colors in settings (purple, orange, yellow defaults)
- Replace mode switcher with independent toggle buttons for each level
- Update highlight rendering to apply level-specific colors using CSS custom properties
- Add CSS styles for three-level highlights in both marker and underline modes
- Classify highlights dynamically based on user's context and follow list
- All three levels can be shown/hidden independently via toggle buttons
2025-10-05 20:11:10 +01:00
Gigi
7f95eae405 fix: ensure highlights are shown for markdown content
- Only show raw ReactMarkdown when there are no highlights
- Wait for finalHtml (with highlights) when highlights are present
- Prevents highlights from being bypassed during markdown conversion
2025-10-05 20:01:41 +01:00
Gigi
8e0970b717 fix: show markdown content immediately when finalHtml is empty
- Render markdown directly with ReactMarkdown when finalHtml is not ready yet
- Prevents empty content display while markdown is being converted to HTML
- Fixes issue where default article text doesn't show
2025-10-05 19:06:53 +01:00
Gigi
320e7f000a fix: prevent 'No readable content' flash for markdown articles
- Check for markdown/html existence before checking finalHtml
- Show empty container while markdown is being converted to HTML
- Fixes issue where nostr blog posts briefly showed error message
2025-10-05 13:34:38 +01:00
Gigi
832740fb59 fix: enable highlights display and scroll-to for markdown content
- Convert markdown to HTML before applying highlights
- Use hidden ReactMarkdown preview to render markdown
- Apply highlights to rendered HTML for both HTML and markdown content
- Fix scroll-to-highlight functionality for nostr blog posts (kind:30023)
- Ensure highlight marks are properly injected into markdown-rendered content
2025-10-05 13:28:49 +01:00
Gigi
43492a4488 refactor: simplify login by handling it directly in sidebar
Instead of navigating to /login route, login now happens directly when
clicking the login button in the sidebar header.

Changes:
- Moved login logic from Login component to SidebarHeader
- Uses Accounts.ExtensionAccount.fromExtension() directly
- Removed onLogin prop chain (App → Bookmarks → BookmarkList)
- Removed unnecessary BookmarksRoute wrapper component
- Shows 'Connecting...' state in button title during login
- Keeps code DRY by reusing same login logic without navigation

Result: Simpler, more direct user experience - one click to log in
from anywhere in the app.
2025-10-05 13:17:22 +01:00
Gigi
1552dd85d9 feat: show login button when logged out instead of logout button
- Added onLogin prop to Bookmarks, BookmarkList, and SidebarHeader
- SidebarHeader now conditionally renders login or logout button
- Login button uses faRightToBracket icon
- Logout button uses faRightFromBracket icon
- Clicking login button navigates to /login route
- Created BookmarksRoute wrapper to handle navigation
- Better UX for anonymous users browsing articles
2025-10-05 13:12:32 +01:00
Gigi
0bc89889e0 feat: show highlights in article content and add mode toggle
Fixes:
- Fixed highlight filtering for Nostr articles in urlHelpers.ts
  Now returns all highlights for nostr: URLs since they're pre-filtered
- This fixes highlights not appearing in article content

Features:
- Added highlight mode toggle: 'my highlights' vs 'other highlights'
- Icons: faUser (mine) and faUserGroup (others)
- Mode toggle only shows when user is logged in
- Filters highlights by user pubkey based on selected mode
- Default mode is 'others' to show community highlights
- Added CSS styling for mode toggle buttons

Result: Highlights now show both in the panel AND underlined in
the article text. Users can switch between viewing their own
highlights vs highlights from others.
2025-10-05 12:57:09 +01:00
Gigi
4d95657bca refactor: keep Bookmarks.tsx under 210 lines by extracting logic
Extracted large functions into separate modules to follow DRY principles
and keep files manageable:

- Created useArticleLoader.ts hook (92 lines)
  - Handles article loading from naddr
  - Fetches article content and highlights
  - Sets up article coordinate for refresh

- Created contentLoader.ts utility (44 lines)
  - Handles both Nostr articles and web URLs
  - Unified content loading logic
  - Reusable across components

Result: Bookmarks.tsx reduced from 282 to 208 lines 

All files now under 210 line limit while maintaining functionality.
2025-10-05 12:47:32 +01:00
Gigi
6f28c3906c fix: show highlights for nostr articles by skipping URL filter
The HighlightsPanel was filtering out ALL highlights that didn't have
a urlReference. But Nostr article highlights reference the article via
the 'a' tag (article coordinate), not a URL.

Since we already fetch highlights specifically for the current article
using fetchHighlightsForArticle(), we don't need to filter them again.

Solution:
- Skip URL filtering when selectedUrl starts with 'nostr:'
- Keep URL filtering for web articles (backwards compatible)
- Highlights are already pre-filtered by the fetch query

This fixes the issue where 101 highlights existed for the default
article but weren't being displayed in the UI.
2025-10-05 12:37:28 +01:00
Gigi
70b85b0cf0 fix: refresh button now works without login for article highlights
- Track current article coordinate and event ID in state
- Update handleFetchHighlights to refresh article highlights if viewing article
- Fall back to fetching user's highlights only if logged in and not viewing article
- Refresh button now works for anonymous article viewing
- No longer requires activeAccount to refresh highlights

Previously the refresh button only worked when logged in because it tried
to fetch highlights BY the user. Now it intelligently fetches highlights
FOR the current article, or falls back to user highlights if logged in.
2025-10-05 12:23:08 +01:00
Gigi
2297d8ae96 fix: query highlights using both a-tag and e-tag
- Highlights on replaceable events include BOTH 'a' and 'e' tags
- Query for highlights using article coordinate (#a tag)
- Also query using event ID (#e tag) for comprehensive results
- Combine and deduplicate results from both queries
- Add detailed logging to help diagnose why highlights aren't found
- Suggest checking highlighter.com if no highlights found

Per NIP-84 and applesauce implementation, highlights on kind:30023
articles include both an addressable reference ('a' tag) and an event
reference ('e' tag).
2025-10-05 09:19:43 +01:00
Gigi
343f176f06 debug: add detailed logging for highlight fetching
- Log article details (event ID, author, kind, d-tag, coordinate)
- Log filter being used for highlight queries
- Log sample highlight tags when found
- This will help debug why highlights aren't showing
2025-10-05 09:18:55 +01:00
Gigi
ca46feb80f fix: fetch highlights by article reference instead of author
- Add fetchHighlightsForArticle() to query highlights by article coordinate
- Use #a tag filter to find highlights that reference the article
- Query well-known relays for highlights even without authentication
- Extract article's d-tag and construct coordinate (kind:pubkey:identifier)
- Keep original fetchHighlights() for fetching user's own highlights
- Add detailed logging for debugging highlight fetching

This fixes the issue where no highlights were shown because we were
querying for highlights created BY the article author rather than
highlights created ABOUT the article.
2025-10-05 09:12:01 +01:00
Gigi
1f5e3f82b0 feat: load default article on startup with collapsed sidebars
- Redirect root path to default article (naddr)
- Start with both sidebars (bookmarks and highlights) collapsed
- Auto-fetch and show highlights for the article author
- No authentication required to view articles
- Highlights panel auto-expands when article loads
- Login page moved to /login route
2025-10-05 09:06:54 +01:00
Gigi
6265af74f2 docs: clarify why we extract image tag directly in BookmarkItem
Add comment explaining that we extract the image tag directly from
bookmark.tags since we don't have the full NostrEvent here. When we
do have full events (like in articleService), we use getArticleImage()
helper from applesauce-core as intended.
2025-10-05 08:24:05 +01:00
Gigi
e8f44986da feat: display article hero images in bookmark views and reader
- Add image prop to ContentPanel to display hero images
- Extract image tag from kind:30023 bookmark tags
- Display article images in Card, Large, and Compact views
- Show hero image at top of article reader view
- Add CSS styling for article-hero-image and reader-hero-image
- Article images clickable to open article in reader
- Per NIP-23: image tag contains header/preview image URL
2025-10-05 08:22:46 +01:00
Gigi
3d304dab15 fix: use bookmark pubkey for article author instead of tag lookup
- Pass pubkey along with bookmark data to handleSelectUrl
- Use bookmark.pubkey directly when constructing naddr
- More reliable article loading with correct author attribution
- Update type signatures across all components
2025-10-05 08:20:38 +01:00