feat: add option to disable filtering for onion relays
This commit is contained in:
@@ -129,6 +129,13 @@ export default function Settings() {
|
|||||||
{copiedNcryptsec ? <Check /> : <Copy />}
|
{copiedNcryptsec ? <Check /> : <Copy />}
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
)}
|
)}
|
||||||
|
<SettingItem className="clickable" onClick={() => push(toSystemSettings())}>
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<Cog />
|
||||||
|
<div>{t('System')}</div>
|
||||||
|
</div>
|
||||||
|
<ChevronRight />
|
||||||
|
</SettingItem>
|
||||||
<AboutInfoDialog>
|
<AboutInfoDialog>
|
||||||
<SettingItem className="clickable">
|
<SettingItem className="clickable">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
@@ -143,13 +150,6 @@ export default function Settings() {
|
|||||||
</div>
|
</div>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
</AboutInfoDialog>
|
</AboutInfoDialog>
|
||||||
<SettingItem className="clickable" onClick={() => push(toSystemSettings())}>
|
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
<Cog />
|
|
||||||
<div>{t('System')}</div>
|
|
||||||
</div>
|
|
||||||
<ChevronRight />
|
|
||||||
</SettingItem>
|
|
||||||
<div className="px-4 mt-4">
|
<div className="px-4 mt-4">
|
||||||
<Donation />
|
<Donation />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ export const StorageKey = {
|
|||||||
PRIMARY_COLOR: 'primaryColor',
|
PRIMARY_COLOR: 'primaryColor',
|
||||||
ENABLE_SINGLE_COLUMN_LAYOUT: 'enableSingleColumnLayout',
|
ENABLE_SINGLE_COLUMN_LAYOUT: 'enableSingleColumnLayout',
|
||||||
FAVICON_URL_TEMPLATE: 'faviconUrlTemplate',
|
FAVICON_URL_TEMPLATE: 'faviconUrlTemplate',
|
||||||
|
FILTER_OUT_ONION_RELAYS: 'filterOutOnionRelays',
|
||||||
MEDIA_UPLOAD_SERVICE: 'mediaUploadService', // deprecated
|
MEDIA_UPLOAD_SERVICE: 'mediaUploadService', // deprecated
|
||||||
HIDE_UNTRUSTED_EVENTS: 'hideUntrustedEvents', // deprecated
|
HIDE_UNTRUSTED_EVENTS: 'hideUntrustedEvents', // deprecated
|
||||||
ACCOUNT_RELAY_LIST_EVENT_MAP: 'accountRelayListEventMap', // deprecated
|
ACCOUNT_RELAY_LIST_EVENT_MAP: 'accountRelayListEventMap', // deprecated
|
||||||
|
|||||||
@@ -532,6 +532,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'فشل الحصول على رمز الدعوة من المرحل',
|
'Failed to get invite code from relay': 'فشل الحصول على رمز الدعوة من المرحل',
|
||||||
'Failed to get invite code': 'فشل الحصول على رمز الدعوة',
|
'Failed to get invite code': 'فشل الحصول على رمز الدعوة',
|
||||||
'Invite code copied to clipboard': 'تم نسخ رمز الدعوة إلى الحافظة',
|
'Invite code copied to clipboard': 'تم نسخ رمز الدعوة إلى الحافظة',
|
||||||
'Favicon URL': 'رابط الأيقونة المفضلة'
|
'Favicon URL': 'رابط الأيقونة المفضلة',
|
||||||
|
'Filter out onion relays': 'تصفية مرحلات onion'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -548,6 +548,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'Fehler beim Abrufen des Einladungscodes vom Relay',
|
'Failed to get invite code from relay': 'Fehler beim Abrufen des Einladungscodes vom Relay',
|
||||||
'Failed to get invite code': 'Fehler beim Abrufen des Einladungscodes',
|
'Failed to get invite code': 'Fehler beim Abrufen des Einladungscodes',
|
||||||
'Invite code copied to clipboard': 'Einladungscode in die Zwischenablage kopiert',
|
'Invite code copied to clipboard': 'Einladungscode in die Zwischenablage kopiert',
|
||||||
'Favicon URL': 'Favicon-URL'
|
'Favicon URL': 'Favicon-URL',
|
||||||
|
'Filter out onion relays': 'Onion-Relays herausfiltern'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -533,6 +533,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'Failed to get invite code from relay',
|
'Failed to get invite code from relay': 'Failed to get invite code from relay',
|
||||||
'Failed to get invite code': 'Failed to get invite code',
|
'Failed to get invite code': 'Failed to get invite code',
|
||||||
'Invite code copied to clipboard': 'Invite code copied to clipboard',
|
'Invite code copied to clipboard': 'Invite code copied to clipboard',
|
||||||
'Favicon URL': 'Favicon URL'
|
'Favicon URL': 'Favicon URL',
|
||||||
|
'Filter out onion relays': 'Filter out onion relays'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -542,6 +542,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'Error al obtener código de invitación del relay',
|
'Failed to get invite code from relay': 'Error al obtener código de invitación del relay',
|
||||||
'Failed to get invite code': 'Error al obtener código de invitación',
|
'Failed to get invite code': 'Error al obtener código de invitación',
|
||||||
'Invite code copied to clipboard': 'Código de invitación copiado al portapapeles',
|
'Invite code copied to clipboard': 'Código de invitación copiado al portapapeles',
|
||||||
'Favicon URL': 'URL del Favicon'
|
'Favicon URL': 'URL del Favicon',
|
||||||
|
'Filter out onion relays': 'Filtrar relés onion'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -537,6 +537,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'دریافت کد دعوت از رله ناموفق بود',
|
'Failed to get invite code from relay': 'دریافت کد دعوت از رله ناموفق بود',
|
||||||
'Failed to get invite code': 'دریافت کد دعوت ناموفق بود',
|
'Failed to get invite code': 'دریافت کد دعوت ناموفق بود',
|
||||||
'Invite code copied to clipboard': 'کد دعوت در کلیپبورد کپی شد',
|
'Invite code copied to clipboard': 'کد دعوت در کلیپبورد کپی شد',
|
||||||
'Favicon URL': 'آدرس نماد سایت'
|
'Favicon URL': 'آدرس نماد سایت',
|
||||||
|
'Filter out onion relays': 'فیلتر کردن رلههای onion'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -547,6 +547,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': "Échec de l'obtention du code d'invitation du relay",
|
'Failed to get invite code from relay': "Échec de l'obtention du code d'invitation du relay",
|
||||||
'Failed to get invite code': "Échec de l'obtention du code d'invitation",
|
'Failed to get invite code': "Échec de l'obtention du code d'invitation",
|
||||||
'Invite code copied to clipboard': "Code d'invitation copié dans le presse-papiers",
|
'Invite code copied to clipboard': "Code d'invitation copié dans le presse-papiers",
|
||||||
'Favicon URL': 'URL du Favicon'
|
'Favicon URL': 'URL du Favicon',
|
||||||
|
'Filter out onion relays': 'Filtrer les relais onion'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -539,6 +539,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'रिले से निमंत्रण कोड प्राप्त करने में विफल',
|
'Failed to get invite code from relay': 'रिले से निमंत्रण कोड प्राप्त करने में विफल',
|
||||||
'Failed to get invite code': 'निमंत्रण कोड प्राप्त करने में विफल',
|
'Failed to get invite code': 'निमंत्रण कोड प्राप्त करने में विफल',
|
||||||
'Invite code copied to clipboard': 'निमंत्रण कोड क्लिपबोर्ड पर कॉपी किया गया',
|
'Invite code copied to clipboard': 'निमंत्रण कोड क्लिपबोर्ड पर कॉपी किया गया',
|
||||||
'Favicon URL': 'फ़ेविकॉन URL'
|
'Favicon URL': 'फ़ेविकॉन URL',
|
||||||
|
'Filter out onion relays': 'ओनियन रिले फ़िल्टर करें'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -534,6 +534,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'Nem sikerült lekérni a meghívókódot a relay-től',
|
'Failed to get invite code from relay': 'Nem sikerült lekérni a meghívókódot a relay-től',
|
||||||
'Failed to get invite code': 'Nem sikerült lekérni a meghívókódot',
|
'Failed to get invite code': 'Nem sikerült lekérni a meghívókódot',
|
||||||
'Invite code copied to clipboard': 'Meghívókód vágólapra másolva',
|
'Invite code copied to clipboard': 'Meghívókód vágólapra másolva',
|
||||||
'Favicon URL': 'Favicon URL'
|
'Favicon URL': 'Favicon URL',
|
||||||
|
'Filter out onion relays': 'Onion relay-ek kiszűrése'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -542,6 +542,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'Impossibile ottenere il codice di invito dal relay',
|
'Failed to get invite code from relay': 'Impossibile ottenere il codice di invito dal relay',
|
||||||
'Failed to get invite code': 'Impossibile ottenere il codice di invito',
|
'Failed to get invite code': 'Impossibile ottenere il codice di invito',
|
||||||
'Invite code copied to clipboard': 'Codice di invito copiato negli appunti',
|
'Invite code copied to clipboard': 'Codice di invito copiato negli appunti',
|
||||||
'Favicon URL': 'URL Favicon'
|
'Favicon URL': 'URL Favicon',
|
||||||
|
'Filter out onion relays': 'Filtra relay onion'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -536,6 +536,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'リレーから招待コードの取得に失敗しました',
|
'Failed to get invite code from relay': 'リレーから招待コードの取得に失敗しました',
|
||||||
'Failed to get invite code': '招待コードの取得に失敗しました',
|
'Failed to get invite code': '招待コードの取得に失敗しました',
|
||||||
'Invite code copied to clipboard': '招待コードをクリップボードにコピーしました',
|
'Invite code copied to clipboard': '招待コードをクリップボードにコピーしました',
|
||||||
'Favicon URL': 'ファビコンURL'
|
'Favicon URL': 'ファビコンURL',
|
||||||
|
'Filter out onion relays': 'Onionリレーを除外'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -536,6 +536,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': '릴레이에서 초대 코드 가져오기 실패',
|
'Failed to get invite code from relay': '릴레이에서 초대 코드 가져오기 실패',
|
||||||
'Failed to get invite code': '초대 코드 가져오기 실패',
|
'Failed to get invite code': '초대 코드 가져오기 실패',
|
||||||
'Invite code copied to clipboard': '초대 코드가 클립보드에 복사되었습니다',
|
'Invite code copied to clipboard': '초대 코드가 클립보드에 복사되었습니다',
|
||||||
'Favicon URL': '파비콘 URL'
|
'Favicon URL': '파비콘 URL',
|
||||||
|
'Filter out onion relays': '어니언 릴레이 필터링'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -542,6 +542,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'Nie udało się uzyskać kodu zaproszenia z przekaźnika',
|
'Failed to get invite code from relay': 'Nie udało się uzyskać kodu zaproszenia z przekaźnika',
|
||||||
'Failed to get invite code': 'Nie udało się uzyskać kodu zaproszenia',
|
'Failed to get invite code': 'Nie udało się uzyskać kodu zaproszenia',
|
||||||
'Invite code copied to clipboard': 'Kod zaproszenia skopiowany do schowka',
|
'Invite code copied to clipboard': 'Kod zaproszenia skopiowany do schowka',
|
||||||
'Favicon URL': 'URL Favicon'
|
'Favicon URL': 'URL Favicon',
|
||||||
|
'Filter out onion relays': 'Filtruj przekaźniki onion'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -539,6 +539,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'Falha ao obter código de convite do relay',
|
'Failed to get invite code from relay': 'Falha ao obter código de convite do relay',
|
||||||
'Failed to get invite code': 'Falha ao obter código de convite',
|
'Failed to get invite code': 'Falha ao obter código de convite',
|
||||||
'Invite code copied to clipboard': 'Código de convite copiado para a área de transferência',
|
'Invite code copied to clipboard': 'Código de convite copiado para a área de transferência',
|
||||||
'Favicon URL': 'URL do Favicon'
|
'Favicon URL': 'URL do Favicon',
|
||||||
|
'Filter out onion relays': 'Filtrar relays onion'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -542,6 +542,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'Falha ao obter código de convite do relay',
|
'Failed to get invite code from relay': 'Falha ao obter código de convite do relay',
|
||||||
'Failed to get invite code': 'Falha ao obter código de convite',
|
'Failed to get invite code': 'Falha ao obter código de convite',
|
||||||
'Invite code copied to clipboard': 'Código de convite copiado para a área de transferência',
|
'Invite code copied to clipboard': 'Código de convite copiado para a área de transferência',
|
||||||
'Favicon URL': 'URL do Favicon'
|
'Favicon URL': 'URL do Favicon',
|
||||||
|
'Filter out onion relays': 'Filtrar relays onion'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -544,6 +544,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'Не удалось получить код приглашения от релея',
|
'Failed to get invite code from relay': 'Не удалось получить код приглашения от релея',
|
||||||
'Failed to get invite code': 'Не удалось получить код приглашения',
|
'Failed to get invite code': 'Не удалось получить код приглашения',
|
||||||
'Invite code copied to clipboard': 'Код приглашения скопирован в буфер обмена',
|
'Invite code copied to clipboard': 'Код приглашения скопирован в буфер обмена',
|
||||||
'Favicon URL': 'URL фавикона'
|
'Favicon URL': 'URL фавикона',
|
||||||
|
'Filter out onion relays': 'Фильтровать onion-релеи'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -530,6 +530,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': 'ไม่สามารถรับรหัสเชิญจากรีเลย์',
|
'Failed to get invite code from relay': 'ไม่สามารถรับรหัสเชิญจากรีเลย์',
|
||||||
'Failed to get invite code': 'ไม่สามารถรับรหัสเชิญ',
|
'Failed to get invite code': 'ไม่สามารถรับรหัสเชิญ',
|
||||||
'Invite code copied to clipboard': 'คัดลอกรหัสเชิญไปยังคลิปบอร์ดแล้ว',
|
'Invite code copied to clipboard': 'คัดลอกรหัสเชิญไปยังคลิปบอร์ดแล้ว',
|
||||||
'Favicon URL': 'URL ไอคอน'
|
'Favicon URL': 'URL ไอคอน',
|
||||||
|
'Filter out onion relays': 'กรองรีเลย์ onion'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -527,6 +527,7 @@ export default {
|
|||||||
'Failed to get invite code from relay': '从中继器获取邀请码失败',
|
'Failed to get invite code from relay': '从中继器获取邀请码失败',
|
||||||
'Failed to get invite code': '获取邀请码失败',
|
'Failed to get invite code': '获取邀请码失败',
|
||||||
'Invite code copied to clipboard': '邀请码已复制到剪贴板',
|
'Invite code copied to clipboard': '邀请码已复制到剪贴板',
|
||||||
'Favicon URL': '网站图标 URL'
|
'Favicon URL': '网站图标 URL',
|
||||||
|
'Filter out onion relays': '过滤洋葱中继'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,16 +5,17 @@ import { buildATag } from './draft-event'
|
|||||||
import { getReplaceableEventIdentifier } from './event'
|
import { getReplaceableEventIdentifier } from './event'
|
||||||
import { getAmountFromInvoice, getLightningAddressFromProfile } from './lightning'
|
import { getAmountFromInvoice, getLightningAddressFromProfile } from './lightning'
|
||||||
import { formatPubkey, pubkeyToNpub } from './pubkey'
|
import { formatPubkey, pubkeyToNpub } from './pubkey'
|
||||||
import { getEmojiInfosFromEmojiTags, generateBech32IdFromETag, tagNameEquals } from './tag'
|
import { generateBech32IdFromETag, getEmojiInfosFromEmojiTags, tagNameEquals } from './tag'
|
||||||
import { isWebsocketUrl, normalizeHttpUrl, normalizeUrl } from './url'
|
import { isOnionUrl, isWebsocketUrl, normalizeHttpUrl, normalizeUrl } from './url'
|
||||||
import { isTorBrowser } from './utils'
|
|
||||||
|
|
||||||
export function getRelayListFromEvent(event?: Event | null) {
|
export function getRelayListFromEvent(
|
||||||
|
event?: Event | null,
|
||||||
|
filterOutOnionRelays: boolean = true
|
||||||
|
): TRelayList {
|
||||||
if (!event) {
|
if (!event) {
|
||||||
return { write: BIG_RELAY_URLS, read: BIG_RELAY_URLS, originalRelays: [] }
|
return { write: BIG_RELAY_URLS, read: BIG_RELAY_URLS, originalRelays: [] }
|
||||||
}
|
}
|
||||||
|
|
||||||
const torBrowserDetected = isTorBrowser()
|
|
||||||
const relayList = { write: [], read: [], originalRelays: [] } as TRelayList
|
const relayList = { write: [], read: [], originalRelays: [] } as TRelayList
|
||||||
event.tags.filter(tagNameEquals('r')).forEach(([, url, type]) => {
|
event.tags.filter(tagNameEquals('r')).forEach(([, url, type]) => {
|
||||||
if (!url || !isWebsocketUrl(url)) return
|
if (!url || !isWebsocketUrl(url)) return
|
||||||
@@ -25,8 +26,7 @@ export function getRelayListFromEvent(event?: Event | null) {
|
|||||||
const scope = type === 'read' ? 'read' : type === 'write' ? 'write' : 'both'
|
const scope = type === 'read' ? 'read' : type === 'write' ? 'write' : 'both'
|
||||||
relayList.originalRelays.push({ url: normalizedUrl, scope })
|
relayList.originalRelays.push({ url: normalizedUrl, scope })
|
||||||
|
|
||||||
// Filter out .onion URLs if not using Tor browser
|
if (filterOutOnionRelays && isOnionUrl(normalizedUrl)) return
|
||||||
if (normalizedUrl.endsWith('.onion/') && !torBrowserDetected) return
|
|
||||||
|
|
||||||
if (type === 'write') {
|
if (type === 'write') {
|
||||||
relayList.write.push(normalizedUrl)
|
relayList.write.push(normalizedUrl)
|
||||||
|
|||||||
@@ -2,6 +2,15 @@ export function isWebsocketUrl(url: string): boolean {
|
|||||||
return /^wss?:\/\/.+$/.test(url)
|
return /^wss?:\/\/.+$/.test(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isOnionUrl(url: string): boolean {
|
||||||
|
try {
|
||||||
|
const hostname = new URL(url).hostname
|
||||||
|
return hostname.endsWith('.onion')
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// copy from nostr-tools/utils
|
// copy from nostr-tools/utils
|
||||||
export function normalizeUrl(url: string): string {
|
export function normalizeUrl(url: string): string {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
import { Input } from '@/components/ui/input'
|
import { Input } from '@/components/ui/input'
|
||||||
import { Label } from '@/components/ui/label'
|
import { Label } from '@/components/ui/label'
|
||||||
|
import { Switch } from '@/components/ui/switch'
|
||||||
import { DEFAULT_FAVICON_URL_TEMPLATE } from '@/constants'
|
import { DEFAULT_FAVICON_URL_TEMPLATE } from '@/constants'
|
||||||
import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
|
import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
|
||||||
import { useContentPolicy } from '@/providers/ContentPolicyProvider'
|
import { useContentPolicy } from '@/providers/ContentPolicyProvider'
|
||||||
import { forwardRef } from 'react'
|
import storage from '@/services/local-storage.service'
|
||||||
|
import { forwardRef, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
const SystemSettingsPage = forwardRef(({ index }: { index?: number }, ref) => {
|
const SystemSettingsPage = forwardRef(({ index }: { index?: number }, ref) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { faviconUrlTemplate, setFaviconUrlTemplate } = useContentPolicy()
|
const { faviconUrlTemplate, setFaviconUrlTemplate } = useContentPolicy()
|
||||||
|
const [filterOutOnionRelays, setFilterOutOnionRelays] = useState(
|
||||||
|
storage.getFilterOutOnionRelays()
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SecondaryPageLayout ref={ref} index={index} title={t('System')}>
|
<SecondaryPageLayout ref={ref} index={index} title={t('System')}>
|
||||||
@@ -25,6 +30,19 @@ const SystemSettingsPage = forwardRef(({ index }: { index?: number }, ref) => {
|
|||||||
placeholder={DEFAULT_FAVICON_URL_TEMPLATE}
|
placeholder={DEFAULT_FAVICON_URL_TEMPLATE}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex justify-between items-center px-4 min-h-9">
|
||||||
|
<Label htmlFor="filter-out-onion-relays" className="text-base font-normal">
|
||||||
|
{t('Filter out onion relays')}
|
||||||
|
</Label>
|
||||||
|
<Switch
|
||||||
|
id="filter-out-onion-relays"
|
||||||
|
checked={filterOutOnionRelays}
|
||||||
|
onCheckedChange={(checked) => {
|
||||||
|
storage.setFilterOutOnionRelays(checked)
|
||||||
|
setFilterOutOnionRelays(checked)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SecondaryPageLayout>
|
</SecondaryPageLayout>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
|
|||||||
indexedDb.getReplaceableEvent(account.pubkey, kinds.Pinlist)
|
indexedDb.getReplaceableEvent(account.pubkey, kinds.Pinlist)
|
||||||
])
|
])
|
||||||
if (storedRelayListEvent) {
|
if (storedRelayListEvent) {
|
||||||
setRelayList(getRelayListFromEvent(storedRelayListEvent))
|
setRelayList(getRelayListFromEvent(storedRelayListEvent, storage.getFilterOutOnionRelays()))
|
||||||
}
|
}
|
||||||
if (storedProfileEvent) {
|
if (storedProfileEvent) {
|
||||||
setProfileEvent(storedProfileEvent)
|
setProfileEvent(storedProfileEvent)
|
||||||
@@ -237,7 +237,7 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
|
|||||||
authors: [account.pubkey]
|
authors: [account.pubkey]
|
||||||
})
|
})
|
||||||
const relayListEvent = getLatestEvent(relayListEvents) ?? storedRelayListEvent
|
const relayListEvent = getLatestEvent(relayListEvents) ?? storedRelayListEvent
|
||||||
const relayList = getRelayListFromEvent(relayListEvent)
|
const relayList = getRelayListFromEvent(relayListEvent, storage.getFilterOutOnionRelays())
|
||||||
if (relayListEvent) {
|
if (relayListEvent) {
|
||||||
client.updateRelayListCache(relayListEvent)
|
client.updateRelayListCache(relayListEvent)
|
||||||
await indexedDb.putReplaceableEvent(relayListEvent)
|
await indexedDb.putReplaceableEvent(relayListEvent)
|
||||||
@@ -705,7 +705,7 @@ export function NostrProvider({ children }: { children: React.ReactNode }) {
|
|||||||
|
|
||||||
const updateRelayListEvent = async (relayListEvent: Event) => {
|
const updateRelayListEvent = async (relayListEvent: Event) => {
|
||||||
const newRelayList = await client.updateRelayListCache(relayListEvent)
|
const newRelayList = await client.updateRelayListCache(relayListEvent)
|
||||||
setRelayList(getRelayListFromEvent(newRelayList))
|
setRelayList(getRelayListFromEvent(newRelayList, storage.getFilterOutOnionRelays()))
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateProfileEvent = async (profileEvent: Event) => {
|
const updateProfileEvent = async (profileEvent: Event) => {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import {
|
|||||||
} from 'nostr-tools'
|
} from 'nostr-tools'
|
||||||
import { AbstractRelay } from 'nostr-tools/abstract-relay'
|
import { AbstractRelay } from 'nostr-tools/abstract-relay'
|
||||||
import indexedDb from './indexed-db.service'
|
import indexedDb from './indexed-db.service'
|
||||||
|
import storage from './local-storage.service'
|
||||||
|
|
||||||
type TTimelineRef = [string, number]
|
type TTimelineRef = [string, number]
|
||||||
|
|
||||||
@@ -1131,7 +1132,7 @@ class ClientService extends EventTarget {
|
|||||||
|
|
||||||
return relayEvents.map((event) => {
|
return relayEvents.map((event) => {
|
||||||
if (event) {
|
if (event) {
|
||||||
return getRelayListFromEvent(event)
|
return getRelayListFromEvent(event, storage.getFilterOutOnionRelays())
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
write: BIG_RELAY_URLS,
|
write: BIG_RELAY_URLS,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
} from '@/constants'
|
} from '@/constants'
|
||||||
import { isSameAccount } from '@/lib/account'
|
import { isSameAccount } from '@/lib/account'
|
||||||
import { randomString } from '@/lib/random'
|
import { randomString } from '@/lib/random'
|
||||||
|
import { isTorBrowser } from '@/lib/utils'
|
||||||
import {
|
import {
|
||||||
TAccount,
|
TAccount,
|
||||||
TAccountPointer,
|
TAccountPointer,
|
||||||
@@ -54,6 +55,7 @@ class LocalStorageService {
|
|||||||
private primaryColor: TPrimaryColor = 'DEFAULT'
|
private primaryColor: TPrimaryColor = 'DEFAULT'
|
||||||
private enableSingleColumnLayout: boolean = true
|
private enableSingleColumnLayout: boolean = true
|
||||||
private faviconUrlTemplate: string = DEFAULT_FAVICON_URL_TEMPLATE
|
private faviconUrlTemplate: string = DEFAULT_FAVICON_URL_TEMPLATE
|
||||||
|
private filterOutOnionRelays: boolean = !isTorBrowser()
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
if (!LocalStorageService.instance) {
|
if (!LocalStorageService.instance) {
|
||||||
@@ -210,6 +212,11 @@ class LocalStorageService {
|
|||||||
this.faviconUrlTemplate =
|
this.faviconUrlTemplate =
|
||||||
window.localStorage.getItem(StorageKey.FAVICON_URL_TEMPLATE) ?? DEFAULT_FAVICON_URL_TEMPLATE
|
window.localStorage.getItem(StorageKey.FAVICON_URL_TEMPLATE) ?? DEFAULT_FAVICON_URL_TEMPLATE
|
||||||
|
|
||||||
|
const filterOutOnionRelaysStr = window.localStorage.getItem(StorageKey.FILTER_OUT_ONION_RELAYS)
|
||||||
|
if (filterOutOnionRelaysStr) {
|
||||||
|
this.filterOutOnionRelays = filterOutOnionRelaysStr !== 'false'
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up deprecated data
|
// Clean up deprecated data
|
||||||
window.localStorage.removeItem(StorageKey.ACCOUNT_PROFILE_EVENT_MAP)
|
window.localStorage.removeItem(StorageKey.ACCOUNT_PROFILE_EVENT_MAP)
|
||||||
window.localStorage.removeItem(StorageKey.ACCOUNT_FOLLOW_LIST_EVENT_MAP)
|
window.localStorage.removeItem(StorageKey.ACCOUNT_FOLLOW_LIST_EVENT_MAP)
|
||||||
@@ -529,6 +536,15 @@ class LocalStorageService {
|
|||||||
this.faviconUrlTemplate = template
|
this.faviconUrlTemplate = template
|
||||||
window.localStorage.setItem(StorageKey.FAVICON_URL_TEMPLATE, template)
|
window.localStorage.setItem(StorageKey.FAVICON_URL_TEMPLATE, template)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFilterOutOnionRelays() {
|
||||||
|
return this.filterOutOnionRelays
|
||||||
|
}
|
||||||
|
|
||||||
|
setFilterOutOnionRelays(filterOut: boolean) {
|
||||||
|
this.filterOutOnionRelays = filterOut
|
||||||
|
window.localStorage.setItem(StorageKey.FILTER_OUT_ONION_RELAYS, filterOut.toString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const instance = new LocalStorageService()
|
const instance = new LocalStorageService()
|
||||||
|
|||||||
Reference in New Issue
Block a user