From 0ee93718da70914466bc5a1d4711c5e7bac009d5 Mon Sep 17 00:00:00 2001 From: codytseng Date: Tue, 23 Dec 2025 22:28:07 +0800 Subject: [PATCH] feat: add relay recommendations based on user language --- src/components/Explore/index.tsx | 32 +++++++++++++++++++++++++------- src/i18n/locales/ar.ts | 3 ++- src/i18n/locales/de.ts | 3 ++- src/i18n/locales/en.ts | 3 ++- src/i18n/locales/es.ts | 3 ++- src/i18n/locales/fa.ts | 3 ++- src/i18n/locales/fr.ts | 3 ++- src/i18n/locales/hi.ts | 3 ++- src/i18n/locales/hu.ts | 3 ++- src/i18n/locales/it.ts | 3 ++- src/i18n/locales/ja.ts | 3 ++- src/i18n/locales/ko.ts | 3 ++- src/i18n/locales/pl.ts | 3 ++- src/i18n/locales/pt-BR.ts | 3 ++- src/i18n/locales/pt-PT.ts | 3 ++- src/i18n/locales/ru.ts | 3 ++- src/i18n/locales/th.ts | 3 ++- src/i18n/locales/zh-TW.ts | 3 ++- src/i18n/locales/zh.ts | 3 ++- src/lib/relay.ts | 24 ++++++++++++++++++++++++ src/types/index.d.ts | 11 +++++++---- 21 files changed, 92 insertions(+), 29 deletions(-) diff --git a/src/components/Explore/index.tsx b/src/components/Explore/index.tsx index 11fc31e..aa5f0cd 100644 --- a/src/components/Explore/index.tsx +++ b/src/components/Explore/index.tsx @@ -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(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 (
@@ -31,9 +39,19 @@ export default function Explore() { return (
- {collections.map((collection) => ( - - ))} + {recommendedRelays.length > 0 && ( + + )} + {collections && + collections.map((collection) => ( + + ))}
) } diff --git a/src/i18n/locales/ar.ts b/src/i18n/locales/ar.ts index b90cc6f..57cd72a 100644 --- a/src/i18n/locales/ar.ts +++ b/src/i18n/locales/ar.ts @@ -633,6 +633,7 @@ export default { 'أضف كلمة مرور لتشفير مفتاحك الخاص في هذا المتصفح. هذا اختياري لكنه موصى به بشدة لأمان أفضل.', 'Create a password (or skip)': 'أنشئ كلمة مرور (أو تخطى)', 'Enter your password again': 'أدخل كلمة المرور مرة أخرى', - 'Complete Signup': 'إكمال التسجيل' + 'Complete Signup': 'إكمال التسجيل', + Recommended: 'موصى به' } } diff --git a/src/i18n/locales/de.ts b/src/i18n/locales/de.ts index 95f7bda..0fc4830 100644 --- a/src/i18n/locales/de.ts +++ b/src/i18n/locales/de.ts @@ -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' } } diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index b08ace3..83abca1 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -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' } } diff --git a/src/i18n/locales/es.ts b/src/i18n/locales/es.ts index 95bc827..4efcb29 100644 --- a/src/i18n/locales/es.ts +++ b/src/i18n/locales/es.ts @@ -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' } } diff --git a/src/i18n/locales/fa.ts b/src/i18n/locales/fa.ts index dcdd238..83e35b2 100644 --- a/src/i18n/locales/fa.ts +++ b/src/i18n/locales/fa.ts @@ -643,6 +643,7 @@ export default { 'یک رمز عبور برای رمزگذاری کلید خصوصی خود در این مرورگر اضافه کنید. این اختیاری است اما برای امنیت بهتر به شدت توصیه می‌شود.', 'Create a password (or skip)': 'یک رمز عبور ایجاد کنید (یا رد کنید)', 'Enter your password again': 'رمز عبور خود را دوباره وارد کنید', - 'Complete Signup': 'تکمیل ثبت‌نام' + 'Complete Signup': 'تکمیل ثبت‌نام', + Recommended: 'توصیه شده' } } diff --git a/src/i18n/locales/fr.ts b/src/i18n/locales/fr.ts index d83f8f5..e2585a6 100644 --- a/src/i18n/locales/fr.ts +++ b/src/i18n/locales/fr.ts @@ -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é' } } diff --git a/src/i18n/locales/hi.ts b/src/i18n/locales/hi.ts index b3a39a3..669a1d7 100644 --- a/src/i18n/locales/hi.ts +++ b/src/i18n/locales/hi.ts @@ -644,6 +644,7 @@ export default { 'इस ब्राउज़र में अपनी निजी कुंजी को एन्क्रिप्ट करने के लिए पासवर्ड जोड़ें। यह वैकल्पिक है लेकिन बेहतर सुरक्षा के लिए दृढ़ता से अनुशंसित है।', 'Create a password (or skip)': 'एक पासवर्ड बनाएं (या छोड़ें)', 'Enter your password again': 'अपना पासवर्ड फिर से दर्ज करें', - 'Complete Signup': 'साइनअप पूर्ण करें' + 'Complete Signup': 'साइनअप पूर्ण करें', + Recommended: 'अनुशंसित' } } diff --git a/src/i18n/locales/hu.ts b/src/i18n/locales/hu.ts index f9e60cb..4f6fdc2 100644 --- a/src/i18n/locales/hu.ts +++ b/src/i18n/locales/hu.ts @@ -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' } } diff --git a/src/i18n/locales/it.ts b/src/i18n/locales/it.ts index 0b356ef..a439124 100644 --- a/src/i18n/locales/it.ts +++ b/src/i18n/locales/it.ts @@ -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' } } diff --git a/src/i18n/locales/ja.ts b/src/i18n/locales/ja.ts index 8b8ec7b..eb68621 100644 --- a/src/i18n/locales/ja.ts +++ b/src/i18n/locales/ja.ts @@ -642,6 +642,7 @@ export default { 'このブラウザで秘密鍵を暗号化するパスワードを追加します。オプションですが、より良いセキュリティのために強くお勧めします。', 'Create a password (or skip)': 'パスワードを作成(またはスキップ)', 'Enter your password again': 'パスワードをもう一度入力', - 'Complete Signup': '登録を完了' + 'Complete Signup': '登録を完了', + Recommended: 'おすすめ' } } diff --git a/src/i18n/locales/ko.ts b/src/i18n/locales/ko.ts index 1a2aafd..6a8ce38 100644 --- a/src/i18n/locales/ko.ts +++ b/src/i18n/locales/ko.ts @@ -639,6 +639,7 @@ export default { '이 브라우저에서 개인 키를 암호화할 비밀번호를 추가합니다. 선택사항이지만 더 나은 보안을 위해 강력히 권장합니다.', 'Create a password (or skip)': '비밀번호 생성(또는 건너뛰기)', 'Enter your password again': '비밀번호를 다시 입력하세요', - 'Complete Signup': '가입 완료' + 'Complete Signup': '가입 완료', + Recommended: '추천' } } diff --git a/src/i18n/locales/pl.ts b/src/i18n/locales/pl.ts index a31702c..bd6d924 100644 --- a/src/i18n/locales/pl.ts +++ b/src/i18n/locales/pl.ts @@ -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' } } diff --git a/src/i18n/locales/pt-BR.ts b/src/i18n/locales/pt-BR.ts index fdd282a..11b44da 100644 --- a/src/i18n/locales/pt-BR.ts +++ b/src/i18n/locales/pt-BR.ts @@ -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' } } diff --git a/src/i18n/locales/pt-PT.ts b/src/i18n/locales/pt-PT.ts index 056f5b8..7fe7c57 100644 --- a/src/i18n/locales/pt-PT.ts +++ b/src/i18n/locales/pt-PT.ts @@ -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' } } diff --git a/src/i18n/locales/ru.ts b/src/i18n/locales/ru.ts index c419456..1cba1d7 100644 --- a/src/i18n/locales/ru.ts +++ b/src/i18n/locales/ru.ts @@ -648,6 +648,7 @@ export default { 'Добавьте пароль для шифрования вашего приватного ключа в этом браузере. Это необязательно, но настоятельно рекомендуется для лучшей безопасности.', 'Create a password (or skip)': 'Создайте пароль (или пропустите)', 'Enter your password again': 'Введите пароль еще раз', - 'Complete Signup': 'Завершить регистрацию' + 'Complete Signup': 'Завершить регистрацию', + Recommended: 'Рекомендуемые' } } diff --git a/src/i18n/locales/th.ts b/src/i18n/locales/th.ts index dd3478c..2824be3 100644 --- a/src/i18n/locales/th.ts +++ b/src/i18n/locales/th.ts @@ -633,6 +633,7 @@ export default { 'เพิ่มรหัสผ่านเพื่อเข้ารหัสคีย์ส่วนตัวของคุณในเบราว์เซอร์นี้ เป็นตัวเลือก แต่แนะนำอย่างยิ่งเพื่อความปลอดภัยที่ดีขึ้น', 'Create a password (or skip)': 'สร้างรหัสผ่าน (หรือข้าม)', 'Enter your password again': 'ป้อนรหัสผ่านของคุณอีกครั้ง', - 'Complete Signup': 'เสร็จสิ้นการลงทะเบียน' + 'Complete Signup': 'เสร็จสิ้นการลงทะเบียน', + Recommended: 'แนะนำ' } } diff --git a/src/i18n/locales/zh-TW.ts b/src/i18n/locales/zh-TW.ts index 9cbeeb2..a54ecf0 100644 --- a/src/i18n/locales/zh-TW.ts +++ b/src/i18n/locales/zh-TW.ts @@ -619,6 +619,7 @@ export default { '新增密碼以在此瀏覽器中加密你的私鑰。這是可選的,但強烈建議設定以獲得更好的安全性。', 'Create a password (or skip)': '建立密碼(或跳過)', 'Enter your password again': '再次輸入你的密碼', - 'Complete Signup': '完成註冊' + 'Complete Signup': '完成註冊', + Recommended: '推薦' } } diff --git a/src/i18n/locales/zh.ts b/src/i18n/locales/zh.ts index 0da69b0..25b8aa5 100644 --- a/src/i18n/locales/zh.ts +++ b/src/i18n/locales/zh.ts @@ -624,6 +624,7 @@ export default { '添加密码以在此浏览器中加密你的私钥。这是可选的,但强烈建议设置以获得更好的安全性。', 'Create a password (or skip)': '创建密码(或跳过)', 'Enter your password again': '再次输入你的密码', - 'Complete Signup': '完成注册' + 'Complete Signup': '完成注册', + Recommended: '推荐' } } diff --git a/src/lib/relay.ts b/src/lib/relay.ts index 04664ae..de6c733 100644 --- a/src/lib/relay.ts +++ b/src/lib/relay.ts @@ -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 [] +} diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 004169c..40b2cc6 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -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 & { 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]