Commit Graph

1361 Commits

Author SHA1 Message Date
Gigi
cb43b748e4 temp: disable auto-load of contacts for testing
- Comment out contacts state and subscriptions
- Comment out auto-load effect
- Allows manual testing of contact loading in Debug page
- Remember to re-enable after testing
2025-10-18 20:59:14 +02:00
Gigi
ff9ce46448 refactor: simplify friends highlights loading to use cached contacts
- Remove redundant contact loading check
- Directly use contacts from centralized controller
- App.tsx already auto-loads contacts on login
- Clearer message indicating cached contacts are being used
- Faster execution since no contact loading needed
2025-10-18 20:58:14 +02:00
Gigi
1e6718fe1e fix: improve Load Friends button behavior in Debug
- Add local loading state for button (friendsButtonLoading)
- Clear friends list before loading to show streaming
- Set final result after controller completes
- Add error handling and logging
- Remove unused global friendsLoading subscription
- Button now properly shows loading state and results
2025-10-18 20:56:53 +02:00
Gigi
d6a913f2a6 feat: add centralized contacts controller
- Create contactsController similar to bookmarkController
- Manage friends/contacts list in one place across the app
- Auto-load contacts on login, cache results per pubkey
- Stream partial contacts as they arrive
- Update App.tsx to subscribe to contacts controller
- Update Debug.tsx to use centralized contacts instead of fetching directly
- Reset contacts on logout
- Contacts won't reload unnecessarily (cached by pubkey)
- Debug 'Load Friends' button forces reload to show streaming behavior
2025-10-18 20:51:03 +02:00
Gigi
8030e2fa00 feat: make friends highlights loading non-blocking
- Start fetching highlights immediately when partial contacts arrive
- Track seen authors to avoid duplicate queries
- Fire-and-forget pattern for partial fetches (like bookmark loading)
- Only await final batch for remaining authors
- Highlights stream in progressively as contacts are discovered
- Matches the non-blocking pattern used in Explore.tsx and bookmark loading
2025-10-18 20:47:35 +02:00
Gigi
1ff2f28566 chore: increase nostrverse highlights limit from 100 to 500
- Better for testing and debugging with more realistic data volumes
2025-10-18 20:43:37 +02:00
Gigi
78457335c6 refactor: simplify nostrverse highlights loading to direct query
- Use direct queryEvents with kind:9802 filter instead of service wrapper
- Add streaming with onEvent callback for immediate UI updates
- Track first event timing for performance analysis
- Remove unused fetchNostrverseHighlights import
2025-10-18 20:43:02 +02:00
Gigi
553feb10df feat: add debug buttons for highlight loading and Web of Trust
- Add three quick-load buttons: Load My Highlights, Load Friends Highlights, Load Nostrverse Highlights
- Add Web of Trust section with Load Friends button to display followed npubs
- Stream highlights with dedupe and timing metrics
- Display friends count and scrollable list of npubs
- All buttons respect loading states and account requirements
2025-10-18 20:39:57 +02:00
Gigi
ba5d7df3bd fix: show highlight button for all reading content
- Show highlight button when readerContent exists (both nostr articles and external URLs)
- Hide highlight button when browsing app pages like explore, settings, etc.
- Ensures highlighting is available for all readable content but not for navigation pages
2025-10-18 20:26:11 +02:00
Gigi
cf3ca2d527 feat: show highlight button only when viewing articles
- Only display the floating highlight button when currentArticle exists or selectedUrl is a nostr article
- Prevents highlight button from showing on external URLs, videos, or other content types
- Improves UX by showing highlight functionality only where it's relevant
2025-10-18 20:23:45 +02:00
Gigi
06763d5307 fix: resolve unused variable linting error in Debug.tsx 2025-10-18 20:23:18 +02:00
Gigi
bc7b4ae42d feat(debug): add time-to-first-event tracking for bookmarks
- Track and display time to first bookmark event arrival
- Mirror highlight loading metrics for consistency
- Shows how quickly local/fast relays respond
- Renamed 'load' stat to 'total' for clarity
- Clear first event timing on reset
2025-10-18 20:20:59 +02:00
Gigi
4dc1894ef3 feat(debug): default highlight loading to logged-in user
- Author mode now defaults to current user's pubkey if not specified
- Changed default mode from 'article' to 'author' for better UX
- Updated placeholder to show logged-in user's pubkey
- Updated description to clarify default behavior
- Makes 'Load Highlights' button immediately useful without input
2025-10-18 20:19:53 +02:00
Gigi
f00f26dfe0 feat(debug): add Highlight Loading section with streaming metrics
- Add query mode selector (Article/#a, URL/#r, Author)
- Stream highlight events as they arrive with onEvent callback
- Track timing metrics: total load time and time-to-first-event
- Display highlight summaries with content, tags, and metadata
- Support EOSE-based completion via queryEvents helper
- Mirror bookmark loading section UX for consistency
2025-10-18 10:05:56 +02:00
Gigi
2e59bc9375 feat(highlights): add optional session cache with TTL
- Add in-memory cache with 60s TTL for article/url/author queries
- Check cache before network fetch to reduce redundant queries
- Support force flag to bypass cache when needed
- Stream cached results through onHighlight callback for consistency
2025-10-18 10:04:13 +02:00
Gigi
0d50d05245 feat(highlights): refactor fetchers to use EOSE-based queryEvents
- Replace ad-hoc Rx timeout-based queries with centralized queryEvents helper
- Remove artificial timeouts (1200ms/6000ms) in favor of EOSE signals
- Use KINDS.Highlights consistently instead of hardcoded 9802
- Maintain streaming callbacks for instant UI updates
- Parallel queries for article #a and #e tags
- Local-first relay prioritization via queryEvents
2025-10-18 10:03:13 +02:00
Gigi
efa6d13726 feat: improve bunker error message formatting
- Add 'Failed:' prefix to error messages
- Add line breaks between error and signer suggestions
- Clearer visual separation of error and help text
2025-10-18 09:40:29 +02:00
Gigi
6116dd12bc feat: hide bookmark controls when logged out
- Only show heart/support button when logged out
- Hide refresh, grouping, and view mode buttons when not logged in
- Cleaner, simpler footer for logged out state
2025-10-18 09:37:17 +02:00
Gigi
210cdd41ec feat: rename Bunker button to Signer
Change button label from 'Bunker' to 'Signer' for better clarity and user-friendliness
2025-10-18 09:35:28 +02:00
Gigi
9378b3c9a9 feat: left-align error message text
- Add text-align: left to login-error
- Change align-items to flex-start for better multi-line text alignment
- Icon now aligns to top instead of center
2025-10-18 09:35:04 +02:00
Gigi
973409e82a feat: add signer suggestions to bunker URI validation error
- Show Amber and Aegis links when bunker URI format is invalid
- Consistent helpful messaging across all bunker errors
- Helps users even when they don't have the right format
2025-10-18 09:34:25 +02:00
Gigi
5d6f48b9a8 feat: add signer suggestions to bunker error messages
- Show helpful message when bunker connection fails
- Suggest Amber (Android) and Aegis (iOS) signers with links
- Links: Amber GitHub and Aegis TestFlight
- Similar pattern to extension error message
2025-10-18 09:33:18 +02:00
Gigi
4921427ad4 feat: simplify login description text
Change 'Connect your nostr npub' → 'Connect your npub'
npub is already nostr-specific, so 'nostr' is redundant
2025-10-18 09:23:20 +02:00
Gigi
ad8cad29d3 fix: ensure bunker input stays centered and constrained
- Add width: 100% to bunker-input-container and bunker-input
- Add box-sizing: border-box to properly calculate width with padding
- Prevents bunker dialog from extending beyond centered layout
2025-10-18 09:22:49 +02:00
Gigi
8d4a4a04a3 fix: catch 'Signer extension missing' error message
- Add check for 'Signer extension missing' error
- Add case-insensitive check for 'extension missing'
- Ensure nos2x link is shown when no extension is found
2025-10-18 09:21:45 +02:00
Gigi
1dc44930b4 feat: make error message links more obvious
- Add primary color and underline to links in error messages
- Increase font weight to 600 for better visibility
- Add hover state with color transition
- nos2x link now clearly stands out as clickable
2025-10-18 09:21:05 +02:00
Gigi
c77907f87a feat: improve extension login error messages
- Show specific message when no extension is found
- Show message when authentication is cancelled/denied
- Display actual error message for other failures
- Remove generic 'Login failed' message
2025-10-18 09:20:33 +02:00
Gigi
9345228e66 feat: add nos2x link to extension error message
- Update error message to mention 'like nos2x'
- Add clickable link to nos2x Chrome Web Store
- Change error type to support React nodes for richer messages
2025-10-18 09:19:20 +02:00
Gigi
811362175c feat: hide Extension button when Bunker input is shown
- Extension button now hidden when bunker input is visible
- Reduces visual clutter and confusion
- Clear focus on the active login method
2025-10-18 09:17:44 +02:00
Gigi
3d22e7a3cb feat: simplify button text to single words
- 'Extension Login' → 'Extension'
- 'Bunker Login' → 'Bunker'
Icons + context make the action clear, minimalist approach
2025-10-18 09:16:52 +02:00
Gigi
0b0d3c2859 feat: use nostr-native language in login description
Change 'Login to see' → 'Connect your nostr npub to see'
More specific and aligned with nostr terminology
2025-10-18 09:16:18 +02:00
Gigi
1f8d18071c feat: shorten login button text for cleaner UI
- 'Login with Extension' → 'Extension Login'
- 'Login with Bunker' → 'Bunker Login'
More concise and easier to scan
2025-10-18 09:15:13 +02:00
Gigi
a4afe59437 fix: properly display FontAwesome icons in login buttons
- Import and use FontAwesomeIcon component from @fortawesome/react-fontawesome
- Add puzzle piece icon (faPuzzlePiece) for Extension button
- Add shield icon (faShieldHalved) for Bunker button
- Add info circle icon (faCircleInfo) for error messages
- Update CSS to properly style SVG icons with correct sizing
2025-10-18 09:14:45 +02:00
Gigi
1fe3786a3d feat: update login title to be more personable
Change 'Welcome to Boris' to 'Hi! I'm Boris.' for a friendlier, more welcoming first impression
2025-10-18 09:13:05 +02:00
Gigi
42d265731f feat: hide login button and user icon when logged out
- Remove redundant login button from sidebar header
- Hide profile avatar when no active account
- Users can now only login through the main login screen
- Logout button only shown when logged in
- Clean up unused imports (useState, Accounts, faRightToBracket)
2025-10-18 09:12:22 +02:00
Gigi
e4b4b97874 feat: highlight 'your own highlights' in login copy
- Style 'your own highlights' text with user's mine highlight color
- Uses --highlight-color-mine CSS variable from settings
- Adds subtle padding and border-radius for clean highlight effect
2025-10-18 09:11:04 +02:00
Gigi
1870c307da feat: improve login UI with better copy and modern design
- Add welcoming title 'Welcome to Boris'
- Update description to highlight key features (bookmarks, long-form articles, highlights)
- Change button labels to 'Login with Extension' and 'Login with Bunker'
- Add FontAwesome icons to login buttons
- Create dedicated login.css with modern, mobile-first styling
- Improve bunker input UI with better spacing and visual hierarchy
- Use softer error styling with amber/warning colors instead of harsh red
- Add smooth transitions and hover effects
- Ensure mobile-optimized touch targets
2025-10-18 09:10:14 +02:00
Gigi
bcb6cfbe97 feat: auto-load bookmarks on login and page mount
Added centralized auto-loading effect that handles all scenarios:
- User logs in (activeAccount becomes available)
- Page loads with existing session
- User logs out and back in (bookmarks cleared by reset)

Watches activeAccount and relayPool, triggers when both ready and no
bookmarks loaded yet. Handles all login methods (extension, bunker) via
single reactive effect.
2025-10-18 01:05:29 +02:00
Gigi
6ba1ce27b7 fix: add extraRelays to EventLoader and AddressLoader
The loaders were initialized without extraRelays, so they had no relays
to fetch from. Added RELAYS config as extraRelays option for both loaders.

This ensures the loaders know where to query for events when hydrating
bookmarks in the background.
2025-10-18 00:58:34 +02:00
Gigi
2f620265f4 chore: clean up verbose debug logging in hydration methods
Removed excessive per-event logging from EventLoader and AddressLoader
subscriptions. Keep only essential logs:
- Initial hydration count
- Error logging

This reduces console noise while maintaining visibility into hydration
progress and errors.
2025-10-18 00:54:56 +02:00
Gigi
61ae31c6a2 refactor: replace manual batching with applesauce EventLoader and AddressLoader
Replaced manual queryEvents batching with applesauce built-in loaders.

Key Changes:
- EventLoader for regular events (by ID) - auto-batches and streams
- AddressLoader for addressable events (coordinates) - handles kind batching
- Added EventStore instance to BookmarkController
- Initialize loaders in start() method
- hydrateByIds and hydrateByCoordinates now synchronous
- Removed manual chunk, IDS_BATCH_SIZE, etc.

Benefits:
- Follows applesauce best practices from examples
- More reliable (no manual timeout logic)
- Better performance (intelligent batching)
- Streaming results (progressive updates)
- Built-in deduplication via EventStore

Pattern: merge pointers through loader, subscribe to stream results.
2025-10-18 00:54:18 +02:00
Gigi
b0fcb0e897 debug: add detailed logging to diagnose hydration hanging
Added extensive logging to track queryEvents lifecycle:
- Log when queryEvents is called
- Log each event as it's received via onEvent callback
- Log when batch completes with event count
- Log errors if batch fails

This will help identify where the hydration is hanging - whether:
- queryEvents never returns
- No events are received
- Some batches fail silently

No functional changes, only diagnostic logging.
2025-10-18 00:49:05 +02:00
Gigi
3b08cd5d23 fix: remove setName filter from Amethyst bookmark grouping
Fixed issue where 489 kind:30001 bookmarks were not appearing in groups
because they had setName: undefined instead of setName: 'bookmark'.

Changes:
- Removed setName === 'bookmark' requirement from amethystPublic/Private filters
- Now all kind:30001 bookmarks are grouped correctly regardless of setName
- Removed debug logging that was added to diagnose the issue

Before: Only 40 bookmarks shown (26 NIP-51 + 7 standalone + 7 web)
After: All 522 bookmarks shown (26 NIP-51 + 489 Amethyst + 7 web)
2025-10-18 00:44:54 +02:00
Gigi
a3a00b8456 debug: add setName distribution logging for kind:30001 bookmarks
Added console log to show the distribution of setName values for all
kind:30001 bookmarks. This will help diagnose why 489 Amethyst bookmarks
aren't appearing in the amethystPublic/amethystPrivate groups.

Expected to see setName='bookmark' but need to verify what values are
actually present in the data.
2025-10-18 00:43:18 +02:00
Gigi
7fecc0c0c3 debug: add logging to diagnose bookmark grouping issue
Added console logs in groupIndividualBookmarks to show:
- Distribution of sourceKind values across all bookmarks
- Sample items with their sourceKind, isPrivate, setName, and id
- Count of items in each group after filtering

This will help identify why grouped view shows only ~40 bookmarks
while flat view shows 500+.
2025-10-18 00:36:40 +02:00
Gigi
93d0284fd6 feat: implement batched background hydration for bookmarks
Implemented efficient background event fetching with:

1. Batching constants:
- IDS_BATCH_SIZE = 100 (regular events)
- D_TAG_BATCH_SIZE = 50 (identifiers)
- AUTHORS_BATCH_SIZE = 50 (authors)

2. Utility functions:
- chunk<T>(arr, size) - split arrays into batches
- hydrationGeneration field - cancellation token

3. Two hydration methods:
- hydrateByIds: Fetches events by ID in batches of 100
- hydrateByCoordinates: Fetches addressable events by kind with 50×50 author×id batches

4. Progressive updates:
- Emit bookmarks instantly with placeholders (IDs only)
- Re-emit after each event arrives via onEvent callback
- All hydration runs in background (fire-and-forget)

5. Cancellation support:
- Increment hydrationGeneration on reset()/start()
- All hydration loops check generation and exit if changed
- Cleanly cancels in-flight fetching when user reloads

Benefits:
- No more hanging with 400+ bookmarked events
- Progressive UI updates as metadata loads
- Efficient relay usage with batched queries
- Clean cancellation on navigation/reload

All bookmarks appear instantly, titles/content hydrate progressively.
2025-10-18 00:34:26 +02:00
Gigi
5965bc1747 fix: check d-tag bookmark for Amethyst grouping 2025-10-18 00:21:33 +02:00
Gigi
0fbf80b04f chore: remove debug logging from bookmark grouping
Removed temporary console.log statements added for debugging. The issue has been identified and fixed - bookmarks were being filtered out by hasContent() when they only had IDs.
2025-10-18 00:18:33 +02:00
Gigi
2004ce76c9 fix: show bookmarks even when they only have IDs (no content yet)
Root cause: hasContent() was filtering out bookmarks that didn't have content text yet. When we skip event fetching for large collections (>100 IDs), bookmarks only have IDs as placeholders, causing 511/522 bookmarks to be filtered out.

Solution: Updated hasContent() to return true if bookmark has either:
- Valid content (original behavior)
- OR a valid ID (placeholder until events are fetched)

This allows all 522 bookmarks to appear in the sidebar immediately, showing IDs/URLs as placeholders until full event data loads.

Removed debug logging from bookmarkUtils as it served its purpose.
2025-10-18 00:18:13 +02:00
Gigi
90c79e34eb debug: add logging to bookmark grouping to diagnose missing bookmarks
Added console logs to groupIndividualBookmarks to see:
- Total items being grouped
- Count per group (nip51Public, nip51Private, amethystPublic, amethystPrivate, standaloneWeb)
- Sample of first 3 items with their sourceKind and isPrivate properties

This will help diagnose why 532 bookmarks are emitted but not appearing in sidebar.
2025-10-18 00:16:34 +02:00