diff --git a/src/components/Bookmarks.tsx b/src/components/Bookmarks.tsx index eb6b429b..d7e17b76 100644 --- a/src/components/Bookmarks.tsx +++ b/src/components/Bookmarks.tsx @@ -11,6 +11,10 @@ interface Bookmark { content: string created_at: number tags: string[][] + bookmarkCount?: number + eventReferences?: string[] + articleReferences?: string[] + urlReferences?: string[] } interface BookmarksProps { @@ -87,37 +91,31 @@ const Bookmarks: React.FC = ({ addressLoader, onLogout }) => { const parseBookmarkEvent = (event: NostrEvent): Bookmark | null => { try { - // Parse the event content as JSON (bookmark list) - const content = JSON.parse(event.content || '{}') + // According to NIP-51, bookmark lists (kind 10003) contain: + // - "e" tags for event references (the actual bookmarks) + // - "a" tags for article references + // - "r" tags for URL references - if (content.bookmarks && Array.isArray(content.bookmarks)) { - // Handle bookmark list format - return { - id: event.id, - title: content.name || 'Untitled Bookmark List', - url: '', - content: event.content, - created_at: event.created_at, - tags: event.tags - } - } - - // Handle individual bookmark entries - const urlTag = event.tags.find((tag: string[]) => tag[0] === 'r' && tag[1]) - const titleTag = event.tags.find((tag: string[]) => tag[0] === 'title' && tag[1]) + const eventTags = event.tags.filter((tag: string[]) => tag[0] === 'e') + const articleTags = event.tags.filter((tag: string[]) => tag[0] === 'a') + const urlTags = event.tags.filter((tag: string[]) => tag[0] === 'r') - if (urlTag) { - return { - id: event.id, - title: titleTag?.[1] || 'Untitled', - url: urlTag[1], - content: event.content, - created_at: event.created_at, - tags: event.tags - } + // Get the title from content or use a default + const title = event.content || `Bookmark List (${eventTags.length + articleTags.length + urlTags.length} items)` + + return { + id: event.id, + title: title, + url: '', // Bookmark lists don't have a single URL + content: event.content, + created_at: event.created_at, + tags: event.tags, + // Add metadata about the bookmark list + bookmarkCount: eventTags.length + articleTags.length + urlTags.length, + eventReferences: eventTags.map(tag => tag[1]), + articleReferences: articleTags.map(tag => tag[1]), + urlReferences: urlTags.map(tag => tag[1]) } - - return null } catch (error) { console.error('Error parsing bookmark event:', error) return null @@ -189,21 +187,41 @@ const Bookmarks: React.FC = ({ addressLoader, onLogout }) => { {bookmarks.map((bookmark) => (

{bookmark.title}

- {bookmark.url && ( - - {bookmark.url} - + {bookmark.bookmarkCount && ( +

+ {bookmark.bookmarkCount} bookmarks in this list +

+ )} + {bookmark.urlReferences && bookmark.urlReferences.length > 0 && ( +
+

URLs:

+ {bookmark.urlReferences.map((url, index) => ( + + {url} + + ))} +
+ )} + {bookmark.eventReferences && bookmark.eventReferences.length > 0 && ( +
+

Event References ({bookmark.eventReferences.length}):

+
+ {bookmark.eventReferences.slice(0, 3).map((eventId, index) => ( + + {eventId.slice(0, 8)}...{eventId.slice(-8)} + + ))} + {bookmark.eventReferences.length > 3 && ( + ... and {bookmark.eventReferences.length - 3} more + )} +
+
)} {bookmark.content && (

{bookmark.content}

)}
- Added: {formatDate(bookmark.created_at)} + Created: {formatDate(bookmark.created_at)}
))} diff --git a/src/index.css b/src/index.css index 4605671f..d2061b72 100644 --- a/src/index.css +++ b/src/index.css @@ -122,6 +122,65 @@ body { font-family: monospace; } +.bookmark-count { + color: #666; + font-size: 0.9rem; + margin: 0.5rem 0; +} + +.bookmark-urls { + margin: 1rem 0; +} + +.bookmark-urls h4 { + margin: 0 0 0.5rem 0; + font-size: 0.9rem; + color: #666; +} + +.bookmark-url { + display: block; + margin: 0.25rem 0; + color: #007bff; + text-decoration: none; + word-break: break-all; +} + +.bookmark-url:hover { + text-decoration: underline; +} + +.bookmark-events { + margin: 1rem 0; +} + +.bookmark-events h4 { + margin: 0 0 0.5rem 0; + font-size: 0.9rem; + color: #666; +} + +.event-ids { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} + +.event-id { + background: #f5f5f5; + padding: 0.25rem 0.5rem; + border-radius: 4px; + font-family: monospace; + font-size: 0.8rem; + color: #666; +} + +.more-events { + color: #999; + font-style: italic; + font-size: 0.8rem; +} + .logout-button { background: #dc3545; color: white;