feat: sync relay sets

This commit is contained in:
codytseng
2025-01-07 23:26:05 +08:00
parent 4343765aba
commit 7bd5b915eb
38 changed files with 1069 additions and 686 deletions

View File

@@ -3,7 +3,7 @@ import { Drawer, DrawerContent } from '@/components/ui/drawer'
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
import { simplifyUrl } from '@/lib/url'
import { useFeed } from '@/providers/FeedProvider'
import { useRelaySettings } from '@/providers/RelaySettingsProvider'
import { useRelaySets } from '@/providers/RelaySetsProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { ChevronDown, Server, UsersRound } from 'lucide-react'
import { forwardRef, HTMLAttributes, useState } from 'react'
@@ -43,21 +43,21 @@ export default function FeedButton() {
const FeedSwitcherTrigger = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
(props, ref) => {
const { t } = useTranslation()
const { feedType } = useFeed()
const { relayGroups, temporaryRelayUrls } = useRelaySettings()
const activeGroup = relayGroups.find((group) => group.isActive)
const { feedType, relayUrls, activeRelaySetId } = useFeed()
const { relaySets } = useRelaySets()
const activeRelaySet = activeRelaySetId
? relaySets.find((set) => set.id === activeRelaySetId)
: undefined
const title =
feedType === 'following'
? t('Following')
: temporaryRelayUrls.length > 0
? temporaryRelayUrls.length === 1
? simplifyUrl(temporaryRelayUrls[0])
: t('Temporary')
: activeGroup
? activeGroup.relayUrls.length === 1
? simplifyUrl(activeGroup.relayUrls[0])
: activeGroup.groupName
: t('Choose a relay collection')
: relayUrls.length > 0
? relayUrls.length === 1
? simplifyUrl(relayUrls[0])
: activeRelaySet
? activeRelaySet.name
: t('Temporary')
: t('Choose a relay set')
return (
<div

View File

@@ -1,10 +1,7 @@
import NoteList from '@/components/NoteList'
import { BIG_RELAY_URLS } from '@/constants'
import PrimaryPageLayout from '@/layouts/PrimaryPageLayout'
import { useFeed } from '@/providers/FeedProvider'
import { useNostr } from '@/providers/NostrProvider'
import { useRelaySettings } from '@/providers/RelaySettingsProvider'
import { useEffect, useMemo, useRef } from 'react'
import { useEffect, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import FeedButton from './FeedButton'
import SearchButton from './SearchButton'
@@ -12,18 +9,7 @@ import SearchButton from './SearchButton'
export default function NoteListPage() {
const { t } = useTranslation()
const layoutRef = useRef<{ scrollToTop: () => void }>(null)
const { feedType } = useFeed()
const { relayUrls, temporaryRelayUrls } = useRelaySettings()
const { pubkey, relayList, followings } = useNostr()
const urls = useMemo(() => {
return feedType === 'following'
? relayList?.read.length
? relayList.read.slice(0, 4)
: BIG_RELAY_URLS
: temporaryRelayUrls.length > 0
? temporaryRelayUrls
: relayUrls
}, [feedType, relayUrls, relayList, temporaryRelayUrls])
const { feedType, relayUrls, isReady, filter } = useFeed()
useEffect(() => {
if (layoutRef.current) {
@@ -38,20 +24,8 @@ export default function NoteListPage() {
titlebar={<NoteListPageTitlebar />}
displayScrollToTopButton
>
{!!urls.length && (feedType === 'relays' || (relayList && followings)) ? (
<NoteList
relayUrls={urls}
filter={
feedType === 'following'
? {
authors:
pubkey && !followings?.includes(pubkey)
? [...(followings ?? []), pubkey]
: (followings ?? [])
}
: {}
}
/>
{isReady ? (
<NoteList relayUrls={relayUrls} filter={filter} />
) : (
<div className="text-center text-sm text-muted-foreground">{t('loading...')}</div>
)}

View File

@@ -1,16 +1,17 @@
import NoteList from '@/components/NoteList'
import { SEARCHABLE_RELAY_URLS } from '@/constants'
import { useSearchParams } from '@/hooks'
import { useFetchRelayInfos, useSearchParams } from '@/hooks'
import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
import { isWebsocketUrl, simplifyUrl } from '@/lib/url'
import { useRelaySettings } from '@/providers/RelaySettingsProvider'
import { useFeed } from '@/providers/FeedProvider'
import { Filter } from 'nostr-tools'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
export default function NoteListPage({ index }: { index?: number }) {
const { t } = useTranslation()
const { relayUrls, searchableRelayUrls } = useRelaySettings()
const { relayUrls } = useFeed()
const { searchableRelayUrls } = useFetchRelayInfos(relayUrls)
const { searchParams } = useSearchParams()
const relayUrlsString = JSON.stringify(relayUrls)
const {
@@ -31,10 +32,7 @@ export default function NoteListPage({ index }: { index?: number }) {
return {
title: `${t('Search')}: ${search}`,
filter: { search },
urls:
searchableRelayUrls.length < 4
? searchableRelayUrls.concat(SEARCHABLE_RELAY_URLS).slice(0, 4)
: searchableRelayUrls
urls: searchableRelayUrls.concat(SEARCHABLE_RELAY_URLS).slice(0, 4)
}
}
const relayUrl = searchParams.get('relay')
@@ -44,16 +42,6 @@ export default function NoteListPage({ index }: { index?: number }) {
return { urls: relayUrls }
}, [searchParams, relayUrlsString])
if (filter?.search && searchableRelayUrls.length === 0) {
return (
<SecondaryPageLayout index={index} titlebarContent={title}>
<div className="text-center text-sm text-muted-foreground">
{t('The relays you are connected to do not support search')}
</div>
</SecondaryPageLayout>
)
}
return (
<SecondaryPageLayout index={index} titlebarContent={title} displayScrollToTopButton>
<NoteList key={title} filter={filter} relayUrls={urls} />

View File

@@ -1,7 +1,8 @@
import UserItem from '@/components/UserItem'
import { useSearchParams } from '@/hooks'
import { SEARCHABLE_RELAY_URLS } from '@/constants'
import { useFetchRelayInfos, useSearchParams } from '@/hooks'
import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
import { useRelaySettings } from '@/providers/RelaySettingsProvider'
import { useFeed } from '@/providers/FeedProvider'
import client from '@/services/client.service'
import dayjs from 'dayjs'
import { Filter } from 'nostr-tools'
@@ -13,7 +14,8 @@ const LIMIT = 50
export default function ProfileListPage({ index }: { index?: number }) {
const { t } = useTranslation()
const { searchParams } = useSearchParams()
const { relayUrls, searchableRelayUrls } = useRelaySettings()
const { relayUrls } = useFeed()
const { searchableRelayUrls } = useFetchRelayInfos(relayUrls)
const [until, setUntil] = useState<number>(() => dayjs().unix())
const [hasMore, setHasMore] = useState<boolean>(true)
const [pubkeySet, setPubkeySet] = useState(new Set<string>())
@@ -27,7 +29,7 @@ export default function ProfileListPage({ index }: { index?: number }) {
return f
}, [searchParams, until])
const urls = useMemo(() => {
return filter.search ? searchableRelayUrls : relayUrls
return filter.search ? searchableRelayUrls.concat(SEARCHABLE_RELAY_URLS).slice(0, 4) : relayUrls
}, [relayUrls, searchableRelayUrls, filter])
const title = useMemo(() => {
return filter.search ? `${t('Search')}: ${filter.search}` : t('All users')

View File

@@ -13,9 +13,9 @@ import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
import { toFollowingList } from '@/lib/link'
import { generateImageByPubkey } from '@/lib/pubkey'
import { SecondaryPageLink } from '@/PageManager'
import { useFeed } from '@/providers/FeedProvider'
import { useFollowList } from '@/providers/FollowListProvider'
import { useNostr } from '@/providers/NostrProvider'
import { useRelaySettings } from '@/providers/RelaySettingsProvider'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import NotFoundPage from '../NotFoundPage'
@@ -24,9 +24,12 @@ export default function ProfilePage({ id, index }: { id?: string; index?: number
const { t } = useTranslation()
const { profile, isFetching } = useFetchProfile(id)
const { relayList, isFetching: isFetchingRelayInfo } = useFetchRelayList(profile?.pubkey)
const { relayUrls: currentRelayUrls } = useRelaySettings()
const { relayUrls: currentRelayUrls } = useFeed()
const relayUrls = useMemo(
() => relayList.write.slice(0, 4).concat(currentRelayUrls.slice(0, 1)),
() =>
relayList.write.length < 4
? relayList.write.concat(currentRelayUrls).slice(0, 4)
: relayList.write.slice(0, 4),
[relayList, currentRelayUrls]
)
const { pubkey: accountPubkey } = useNostr()

View File

@@ -1,4 +1,4 @@
import RelaySettings from '@/components/RelaySettings'
import RelaySetsSetting from '@/components/RelaySetsSetting'
import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
import { useTranslation } from 'react-i18next'
@@ -8,7 +8,7 @@ export default function RelaySettingsPage({ index }: { index?: number }) {
return (
<SecondaryPageLayout index={index} titlebarContent={t('Relay settings')}>
<div className="px-4">
<RelaySettings hideTitle />
<RelaySetsSetting />
</div>
</SecondaryPageLayout>
)