fix: 🐛

This commit is contained in:
codytseng
2025-09-01 22:31:32 +08:00
parent a1285fe44d
commit d189d51e26
5 changed files with 34 additions and 11 deletions

View File

@@ -108,7 +108,7 @@ export default function Note({
<div className="flex items-center space-x-2 flex-1">
<UserAvatar userId={event.pubkey} size={size === 'small' ? 'medium' : 'normal'} />
<div className="flex-1 w-0">
<div className="flex gap-2 items-baseline">
<div className="flex gap-2 items-center">
<Username
userId={event.pubkey}
className={`font-semibold flex truncate ${size === 'small' ? 'text-sm' : ''}`}

View File

@@ -2,7 +2,7 @@ import { SEARCHABLE_RELAY_URLS } from '@/constants'
import client from '@/services/client.service'
import dayjs from 'dayjs'
import { useEffect, useRef, useState } from 'react'
import UserItem from '../UserItem'
import UserItem, { UserItemSkeleton } from '../UserItem'
const LIMIT = 50
@@ -12,6 +12,13 @@ export function ProfileListBySearch({ search }: { search: string }) {
const [pubkeySet, setPubkeySet] = useState(new Set<string>())
const bottomRef = useRef<HTMLDivElement>(null)
useEffect(() => {
setUntil(dayjs().unix())
setHasMore(true)
setPubkeySet(new Set<string>())
loadMore()
}, [search])
useEffect(() => {
if (!hasMore) return
const options = {
@@ -39,7 +46,7 @@ export function ProfileListBySearch({ search }: { search: string }) {
}
}, [hasMore, search, until])
async function loadMore() {
const loadMore = async () => {
const profiles = await client.searchProfiles(SEARCHABLE_RELAY_URLS, {
search,
until,
@@ -62,6 +69,7 @@ export function ProfileListBySearch({ search }: { search: string }) {
{Array.from(pubkeySet).map((pubkey, index) => (
<UserItem key={`${index}-${pubkey}`} pubkey={pubkey} />
))}
{hasMore && <UserItemSkeleton />}
{hasMore && <div ref={bottomRef} />}
</div>
)

View File

@@ -1,6 +1,5 @@
import Nip05 from '@/components/Nip05'
import SearchInput from '@/components/SearchInput'
import { ScrollArea } from '@/components/ui/scroll-area'
import UserAvatar from '@/components/UserAvatar'
import Username from '@/components/Username'
import { useSearchProfiles } from '@/hooks'
@@ -24,6 +23,7 @@ import {
useState
} from 'react'
import { useTranslation } from 'react-i18next'
import { UserItemSkeleton } from '../UserItem'
const SearchBar = forwardRef<
TSearchBarRef,
@@ -37,7 +37,7 @@ const SearchBar = forwardRef<
const { push } = useSecondaryPage()
const { isSmallScreen } = useScreenSize()
const [debouncedInput, setDebouncedInput] = useState(input)
const { profiles } = useSearchProfiles(debouncedInput, 10)
const { profiles, isFetching: isFetchingProfiles } = useSearchProfiles(debouncedInput, 5)
const [searching, setSearching] = useState(false)
const searchInputRef = useRef<HTMLInputElement>(null)
const normalizedUrl = useMemo(() => {
@@ -154,7 +154,8 @@ const SearchBar = forwardRef<
}
/>
))}
{profiles.length >= 10 && (
{isFetchingProfiles && profiles.length < 5 && <UserItemSkeleton hideFollowButton />}
{profiles.length >= 5 && (
<Item onClick={() => updateSearch({ type: 'profiles', search })}>
<div className="font-semibold">{t('Show more...')}</div>
</Item>
@@ -179,16 +180,15 @@ const SearchBar = forwardRef<
<>
<div
className={cn(
'bg-surface-background rounded-b-lg shadow-lg',
'bg-surface-background rounded-b-lg shadow-lg z-50',
isSmallScreen
? 'fixed top-12 inset-x-0'
: 'absolute top-full -translate-y-1 inset-x-0 pt-1 ',
searching ? 'z-50' : ''
: 'absolute top-full -translate-y-1 inset-x-0 pt-1 '
)}
onMouseDown={(e) => e.preventDefault()}
>
{list ? (
<ScrollArea className="h-[60vh]">{list}</ScrollArea>
<div className="h-fit">{list}</div>
) : (
<div className="p-4 text-muted-foreground text-center h-20">
{t('Type searching for people, keywords, or relays')}

View File

@@ -2,6 +2,7 @@ import FollowButton from '@/components/FollowButton'
import Nip05 from '@/components/Nip05'
import UserAvatar from '@/components/UserAvatar'
import Username from '@/components/Username'
import { Skeleton } from '@/components/ui/skeleton'
export default function UserItem({ pubkey }: { pubkey: string }) {
return (
@@ -19,3 +20,17 @@ export default function UserItem({ pubkey }: { pubkey: string }) {
</div>
)
}
export function UserItemSkeleton({ hideFollowButton }: { hideFollowButton?: boolean }) {
return (
<div className="flex gap-2 items-center h-14">
<Skeleton className="w-10 h-10 rounded-full shrink-0" />
<div className="w-full">
<div className="py-1">
<Skeleton className="w-16 h-4" />
</div>
</div>
{!hideFollowButton && <Skeleton className="rounded-full min-w-28 h-9" />}
</div>
)
}