Commit Graph

409 Commits

Author SHA1 Message Date
Gigi
1a84817453 perf: publish bookmarks to relays in background
- Remove await on relayPool.publish() to not block UI
- Bookmark modal now closes immediately after signing
- Publishing happens asynchronously in the background
- Added error handling for failed relay publishes
- Fixes slow save issue caused by waiting for all 12 relays
2025-10-08 10:02:04 +01:00
Gigi
a0b98231b7 feat: add tags support to web bookmarks per NIP-B0
- Added tags input field to bookmark modal (comma-separated)
- Updated createWebBookmark to accept tags array
- Tags are added as 't' tags per NIP-B0 spec
- Added published_at tag with current timestamp
- Moved description to content field (per spec, not summary tag)
- d tag now uses URL without scheme (host + path + search + hash)
- Added helper text to explain tag formatting
- Styled form-helper-text for better UX
2025-10-08 09:51:33 +01:00
Gigi
d452f96f79 fix: pass relayPool as prop instead of using non-existent hook
- 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
2025-10-08 09:49:02 +01:00
Gigi
dcf43cfce1 feat: add web bookmark creation (NIP-B0, kind:39701)
- Created webBookmarkService for creating web bookmarks
- Added AddBookmarkModal component with URL, title, and description fields
- Added plus button to sidebar header (visible when logged in)
- Modal validates URL format and publishes to relays
- Auto-refreshes bookmarks after creation
- Styled modal with dark theme matching app design
- Follows NIP-B0 spec: URL in 'd' tag, title and summary tags
2025-10-08 09:44:45 +01:00
Gigi
815b3cc57d fix: correct type signature for addZapTags function
- Changed event parameter type from NostrEvent to { tags: string[][] }
- Allows function to accept both EventTemplate and NostrEvent
- Fixes TypeScript error where EventTemplate was passed before signing
- No functional changes, just type safety improvement
2025-10-08 09:27:36 +01:00
Gigi
7e54a01237 feat: add zap split preset buttons
- Added 4 preset buttons: Default, Generous, Selfless, and Boris 🧡
- Default: 50/2.1/50 (You: 49%, Author: 49%, Boris: 2%)
- Generous: 5/10/75 (You: 6%, Author: 83%, Boris: 11%)
- Selfless: 1/19/80 (You: 1%, Author: 80%, Boris: 19%)
- Boris 🧡: 10/80/10 (You: 10%, Author: 10%, Boris: 80%)
- One-click setup for common zap split configurations
- Hover tooltips show actual percentage splits
2025-10-08 09:25:37 +01:00
Gigi
ec4692da15 fix: prevent sliders from jumping when resetting settings
- Added debouncing (300ms) to settings auto-save
- Added flag to prevent external settings updates during local editing
- External updates are blocked for 500ms after save completes
- Fixes issue where rapid save/subscription cycle caused sliders to jump
- Settings now update smoothly when resetting to defaults
2025-10-08 07:14:06 +01:00
Gigi
f6d2f98eae refactor: make zap split sliders independent using weights
- Changed from percentage-based to weight-based zap splits
- All three sliders (highlighter, author, Boris) are now independent
- Weights are normalized to calculate actual percentages
- UI shows both weight value and calculated percentage
- Added migration logic for users with old percentage-based settings
- Each slider can be adjusted without affecting the others
- Prevents interdependent slider behavior that was confusing

Breaking change: Settings now use zapSplitHighlighterWeight,
zapSplitAuthorWeight, and zapSplitBorisWeight instead of
zapSplitPercentage and borisSupportPercentage
2025-10-08 07:06:42 +01:00
Gigi
9b97715274 feat: add Boris support percentage to zap splits
- Added borisSupportPercentage setting (default 2.1%)
- Added separate slider in ZapSettings for Boris support
- Updated zap split calculation to include three-way split:
  - Highlighter gets their configured percentage
  - Boris gets their support percentage (0-10%)
  - Author(s) get remaining percentage, split proportionally
- Display all three percentages in the UI
- Updated addZapTags to include Boris as zap recipient
- Boris support is optional and adjustable (0-10% range)
2025-10-08 07:03:47 +01:00
Gigi
fa1e536a26 refactor: move zap splits to dedicated settings section
- Created new ZapSettings component as separate section
- Moved zap split slider from ReadingDisplaySettings
- Placed at end of settings page as requested
- Updated description to mention multiple authors support
2025-10-08 07:02:02 +01:00
Gigi
29edd159e7 feat: respect existing zap tags in source content when creating highlights
- Updated addZapTags function to check for existing zap tags in source event
- When source has zap tags (author group), split proportionally:
  - Highlighter gets their configured percentage
  - Remaining percentage distributed among existing authors proportionally
