Commit Graph

24 Commits

Author SHA1 Message Date
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
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
07a5826774 refactor: extract components to keep files under 210 lines
- Extract ColorPicker component from Settings
- Extract FontSelector component from Settings
- Move hexToRgb helper to colorHelpers utils
- Export HIGHLIGHT_COLORS constant from colorHelpers
- Settings.tsx now 209 lines (was 242)
- ContentPanel.tsx now 197 lines (was 204)

Keeps code DRY and improves maintainability
2025-10-05 04:17:03 +01:00
Gigi
b59a295ad3 feat: add highlight style setting (marker & underline) 2025-10-05 04:08:58 +01:00
Gigi
a95c0ed3ff refactor: reduce file sizes to meet 210 line limit
- Extract URL normalization to urlHelpers utility (DRY)
- Condense Settings.tsx from 212 to 190 lines
  - Inline IconButton props on single lines
  - Shorten preview text
- Condense ContentPanel.tsx from 223 to 190 lines
  - Extract filterHighlightsByUrl function
  - Remove unnecessary logic
- All files now under 210 line limit
- All lint and type checks pass
2025-10-05 04:02:49 +01:00
Gigi
9a1efd5b18 fix: prevent duplicate highlight application
- Store original HTML in ref to prevent re-highlighting already highlighted content
- Separate highlight application from click handler attachment effects
- Remove onHighlightClick from highlight application dependencies
- Remove verbose console logging for cleaner code
- Highlights now apply correctly without stacking on top of each other
2025-10-05 03:09:59 +01:00
Gigi
0ccad88dfd feat: add configurable reading font using Bunny Fonts
- Add readingFont setting to UserSettings interface
- Create fontLoader utility to load fonts from Bunny Fonts
- Add font selector dropdown in settings with popular reading fonts
- Use CSS variable --reading-font to apply font to reader content
- Support fonts: Inter, Lora, Merriweather, Open Sans, Roboto, Source Serif 4, Crimson Text, Libre Baskerville, PT Serif
- Fonts loaded from https://fonts.bunny.net/ (GDPR-friendly)
2025-10-05 02:52:21 +01:00
Gigi
e98dc1c5da fix: resolve all linting and type errors
- Remove unused applyHighlightsToText import from ContentPanel
- Replace while(true) with proper condition in findHighlightMatches
- Remove unused match parameter from replaceTextWithMark function

All ESLint and TypeScript checks now pass with no errors.
2025-10-04 22:13:31 +01:00
Gigi
38b80bc85b refactor: DRY up highlightMatching to stay under 210 lines
- Extract helper functions: normalizeWhitespace, createMarkElement, replaceTextWithMark
- Consolidate duplicate exact/normalized matching logic into tryMarkInTextNodes
- Reduce from 242 lines to 209 lines
- Maintain all functionality while improving code reusability
2025-10-04 20:45:06 +01:00
Gigi
0803417755 feat: improve highlight URL and text matching
- Use proper URL parsing to normalize URLs (remove www, query params, fragments)
- Add detailed logging for URL comparison to debug matching issues
- Implement two-pass text matching: exact match first, then normalized whitespace
- Handle whitespace variations in highlighted text more flexibly
- Add context to debug logs showing surrounding text

This should make highlights appear more reliably even with URL variations
and whitespace differences between the highlight and the actual content.
2025-10-04 20:32:55 +01:00
Gigi
a602f163fb fix: improve HTML highlight matching with DOM manipulation
- Replace simple string replacement with proper DOM tree walking
- Find text nodes and split them to insert mark elements
- Add extensive debugging to track highlight matching
- Handle text that spans across HTML elements correctly

This should fix the issue where highlights weren't showing up in
article content due to HTML tags breaking up the text.
2025-10-04 20:14:25 +01:00
Gigi
296600bb0d feat: add inline highlight annotations in content panel
- Create highlightMatching utility to find and apply highlights to text/HTML
- Update ContentPanel to accept highlights and match them to current URL
- Add visual highlighting with yellow background and blue underline
- Show highlight count indicator when content has highlights
- Add hover effects and tooltips showing highlight date
- Support both HTML and markdown content highlighting

