- Add useEffect to watch highlight.isOfflineCreated prop changes
- State now updates when prop changes (not just on initial mount)
- Add isOfflineCreated to console log for easier debugging
- Fixes issue where plane icon wouldn't appear for new offline highlights
The bug was that showOfflineIndicator state was only set once during
component initialization. If the highlight prop didn't have isOfflineCreated
set at that moment, the icon would never appear even if the prop changed later.
Major UX improvement:
- Store event in EventStore FIRST (before publishing)
- Return highlight immediately (no await on relay publish)
- Publish to relays in background asynchronously
- UI now updates instantly (<50ms) instead of waiting seconds
Before:
1. Create event
2. Wait for relay publish (1-5 seconds)
3. Store in EventStore
4. Return to UI
After:
1. Create event
2. Store in EventStore
3. Return to UI immediately ⚡
4. Publish to relays in background
Benefits:
- Instant highlight appearance in UI
- No blocking on network operations
- Better perceived performance
- Especially noticeable in flight mode with slow local relays
- Event still saved even if publishing fails
- Check actual relay connectivity before rebroadcasting
- Skip rebroadcast to all relays if no remote relays connected
- Still allows rebroadcast to local relays in flight mode
- Prevents unnecessary publish attempts to unreachable relays
- Logs: '✈️ Flight mode: skipping rebroadcast to remote relays'
This prevents the app from trying to rebroadcast fetched events to
remote relays when only local relays are connected (flight mode).
- Show spinning blue icon while event is syncing to remote relays
- Hide offline indicator completely after successful sync
- Add sync state tracking with listeners for real-time updates
- Track successful vs failed syncs separately
- Only clear offline flag for successfully synced events
- Blue spinner (#3b82f6) indicates active sync
- Clean UI: no indicator after sync completes
Behavior:
1. Create highlight offline → plane icon
2. Come back online → spinner replaces plane
3. Sync completes → no indicator (clean)
4. Sync fails → plane icon returns
Major improvements:
- Store highlights in EventStore immediately when created
- Query EventStore instead of local relays for offline sync
- Pass eventStore to highlight creation service and hooks
- Simplified offline sync: no more relay queries, just EventStore lookups
- More efficient and reliable offline event tracking
- Better integration with applesauce architecture
Benefits:
- Faster sync (no relay queries needed)
- More reliable (events always in EventStore)
- Cleaner code (leveraging applesauce patterns)
- Better separation of concerns
- Add isOfflineCreated property to Highlight type
- Set flag when highlight is created in local-only mode
- Display small plane icon in highlight sidebar for offline-created highlights
- Lighter amber color (#fbbf24) to distinguish from Local badge
- Tooltip: 'Created while in flight mode'
- Visual indicator helps users track which highlights need syncing
- Track events explicitly when created in offline mode
- Mark highlights as offline-created when isLocalOnly is true
- Add extensive debug logging throughout sync process
- Increase query timeout from 5s to 10s for better reliability
- Add 2-second delay before syncing to allow relays to connect
- Log relay state transitions and event counts
- Log each event received during sync query
- Should help diagnose and fix offline sync issues
- Remove duplicate state tracking from service
- State transition detection now fully handled by hook
- Fix remaining syncState reference bug
- Simplify sync lock mechanism
- Create offlineSyncService to sync local-only events to remote relays
- Create useOfflineSync hook to detect online/offline transitions
- When user comes back online (remote relays connect), automatically:
- Query local relays for user's events from last 24 hours
- Rebroadcast highlights and bookmarks to remote relays
- Integrate sync into Bookmarks component
- Enables seamless offline workflow:
- User can work offline with local relays
- Events are automatically synced when connection restored
- No manual intervention required
- Change 'Local Only' to 'Flight Mode' in relay status indicator
- Rename settings section from 'Offline Mode' to 'Flight Mode'
- Better reflects the airplane icon metaphor
- More intuitive terminology for local-only relay mode
- Replace red dot (faCircle) with red wifi icon (faWifi)
- Better visual representation of network disconnection
- Icon size now consistent at 1rem across all states
- Remove separate 'Offline' section, show all relays in one list
- Local relays always shown first (sorted to top)
- Local relays use airplane icon instead of checkmark
- Airplane icon is green when connected, red when offline
- Remote relays use green checkmark (connected) or red dot (offline)
- Last seen timestamp shown only for disconnected relays
- Simplified layout for better readability
- Check relay.connected property to determine if relay is actually connected
- Previously only checked if relay was in pool, not if connection was active
- Add debug logging to help diagnose connection status issues
- This should fix the airplane indicator not showing when offline
- Relays should now correctly show as disconnected after being offline
- Change font sizes from [14,16,18,20,22,24] to [16,18,21,24,28,32]
- Larger sizes now more spread out (28px and 32px)
- Set default font size to 21px instead of 18px
- Better progression for reading comfort
- Use shorter date format (MMM d, yyyy instead of MMMM d, yyyy)
- Add subtle styling with reduced opacity and smaller font
- Make calendar icon smaller and more muted
- Style overlay version for hero images with subtle white text
- Wrap both settings in a flex container
- Reading Font takes flexible space with min-width
- Font Size takes only necessary space
- Responsive with flex-wrap for smaller screens
- Better use of horizontal space in settings UI
- Move recommendation text from Relays to Offline Mode section
- Info box about Citrine and nostr-relay-tray now appears at end of Offline Mode
- Remove unused handleLinkClick and useNavigate from RelaySettings
- Add handleLinkClick to OfflineModeSettings for clickable links
- Clean up unused onClose prop in RelaySettings
- Create new OfflineModeSettings component
- Move 'Use local relay(s) as cache' checkbox
- Move 'Rebroadcast events to all relays' checkbox
- Position Offline Mode section before Relays section
- Keep consistent checkbox styling
- Remove settings/onUpdate props from RelaySettings (no longer needed)
- Match existing checkbox pattern from other settings
- Use setting-group, checkbox-label, and setting-checkbox classes
- Add proper id and htmlFor attributes for accessibility
- Consistent with LayoutNavigationSettings and other checkbox settings
- Keep code DRY with unified styling approach
- Remove icons from checkbox labels
- Shorten text to simple checkbox labels
- Cleaner, more minimal design
- Settings: 'Use local relay(s) as cache' and 'Rebroadcast events to all relays'
- Move rebroadcast checkboxes from separate section into Relays section
- Add plane and globe icons to rebroadcast settings
- Remove separate RelayRebroadcastSettings component
- Settings now flow better with rebroadcast options at top, relay list below
- Maintains all functionality while improving UI organization
- Add two new settings:
- Use local relay(s) as cache (default: enabled)
- Rebroadcast events to all relays (default: disabled)
- Create rebroadcastService to handle rebroadcasting events
- Hook into article, bookmark, and highlight fetching services
- Automatically rebroadcast fetched events based on settings:
- Articles when opened
- Bookmarks when fetched
- Highlights when fetched
- Add RelayRebroadcastSettings component with plane/globe icons
- Benefits:
- Local caching for offline access
- Content propagation across nostr network
- User control over bandwidth usage
- Reduce relay connection window from 20 minutes to 10 seconds
- Change 'Recently Seen' section to 'Offline' with red styling
- Use red circle icon for offline relays instead of gray
- Poll relay status every 2 seconds in settings (faster feedback)
- Poll relay status every 2 seconds in status indicator
- Now when entering flight mode:
- Local relay stays connected (green checkmark with plane icon)
- All remote relays move to red 'Offline' section within 10 seconds
- Status is highly responsive and clear
- Show plane icon badge next to local relays in relay list
- Badge appears for both active and recently seen local relays
- Uses amber styling to match local-only mode theme
- Includes tooltip explaining the relay is local
- Makes it easy to identify local relays at a glance in settings
- 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
- Wrap relay publish in try-catch to handle failures gracefully
- Attempt to publish to local relay even when no relays are connected
- Always return highlight object even if publish fails completely
- Add detailed logging to track publish status and failures
- Mark highlights as local-only when publish fails or only local relays available
- Ensure UI always displays newly created highlights immediately
- Add relay tracking to Highlight type (publishedRelays, isLocalOnly fields)
- Create utility functions to identify local relays (localhost/127.0.0.1)
- Update highlight creation service to track which relays received the event
- Detect when highlights are only on local relays and mark accordingly
- Add visual indicator in UI for local-only highlights with amber badge
- Enable immediate display of highlights created offline
- Ensure highlights work even when only local relay is available
- Add isPresetActive function to detect current preset
- Add 'active' class to preset button matching current weights
- Organize presets in a central object for easier maintenance
- Users can now see which preset is currently applied
- Reorder settings for better logical flow
- Show highlights toggle now appears after visibility controls
- Positioned right before the preview section
- Wrap FontSelector in setting-control div
- Prevents dropdown from stretching across full page width
- Matches layout of other inline controls like color pickers
- Add /settings route to router
- Derive showSettings from location.pathname instead of state
- Update onOpenSettings to navigate to /settings
- Update onCloseSettings to navigate back to previous location
- Track previous location to restore context when closing settings
- Remove showSettings state from useBookmarksUI hook
- Move setting from Startup Preferences to Reading & Display section
- Position above preview so changes are immediately visible
- Update preview to respect defaultHighlightVisibility settings
- Each highlight level (mine/friends/nostrverse) now toggles in preview
- Replace generic IconButton with colored level-toggle-btn elements
- Match the UI style from HighlightsPanelHeader in sidebar
- Show highlight colors (purple, orange, yellow) when active
- Use same CSS classes and structure for visual consistency
- Add message with links to learn about relays (nostr.how and substack article)
- Links open in Boris's reader view via /r/ route instead of external tabs
- Close settings panel when links are clicked to show the content
- Use react-router navigation for seamless in-app experience
- 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
- Replace array accumulation with Map keyed by highlight ID
- Prevents duplicate highlights when same event arrives from multiple relays
- Fix applied in useArticleLoader and useBookmarksData hooks
- Only updates UI when new unique highlight arrives
- Resolves issue where highlights appeared twice in sidebar