feat: add relay recommendations based on user language
This commit is contained in:
@@ -1,22 +1,30 @@
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import { useFetchRelayInfo } from '@/hooks'
|
||||
import { toRelay } from '@/lib/link'
|
||||
import { recommendRelaysByLanguage } from '@/lib/relay'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useSecondaryPage } from '@/PageManager'
|
||||
import { useDeepBrowsing } from '@/providers/DeepBrowsingProvider'
|
||||
import relayInfoService from '@/services/relay-info.service'
|
||||
import { TAwesomeRelayCollection } from '@/types'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import RelaySimpleInfo, { RelaySimpleInfoSkeleton } from '../RelaySimpleInfo'
|
||||
import { useDeepBrowsing } from '@/providers/DeepBrowsingProvider'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export default function Explore() {
|
||||
const { t, i18n } = useTranslation()
|
||||
const [collections, setCollections] = useState<TAwesomeRelayCollection[] | null>(null)
|
||||
const recommendedRelays = useMemo(() => {
|
||||
const lang = i18n.language
|
||||
const relays = recommendRelaysByLanguage(lang)
|
||||
return relays
|
||||
}, [i18n.language])
|
||||
|
||||
useEffect(() => {
|
||||
relayInfoService.getAwesomeRelayCollections().then(setCollections)
|
||||
}, [])
|
||||
|
||||
if (!collections) {
|
||||
if (!collections && recommendedRelays.length === 0) {
|
||||
return (
|
||||
<div>
|
||||
<div className="p-4 max-md:border-b">
|
||||
@@ -31,9 +39,19 @@ export default function Explore() {
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{collections.map((collection) => (
|
||||
<RelayCollection key={collection.id} collection={collection} />
|
||||
))}
|
||||
{recommendedRelays.length > 0 && (
|
||||
<RelayCollection
|
||||
collection={{
|
||||
id: 'recommended',
|
||||
name: t('Recommended'),
|
||||
relays: recommendedRelays
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{collections &&
|
||||
collections.map((collection) => (
|
||||
<RelayCollection key={collection.id} collection={collection} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -633,6 +633,7 @@ export default {
|
||||
'أضف كلمة مرور لتشفير مفتاحك الخاص في هذا المتصفح. هذا اختياري لكنه موصى به بشدة لأمان أفضل.',
|
||||
'Create a password (or skip)': 'أنشئ كلمة مرور (أو تخطى)',
|
||||
'Enter your password again': 'أدخل كلمة المرور مرة أخرى',
|
||||
'Complete Signup': 'إكمال التسجيل'
|
||||
'Complete Signup': 'إكمال التسجيل',
|
||||
Recommended: 'موصى به'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,6 +654,7 @@ export default {
|
||||
'Fügen Sie ein Passwort hinzu, um Ihren privaten Schlüssel in diesem Browser zu verschlüsseln. Dies ist optional, aber für bessere Sicherheit dringend empfohlen.',
|
||||
'Create a password (or skip)': 'Erstellen Sie ein Passwort (oder überspringen)',
|
||||
'Enter your password again': 'Geben Sie Ihr Passwort erneut ein',
|
||||
'Complete Signup': 'Registrierung abschließen'
|
||||
'Complete Signup': 'Registrierung abschließen',
|
||||
Recommended: 'Empfohlen'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -638,6 +638,7 @@ export default {
|
||||
'Add a password to encrypt your private key in this browser. This is optional but strongly recommended for better security.',
|
||||
'Create a password (or skip)': 'Create a password (or skip)',
|
||||
'Enter your password again': 'Enter your password again',
|
||||
'Complete Signup': 'Complete Signup'
|
||||
'Complete Signup': 'Complete Signup',
|
||||
Recommended: 'Recommended'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,6 +648,7 @@ export default {
|
||||
'Añade una contraseña para cifrar tu clave privada en este navegador. Esto es opcional pero muy recomendado para mayor seguridad.',
|
||||
'Create a password (or skip)': 'Crear una contraseña (o saltar)',
|
||||
'Enter your password again': 'Ingresa tu contraseña nuevamente',
|
||||
'Complete Signup': 'Completar registro'
|
||||
'Complete Signup': 'Completar registro',
|
||||
Recommended: 'Recomendado'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -643,6 +643,7 @@ export default {
|
||||
'یک رمز عبور برای رمزگذاری کلید خصوصی خود در این مرورگر اضافه کنید. این اختیاری است اما برای امنیت بهتر به شدت توصیه میشود.',
|
||||
'Create a password (or skip)': 'یک رمز عبور ایجاد کنید (یا رد کنید)',
|
||||
'Enter your password again': 'رمز عبور خود را دوباره وارد کنید',
|
||||
'Complete Signup': 'تکمیل ثبتنام'
|
||||
'Complete Signup': 'تکمیل ثبتنام',
|
||||
Recommended: 'توصیه شده'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,6 +651,7 @@ export default {
|
||||
"Ajoutez un mot de passe pour chiffrer votre clé privée dans ce navigateur. C'est facultatif mais fortement recommandé pour une meilleure sécurité.",
|
||||
'Create a password (or skip)': 'Créez un mot de passe (ou ignorez)',
|
||||
'Enter your password again': 'Entrez à nouveau votre mot de passe',
|
||||
'Complete Signup': "Terminer l'inscription"
|
||||
'Complete Signup': "Terminer l'inscription",
|
||||
Recommended: 'Recommandé'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -644,6 +644,7 @@ export default {
|
||||
'इस ब्राउज़र में अपनी निजी कुंजी को एन्क्रिप्ट करने के लिए पासवर्ड जोड़ें। यह वैकल्पिक है लेकिन बेहतर सुरक्षा के लिए दृढ़ता से अनुशंसित है।',
|
||||
'Create a password (or skip)': 'एक पासवर्ड बनाएं (या छोड़ें)',
|
||||
'Enter your password again': 'अपना पासवर्ड फिर से दर्ज करें',
|
||||
'Complete Signup': 'साइनअप पूर्ण करें'
|
||||
'Complete Signup': 'साइनअप पूर्ण करें',
|
||||
Recommended: 'अनुशंसित'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,6 +636,7 @@ export default {
|
||||
'Adj hozzá jelszót a privát kulcsod titkosításához ebben a böngészőben. Ez opcionális, de erősen ajánlott a jobb biztonság érdekében.',
|
||||
'Create a password (or skip)': 'Hozz létre jelszót (vagy hagyd ki)',
|
||||
'Enter your password again': 'Add meg újra a jelszavad',
|
||||
'Complete Signup': 'Regisztráció befejezése'
|
||||
'Complete Signup': 'Regisztráció befejezése',
|
||||
Recommended: 'Ajánlott'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,6 +648,7 @@ export default {
|
||||
'Aggiungi una password per crittografare la tua chiave privata in questo browser. È facoltativo ma fortemente consigliato per una migliore sicurezza.',
|
||||
'Create a password (or skip)': 'Crea una password (o salta)',
|
||||
'Enter your password again': 'Inserisci di nuovo la tua password',
|
||||
'Complete Signup': 'Completa registrazione'
|
||||
'Complete Signup': 'Completa registrazione',
|
||||
Recommended: 'Consigliato'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -642,6 +642,7 @@ export default {
|
||||
'このブラウザで秘密鍵を暗号化するパスワードを追加します。オプションですが、より良いセキュリティのために強くお勧めします。',
|
||||
'Create a password (or skip)': 'パスワードを作成(またはスキップ)',
|
||||
'Enter your password again': 'パスワードをもう一度入力',
|
||||
'Complete Signup': '登録を完了'
|
||||
'Complete Signup': '登録を完了',
|
||||
Recommended: 'おすすめ'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,6 +639,7 @@ export default {
|
||||
'이 브라우저에서 개인 키를 암호화할 비밀번호를 추가합니다. 선택사항이지만 더 나은 보안을 위해 강력히 권장합니다.',
|
||||
'Create a password (or skip)': '비밀번호 생성(또는 건너뛰기)',
|
||||
'Enter your password again': '비밀번호를 다시 입력하세요',
|
||||
'Complete Signup': '가입 완료'
|
||||
'Complete Signup': '가입 완료',
|
||||
Recommended: '추천'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,6 +649,7 @@ export default {
|
||||
'Dodaj hasło, aby zaszyfrować swój klucz prywatny w tej przeglądarce. Jest to opcjonalne, ale zdecydowanie zalecane dla lepszego bezpieczeństwa.',
|
||||
'Create a password (or skip)': 'Utwórz hasło (lub pomiń)',
|
||||
'Enter your password again': 'Wprowadź hasło ponownie',
|
||||
'Complete Signup': 'Zakończ rejestrację'
|
||||
'Complete Signup': 'Zakończ rejestrację',
|
||||
Recommended: 'Polecane'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -644,6 +644,7 @@ export default {
|
||||
'Adicione uma senha para criptografar sua chave privada neste navegador. Isso é opcional, mas fortemente recomendado para melhor segurança.',
|
||||
'Create a password (or skip)': 'Crie uma senha (ou pule)',
|
||||
'Enter your password again': 'Digite sua senha novamente',
|
||||
'Complete Signup': 'Concluir cadastro'
|
||||
'Complete Signup': 'Concluir cadastro',
|
||||
Recommended: 'Recomendado'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -647,6 +647,7 @@ export default {
|
||||
'Adicione uma palavra-passe para encriptar a sua chave privada neste navegador. Isto é opcional, mas fortemente recomendado para melhor segurança.',
|
||||
'Create a password (or skip)': 'Crie uma palavra-passe (ou ignore)',
|
||||
'Enter your password again': 'Introduza novamente a sua palavra-passe',
|
||||
'Complete Signup': 'Concluir registo'
|
||||
'Complete Signup': 'Concluir registo',
|
||||
Recommended: 'Recomendado'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,6 +648,7 @@ export default {
|
||||
'Добавьте пароль для шифрования вашего приватного ключа в этом браузере. Это необязательно, но настоятельно рекомендуется для лучшей безопасности.',
|
||||
'Create a password (or skip)': 'Создайте пароль (или пропустите)',
|
||||
'Enter your password again': 'Введите пароль еще раз',
|
||||
'Complete Signup': 'Завершить регистрацию'
|
||||
'Complete Signup': 'Завершить регистрацию',
|
||||
Recommended: 'Рекомендуемые'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,6 +633,7 @@ export default {
|
||||
'เพิ่มรหัสผ่านเพื่อเข้ารหัสคีย์ส่วนตัวของคุณในเบราว์เซอร์นี้ เป็นตัวเลือก แต่แนะนำอย่างยิ่งเพื่อความปลอดภัยที่ดีขึ้น',
|
||||
'Create a password (or skip)': 'สร้างรหัสผ่าน (หรือข้าม)',
|
||||
'Enter your password again': 'ป้อนรหัสผ่านของคุณอีกครั้ง',
|
||||
'Complete Signup': 'เสร็จสิ้นการลงทะเบียน'
|
||||
'Complete Signup': 'เสร็จสิ้นการลงทะเบียน',
|
||||
Recommended: 'แนะนำ'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,6 +619,7 @@ export default {
|
||||
'新增密碼以在此瀏覽器中加密你的私鑰。這是可選的,但強烈建議設定以獲得更好的安全性。',
|
||||
'Create a password (or skip)': '建立密碼(或跳過)',
|
||||
'Enter your password again': '再次輸入你的密碼',
|
||||
'Complete Signup': '完成註冊'
|
||||
'Complete Signup': '完成註冊',
|
||||
Recommended: '推薦'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -624,6 +624,7 @@ export default {
|
||||
'添加密码以在此浏览器中加密你的私钥。这是可选的,但强烈建议设置以获得更好的安全性。',
|
||||
'Create a password (or skip)': '创建密码(或跳过)',
|
||||
'Enter your password again': '再次输入你的密码',
|
||||
'Complete Signup': '完成注册'
|
||||
'Complete Signup': '完成注册',
|
||||
Recommended: '推荐'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,3 +16,27 @@ export function checkNip43Support(relayInfo: TRelayInfo | undefined) {
|
||||
export function filterOutBigRelays(relayUrls: string[]) {
|
||||
return relayUrls.filter((url) => !BIG_RELAY_URLS.includes(url))
|
||||
}
|
||||
|
||||
export function recommendRelaysByLanguage(i18nLanguage: string) {
|
||||
if (i18nLanguage.startsWith('zh')) {
|
||||
return [
|
||||
'wss://relay.nostrzh.org/',
|
||||
'wss://relay.nostr.moe/',
|
||||
'wss://lang.relays.land/zh',
|
||||
'wss://relay.stream/'
|
||||
]
|
||||
}
|
||||
if (i18nLanguage.startsWith('ja')) {
|
||||
return ['wss://yabu.me/', 'wss://lang.relays.land/ja']
|
||||
}
|
||||
if (i18nLanguage.startsWith('es')) {
|
||||
return ['wss://lang.relays.land/es']
|
||||
}
|
||||
if (i18nLanguage.startsWith('it')) {
|
||||
return ['wss://lang.relays.land/it']
|
||||
}
|
||||
if (i18nLanguage.startsWith('pt')) {
|
||||
return ['wss://lang.relays.land/pt']
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
11
src/types/index.d.ts
vendored
11
src/types/index.d.ts
vendored
@@ -1,5 +1,10 @@
|
||||
import { Event, Filter, VerifiedEvent } from 'nostr-tools'
|
||||
import { MEDIA_AUTO_LOAD_POLICY, NOTIFICATION_LIST_STYLE, NSFW_DISPLAY_POLICY, POLL_TYPE } from '../constants'
|
||||
import {
|
||||
MEDIA_AUTO_LOAD_POLICY,
|
||||
NOTIFICATION_LIST_STYLE,
|
||||
NSFW_DISPLAY_POLICY,
|
||||
POLL_TYPE
|
||||
} from '../constants'
|
||||
|
||||
export type TSubRequestFilter = Omit<Filter, 'since' | 'until'> & { limit: number }
|
||||
|
||||
@@ -200,12 +205,10 @@ export type TNotificationStyle =
|
||||
export type TAwesomeRelayCollection = {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
relays: string[]
|
||||
}
|
||||
|
||||
export type TMediaAutoLoadPolicy =
|
||||
(typeof MEDIA_AUTO_LOAD_POLICY)[keyof typeof MEDIA_AUTO_LOAD_POLICY]
|
||||
|
||||
export type TNsfwDisplayPolicy =
|
||||
(typeof NSFW_DISPLAY_POLICY)[keyof typeof NSFW_DISPLAY_POLICY]
|
||||
export type TNsfwDisplayPolicy = (typeof NSFW_DISPLAY_POLICY)[keyof typeof NSFW_DISPLAY_POLICY]
|
||||
|
||||
Reference in New Issue
Block a user