import { useFetchEvent } from '@/hooks' import { generateBech32IdFromATag, generateBech32IdFromETag } from '@/lib/tag' import { useNostr } from '@/providers/NostrProvider' import { useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import NoteCard, { NoteCardLoadingSkeleton } from '../NoteCard' const SHOW_COUNT = 10 export default function BookmarkList() { const { t } = useTranslation() const { bookmarkListEvent } = useNostr() const eventIds = useMemo(() => { if (!bookmarkListEvent) return [] return ( bookmarkListEvent.tags .map((tag) => tag[0] === 'e' ? generateBech32IdFromETag(tag) : tag[0] === 'a' ? generateBech32IdFromATag(tag) : null ) .filter(Boolean) as (`nevent1${string}` | `naddr1${string}`)[] ).reverse() }, [bookmarkListEvent]) const [showCount, setShowCount] = useState(SHOW_COUNT) const bottomRef = useRef(null) useEffect(() => { const options = { root: null, rootMargin: '10px', threshold: 0.1 } const loadMore = () => { if (showCount < eventIds.length) { setShowCount((prev) => prev + SHOW_COUNT) } } const observerInstance = new IntersectionObserver((entries) => { if (entries[0].isIntersecting) { loadMore() } }, options) const currentBottomRef = bottomRef.current if (currentBottomRef) { observerInstance.observe(currentBottomRef) } return () => { if (observerInstance && currentBottomRef) { observerInstance.unobserve(currentBottomRef) } } }, [showCount, eventIds]) if (eventIds.length === 0) { return (
{t('no bookmarks found')}
) } return (
{eventIds.slice(0, showCount).map((eventId) => ( ))} {showCount < eventIds.length ? (
) : (
{t('no more bookmarks')}
)}
) } function BookmarkedNote({ eventId }: { eventId: string }) { const { event, isFetching } = useFetchEvent(eventId) if (isFetching) { return } if (!event) { return null } return }