feat: add note search to profile page
This commit is contained in:
@@ -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}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -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} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user