Instead of 'no relay info', show the list of remote relays we're connected to as a fallback for highlights that don't have publishedRelays metadata (i.e., highlights fetched from other users)
Update tooltip text to be more accurate about relay information:
- Show 'Published to X relays' for user-created highlights with publishedRelays
- Show 'Seen on X relays' for highlights with seenOnRelays tracking
- Show 'Fetched from network' for highlights without relay metadata
- Add seenOnRelays field to Highlight type for future relay tracking
Previously the relay indicator was only shown for highlights with publishedRelays info (user-created highlights). Now it's always visible:
- Show server icon by default for all highlights
- Show plane icon for local-only/offline highlights
- Show spinner during rebroadcast/sync
- Always allow clicking to rebroadcast any highlight
Show automatic rebroadcast/sync state in the relay indicator instead of separate meta spinner:
- Relay indicator shows spinner during both manual rebroadcast and auto-sync
- Update tooltip to distinguish between manual rebroadcast and auto-sync
- Remove redundant syncing indicator from meta area
- Clean up unused CSS for syncing indicator
This provides a single, consistent visual indicator for all relay broadcast states.
Make relay indicator icons clickable to trigger manual rebroadcast to all connected relays:
- Click plane icon (local/offline) to rebroadcast to remote relays
- Click server icon to rebroadcast to all relays
- Show spinner while rebroadcasting
- Update icon from plane to server on successful rebroadcast
- Keep plane icon on failure
- Pass relayPool and eventStore through component chain
- Add local state management for highlight updates in HighlightsPanel
- Enhance CSS with scale animation on hover/active
Replace multiple redundant indicators (flight mode, local only, relay info) with a single relay indicator icon in the bottom-left of each highlight:
- Show plane icon for local-only or offline-created highlights
- Show server icon for highlights published to remote relays
- Keep spinner in meta area for actively syncing highlights
- Remove duplicate indicators from meta area
- Clean up unused CSS and imports
Previously only local relays had keep-alive subscriptions, causing remote relays to disconnect when no active subscriptions were running. This made the app appear to be in flight mode even when online.
Now create a persistent subscription for all relays to maintain connections.
Add a small server icon at the bottom-left of each highlight that shows which relays the highlight was published to. The icon appears when publishedRelays information is available (for user-created highlights) and displays a tooltip with the list of relay URLs on hover.
- Import faServer icon from FontAwesome
- Add relay indicator to HighlightItem component
- Display formatted relay list in tooltip
- Add CSS styling for the indicator with hover effects
- Support both dark and light modes
The highlight creation service was getting all relays from the pool without checking if they were actually connected. This caused highlights to only be published to a subset of relays (sometimes just one).
Now properly filters relays using relay.connected to ensure highlights are published to all actually connected relays when online.
- Remove calendar icon (faCalendar) from publication date display
- Display only the formatted date text
- Remove icon-specific CSS styling (gap, svg styles)
- Cleaner, more minimal date display in top-right corner
- Remove background and border from publication date
- Use white text with subtle drop shadow for all layouts
- Icon now uses drop-shadow filter for better visibility
- Cleaner, more minimal appearance that works well on any background
- Position publication date in top-right corner of article header
- Works for both hero image and non-image layouts
- Add subtle background and border for better visibility
- On hero images: dark semi-transparent background with backdrop blur
- On regular headers: uses surface-secondary background
- Remove date from inline metadata (reading time and highlights remain)
- Import IAccount from applesauce-accounts (not applesauce-core)
- Remove unused account parameter from syncLocalEventsToRemote
- Fix undefined vs null type mismatch in Bookmarks component
- All linter and type checks now pass cleanly
- Add persistent keep-alive subscription for local relays
- Prevents disconnection when no other subscriptions are active
- Uses minimal subscription (kinds: [0], limit: 0) to keep connection open
- Properly cleans up subscription on app unmount
- Resolves issue where local relays disconnect after idle period in flight mode
- 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