feat: add support for web bookmarks (NIP-B0, kind:39701)

- Update bookmarkService to fetch kind:39701 events
- Add processing logic for web bookmark events in bookmarkProcessing
- Update bookmark deduplication to handle web bookmarks
- Add 'web' type to IndividualBookmark interface
- Implement distinct icon (fa-bookmark + fa-globe) for web bookmarks
- Update CompactView and CardView to display web bookmark icon
- Add web-bookmarks rule documentation
This commit is contained in:
Gigi
2025-10-06 20:30:53 +01:00
parent 1f9dbf576c
commit 1a7a8367a0
7 changed files with 52 additions and 8 deletions

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faBookmark, faUserLock, faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons'
import { faBookmark, faUserLock, faChevronDown, faChevronUp, faGlobe } from '@fortawesome/free-solid-svg-icons'
import { IndividualBookmark } from '../../types/bookmarks'
import { formatDate, renderParsedContent } from '../../utils/bookmarkUtils'
import ContentWithResolvedProfiles from '../ContentWithResolvedProfiles'
@@ -42,6 +42,7 @@ export const CardView: React.FC<CardViewProps> = ({
const contentLength = (bookmark.content || '').length
const shouldTruncate = !expanded && contentLength > 210
const isArticle = bookmark.kind === 30023
const isWebBookmark = bookmark.kind === 39701
return (
<div key={`${bookmark.id}-${index}`} className={`individual-bookmark ${bookmark.isPrivate ? 'private-bookmark' : ''}`}>
@@ -54,7 +55,12 @@ export const CardView: React.FC<CardViewProps> = ({
)}
<div className="bookmark-header">
<span className="bookmark-type">
{bookmark.isPrivate ? (
{isWebBookmark ? (
<span className="fa-layers fa-fw">
<FontAwesomeIcon icon={faBookmark} className="bookmark-visibility public" />
<FontAwesomeIcon icon={faGlobe} className="bookmark-visibility public" transform="shrink-8 down-2" />
</span>
) : bookmark.isPrivate ? (
<>
<FontAwesomeIcon icon={faBookmark} className="bookmark-visibility public" />
<FontAwesomeIcon icon={faUserLock} className="bookmark-visibility private" />

View File

@@ -1,6 +1,6 @@
import React from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faBookmark, faUserLock } from '@fortawesome/free-solid-svg-icons'
import { faBookmark, faUserLock, faGlobe } from '@fortawesome/free-solid-svg-icons'
import { IndividualBookmark } from '../../types/bookmarks'
import { formatDate } from '../../utils/bookmarkUtils'
import ContentWithResolvedProfiles from '../ContentWithResolvedProfiles'
@@ -27,7 +27,8 @@ export const CompactView: React.FC<CompactViewProps> = ({
firstUrlClassification
}) => {
const isArticle = bookmark.kind === 30023
const isClickable = hasUrls || isArticle
const isWebBookmark = bookmark.kind === 39701
const isClickable = hasUrls || isArticle || isWebBookmark
const handleCompactClick = () => {
if (!onSelectUrl) return
@@ -48,7 +49,12 @@ export const CompactView: React.FC<CompactViewProps> = ({
tabIndex={isClickable ? 0 : undefined}
>
<span className="bookmark-type-compact">
{bookmark.isPrivate ? (
{isWebBookmark ? (
<span className="fa-layers fa-fw">
<FontAwesomeIcon icon={faBookmark} className="bookmark-visibility public" />
<FontAwesomeIcon icon={faGlobe} className="bookmark-visibility public" transform="shrink-8 down-2" />
</span>
) : bookmark.isPrivate ? (
<>
<FontAwesomeIcon icon={faBookmark} className="bookmark-visibility public" />
<FontAwesomeIcon icon={faUserLock} className="bookmark-visibility private" />