feat: add note search to profile page

This commit is contained in:
codytseng
2025-10-15 22:35:24 +08:00
parent f5ce41dc54
commit 72d43cceec
2 changed files with 50 additions and 12 deletions

View File

@@ -1,13 +1,14 @@
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 { BIG_RELAY_URLS, MAX_PINNED_NOTES, SEARCHABLE_RELAY_URLS } from '@/constants'
import { generateBech32IdFromETag } from '@/lib/tag'
import { isTouchDevice } from '@/lib/utils'
import { useKindFilter } from '@/providers/KindFilterProvider'
import { useNostr } from '@/providers/NostrProvider'
import client from '@/services/client.service'
import storage from '@/services/local-storage.service'
import relayInfoService from '@/services/relay-info.service'
import { TFeedSubRequest, TNoteListMode } from '@/types'
import { NostrEvent } from 'nostr-tools'
import { useEffect, useMemo, useRef, useState } from 'react'
@@ -15,10 +16,12 @@ import { RefreshButton } from '../RefreshButton'
export default function ProfileFeed({
pubkey,
topSpace = 0
topSpace = 0,
search = ''
}: {
pubkey: string
topSpace?: number
search?: string
}) {
const { pubkey: myPubkey, pinListEvent: myPinListEvent } = useNostr()
const { showKinds } = useKindFilter()
@@ -106,17 +109,32 @@ export default function ProfileFeed({
}
const relayList = await client.fetchRelayList(pubkey)
setSubRequests([
{
urls: relayList.write.concat(BIG_RELAY_URLS).slice(0, 8),
filter: {
authors: [pubkey]
if (search) {
const writeRelays = relayList.write.slice(0, 8)
const relayInfos = await relayInfoService.getRelayInfos(writeRelays)
const searchableRelays = writeRelays.filter((_, index) =>
relayInfos[index]?.supported_nips?.includes(50)
)
setSubRequests([
{
urls: searchableRelays.concat(SEARCHABLE_RELAY_URLS).slice(0, 8),
filter: { authors: [pubkey], search }
}
}
])
])
} else {
setSubRequests([
{
urls: relayList.write.concat(BIG_RELAY_URLS).slice(0, 8),
filter: {
authors: [pubkey]
}
}
])
}
}
init()
}, [pubkey, listMode])
}, [pubkey, listMode, search])
const handleListModeChange = (mode: TNoteListMode) => {
setListMode(mode)
@@ -150,7 +168,7 @@ export default function ProfileFeed({
showKinds={temporaryShowKinds}
hideReplies={listMode === 'posts'}
filterMutedNotes={false}
pinnedEventIds={listMode === 'you' ? [] : pinnedEventIds}
pinnedEventIds={listMode === 'you' || !!search ? [] : pinnedEventIds}
/>
</>
)

View File

@@ -21,6 +21,7 @@ import { Link, Zap } from 'lucide-react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import NotFound from '../NotFound'
import SearchInput from '../SearchInput'
import FollowedBy from './FollowedBy'
import Followings from './Followings'
import ProfileFeed from './ProfileFeed'
@@ -32,6 +33,8 @@ export default function Profile({ id }: { id?: string }) {
const { profile, isFetching } = useFetchProfile(id)
const { pubkey: accountPubkey } = useNostr()
const { mutePubkeySet } = useMuteList()
const [searchInput, setSearchInput] = useState('')
const [debouncedInput, setDebouncedInput] = useState(searchInput)
const { followings } = useFetchFollowings(profile?.pubkey)
const isFollowingYou = useMemo(() => {
return (
@@ -51,6 +54,16 @@ export default function Profile({ id }: { id?: string }) {
}
}, [])
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedInput(searchInput.trim())
}, 1000)
return () => {
clearTimeout(handler)
}
}, [searchInput])
useEffect(() => {
if (!profile?.pubkey) return
@@ -185,8 +198,15 @@ export default function Profile({ id }: { id?: string }) {
</div>
</div>
</div>
<div className="px-4 pt-2 pb-0.5">
<SearchInput
value={searchInput}
onChange={(e) => setSearchInput(e.target.value)}
placeholder={t('Search')}
/>
</div>
</div>
<ProfileFeed pubkey={pubkey} topSpace={topContainerHeight + 100} />
<ProfileFeed pubkey={pubkey} topSpace={topContainerHeight + 100} search={debouncedInput} />
</>
)
}