diff --git a/src/components/NoteList/index.tsx b/src/components/NoteList/index.tsx index c2714cbd..9dab79a5 100644 --- a/src/components/NoteList/index.tsx +++ b/src/components/NoteList/index.tsx @@ -16,6 +16,7 @@ import client from '@/services/client.service' import { TFeedSubRequest } from '@/types' import dayjs from 'dayjs' import { Event } from 'nostr-tools' +import { decode } from 'nostr-tools/nip19' import { forwardRef, useCallback, @@ -29,6 +30,7 @@ import { useTranslation } from 'react-i18next' import PullToRefresh from 'react-simple-pull-to-refresh' import { toast } from 'sonner' import NoteCard, { NoteCardLoadingSkeleton } from '../NoteCard' +import PinnedNoteCard from '../PinnedNoteCard' const LIMIT = 200 const ALGO_LIMIT = 500 @@ -44,7 +46,7 @@ const NoteList = forwardRef( hideUntrustedNotes = false, areAlgoRelays = false, showRelayCloseReason = false, - filteredEventHexIdSet = new Set() + pinnedEventIds = [] }: { subRequests: TFeedSubRequest[] showKinds: number[] @@ -53,7 +55,7 @@ const NoteList = forwardRef( hideUntrustedNotes?: boolean areAlgoRelays?: boolean showRelayCloseReason?: boolean - filteredEventHexIdSet?: Set + pinnedEventIds?: string[] }, ref ) => { @@ -76,7 +78,19 @@ const NoteList = forwardRef( const shouldHideEvent = useCallback( (evt: Event) => { - if (filteredEventHexIdSet.has(evt.id)) return true + const pinnedEventHexIdSet = new Set() + pinnedEventIds.forEach((id) => { + try { + const { type, data } = decode(id) + if (type === 'nevent') { + pinnedEventHexIdSet.add(data.id) + } + } catch { + // ignore + } + }) + + if (pinnedEventHexIdSet.has(evt.id)) return true if (isEventDeleted(evt)) return true if (hideReplies && isReplyNoteEvent(evt)) return true if (hideUntrustedNotes && !isUserTrusted(evt.pubkey)) return true @@ -91,7 +105,7 @@ const NoteList = forwardRef( return false }, - [hideReplies, hideUntrustedNotes, mutePubkeySet, filteredEventHexIdSet, isEventDeleted] + [hideReplies, hideUntrustedNotes, mutePubkeySet, pinnedEventIds, isEventDeleted] ) const filteredEvents = useMemo(() => { @@ -284,6 +298,9 @@ const NoteList = forwardRef( const list = (
+ {pinnedEventIds.map((id) => ( + + ))} {filteredEvents.map((event) => ( + } + + if (!event) { + return null + } + + return +} diff --git a/src/components/Profile/ProfileFeed.tsx b/src/components/Profile/ProfileFeed.tsx index 1e6811da..f4afd614 100644 --- a/src/components/Profile/ProfileFeed.tsx +++ b/src/components/Profile/ProfileFeed.tsx @@ -2,7 +2,6 @@ import KindFilter from '@/components/KindFilter' import NoteList, { TNoteListRef } from '@/components/NoteList' import Tabs from '@/components/Tabs' import { BIG_RELAY_URLS, MAX_PINNED_NOTES } from '@/constants' -import { useFetchEvent } from '@/hooks' import { generateBech32IdFromETag } from '@/lib/tag' import { isTouchDevice } from '@/lib/utils' import { useKindFilter } from '@/providers/KindFilterProvider' @@ -12,7 +11,6 @@ import storage from '@/services/local-storage.service' import { TFeedSubRequest, TNoteListMode } from '@/types' import { NostrEvent } from 'nostr-tools' import { useEffect, useMemo, useRef, useState } from 'react' -import NoteCard, { NoteCardLoadingSkeleton } from '../NoteCard' import { RefreshButton } from '../RefreshButton' export default function ProfileFeed({ @@ -28,7 +26,6 @@ export default function ProfileFeed({ const [listMode, setListMode] = useState(() => storage.getNoteListMode()) const [subRequests, setSubRequests] = useState([]) const [pinnedEventIds, setPinnedEventIds] = useState([]) - const [pinnedEventHexIdSet, setPinnedEventHexIdSet] = useState>(new Set()) const tabs = useMemo(() => { const _tabs = [ { value: 'posts', label: 'Notes' }, @@ -43,7 +40,6 @@ export default function ProfileFeed({ }, [myPubkey, pubkey]) const supportTouch = useMemo(() => isTouchDevice(), []) const noteListRef = useRef(null) - const topRef = useRef(null) useEffect(() => { const initPinnedEventIds = async () => { @@ -73,7 +69,6 @@ export default function ProfileFeed({ }) .filter(Boolean) as string[]) ?? [] setPinnedEventIds(ids) - setPinnedEventHexIdSet(hexIdSet) } initPinnedEventIds() }, [pubkey, myPubkey, myPinListEvent]) @@ -125,12 +120,12 @@ export default function ProfileFeed({ const handleListModeChange = (mode: TNoteListMode) => { setListMode(mode) - topRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' }) + noteListRef.current?.scrollToTop('smooth') } const handleShowKindsChange = (newShowKinds: number[]) => { setTemporaryShowKinds(newShowKinds) - topRef.current?.scrollIntoView({ behavior: 'instant', block: 'start' }) + noteListRef.current?.scrollToTop('instant') } return ( @@ -149,32 +144,14 @@ export default function ProfileFeed({ } /> -
- {pinnedEventIds.map((eventId) => ( - - ))} ) } - -function PinnedNote({ eventId }: { eventId: string }) { - const { event, isFetching } = useFetchEvent(eventId) - - if (isFetching) { - return - } - - if (!event) { - return null - } - - return -}