Commit Graph

133 Commits

Author SHA1 Message Date
Gigi
d067193f21 fix(reader): force re-mount of markdown preview and rendered HTML per-content to eliminate stale display when switching articles 2025-10-22 13:46:57 +02:00
Gigi
92a85761ef feat: make highlight count clickable to open highlights sidebar 2025-10-22 11:48:41 +02:00
Gigi
b913cc4d7f fix: hide 'Open Original' button for nostr-native events
Only external URLs (/r/ paths) have original sources.
Nostr-native events don't need this option in the three-dot menu.
2025-10-22 11:21:08 +02:00
Gigi
bc1aed30b4 fix: open nostr events directly on ants.sh instead of as search query
When clicking search in the three-dot menu for a nostr event,
now opens https://ants.sh/e/<eventId> directly instead of
https://ants.sh/?q=nostr-event:<eventId>
2025-10-22 11:20:12 +02:00
Gigi
c7b885cfcd refactor(reader): use startReadingPositionStream in ContentPanel 2025-10-22 08:55:50 +02:00
Gigi
bb66823915 fix(/e/): Search button opens note via /e/ path not search portal
- For kind:1 notes, open directly via /e/{eventId}
- For articles (kind:30023), continue using search portal
- Removes nostr-event: prefix in URLs
2025-10-22 01:18:51 +02:00
Gigi
b92f5716dc feat(tts): use default speed from settings in TTSControls 2025-10-20 22:05:04 +02:00
Gigi
b3206d5e79 feat(reader): integrate TTS controls in ContentPanel 2025-10-20 21:41:31 +02:00
Gigi
568890e131 fix: prevent ReactMarkdown img renderer from injecting unknown props
- Remove props spread to avoid node="[object Object]" artifacts
- Ensures downstream VideoEmbedProcessor can cleanly replace video <img> tags
2025-10-20 21:19:27 +02:00
Gigi
64aad42be3 fix: prevent double video player rendering
- Modified ContentPanel to disable VideoEmbedProcessor when isExternalVideo is true
- This prevents both ContentPanel and VideoEmbedProcessor from rendering ReactPlayer for the same video URL
- Fixes issue where video players were showing twice
2025-10-20 20:44:38 +02:00
Gigi
975399e293 feat: add video embed setting and processor
- Add renderVideoLinksAsEmbeds setting to UserSettings interface
- Add checkbox control in ReadingDisplaySettings component
- Create VideoEmbedProcessor component to handle video link embedding
- Integrate VideoEmbedProcessor into ContentPanel for article rendering
- Support .mp4, .webm, .ogg, .mov, .avi, .mkv, .m4v video formats
- Use ReactPlayer for embedded video playback
- Default to false (render as links)
- When enabled, video links are rendered as embedded players
2025-10-20 20:37:45 +02:00
Gigi
15fd19f6a4 fix: resolve all linting issues
- Remove unused DebugBus import from App.tsx
- Remove unused NostrEvent import from relayListService.ts
- Add comment to empty catch block in ContentPanel.tsx
- Remove unused targetUrlsMap variable from relayManager.ts
- All linting errors resolved, TypeScript type checking passes
2025-10-20 20:01:40 +02:00
Gigi
0b42aeb383 refactor: remove non-relay console.log statements
- Remove console.log statements from ContentPanel.tsx (archive/content related)
- Remove console.log statements from readingProgressController.ts (reading progress related)
- Remove console.log statements from reactionService.ts (reaction related)
- Remove debug console.log block from Me.tsx (archive/me related)
- Preserve all relay-related console.log statements in App.tsx and relayManager.ts
2025-10-20 19:46:50 +02:00
Gigi
fc025b9579 feat: integrate user relay lists (NIP-65) and blocked relays (NIP-51)
- Add relayListService to load kind:10002 (user relay list) and kind:10006 (blocked relays)
- Add relayManager to compute active relay set and dynamically manage pool membership
- Update App.tsx to fetch and apply user relays on login, reset on logout
- Replace all hardcoded RELAYS usages with dynamic getActiveRelayUrls() across services and components
- Always preserve localhost relays (ws://localhost:10547, ws://localhost:4869) regardless of user blocks
- Merge bunker relays, user relays, and hardcoded relays while excluding blocked relays
- Update keep-alive subscription and address loaders to use dynamic relay set
- Modified files: App.tsx, relayListService.ts (new), relayManager.ts (new), readsService.ts, readingProgressController.ts, archiveController.ts, libraryService.ts, reactionService.ts, writeService.ts, HighlightItem.tsx, ContentPanel.tsx, BookmarkList.tsx, Profile.tsx
2025-10-20 18:40:23 +02:00
Gigi
6f9c0a35e2 fix(reader): trigger archive animation even if already archived on auto-complete 2025-10-20 13:17:35 +02:00
Gigi
27cbcb56ec ui(reader): keep Archived label and subtle style while remaining clickable 2025-10-20 12:43:28 +02:00
Gigi
7f150003b5 feat(reader): wire unarchive actions to delete matching reactions and clear controller 2025-10-20 12:39:28 +02:00
Gigi
1f50d8e1b6 feat(reader): make Archived button clickable and perform unarchive via NIP-09 2025-10-20 12:39:09 +02:00
Gigi
f272943b64 chore: commit pending working changes before implementing unarchive behavior 2025-10-20 12:36:27 +02:00
Gigi
49745e1b8a refactor(archive): remove direct markedIds mutation; use controller.mark/unmark for DRY updates; fix duplicate import in reactionService 2025-10-20 11:23:45 +02:00
Gigi
470f4fb34e feat(archive): support un-archive toggle; add ArchiveController mark/unmark; prep NIP-09 deletion hook 2025-10-20 11:21:59 +02:00
Gigi
8cde36c08c fix(archive): add 'a' coord tag to mark-as-read reactions for articles; archiveController maps a-tag instantly; add debug 2025-10-20 11:17:30 +02:00
Gigi
c9fef5804b chore(debug): add [archive] debug logs in archiveController, Me, and ContentPanel to trace archive filter behavior 2025-10-20 10:48:44 +02:00
Gigi
8337622a22 feat(archive): introduce archiveController to manage marked-as-read (kind:7/17); wire into App, Me, and ContentPanel for DRY archive state 2025-10-20 10:33:42 +02:00
Gigi
28123b5e13 feat(archive): rename 'Mark as Read' UI to 'Move to Archive' and show 'Archived' state; update settings and filters wording 2025-10-20 09:42:34 +02:00
Gigi
e17e1bc824 fix(lint): resolve unused var and empty catch issues 2025-10-20 00:47:11 +02:00
Gigi
4cc9d557a0 feat(reads): add emoji filter, refine completed to 95%+, and show checkmark only at >=95% progress 2025-10-20 00:43:31 +02:00
Gigi
adf73cb9d1 fix: resolve all linting and type errors
- Fix empty catch blocks by adding explanatory comments
- Remove unused variables or prefix with underscore
- Remove orphaned object literals from removed console.log statements
- Fix unnecessary dependency array entries
- Ensure all empty code blocks have comments to satisfy eslint no-empty rule
2025-10-19 22:41:35 +02:00
Gigi
4202807777 refactor: remove all console.log debug output 2025-10-19 22:35:45 +02:00
Gigi
5c82dff8df feat: only track reading progress for articles above minimum length
- Add MIN_CONTENT_LENGTH constant (1000 chars ≈ 150 words) to config/kinds
- Create shouldTrackReadingProgress helper to validate content length
- Strip HTML tags when calculating character count
- Only save reading progress for articles meeting the threshold
- Log when content is too short to track

This prevents noisy tracking of very short articles or excerpts.
2025-10-19 22:13:37 +02:00
Gigi
676be1a932 feat: make reading position sync default-on in runtime paths
- Treat undefined as enabled in ContentPanel (only false disables)
- Keeps DEFAULT_SETTINGS at true; ensures consistent behavior even for users without the new setting persisted yet
2025-10-19 16:15:43 +02:00
Gigi
3a10ac8691 debug: add logs to show why reading position saves are skipped
- Log when scheduleSave returns early (syncEnabled false, no onSave callback)
- Log when position is too low (<5%)
- Log when change is not significant enough (<1%)
- Log ContentPanel sync status (enabled, settings, requirements)
- This will help diagnose why no events are being created
2025-10-19 11:41:38 +02:00
Gigi
205879f948 debug: add comprehensive logging for reading position calculation and event publishing
- Add logs in useReadingPosition: scroll position calculation (throttled to 5% changes)
- Add logs for scheduling and triggering auto-save
- Add detailed logs in ContentPanel handleSavePosition
- Add logs in saveReadingPosition: event creation, signing, publishing
- Add logs in publishEvent: event store addition, relay status, publishing
- All logs prefixed with [progress] for easy filtering
- Shows complete flow from scroll → calculate → save → create event → publish to relays
2025-10-19 11:39:25 +02:00
Gigi
3b31eceeab feat: improve reading progress with validation and auto-mark
- Add autoMarkAsReadOnCompletion setting (opt-in, default: false)
- Implement auto-mark as read when reaching 95%+ completion
- Add validation for progress bounds (0-1) per NIP-39802 spec
- Align completion threshold to 95% to match filter behavior
- Skip invalid progress events with warning log

Improvements ensure consistency between completion detection and
filtering, while adding safety validation per the NIP spec.
2025-10-19 10:34:53 +02:00
Gigi
442c138d6a refactor: simplify NIP-39802 implementation - remove migration complexity
- Remove dual-write logic: only write kind 39802
- Remove legacy kind 30078 read fallback
- Remove migration settings flags (useReadingProgressKind, writeLegacyReadingPosition)
- Simplify readingPositionService: single write/read path
- Remove processReadingPositions() legacy processor
- Update readsService and linksService to only query kind 39802
- Simplify NIP-39802 spec: remove migration section
- Delete READING_PROGRESS_MIGRATION.md (not needed for unreleased app)
- Clean up imports and comments

No backward compatibility needed since app hasn't been released yet.
2025-10-19 10:14:37 +02:00
Gigi
7d373015b4 feat: implement NIP-39802 reading progress with dual-write migration
- Add kind 39802 (ReadingProgress) as dedicated parameterized replaceable event
- Create NIP-39802 specification document in public/md/
- Implement dual-write: publish both kind 39802 and legacy kind 30078
- Implement dual-read: prefer kind 39802, fall back to kind 30078
- Add migration flags to settings (useReadingProgressKind, writeLegacyReadingPosition)
- Update readingPositionService with new d-tag generation and tag helpers
- Add processReadingProgress() for kind 39802 events in readingDataProcessor
- Update readsService and linksService to query and process both kinds
- Use event.created_at as authoritative timestamp per NIP-39802 spec
- ContentPanel respects migration flags from settings
- Maintain backward compatibility during migration phase
2025-10-19 10:09:09 +02:00
Gigi
5568437663 Revert "Add reading progress filters and split Reads/Links tabs" 2025-10-16 08:05:20 +02:00
Gigi
1982d25fa8 feat: add fancy animation to Mark as Read button
- Icon spins 360° with bounce effect (scale up during spin)
- Button background changes to vibrant green gradient (#10b981)
- Green pulsing box-shadow effect on activation
- Button scales up slightly on click for emphasis
- Holds green state for 1.5 seconds
- Smoothly fades to gray after animation
- Final state is gray button to indicate marked status
- Uses cubic-bezier easing for modern, smooth feel
- Total animation duration: 2.5 seconds
- Prevents interaction during animation
2025-10-15 23:39:14 +02:00
Gigi
fd5ce80a06 feat: add auto-mark as read at 100% reading progress
- Add autoMarkAsReadAt100 setting (default: false)
- Add checkbox in Layout & Behavior settings
- Automatically mark article as read after 2 seconds at 100% progress
- Trigger same animation as manual mark as read button
- Move isNostrArticle computation earlier for useCallback deps
- Move handleMarkAsRead to useCallback for use in auto-mark effect
2025-10-15 23:28:50 +02:00
Gigi
474da25f77 fix: add autoScrollToPosition to useEffect dependency array
- Fixes react-hooks/exhaustive-deps warning
- Ensures effect reruns when auto-scroll setting changes
2025-10-15 23:08:21 +02:00
Gigi
8800791723 feat: add auto-scroll to reading position setting
- Add autoScrollToPosition setting (default: true)
- Add checkbox in Layout & Behavior settings
- Only auto-scroll when setting is enabled
- Allows users to disable auto-scrolling while keeping sync enabled
2025-10-15 22:53:47 +02:00
Gigi
f4a227e40a fix: improve reading position calculation to reach 100%
- Add 5px threshold to detect when scrolled to bottom
- Set position to exactly 1.0 (100%) when within 5px of bottom
- Remove upper limit on saving positions (now saves 100% completion)
- Always save when reaching 100% completion (important milestone)
- Don't restore position for completed articles (100%), start from top
- Better handling of edge cases in position detection
- Matches ReadingProgressIndicator calculation logic
2025-10-15 22:39:51 +02:00
Gigi
8f89165711 debug: add comprehensive logging for reading position sync
- Add detailed console logs with emoji prefixes for easy filtering
- Log save/load operations in readingPositionService
- Log position restore in ContentPanel with requirements check
- Log Archive tab position loading with article details
- All logs prefixed with component/service name for clarity
- Log shows position percentages, identifiers, and timestamps
- Helps debug why positions may not be showing or syncing
2025-10-15 22:23:40 +02:00
Gigi
ab2ca1f5e7 fix: remove unused IEventStore import in ContentPanel 2025-10-15 22:09:58 +02:00
Gigi
cf2d227f61 feat: add reading position sync across devices using Nostr Kind 30078
- Create readingPositionService.ts for save/load operations
- Add syncReadingPosition setting (opt-in via Settings > Layout & Behavior)
- Enhance useReadingPosition hook with auto-save (debounced 5s) and immediate save on navigation
- Integrate position restore in ContentPanel with smooth scroll to saved position
- Support both Nostr articles (naddr) and external URLs
- Reading positions stored privately to user's relays
- Auto-save excludes first 5% and last 5% of content to avoid noise
- Position automatically restored when returning to article
2025-10-15 22:08:12 +02:00
Gigi
e38237ca8e fix: resolve linter errors for unused variables 2025-10-15 17:39:22 +02:00
Gigi
1fff44fc6c chore: update button label from 'Open on Nostr' to 'Open with njump' 2025-10-15 17:37:38 +02:00
Gigi
4e50073e07 feat: update gateway config to use nostr.at and define ants.sh as search portal 2025-10-15 17:31:39 +02:00
Gigi
0ce64fe83f feat: open three-dot menus upward when insufficient space below 2025-10-15 17:28:44 +02:00
Gigi
ef848aa93e feat: update external article menu with Share (Boris link) and Search options 2025-10-15 17:25:29 +02:00