feat: explore (#85)

This commit is contained in:
Cody Tseng
2025-02-11 16:33:31 +08:00
committed by GitHub
parent 80893ec033
commit b91f46723e
35 changed files with 811 additions and 179 deletions

View File

@@ -1,12 +1,15 @@
import { Badge } from '@/components/ui/badge'
import { useFetchRelayInfo } from '@/hooks'
import { TRelayInfo } from '@/types'
import { normalizeHttpUrl } from '@/lib/url'
import { GitBranch, Mail, SquareCode } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import RelayBadges from '../RelayBadges'
import RelayIcon from '../RelayIcon'
import UserAvatar from '../UserAvatar'
import Username from '../Username'
export default function RelayInfo({ url }: { url: string }) {
const { t } = useTranslation()
const { relayInfo, isFetching } = useFetchRelayInfo(url)
if (isFetching || !relayInfo) {
return null
@@ -33,10 +36,45 @@ export default function RelayInfo({ url }: { url: string }) {
</div>
)}
</div>
{!!relayInfo.supported_nips?.length && (
<div className="space-y-2">
<div className="text-sm font-semibold text-muted-foreground">{t('Supported NIPs')}</div>
<div className="flex flex-wrap gap-2">
{relayInfo.supported_nips
.sort((a, b) => a - b)
.map((nip) => (
<Badge
key={nip}
variant="secondary"
className="clickable"
onClick={() =>
window.open(
`https://github.com/nostr-protocol/nips/blob/master/${formatNip(nip)}.md`
)
}
>
{formatNip(nip)}
</Badge>
))}
</div>
</div>
)}
{relayInfo.payments_url && (
<div className="space-y-2">
<div className="text-sm font-semibold text-muted-foreground">{t('Payment page')}:</div>
<a
href={normalizeHttpUrl(relayInfo.payments_url)}
target="_blank"
className="hover:underline text-primary"
>
{relayInfo.payments_url}
</a>
</div>
)}
<div className="flex flex-wrap gap-4">
{relayInfo.pubkey && (
<div className="space-y-2 flex-1">
<div className="text-sm font-semibold text-muted-foreground">Operator</div>
<div className="text-sm font-semibold text-muted-foreground">{t('Operator')}</div>
<div className="flex gap-2 items-center">
<UserAvatar userId={relayInfo.pubkey} size="small" />
<Username userId={relayInfo.pubkey} className="font-semibold" />
@@ -45,7 +83,7 @@ export default function RelayInfo({ url }: { url: string }) {
)}
{relayInfo.contact && (
<div className="space-y-2 flex-1">
<div className="text-sm font-semibold text-muted-foreground">Contact</div>
<div className="text-sm font-semibold text-muted-foreground">{t('Contact')}</div>
<div className="flex gap-2 items-center font-semibold">
<Mail />
{relayInfo.contact}
@@ -54,7 +92,7 @@ export default function RelayInfo({ url }: { url: string }) {
)}
{relayInfo.software && (
<div className="space-y-2 flex-1">
<div className="text-sm font-semibold text-muted-foreground">Software</div>
<div className="text-sm font-semibold text-muted-foreground">{t('Software')}</div>
<div className="flex gap-2 items-center font-semibold">
<SquareCode />
{formatSoftware(relayInfo.software)}
@@ -63,7 +101,7 @@ export default function RelayInfo({ url }: { url: string }) {
)}
{relayInfo.version && (
<div className="space-y-2 flex-1">
<div className="text-sm font-semibold text-muted-foreground">Version</div>
<div className="text-sm font-semibold text-muted-foreground">{t('Version')}</div>
<div className="flex gap-2 items-center font-semibold">
<GitBranch />
{relayInfo.version}
@@ -80,21 +118,9 @@ function formatSoftware(software: string) {
return parts[parts.length - 1]
}
export function RelayBadges({ relayInfo }: { relayInfo: TRelayInfo }) {
return (
<div className="flex gap-2">
{relayInfo.supported_nips?.includes(42) && (
<Badge className="bg-green-400 hover:bg-green-400/80">Auth</Badge>
)}
{relayInfo.supported_nips?.includes(50) && (
<Badge className="bg-pink-400 hover:bg-pink-400/80">Search</Badge>
)}
{relayInfo.limitation?.payment_required && (
<Badge className="bg-orange-400 hover:bg-orange-400/80">Payment</Badge>
)}
{relayInfo.supported_nips?.includes(29) && (
<Badge className="bg-blue-400 hover:bg-blue-400/80">Groups</Badge>
)}
</div>
)
function formatNip(nip: number) {
if (nip < 10) {
return `0${nip}`
}
return `${nip}`
}