refactor: use applesauce helpers for highlight parsing

- Replace manual tag parsing with applesauce-core helper functions
- Use getHighlightText, getHighlightContext, getHighlightComment, etc.
- Add support for highlight comments in UI
- Extract author from attributions using proper helper
- Handle both event and address pointers correctly
- Add styling for highlight comments

This follows applesauce best practices and makes the code more robust.
This commit is contained in:
Gigi
2025-10-04 20:41:26 +01:00
parent 1d7ab59272
commit c0de624fe6
4 changed files with 49 additions and 20 deletions

View File

@@ -37,6 +37,12 @@ export const HighlightItem: React.FC<HighlightItemProps> = ({ highlight, onSelec
{highlight.content}
</blockquote>
{highlight.comment && (
<div className="highlight-comment">
{highlight.comment}
</div>
)}
{highlight.context && (
<details className="highlight-context">
<summary>Show context</summary>

View File

@@ -1229,6 +1229,17 @@ body {
font-size: 0.95rem;
}
.highlight-comment {
margin-top: 0.5rem;
padding: 0.75rem;
background: rgba(100, 108, 255, 0.1);
border-left: 3px solid #646cff;
border-radius: 4px;
font-size: 0.875rem;
color: #ddd;
line-height: 1.5;
}
.highlight-context {
margin-top: 0.5rem;
}

View File

@@ -1,17 +1,17 @@
import { RelayPool, completeOnEose } from 'applesauce-relay'
import { lastValueFrom, takeUntil, timer, toArray } from 'rxjs'
import { NostrEvent } from 'nostr-tools'
import {
getHighlightText,
getHighlightContext,
getHighlightComment,
getHighlightSourceEventPointer,
getHighlightSourceAddressPointer,
getHighlightSourceUrl,
getHighlightAttributions
} from 'applesauce-core/helpers'
import { Highlight } from '../types/highlights'
interface NostrEvent {
id: string
pubkey: string
created_at: number
kind: number
tags: string[][]
content: string
sig: string
}
/**
* Deduplicate highlight events by ID
* Since highlights can come from multiple relays, we need to ensure
@@ -51,22 +51,33 @@ export const fetchHighlights = async (
console.log('📊 Unique highlight events after deduplication:', uniqueEvents.length)
const highlights: Highlight[] = uniqueEvents.map((event: NostrEvent) => {
// Extract relevant tags
const eventRef = event.tags.find(t => t[0] === 'e' || t[0] === 'a')?.[1]
const urlRef = event.tags.find(t => t[0] === 'r')?.[1]
const authorTag = event.tags.find(t => t[0] === 'p' && t[3] === 'author')
const contextTag = event.tags.find(t => t[0] === 'context')
// Use applesauce helpers to extract highlight data
const highlightText = getHighlightText(event)
const context = getHighlightContext(event)
const comment = getHighlightComment(event)
const sourceEventPointer = getHighlightSourceEventPointer(event)
const sourceAddressPointer = getHighlightSourceAddressPointer(event)
const sourceUrl = getHighlightSourceUrl(event)
const attributions = getHighlightAttributions(event)
// Get author from attributions
const author = attributions.find(a => a.role === 'author')?.pubkey
// Get event reference (prefer event pointer, fallback to address pointer)
const eventReference = sourceEventPointer?.id ||
(sourceAddressPointer ? `${sourceAddressPointer.kind}:${sourceAddressPointer.pubkey}:${sourceAddressPointer.identifier}` : undefined)
return {
id: event.id,
pubkey: event.pubkey,
created_at: event.created_at,
content: event.content,
content: highlightText,
tags: event.tags,
eventReference: eventRef,
urlReference: urlRef,
author: authorTag?.[1],
context: contextTag?.[1]
eventReference,
urlReference: sourceUrl,
author,
context,
comment
}
})

View File

@@ -10,5 +10,6 @@ export interface Highlight {
urlReference?: string // 'r' tag
author?: string // 'p' tag with 'author' role
context?: string // surrounding text context
comment?: string // optional comment about the highlight
}