Highlighted text now appears underlined in the main content panel when
viewing URLs that have associated NIP-84 highlights.
2025-10-04 19:58:10 +01:00
Gigi
3d6403f139 feat: fetch article hero images using free CORS proxy
- Add Open Graph image extraction from article HTML
- Use allorigins.win as free CORS proxy (no auth required)
- Implement HTML parsing to extract og:image meta tags
- Add in-memory caching to avoid repeated fetches
- Async loading with React useEffect for non-YouTube URLs
- 5 second timeout for fetch requests
- Graceful fallback to icon placeholder on errors
2025-10-03 10:24:34 +02:00
Gigi
57c5be9907 feat: add image preview for large view cards
- Extract YouTube video thumbnails from URLs
- Display thumbnail images as background in large preview cards
- Add gradient overlay for better text contrast
- Fallback to icon placeholder for non-YouTube URLs
- Handle multiple YouTube URL formats (watch, youtu.be, shorts)
- Gracefully handle missing images with icon fallback
2025-10-03 10:16:22 +02:00
Gigi
d6756dc5a1 refactor: remove duplicate formatDate function from helpers.ts
- Keep single formatDate implementation in bookmarkUtils.tsx
- Both BookmarkList and BookmarkItem already import from bookmarkUtils
- Maintain DRY principle by eliminating duplication
2025-10-03 09:27:56 +02:00
Gigi
5ea81bda8e fix(deps): replace relative-time with date-fns for timestamp formatting
- Replace relative-time package (which uses Temporal API) with date-fns
- Update formatDate to use formatDistanceToNow from date-fns
- Remove relative-time type declarations
- Apply fix to both helpers.ts and bookmarkUtils.tsx
- Fix runtime error: relative-time expects Temporal objects, not Date objects
- date-fns provides better compatibility with current JavaScript standards
2025-10-03 09:25:05 +02:00
Gigi
6ad273b5f9 fix(deps): correct relative-time package usage
- Change from calling relativeTime as function to instantiating RelativeTime class
- Use relativeTime.from(date) method instead of relativeTime(date)
- Update TypeScript type definitions to reflect class-based API
- Fix runtime error: 'Cannot call a class as a function'
- Apply fix to both bookmarkUtils.tsx and helpers.ts
2025-10-03 09:22:19 +02:00
Gigi
0d956ed692 feat(ui): display timestamps as relative time
- Install relative-time package from npm
- Update formatDate functions to use relative-time instead of toLocaleDateString
- Add TypeScript type definitions for relative-time module
- Show human-friendly relative times (e.g., '2 hours ago', 'yesterday')
- Apply to all timestamp displays (bookmark dates, created dates)
2025-10-03 02:03:31 +02:00
Gigi
448c4dac1c feat(bookmarks): classify URLs by type and adjust action buttons
- Add URL classification system (article, video, youtube, image)
- Classify based on domain (youtube) and file extensions
- Update button text: 'READ NOW' for articles, 'WATCH NOW' for videos, 'VIEW NOW' for images
- Update icons: faBookOpen for articles, faPlay for videos, faEye for images
- Apply classification to both individual URL buttons and main action button
2025-10-03 01:53:49 +02:00
Gigi
81a48bd0f6 feat(ui): resolve nprofile/npub mentions to names in content
- Add ResolvedMention component using applesauce ProfileModel
- Update parsed content renderer to use ResolvedMention for mentions
- Mentions now show @name and link to search page
2025-10-03 00:46:11 +02:00
Gigi
21890f002d chore(lint): fix hooks rule error by separating content resolver component and helpers
- Move shared helpers into src/utils/helpers.ts
- Add ContentWithResolvedProfiles component file to avoid hooks rule violation
- Use strong IconDefinition type in icon map
- Resolve linter warnings and errors
2025-10-03 00:12:40 +02:00
Gigi
6d585dcef6 feat(ui): resolve nprofile strings to human-readable names
- Add extractNprofilePubkeys utility to parse nprofile strings from content
- Create ContentWithResolvedProfiles component using applesauce ProfileModel
- Replace nprofile strings with @displayName in bookmark content
- Update BookmarkItem to use resolved content rendering
- Improves readability by showing names instead of long nprofile strings
2025-10-03 00:02:22 +02:00
Gigi
2253172e04 refactor: extract components and utilities to keep files under 210 lines
- Extract types to src/types/bookmarks.ts
- Extract utility functions to src/utils/bookmarkUtils.tsx
- Extract BookmarkItem component to src/components/BookmarkItem.tsx
- Extract BookmarkList component to src/components/BookmarkList.tsx
- Extract bookmark fetching logic to src/services/bookmarkService.ts
- Reduce main Bookmarks component from 416 to 100 lines
- Maintain all functionality while improving code organization
- Pass all linting and type checking
2025-10-02 09:19:44 +02:00