diff --git a/dist/index.html b/dist/index.html
index 971caa06..dc5b4fa9 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 780cf0b0..b0d4666f 100644
--- a/src/components/Bookmarks.tsx
+++ b/src/components/Bookmarks.tsx
@@ -7,7 +7,7 @@ import { Bookmark } from '../types/bookmarks'
import { Highlight } from '../types/highlights'
import { BookmarkList } from './BookmarkList'
import { fetchBookmarks } from '../services/bookmarkService'
-import { fetchHighlights, fetchHighlightsForArticle } from '../services/highlightService'
+import { fetchHighlights, fetchHighlightsForArticle, fetchHighlightsForUrl } from '../services/highlightService'
import { fetchContacts } from '../services/contactService'
import ContentPanel from './ContentPanel'
import { HighlightsPanel } from './HighlightsPanel'
@@ -225,15 +225,23 @@ const Bookmarks: React.FC = ({ relayPool, onLogout }) => {
const handleHighlightCreated = async () => {
// Refresh highlights after creating a new one
- if (!relayPool || !currentArticleCoordinate) return
+ if (!relayPool) return
try {
- const newHighlights = await fetchHighlightsForArticle(
- relayPool,
- currentArticleCoordinate,
- currentArticleEventId
- )
- setHighlights(newHighlights)
+ // Refresh based on what we're currently viewing
+ if (currentArticleCoordinate) {
+ // Viewing a nostr article - fetch by article coordinate
+ const newHighlights = await fetchHighlightsForArticle(
+ relayPool,
+ currentArticleCoordinate,
+ currentArticleEventId
+ )
+ setHighlights(newHighlights)
+ } else if (selectedUrl && !selectedUrl.startsWith('nostr:')) {
+ // Viewing an external URL - fetch by URL
+ const newHighlights = await fetchHighlightsForUrl(relayPool, selectedUrl)
+ setHighlights(newHighlights)
+ }
} catch (err) {
console.error('Failed to refresh highlights:', err)
}
@@ -248,17 +256,32 @@ const Bookmarks: React.FC = ({ relayPool, onLogout }) => {
}, [])
const handleCreateHighlight = useCallback(async (text: string) => {
- if (!activeAccount || !relayPool || !currentArticle) {
+ if (!activeAccount || !relayPool) {
console.error('Missing requirements for highlight creation')
return
}
+ // Need either a nostr article or an external URL
+ if (!currentArticle && !selectedUrl) {
+ console.error('No source available for highlight creation')
+ return
+ }
+
try {
+ // Determine the source: prefer currentArticle (for nostr content), fallback to selectedUrl (for external URLs)
+ const source = currentArticle || selectedUrl!
+
+ // For context extraction, use article content or reader content
+ const contentForContext = currentArticle
+ ? currentArticle.content
+ : readerContent?.markdown || readerContent?.html
+
await createHighlight(
text,
- currentArticle,
+ source,
activeAccount,
- relayPool
+ relayPool,
+ contentForContext
)
console.log('✅ Highlight created successfully!')
@@ -269,7 +292,7 @@ const Bookmarks: React.FC = ({ relayPool, onLogout }) => {
} catch (error) {
console.error('Failed to create highlight:', error)
}
- }, [activeAccount, relayPool, currentArticle, handleHighlightCreated])
+ }, [activeAccount, relayPool, currentArticle, selectedUrl, readerContent, handleHighlightCreated])
return (
<>
diff --git a/src/services/highlightCreationService.ts b/src/services/highlightCreationService.ts
index ebeaaa84..2afd0a5a 100644
--- a/src/services/highlightCreationService.ts
+++ b/src/services/highlightCreationService.ts
@@ -8,32 +8,45 @@ import { RELAYS } from '../config/relays'
/**
* Creates and publishes a highlight event (NIP-84)
+ * Supports both nostr-native articles and external URLs
*/
export async function createHighlight(
selectedText: string,
- article: NostrEvent | null,
+ source: NostrEvent | string,
account: IAccount,
relayPool: RelayPool,
+ contentForContext?: string,
comment?: string
): Promise {
- if (!selectedText || !article) {
+ if (!selectedText || !source) {
throw new Error('Missing required data to create highlight')
}
// Create EventFactory with the account as signer
const factory = new EventFactory({ signer: account })
- // Parse article coordinate to get address pointer
- const addressPointer = parseArticleCoordinate(article)
+ let blueprintSource: NostrEvent | AddressPointer | string
+ let context: string | undefined
- // Extract context (previous and next sentences from the same paragraph)
- const context = extractContext(selectedText, article.content)
+ // Handle NostrEvent (article) source
+ if (typeof source === 'object' && 'kind' in source) {
+ blueprintSource = parseArticleCoordinate(source)
+ context = extractContext(selectedText, source.content)
+ }
+ // Handle URL string source
+ else {
+ blueprintSource = source
+ // Try to extract context from provided content if available
+ if (contentForContext) {
+ context = extractContext(selectedText, contentForContext)
+ }
+ }
// Create highlight event using the blueprint
const highlightEvent = await factory.create(
HighlightBlueprint,
selectedText,
- addressPointer,
+ blueprintSource,
context ? { comment, context } : comment ? { comment } : undefined
)