feat: remove default favorite relays

This commit is contained in:
codytseng
2025-11-01 15:56:11 +08:00
parent 24348d4f01
commit 38bc425d50
27 changed files with 216 additions and 172 deletions

View File

@@ -1,7 +1,6 @@
import Sidebar from '@/components/Sidebar'
import { cn } from '@/lib/utils'
import NoteListPage from '@/pages/primary/NoteListPage'
import HomePage from '@/pages/secondary/HomePage'
import { CurrentRelaysProvider } from '@/providers/CurrentRelaysProvider'
import { TPageRef } from '@/types'
import {
@@ -455,7 +454,8 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) {
<div
className={cn(
'bg-background overflow-hidden',
themeSetting === 'pure-black' ? 'border-l' : 'rounded-lg shadow-lg'
themeSetting === 'pure-black' ? 'border-l' : 'rounded-lg shadow-lg',
secondaryStack.length === 0 ? 'bg-surface' : ''
)}
>
{secondaryStack.map((item, index) => (
@@ -467,13 +467,6 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) {
{item.component}
</div>
))}
<div
key="home"
className="w-full"
style={{ display: secondaryStack.length === 0 ? 'block' : 'none' }}
>
<HomePage />
</div>
</div>
</div>
</div>

View File

@@ -1,5 +1,6 @@
import { toRelaySettings } from '@/lib/link'
import { simplifyUrl } from '@/lib/url'
import { cn } from '@/lib/utils'
import { SecondaryPageLink } from '@/PageManager'
import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider'
import { useFeed } from '@/providers/FeedProvider'
@@ -17,9 +18,9 @@ export default function FeedSwitcher({ close }: { close?: () => void }) {
return (
<div className="space-y-2">
{pubkey && (
<FeedSwitcherItem
isActive={feedInfo.feedType === 'following'}
isActive={feedInfo?.feedType === 'following'}
disabled={!pubkey}
onClick={() => {
if (!pubkey) return
switchFeed('following', { pubkey })
@@ -33,7 +34,6 @@ export default function FeedSwitcher({ close }: { close?: () => void }) {
<div>{t('Following')}</div>
</div>
</FeedSwitcherItem>
)}
<div className="flex justify-end items-center text-sm">
<SecondaryPageLink
@@ -50,7 +50,7 @@ export default function FeedSwitcher({ close }: { close?: () => void }) {
<RelaySetCard
key={set.id}
relaySet={set}
select={feedInfo.feedType === 'relays' && set.id === feedInfo.id}
select={feedInfo?.feedType === 'relays' && set.id === feedInfo.id}
onSelectChange={(select) => {
if (!select) return
switchFeed('relays', { activeRelaySetId: set.id })
@@ -61,7 +61,7 @@ export default function FeedSwitcher({ close }: { close?: () => void }) {
{favoriteRelays.map((relay) => (
<FeedSwitcherItem
key={relay}
isActive={feedInfo.feedType === 'relay' && feedInfo.id === relay}
isActive={feedInfo?.feedType === 'relay' && feedInfo.id === relay}
onClick={() => {
switchFeed('relay', { relay })
close?.()
@@ -80,18 +80,27 @@ export default function FeedSwitcher({ close }: { close?: () => void }) {
function FeedSwitcherItem({
children,
isActive,
disabled,
onClick,
controls
}: {
children: React.ReactNode
isActive: boolean
disabled?: boolean
onClick: () => void
controls?: React.ReactNode
}) {
return (
<div
className={`w-full border rounded-lg p-4 ${isActive ? 'border-primary bg-primary/5' : 'clickable'}`}
onClick={onClick}
className={cn(
'w-full border rounded-lg p-4',
disabled && 'opacity-50 pointer-events-none',
isActive ? 'border-primary bg-primary/5' : 'clickable'
)}
onClick={() => {
if (disabled) return
onClick()
}}
>
<div className="flex justify-between items-center">
<div className="font-semibold flex-1">{children}</div>

View File

@@ -2,18 +2,6 @@ import { kinds } from 'nostr-tools'
export const JUMBLE_API_BASE_URL = 'https://api.jumble.social'
export const DEFAULT_FAVORITE_RELAYS = [
'wss://nostr.wine/',
'wss://pyramid.fiatjaf.com/',
'wss://relays.land/spatianostra/',
'wss://theforest.nostr1.com/',
'wss://algo.utxo.one/',
'wss://140.f7z.io/',
'wss://news.utxo.one/'
]
export const RECOMMENDED_RELAYS = DEFAULT_FAVORITE_RELAYS.concat(['wss://yabu.me/'])
export const RECOMMENDED_BLOSSOM_SERVERS = [
'https://blossom.band/',
'https://blossom.primal.net/',

View File

@@ -484,6 +484,11 @@ export default {
Extension: 'امتداد',
Remote: 'عن بُعد',
'Encrypted Key': 'مفتاح مشفر',
'Private Key': 'مفتاح خاص'
'Private Key': 'مفتاح خاص',
'Welcome to Jumble': 'مرحبًا بك في Jumble',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble هو عميل يركز على تصفح المرحلات. ابدأ باستكشاف المرحلات المثيرة للاهتمام أو قم بتسجيل الدخول لعرض خلاصتك.',
'Explore Relays': 'استكشف المرحلات',
'Choose a feed': 'اختر خلاصة'
}
}

View File

@@ -498,6 +498,11 @@ export default {
Extension: 'Erweiterung',
Remote: 'Remote',
'Encrypted Key': 'Verschlüsselter Schlüssel',
'Private Key': 'Privater Schlüssel'
'Private Key': 'Privater Schlüssel',
'Welcome to Jumble': 'Willkommen bei Jumble',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble ist ein Client, der sich auf das Durchsuchen von Relays konzentriert. Beginnen Sie mit der Erkundung interessanter Relays oder melden Sie sich an, um Ihren Following-Feed anzuzeigen.',
'Explore Relays': 'Relays erkunden',
'Choose a feed': 'Wähle einen Feed'
}
}

View File

@@ -483,6 +483,11 @@ export default {
Extension: 'Extension',
Remote: 'Remote',
'Encrypted Key': 'Encrypted Key',
'Private Key': 'Private Key'
'Private Key': 'Private Key',
'Welcome to Jumble': 'Welcome to Jumble',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.',
'Explore Relays': 'Explore Relays',
'Choose a feed': 'Choose a feed'
}
}

View File

@@ -492,6 +492,11 @@ export default {
Extension: 'Extensión',
Remote: 'Remoto',
'Encrypted Key': 'Clave privada cifrada',
'Private Key': 'Clave privada'
'Private Key': 'Clave privada',
'Welcome to Jumble': 'Bienvenido a Jumble',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble es un cliente enfocado en explorar relays. Comienza explorando relays interesantes o inicia sesión para ver tu feed de seguidos.',
'Explore Relays': 'Explorar Relays',
'Choose a feed': 'Elige un feed'
}
}

View File

@@ -487,6 +487,11 @@ export default {
Extension: 'افزونه',
Remote: 'از راه دور',
'Encrypted Key': 'رمزگذاری شده کلید',
'Private Key': 'کلید خصوصی'
'Private Key': 'کلید خصوصی',
'Welcome to Jumble': 'به Jumble خوش آمدید',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble یک کلاینت متمرکز بر مرور رله‌هاست. با کاوش در رله‌های جالب شروع کنید یا وارد شوید تا فید دنبال‌کننده‌های خود را مشاهده کنید.',
'Explore Relays': 'کاوش در رله‌ها',
'Choose a feed': 'یک فید انتخاب کنید'
}
}

View File

@@ -497,6 +497,11 @@ export default {
Extension: 'Extension',
Remote: 'Distant',
'Encrypted Key': 'Clé chiffrée',
'Private Key': 'Clé privée'
'Private Key': 'Clé privée',
'Welcome to Jumble': 'Bienvenue sur Jumble',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
"Jumble est un client axé sur la navigation des relais. Commencez par explorer des relais intéressants ou connectez-vous pour voir votre fil d'abonnements.",
'Explore Relays': 'Explorer les relais',
'Choose a feed': 'Choisir un fil'
}
}

View File

@@ -489,6 +489,11 @@ export default {
Extension: 'एक्सटेंशन',
Remote: 'रिमोट',
'Encrypted Key': 'एन्क्रिप्टेड की',
'Private Key': 'प्राइवेट की'
'Private Key': 'प्राइवेट की',
'Welcome to Jumble': 'Jumble में आपका स्वागत है',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble एक क्लाइंट है जो रिले ब्राउज़ करने पर केंद्रित है। रोचक रिले की खोज करके शुरू करें या अपनी फ़ॉलोइंग फ़ीड देखने के लिए लॉगिन करें।',
'Explore Relays': 'रिले एक्सप्लोर करें',
'Choose a feed': 'एक फीड चुनें'
}
}

View File

@@ -492,6 +492,11 @@ export default {
Extension: 'Estensione',
Remote: 'Remoto',
'Encrypted Key': 'Chiave Crittografata',
'Private Key': 'Chiave Privata'
'Private Key': 'Chiave Privata',
'Welcome to Jumble': 'Benvenuto su Jumble',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble è un client focalizzato sulla navigazione dei relay. Inizia esplorando relay interessanti o effettua il login per visualizzare il tuo feed di following.',
'Explore Relays': 'Esplora Relay',
'Choose a feed': 'Scegli un feed'
}
}

View File

@@ -488,6 +488,11 @@ export default {
Extension: '拡張機能',
Remote: 'リモート',
'Encrypted Key': '暗号化キー',
'Private Key': '暗号化されたキー'
'Private Key': '暗号化されたキー',
'Welcome to Jumble': 'Jumbleへようこそ',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumbleはリレーを閲覧することに焦点を当てたクライアントです。興味深いリレーを探索するか、ログインしてフォロー中のフィードを表示してください。',
'Explore Relays': 'リレーを探索',
'Choose a feed': 'フィードを選択'
}
}

View File

@@ -488,6 +488,11 @@ export default {
Extension: '확장 프로그램',
Remote: '원격',
'Encrypted Key': '암호화된 키',
'Private Key': '개인 키'
'Private Key': '개인 키',
'Welcome to Jumble': 'Jumble에 오신 것을 환영합니다',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble은 릴레이 탐색에 중점을 둔 클라이언트입니다. 흥미로운 릴레이를 탐색하거나 로그인하여 팔로잉 피드를 확인하세요.',
'Explore Relays': '릴레이 탐색',
'Choose a feed': '피드 선택'
}
}

View File

@@ -492,6 +492,11 @@ export default {
Extension: 'Rozszerzenie',
Remote: 'Zdalne',
'Encrypted Key': 'Zaszyfrowany Klucz',
'Private Key': 'Zaszyfrowany Klucz'
'Private Key': 'Zaszyfrowany Klucz',
'Welcome to Jumble': 'Witamy w Jumble',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble to klient skupiony na przeglądaniu relay. Zacznij od eksploracji ciekawych relay lub zaloguj się, aby zobaczyć swój feed obserwowanych.',
'Explore Relays': 'Eksploruj Relay',
'Choose a feed': 'Wybierz feed'
}
}

View File

@@ -489,6 +489,11 @@ export default {
Extension: 'Extensão',
Remote: 'Remoto',
'Encrypted Key': 'Chave Criptografada',
'Private Key': 'Chave Privada'
'Private Key': 'Chave Privada',
'Welcome to Jumble': 'Bem-vindo ao Jumble',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble é um cliente focado em navegar relays. Comece explorando relays interessantes ou faça login para ver seu feed de seguidos.',
'Explore Relays': 'Explorar Relays',
'Choose a feed': 'Escolha um feed'
}
}

View File

@@ -492,6 +492,11 @@ export default {
Extension: 'Extensão',
Remote: 'Remoto',
'Encrypted Key': 'Chave Criptografada',
'Private Key': 'Chave Privada'
'Private Key': 'Chave Privada',
'Welcome to Jumble': 'Bem-vindo ao Jumble',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble é um cliente focado em explorar relays. Comece por explorar relays interessantes ou inicie sessão para ver o seu feed de seguidos.',
'Explore Relays': 'Explorar Relays',
'Choose a feed': 'Escolha um feed'
}
}

View File

@@ -494,6 +494,11 @@ export default {
Extension: 'Расширение',
Remote: 'Удалённый',
'Encrypted Key': 'Зашифрованный ключ',
'Private Key': 'Приватный ключ'
'Private Key': 'Приватный ключ',
'Welcome to Jumble': 'Добро пожаловать в Jumble',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble — это клиент, ориентированный на просмотр relay. Начните с изучения интересных relay или войдите, чтобы увидеть ленту подписок.',
'Explore Relays': 'Исследовать Relay',
'Choose a feed': 'Выберите ленту'
}
}

View File

@@ -482,6 +482,11 @@ export default {
Extension: 'ส่วนขยาย',
Remote: 'ระยะไกล',
'Encrypted Key': 'คีย์ที่เข้ารหัส',
'Private Key': 'คีย์ส่วนตัว'
'Private Key': 'คีย์ส่วนตัว',
'Welcome to Jumble': 'ยินดีต้อนรับสู่ Jumble',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble เป็นไคลเอนต์ที่เน้นการเรียกดูรีเลย์ เริ่มต้นด้วยการสำรวจรีเลย์ที่น่าสนใจ หรือเข้าสู่ระบบเพื่อดูฟีดที่คุณติดตาม',
'Explore Relays': 'สำรวจรีเลย์',
'Choose a feed': 'เลือกฟีด'
}
}

View File

@@ -480,6 +480,11 @@ export default {
Extension: '扩展',
Remote: '远程',
'Encrypted Key': '加密私钥',
'Private Key': '私钥'
'Private Key': '私钥',
'Welcome to Jumble': '欢迎来到 Jumble',
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.':
'Jumble 是一个专注于浏览服务器的客户端。从探索有趣的服务器开始,或者登录查看你的关注动态。',
'Explore Relays': '探索服务器',
'Choose a feed': '选择一个动态'
}
}

View File

@@ -54,21 +54,21 @@ const FeedSwitcherTrigger = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivEle
const { feedInfo, relayUrls } = useFeed()
const { relaySets } = useFavoriteRelays()
const activeRelaySet = useMemo(() => {
return feedInfo.feedType === 'relays' && feedInfo.id
return feedInfo?.feedType === 'relays' && feedInfo.id
? relaySets.find((set) => set.id === feedInfo.id)
: undefined
}, [feedInfo, relaySets])
const title = useMemo(() => {
if (feedInfo.feedType === 'following') {
if (feedInfo?.feedType === 'following') {
return t('Following')
}
if (relayUrls.length === 0) {
return t('Choose a relay')
return t('Choose a feed')
}
if (feedInfo.feedType === 'relay') {
return simplifyUrl(feedInfo.id ?? '')
if (feedInfo?.feedType === 'relay') {
return simplifyUrl(feedInfo?.id ?? '')
}
if (feedInfo.feedType === 'relays') {
if (feedInfo?.feedType === 'relays') {
return activeRelaySet?.name ?? activeRelaySet?.id
}
}, [feedInfo, activeRelaySet])
@@ -79,7 +79,7 @@ const FeedSwitcherTrigger = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivEle
ref={ref}
{...props}
>
{feedInfo.feedType === 'following' ? <UsersRound /> : <Server />}
{feedInfo?.feedType === 'following' ? <UsersRound /> : <Server />}
<div className="text-lg font-semibold truncate">{title}</div>
<ChevronDown />
</div>

View File

@@ -12,7 +12,7 @@ export default function FollowingFeed() {
useEffect(() => {
async function init() {
if (feedInfo.feedType !== 'following' || !pubkey) {
if (feedInfo?.feedType !== 'following' || !pubkey) {
setSubRequests([])
return
}
@@ -22,7 +22,7 @@ export default function FollowingFeed() {
}
init()
}, [feedInfo.feedType, pubkey])
}, [feedInfo?.feedType, pubkey])
return <NormalFeed subRequests={subRequests} isMainFeed />
}

View File

@@ -22,7 +22,7 @@ export default function RelaysFeed() {
return null
}
if (feedInfo.feedType !== 'relay' && feedInfo.feedType !== 'relays') {
if (!feedInfo || (feedInfo.feedType !== 'relay' && feedInfo.feedType !== 'relays')) {
return null
}

View File

@@ -1,4 +1,4 @@
import { useSecondaryPage } from '@/PageManager'
import { usePrimaryPage, useSecondaryPage } from '@/PageManager'
import PostEditor from '@/components/PostEditor'
import RelayInfo from '@/components/RelayInfo'
import { Button } from '@/components/ui/button'
@@ -9,7 +9,7 @@ import { useFeed } from '@/providers/FeedProvider'
import { useNostr } from '@/providers/NostrProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { TPageRef } from '@/types'
import { Info, PencilLine, Search } from 'lucide-react'
import { Compass, Info, LogIn, PencilLine, Search, Sparkles } from 'lucide-react'
import {
Dispatch,
forwardRef,
@@ -28,8 +28,8 @@ const NoteListPage = forwardRef((_, ref) => {
const { t } = useTranslation()
const { addRelayUrls, removeRelayUrls } = useCurrentRelays()
const layoutRef = useRef<TPageRef>(null)
const { pubkey, checkLogin } = useNostr()
const { feedInfo, relayUrls, isReady } = useFeed()
const { pubkey } = useNostr()
const { feedInfo, relayUrls, isReady, switchFeed } = useFeed()
const [showRelayDetails, setShowRelayDetails] = useState(false)
useImperativeHandle(ref, () => layoutRef.current)
@@ -48,17 +48,25 @@ const NoteListPage = forwardRef((_, ref) => {
}
}, [relayUrls])
if (!feedInfo) {
return (
<PrimaryPageLayout
pageName="home"
ref={layoutRef}
titlebar={<NoteListPageTitlebar layoutRef={layoutRef} />}
displayScrollToTopButton
>
<WelcomeGuide />
</PrimaryPageLayout>
)
}
let content: React.ReactNode = null
if (!isReady) {
content = <div className="text-center text-sm text-muted-foreground">{t('loading...')}</div>
} else if (feedInfo.feedType === 'following' && !pubkey) {
content = (
<div className="flex justify-center w-full">
<Button size="lg" onClick={() => checkLogin()}>
{t('Please login to view following feed')}
</Button>
</div>
)
switchFeed(null)
return null
} else if (feedInfo.feedType === 'following') {
content = <FollowingFeed />
} else {
@@ -169,3 +177,38 @@ function SearchButton() {
</Button>
)
}
function WelcomeGuide() {
const { t } = useTranslation()
const { navigate } = usePrimaryPage()
const { checkLogin } = useNostr()
return (
<div className="flex flex-col items-center justify-center min-h-[60vh] px-4 text-center space-y-6">
<div className="space-y-2">
<div className="flex items-center w-full justify-center gap-2">
<Sparkles className="text-yellow-400" />
<h2 className="text-2xl font-bold">{t('Welcome to Jumble')}</h2>
<Sparkles className="text-yellow-400" />
</div>
<p className="text-muted-foreground max-w-md">
{t(
'Jumble is a client focused on browsing relays. Get started by exploring interesting relays or login to view your following feed.'
)}
</p>
</div>
<div className="flex flex-col sm:flex-row gap-3 w-full max-w-md">
<Button size="lg" className="w-full" onClick={() => navigate('explore')}>
<Compass className="size-5" />
{t('Explore Relays')}
</Button>
<Button size="lg" className="w-full" variant="outline" onClick={() => checkLogin()}>
<LogIn className="size-5" />
{t('Login')}
</Button>
</div>
</div>
)
}

View File

@@ -1,79 +0,0 @@
import { usePrimaryPage, useSecondaryPage } from '@/PageManager'
import RelaySimpleInfo from '@/components/RelaySimpleInfo'
import { Button } from '@/components/ui/button'
import { RECOMMENDED_RELAYS } from '@/constants'
import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
import { toRelay } from '@/lib/link'
import relayInfoService from '@/services/relay-info.service'
import { TRelayInfo } from '@/types'
import { ArrowRight, Server } from 'lucide-react'
import { forwardRef, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
const HomePage = forwardRef(({ index }: { index?: number }, ref) => {
const { t } = useTranslation()
const { navigate } = usePrimaryPage()
const { push } = useSecondaryPage()
const [recommendedRelayInfos, setRecommendedRelayInfos] = useState<TRelayInfo[]>([])
useEffect(() => {
const init = async () => {
try {
const relays = await relayInfoService.getRelayInfos(RECOMMENDED_RELAYS)
setRecommendedRelayInfos(relays.filter(Boolean) as TRelayInfo[])
} catch (error) {
console.error('Failed to fetch recommended relays:', error)
}
}
init()
}, [])
if (!recommendedRelayInfos.length) {
return (
<SecondaryPageLayout ref={ref} index={index} hideBackButton hideTitlebarBottomBorder>
<div className="text-muted-foreground w-full h-screen flex items-center justify-center">
{t('Welcome! 🥳')}
</div>
</SecondaryPageLayout>
)
}
return (
<SecondaryPageLayout
ref={ref}
index={index}
title={
<>
<Server />
<div>{t('Recommended relays')}</div>
</>
}
hideBackButton
hideTitlebarBottomBorder
>
<div className="px-4 pt-2">
<div className="grid grid-cols-2 gap-3">
{recommendedRelayInfos.map((relayInfo) => (
<RelaySimpleInfo
key={relayInfo.url}
className="clickable h-auto px-4 py-3 rounded-lg border"
relayInfo={relayInfo}
onClick={(e) => {
e.stopPropagation()
push(toRelay(relayInfo.url))
}}
/>
))}
</div>
<div className="flex mt-2 justify-center">
<Button variant="ghost" onClick={() => navigate('explore')}>
<div>{t('Explore more')}</div>
<ArrowRight />
</Button>
</div>
</div>
</SecondaryPageLayout>
)
})
HomePage.displayName = 'HomePage'
export default HomePage

View File

@@ -1,4 +1,4 @@
import { BIG_RELAY_URLS, DEFAULT_FAVORITE_RELAYS } from '@/constants'
import { BIG_RELAY_URLS } from '@/constants'
import { createFavoriteRelaysDraftEvent, createRelaySetDraftEvent } from '@/lib/draft-event'
import { getReplaceableEventIdentifier } from '@/lib/event'
import { getRelaySetFromEvent } from '@/lib/event-metadata'
@@ -43,7 +43,7 @@ export function FavoriteRelaysProvider({ children }: { children: React.ReactNode
useEffect(() => {
if (!favoriteRelaysEvent) {
const favoriteRelays: string[] = DEFAULT_FAVORITE_RELAYS
const favoriteRelays: string[] = []
const storedRelaySets = storage.getRelaySets()
storedRelaySets.forEach(({ relayUrls }) => {
relayUrls.forEach((url) => {

View File

@@ -1,4 +1,3 @@
import { DEFAULT_FAVORITE_RELAYS } from '@/constants'
import { getRelaySetFromEvent } from '@/lib/event-metadata'
import { isWebsocketUrl, normalizeUrl } from '@/lib/url'
import indexedDb from '@/services/indexed-db.service'
@@ -14,7 +13,7 @@ type TFeedContext = {
relayUrls: string[]
isReady: boolean
switchFeed: (
feedType: TFeedType,
feedType: TFeedType | null,
options?: { activeRelaySetId?: string; pubkey?: string; relay?: string | null }
) => Promise<void>
}
@@ -31,13 +30,10 @@ export const useFeed = () => {
export function FeedProvider({ children }: { children: React.ReactNode }) {
const { pubkey, isInitialized } = useNostr()
const { relaySets, favoriteRelays } = useFavoriteRelays()
const { relaySets } = useFavoriteRelays()
const [relayUrls, setRelayUrls] = useState<string[]>([])
const [isReady, setIsReady] = useState(false)
const [feedInfo, setFeedInfo] = useState<TFeedInfo>({
feedType: 'relay',
id: DEFAULT_FAVORITE_RELAYS[0]
})
const [feedInfo, setFeedInfo] = useState<TFeedInfo>(null)
const feedInfoRef = useRef<TFeedInfo>(feedInfo)
useEffect(() => {
@@ -46,10 +42,7 @@ export function FeedProvider({ children }: { children: React.ReactNode }) {
return
}
let feedInfo: TFeedInfo = {
feedType: 'relay',
id: favoriteRelays[0] ?? DEFAULT_FAVORITE_RELAYS[0]
}
let feedInfo: TFeedInfo = null
if (pubkey) {
const storedFeedInfo = storage.getFeedInfo(pubkey)
if (storedFeedInfo) {
@@ -57,6 +50,10 @@ export function FeedProvider({ children }: { children: React.ReactNode }) {
}
}
if (!feedInfo) {
return
}
if (feedInfo.feedType === 'relays') {
return await switchFeed('relays', { activeRelaySetId: feedInfo.id })
}
@@ -74,14 +71,27 @@ export function FeedProvider({ children }: { children: React.ReactNode }) {
init()
}, [pubkey, isInitialized])
useEffect(() => {
if (pubkey && !feedInfo) {
switchFeed('following', { pubkey })
}
}, [pubkey, feedInfo])
const switchFeed = async (
feedType: TFeedType,
feedType: TFeedType | null,
options: {
activeRelaySetId?: string | null
pubkey?: string | null
relay?: string | null
} = {}
) => {
if (!feedType) {
setFeedInfo(null)
feedInfoRef.current = null
setRelayUrls([])
return
}
setIsReady(false)
if (feedType === 'relay') {
const normalizedUrl = normalizeUrl(options.relay ?? '')

View File

@@ -107,7 +107,7 @@ export type TAccount = {
export type TAccountPointer = Pick<TAccount, 'pubkey' | 'signerType'>
export type TFeedType = 'following' | 'relays' | 'relay'
export type TFeedInfo = { feedType: TFeedType; id?: string }
export type TFeedInfo = { feedType: TFeedType; id?: string } | null
export type TLanguage = 'en' | 'zh' | 'pl'