Bpistle/src/providers/BookmarksProvider.tsx
2025-04-18 21:51:36 +08:00

72 lines
2.3 KiB
TypeScript

import { createBookmarkDraftEvent } from '@/lib/draft-event'
import { createContext, useContext, useMemo } from 'react'
import { useNostr } from './NostrProvider'
import client from '@/services/client.service'
type TBookmarksContext = {
bookmarks: string[][]
addBookmark: (eventId: string, eventPubkey: string, relayHint?: string) => Promise<void>
removeBookmark: (eventId: string) => Promise<void>
}
const BookmarksContext = createContext<TBookmarksContext | undefined>(undefined)
export const useBookmarks = () => {
const context = useContext(BookmarksContext)
if (!context) {
throw new Error('useBookmarks must be used within a BookmarksProvider')
}
return context
}
export function BookmarksProvider({ children }: { children: React.ReactNode }) {
const { pubkey: accountPubkey, bookmarkListEvent, publish, updateBookmarkListEvent } = useNostr()
const bookmarks = useMemo(
() => (bookmarkListEvent ? bookmarkListEvent.tags : []),
[bookmarkListEvent]
)
const addBookmark = async (eventId: string, eventPubkey: string, relayHint?: string) => {
if (!accountPubkey) return
const relayHintToUse = relayHint || client.getEventHint(eventId)
const newTag = ['e', eventId, relayHintToUse, eventPubkey]
const currentTags = bookmarkListEvent?.tags || []
const isDuplicate = currentTags.some((tag) => tag[0] === 'e' && tag[1] === eventId)
if (isDuplicate) return
const newTags = [...currentTags, newTag]
const newBookmarkDraftEvent = createBookmarkDraftEvent(newTags)
const newBookmarkEvent = await publish(newBookmarkDraftEvent)
await updateBookmarkListEvent(newBookmarkEvent)
}
const removeBookmark = async (eventId: string) => {
if (!accountPubkey || !bookmarkListEvent) return
const newTags = bookmarkListEvent.tags.filter((tag) => !(tag[0] === 'e' && tag[1] === eventId))
if (newTags.length === bookmarkListEvent.tags.length) return
const newBookmarkDraftEvent = createBookmarkDraftEvent(newTags)
const newBookmarkEvent = await publish(newBookmarkDraftEvent)
await updateBookmarkListEvent(newBookmarkEvent)
}
return (
<BookmarksContext.Provider
value={{
bookmarks,
addBookmark,
removeBookmark
}}
>
{children}
</BookmarksContext.Provider>
)
}