From 2297d8ae96c1e53a905b52631fe21e70c2b13692 Mon Sep 17 00:00:00 2001 From: Gigi Date: Sun, 5 Oct 2025 09:19:43 +0100 Subject: [PATCH] fix: query highlights using both a-tag and e-tag - Highlights on replaceable events include BOTH 'a' and 'e' tags - Query for highlights using article coordinate (#a tag) - Also query using event ID (#e tag) for comprehensive results - Combine and deduplicate results from both queries - Add detailed logging to help diagnose why highlights aren't found - Suggest checking highlighter.com if no highlights found Per NIP-84 and applesauce implementation, highlights on kind:30023 articles include both an addressable reference ('a' tag) and an event reference ('e' tag). --- dist/index.html | 2 +- src/components/Bookmarks.tsx | 3 ++- src/services/highlightService.ts | 34 +++++++++++++++++++++++++++----- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/dist/index.html b/dist/index.html index e0990789..5fe6ad1c 100644 --- a/dist/index.html +++ b/dist/index.html @@ -5,7 +5,7 @@ Boris - Nostr Bookmarks - + diff --git a/src/components/Bookmarks.tsx b/src/components/Bookmarks.tsx index 0e9454e9..fce8ba99 100644 --- a/src/components/Bookmarks.tsx +++ b/src/components/Bookmarks.tsx @@ -83,7 +83,8 @@ const Bookmarks: React.FC = ({ relayPool, onLogout }) => { try { setHighlightsLoading(true) - const fetchedHighlights = await fetchHighlightsForArticle(relayPool, articleCoordinate) + // Pass both the article coordinate and event ID for comprehensive highlight fetching + const fetchedHighlights = await fetchHighlightsForArticle(relayPool, articleCoordinate, article.event.id) console.log(`📌 Found ${fetchedHighlights.length} highlights for article ${articleCoordinate}`) setHighlights(fetchedHighlights) } catch (err) { diff --git a/src/services/highlightService.ts b/src/services/highlightService.ts index 1b47b38a..26686fbd 100644 --- a/src/services/highlightService.ts +++ b/src/services/highlightService.ts @@ -30,13 +30,15 @@ function dedupeHighlights(events: NostrEvent[]): NostrEvent[] { } /** - * Fetches highlights for a specific article by its address coordinate + * Fetches highlights for a specific article by its address coordinate and/or event ID * @param relayPool - The relay pool to query * @param articleCoordinate - The article's address in format "kind:pubkey:identifier" (e.g., "30023:abc...def:my-article") + * @param eventId - Optional event ID to also query by 'e' tag */ export const fetchHighlightsForArticle = async ( relayPool: RelayPool, - articleCoordinate: string + articleCoordinate: string, + eventId?: string ): Promise => { try { // Use well-known relays for highlights even if user isn't logged in @@ -49,19 +51,41 @@ export const fetchHighlightsForArticle = async ( ] console.log('🔍 Fetching highlights (kind 9802) for article:', articleCoordinate) + console.log('🔍 Event ID:', eventId || 'none') console.log('🔍 From relays:', highlightRelays) - console.log('🔍 Filter:', JSON.stringify({ kinds: [9802], '#a': [articleCoordinate] }, null, 2)) // Query for highlights that reference this article via the 'a' tag - const rawEvents = await lastValueFrom( + console.log('🔍 Filter 1 (a-tag):', JSON.stringify({ kinds: [9802], '#a': [articleCoordinate] }, null, 2)) + const aTagEvents = await lastValueFrom( relayPool .req(highlightRelays, { kinds: [9802], '#a': [articleCoordinate] }) .pipe(completeOnEose(), takeUntil(timer(10000)), toArray()) ) - console.log('📊 Raw highlight events fetched:', rawEvents.length) + console.log('📊 Highlights via a-tag:', aTagEvents.length) + + // If we have an event ID, also query for highlights that reference via the 'e' tag + let eTagEvents: NostrEvent[] = [] + if (eventId) { + console.log('🔍 Filter 2 (e-tag):', JSON.stringify({ kinds: [9802], '#e': [eventId] }, null, 2)) + eTagEvents = await lastValueFrom( + relayPool + .req(highlightRelays, { kinds: [9802], '#e': [eventId] }) + .pipe(completeOnEose(), takeUntil(timer(10000)), toArray()) + ) + console.log('📊 Highlights via e-tag:', eTagEvents.length) + } + + // Combine results from both queries + const rawEvents = [...aTagEvents, ...eTagEvents] + console.log('📊 Total raw highlight events fetched:', rawEvents.length) + if (rawEvents.length > 0) { console.log('📄 Sample highlight tags:', JSON.stringify(rawEvents[0].tags, null, 2)) + } else { + console.log('❌ No highlights found. Article coordinate:', articleCoordinate) + console.log('❌ Event ID:', eventId || 'none') + console.log('💡 Try checking if there are any highlights on this article at https://highlighter.com') } // Deduplicate events by ID