You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.5 KiB
91 lines
2.5 KiB
import { useFetchRelayInfo } from '@/hooks' |
|
import { toRelay } from '@/lib/link' |
|
import { useSmartRelayNavigation } from '@/PageManager' |
|
import { useNostr } from '@/providers/NostrProvider' |
|
import client from '@/services/client.service' |
|
import { useEffect, useRef, useState } from 'react' |
|
import { useTranslation } from 'react-i18next' |
|
import RelaySimpleInfo, { RelaySimpleInfoSkeleton } from '../RelaySimpleInfo' |
|
|
|
const SHOW_COUNT = 10 |
|
|
|
export default function FollowingFavoriteRelayList() { |
|
const { t } = useTranslation() |
|
const { pubkey } = useNostr() |
|
const [loading, setLoading] = useState(true) |
|
const [relays, setRelays] = useState<[string, string[]][]>([]) |
|
const [showCount, setShowCount] = useState(SHOW_COUNT) |
|
const bottomRef = useRef<HTMLDivElement>(null) |
|
|
|
useEffect(() => { |
|
setLoading(true) |
|
|
|
const init = async () => { |
|
if (!pubkey) return |
|
|
|
const relays = (await client.fetchFollowingFavoriteRelays(pubkey)) ?? [] |
|
setRelays(relays) |
|
} |
|
init().finally(() => { |
|
setLoading(false) |
|
}) |
|
}, [pubkey]) |
|
|
|
useEffect(() => { |
|
const options = { |
|
root: null, |
|
rootMargin: '10px', |
|
threshold: 1 |
|
} |
|
|
|
const observerInstance = new IntersectionObserver((entries) => { |
|
if (entries[0].isIntersecting && showCount < relays.length) { |
|
setShowCount((prev) => prev + SHOW_COUNT) |
|
} |
|
}, options) |
|
|
|
const currentBottomRef = bottomRef.current |
|
if (currentBottomRef) { |
|
observerInstance.observe(currentBottomRef) |
|
} |
|
|
|
return () => { |
|
if (observerInstance && currentBottomRef) { |
|
observerInstance.unobserve(currentBottomRef) |
|
} |
|
} |
|
}, [showCount, relays]) |
|
|
|
return ( |
|
<div className="pb-8"> |
|
{relays.slice(0, showCount).map(([url, users]) => ( |
|
<RelayItem key={url} url={url} users={users} /> |
|
))} |
|
{showCount < relays.length && <div ref={bottomRef} />} |
|
{loading && <RelaySimpleInfoSkeleton className="p-4" />} |
|
{!loading && ( |
|
<div className="text-center text-muted-foreground text-sm mt-2"> |
|
{relays.length === 0 ? t('no relays found') : t('no more relays')} |
|
</div> |
|
)} |
|
</div> |
|
) |
|
} |
|
|
|
function RelayItem({ url, users }: { url: string; users: string[] }) { |
|
const { navigateToRelay } = useSmartRelayNavigation() |
|
const { relayInfo } = useFetchRelayInfo(url) |
|
|
|
return ( |
|
<RelaySimpleInfo |
|
key={url} |
|
relayInfo={relayInfo} |
|
users={users} |
|
className="clickable p-4 border-b" |
|
onClick={(e) => { |
|
e.stopPropagation() |
|
navigateToRelay(toRelay(url)) |
|
}} |
|
/> |
|
) |
|
}
|
|
|