- Example: 50/50 split with 2 source authors = 50% highlighter, 25% each author
- Falls back to simple two-way split if no existing zap tags
- Prevents duplicate entries if highlighter is already in author group
2025-10-08 06:53:53 +01:00
Gigi
00d9fbdbab feat: add home button to bookmark bar
- Add home icon button to sidebar header
- Clicking home button navigates to root path '/'
- Position home button before refresh and settings buttons
2025-10-08 06:34:22 +01:00
Gigi
239ab5763d feat: add configurable zap split for highlights on nostr-native content
- Add zapSplitPercentage setting (default 50%) to UserSettings
- Implement NIP-57 Appendix G zap tags for highlight events
- Add zap tags when creating highlights of nostr-native content
- Split zaps between highlighter and article author based on setting
- Add UI slider in settings to configure split percentage
- Include relay URL in zap tags for metadata lookup
- Only add author zap tag if different from highlighter
2025-10-08 06:32:02 +01:00
Gigi
0c3e697df6 fix(reader): wire preview ref to markdown conversion hook
- Update useMarkdownToHTML to return {renderedHtml, previewRef}
- Use returned previewRef in ContentPanel hidden markdown preview
- Resolves article markdown not rendering instantly
2025-10-07 22:16:31 +01:00
Gigi
a9847a8848 fix: add missing useEffect dependencies for article loading
- Fix useBookmarksData hook to include all callback dependencies
- Fix useArticleLoader hook to include all setter function dependencies
- Fix useExternalUrlLoader hook to include all setter function dependencies
- Ensures articles load properly when navigating
2025-10-07 22:04:12 +01:00
Gigi
5ef7d2c41c refactor: DRY up highlight classification and URL normalization
- Extract classifyHighlight and classifyHighlights utilities
- Remove duplicate highlight classification logic from 3 locations
- Use existing normalizeUrl from urlHelpers instead of duplicating
- Reduce code duplication while maintaining functionality
2025-10-07 21:58:17 +01:00
Gigi
e1f704a690 fix: resolve linter errors
- Remove unused imports in ReadingDisplaySettings and useBookmarksData
- Add eslint-disable comments for unavoidable any types from applesauce library
- All lint and type-check validations now pass
2025-10-07 21:57:04 +01:00
Gigi
59ecc29b9c refactor(highlights): split highlighting utilities into modules
- Create textMatching module for text search utilities
- Create domUtils module for DOM manipulation helpers
- Create htmlMatching module for HTML highlight application
- Reduce highlightMatching.tsx from 217 lines to 59 lines
- All files now under 210 lines
2025-10-07 21:54:41 +01:00
Gigi
9ae918f744 refactor(highlights): extract highlights panel components
- Create useFilteredHighlights hook for highlight filtering
- Extract HighlightsPanelCollapsed component
- Extract HighlightsPanelHeader component
- Reduce HighlightsPanel.tsx from 232 lines to 118 lines
2025-10-07 21:53:24 +01:00
Gigi
ac71d0b5a4 refactor(content): extract content rendering hooks
- Create useMarkdownToHTML hook for markdown conversion
- Create useHighlightedContent hook for highlight processing
- Create useHighlightInteractions hook for highlight interactions
- Reduce ContentPanel.tsx from 294 lines to 159 lines
2025-10-07 21:52:05 +01:00
Gigi
7c0d3b909b refactor(settings): split Settings into section components
- Extract ReadingDisplaySettings component
- Extract LayoutNavigationSettings component
- Extract StartupPreferencesSettings component
- Reduce Settings.tsx from 295 lines to 104 lines
2025-10-07 21:50:35 +01:00
Gigi
7b390aae66 refactor(highlights): extract event processing utilities
- Create highlightEventProcessor module with eventToHighlight utility
- Extract dedupeHighlights and sortHighlights functions
- Reduce highlightService.ts from 346 lines to 186 lines
- Eliminate repetitive event-to-highlight conversion code
2025-10-07 21:49:01 +01:00
Gigi
70a830fb66 refactor(bookmarks): split Bookmarks.tsx into smaller hooks and components
- Extract useBookmarksData hook for data fetching
- Extract useContentSelection hook for content selection logic
- Extract useHighlightCreation hook for highlight creation
- Extract useBookmarksUI hook for UI state management
- Create ThreePaneLayout component to reduce JSX complexity
- Reduce Bookmarks.tsx from 392 lines to 209 lines
2025-10-07 21:47:59 +01:00
Gigi
eee7628096 fix: encode/decode URLs in /r/ route to preserve special characters
URLs with special characters like // in https:// were being collapsed by browsers when passed directly in the path. Now using encodeURIComponent when navigating and decodeURIComponent when extracting the URL from the path.
2025-10-07 21:40:43 +01:00
Gigi
0b5bf59e98 feat: hide bookmarks without content or URL 2025-10-07 18:37:45 +01:00
Gigi
4184561583 chore: cleanup after build fixes (remove shims, update locks) 2025-10-07 06:57:42 +01:00
Gigi
8285df487f revert: use documented applesauce imports; remove alias shim
- Import EventStore from 'applesauce-core'
- Remove Vite alias/shim and node:path reference
- Keep config minimal and standard-compliant
2025-10-07 06:24:33 +01:00
Gigi
f455f61795 build: deep import EventStore to bypass re-export resolution on Vercel
- Import EventStore from applesauce-core/dist/event-store/event-store.js
- Add TS module declaration shim for deep import typing
- No functional changes, fixes Vercel bundling for async-event-store.js
2025-10-07 06:15:48 +01:00
Gigi
b4ceaceedc refactor: use main package exports instead of subpath imports
- Import Helpers from 'applesauce-core' instead of 'applesauce-core/helpers'
- Import Blueprints from 'applesauce-factory' instead of 'applesauce-factory/blueprints'
- Use namespace exports as documented in applesauce tutorial
- Fixes Vercel build issue with internal module resolution
- Follows recommended import patterns from applesauce docs
2025-10-07 06:04:07 +01:00
Gigi
85aa77dba8 revert: back to manual NIP-78 event creation
- AppDataBlueprint is not available in npm package (only in local workspace)
- Revert to manual event construction using factory.create()
- This approach works on Vercel's build environment
- Added comment explaining why we can't use the blueprint
2025-10-07 05:48:50 +01:00
Gigi
803df2d22b refactor: use AppDataBlueprint via namespace import
- Import blueprints as namespace: 'import * as Blueprints from applesauce-factory/blueprints'
- Use Blueprints.AppDataBlueprint with proper factory API
- Cleaner than manual event construction
- Should work with Vercel as namespace imports don't require direct named exports
2025-10-07 05:46:20 +01:00
Gigi
a84fbe97b0 fix: create NIP-78 events manually without blueprint import
- Remove AppDataBlueprint import that's not available in npm package
- Create application data events directly using factory.create()
- Manually construct event with kind 30078, d-tag identifier, and JSON content
- Fixes Vercel build by avoiding unavailable blueprint exports
2025-10-07 05:44:59 +01:00
Gigi
21545fc76a fix: avoid deep imports for Vercel compatibility
- Define APP_DATA_KIND constant inline (30078 for NIP-78)
- Implement getAppDataContent helper inline to parse JSON
- Import AppDataBlueprint from 'applesauce-factory/blueprints' main export
- Fixes Vercel build errors with deep package imports
2025-10-07 05:39:41 +01:00
Gigi
303d5a0ac7 fix: correct AppDataBlueprint import path for Vercel build
- Change import from 'applesauce-factory/blueprints' to 'applesauce-factory/blueprints/app-data'
- Fixes TypeScript error TS2305 in production build
2025-10-07 05:36:45 +01:00
Gigi
744642e2b7 fix: ensure bookmarks are sorted newest first after merging lists
- Re-sort all individual bookmarks after flattening from multiple lists
- Sort by added_at first, then fall back to created_at
- Prevents interleaving of sorted lists from breaking overall order
- Ensures newest bookmarks always appear at the top
2025-10-07 05:25:50 +01:00
Gigi
fd28a6e171 feat: parse and display summary tag for nostr articles
- Extract 'summary' tag from kind:30023 article bookmarks
- Display summary in place of truncated content for articles
- Show summary in all view modes (compact, cards, large)
- Add article-summary CSS class for potential styling
- Follows NIP-23 long-form content specification
2025-10-07 05:12:11 +01:00
Gigi
0124de8318 feat: merge and flatten bookmarks from multiple lists
- Extract all individual bookmarks from all bookmark lists
- Display them in a single flat list (already sorted by date in service)
- Remove wrapper metadata like 'N bookmarks in this list'
- Show all bookmarks together, newest first
- Implements NIP-51 and NIP-B0 bookmark list merging
2025-10-07 05:06:00 +01:00
Gigi
b37aac0a33 fix: hide empty bookmarks without content
- Filter out individual bookmarks that have no content
- Keep articles (kind:30023) and web bookmarks (kind:39701) even if empty
- Prevents display of placeholder items showing only icons and timestamps
2025-10-07 05:02:36 +01:00
Gigi
81ef047a31 chore: remove created date from bookmark list display
- Remove bookmark-meta div showing creation timestamp
- Cleaner UI without redundant date information
2025-10-07 04:59:55 +01:00
Gigi
704033e6cb fix: remove encrypted cyphertext display from bookmark list
- Remove display of top-level bookmark.content and bookmark.parsedContent
- These fields contain encrypted data that shouldn't be shown to users
- Individual bookmarks are already displayed properly within each list
2025-10-07 04:56:42 +01:00
Gigi
d59d27419e feat: update URL path when opening bookmarks from sidebar
- Add URL navigation when selecting bookmarks
- Navigate to /a/:naddr for nostr articles (kind:30023)
- Navigate to /r/:url for external URLs
- Encode article bookmarks to naddr format on selection
2025-10-07 04:55:30 +01:00
Gigi
61e948f6a4 refactor: use icon toggle buttons for highlight visibility settings
- Replace checkboxes with IconButton components matching existing UI pattern
- Use faNetworkWired, faUserGroup, and faUser icons
- Maintain consistent visual style with other settings toggles
2025-10-06 20:55:56 +01:00
Gigi
22323591c9 feat: add default highlight visibility settings
- Add defaultHighlightVisibilityNostrverse/Friends/Mine to UserSettings interface
- Add toggle controls in Settings page under Startup Preferences section
- Apply default visibility settings on app startup in Bookmarks component
- Users can now set which highlight levels (nostrverse/friends/mine) should be visible by default
2025-10-06 20:46:33 +01:00
Gigi
1b548cee3c feat: add proxy.nostr-relay.app relay to configuration 2025-10-06 20:43:12 +01:00
Gigi
fbb8fbdc20 fix: handle web bookmarks with URLs in d tag and prevent crash
- Extract URL from 'd' tag for kind:39701 web bookmarks
- Add protocol prefix (https://) if missing from web bookmark URLs
- Make classifyUrl handle undefined input gracefully
- Prevent crash when web bookmarks have no content
2025-10-06 20:34:37 +01:00
Gigi
1e7be50e35 refactor: change nostrverse icon from fa-globe to fa-network-wired
- Avoid icon conflict with web bookmarks which use fa-globe
- fa-network-wired better represents the nostr network/nostrverse concept
2025-10-06 20:31:47 +01:00
Gigi
1a7a8367a0 feat: add support for web bookmarks (NIP-B0, kind:39701)
- Update bookmarkService to fetch kind:39701 events
- Add processing logic for web bookmark events in bookmarkProcessing
- Update bookmark deduplication to handle web bookmarks
- Add 'web' type to IndividualBookmark interface
- Implement distinct icon (fa-bookmark + fa-globe) for web bookmarks
- Update CompactView and CardView to display web bookmark icon
- Add web-bookmarks rule documentation
2025-10-06 20:30:53 +01:00
Gigi
1f9dbf576c fix: load settings from local cache first to eliminate FOUT
- Check eventStore for cached settings before querying relays
- This eliminates the 5-second timeout on every page load
- Still fetch from relays in background to sync updates
- Fixes flash of unstyled text (FOUT) when custom fonts are set
2025-10-06 20:24:28 +01:00
Gigi
630c7ef0a4 feat: add comprehensive logging to settings service
- Add debug logs for settings loading from nostr
- Log when settings are found, missing, or timeout
- Add logging for settings save operations
- Track settings event publishing to relays

This will help diagnose why custom fonts/settings aren't being applied.
2025-10-06 20:20:41 +01:00
Gigi
b01293aa20 fix: ensure fonts are fully loaded before applying styles
- Convert loadFont to async function that returns a Promise
- Use Font Loading API to wait for fonts to be actually ready
- Add comprehensive logging for font loading stages
- Wait for font loading in useSettings before applying CSS variables
- Update Settings component to handle async font loading
- Prevents FOUT (Flash of Unstyled Text) by ensuring fonts are ready
- Fixes timing issue where custom fonts weren't being applied consistently

This ensures custom fonts are fully loaded and ready before being applied,
eliminating the race condition where content would render with system fonts
before custom fonts were available.
2025-10-06 20:04:11 +01:00