import { toRelay } from '@/lib/link' import { useSecondaryPage } from '@/PageManager' import relayInfoService from '@/services/relay-info.service' import { TNip66RelayInfo } from '@/types' import { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import RelaySimpleInfo, { RelaySimpleInfoSkeleton } from '../RelaySimpleInfo' import SearchInput from '../SearchInput' export default function RelayList() { const { t } = useTranslation() const { push } = useSecondaryPage() const [loading, setLoading] = useState(true) const [relays, setRelays] = useState([]) const [showCount, setShowCount] = useState(20) const [input, setInput] = useState('') const [debouncedInput, setDebouncedInput] = useState(input) const bottomRef = useRef(null) useEffect(() => { const search = async () => { const relayInfos = await relayInfoService.search(debouncedInput) setShowCount(20) setRelays(relayInfos) setLoading(false) } search() }, [debouncedInput]) useEffect(() => { const handler = setTimeout(() => { setDebouncedInput(input) }, 1000) return () => { clearTimeout(handler) } }, [input]) useEffect(() => { const options = { root: null, rootMargin: '10px', threshold: 1 } const observerInstance = new IntersectionObserver((entries) => { if (entries[0].isIntersecting && showCount < relays.length) { setShowCount((prev) => prev + 20) } }, options) const currentBottomRef = bottomRef.current if (currentBottomRef) { observerInstance.observe(currentBottomRef) } return () => { if (observerInstance && currentBottomRef) { observerInstance.unobserve(currentBottomRef) } } }, [showCount, relays]) const handleInputChange = (e: React.ChangeEvent) => { setInput(e.target.value) } return (
{relays.slice(0, showCount).map((relay) => ( { e.stopPropagation() push(toRelay(relay.url)) }} /> ))} {showCount < relays.length &&
} {loading && } {!loading && relays.length === 0 && (
{t('no relays found')}
)}
) }