diff --git a/README.md b/README.md index 99315420..c7888b96 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Snort supports the following NIP's: - [x] NIP-25: Reactions - [x] NIP-26: Delegated Event Signing (Display delegated signings only) - [x] NIP-27: Text note references -- [ ] NIP-28: Public Chat +- [x] NIP-28: Public Chat - [x] NIP-30: Custom Emoji - [x] NIP-31: Alt tag for unknown events - [x] NIP-36: Sensitive Content @@ -43,7 +43,7 @@ Snort supports the following NIP's: - [x] NIP-59: Gift Wrap - [x] NIP-65: Relay List Metadata - [x] NIP-75: Zap Goals -- [ ] NIP-78: App specific data +- [x] NIP-78: App specific data - [ ] NIP-89: App handlers - [x] NIP-94: File Metadata - [x] NIP-98: HTTP Auth @@ -58,7 +58,7 @@ To run the application, use $ yarn start ``` -To build the application and nostr package, use +To build the application and system packages, use ``` $ yarn build @@ -73,8 +73,7 @@ Translations are managed on [Crowdin](https://crowdin.com/project/snort) To extract translations run: ```bash -yarn workspace @snort/app intl-extract -yarn workspace @snort/app intl-compile +yarn pre:commit ``` This will create the source file `packages/app/src/translations/en.json` diff --git a/packages/app/config/default.json b/packages/app/config/default.json index cd02a553..f0c779ee 100644 --- a/packages/app/config/default.json +++ b/packages/app/config/default.json @@ -20,6 +20,6 @@ "defaultRelays": { "wss://relay.snort.social/": { "read": true, "write": true }, "wss://nostr.wine/": { "read": true, "write": false }, - "wss://nos.lol/": { "read": true, "write": true } + "wss://eden.nostr.land/": { "read": true, "write": false } } } diff --git a/packages/app/config/iris.json b/packages/app/config/iris.json index 9ddd1c9b..49d54b10 100644 --- a/packages/app/config/iris.json +++ b/packages/app/config/iris.json @@ -19,6 +19,6 @@ "defaultRelays": { "wss://relay.snort.social/": { "read": true, "write": true }, "wss://nostr.wine/": { "read": true, "write": false }, - "wss://nos.lol/": { "read": true, "write": true } + "wss://eden.nostr.land/": { "read": true, "write": false } } } diff --git a/packages/app/src/Const.ts b/packages/app/src/Const.ts index 634aa8d0..2984872a 100644 --- a/packages/app/src/Const.ts +++ b/packages/app/src/Const.ts @@ -59,6 +59,11 @@ export const DefaultImgProxy = { */ export const DerivationPath = "m/44'/1237'/0'/0/0"; +/** + * Blaster relays + */ +export const Blasters = ["wss://nostr.mutinywallet.com"]; + /** * Regex to match email address */ diff --git a/packages/app/src/Element/Embed/Mention.tsx b/packages/app/src/Element/Embed/Mention.tsx index e33add96..b6c95ac5 100644 --- a/packages/app/src/Element/Embed/Mention.tsx +++ b/packages/app/src/Element/Embed/Mention.tsx @@ -14,7 +14,7 @@ export default function Mention({ link }: { link: NostrLink }) { return ( <> - e.stopPropagation()}> + e.stopPropagation()}> @ diff --git a/packages/app/src/Element/Embed/NostrLink.tsx b/packages/app/src/Element/Embed/NostrLink.tsx index 38f3c303..639dcd02 100644 --- a/packages/app/src/Element/Embed/NostrLink.tsx +++ b/packages/app/src/Element/Embed/NostrLink.tsx @@ -8,6 +8,10 @@ export default function NostrLink({ link, depth }: { link: string; depth?: numbe const nav = tryParseNostrLink(link); if (nav?.type === NostrPrefix.PublicKey || nav?.type === NostrPrefix.Profile) { + if (nav.id.startsWith("npub")) { + // eslint-disable-next-line no-debugger + debugger; + } return ; } else if (nav?.type === NostrPrefix.Note || nav?.type === NostrPrefix.Event || nav?.type === NostrPrefix.Address) { if ((depth ?? 0) > 0) { diff --git a/packages/app/src/Element/Relay/Relay.css b/packages/app/src/Element/Relay/Relay.css index 23854ef1..eae0f514 100644 --- a/packages/app/src/Element/Relay/Relay.css +++ b/packages/app/src/Element/Relay/Relay.css @@ -1,5 +1,4 @@ .relay { - background-color: var(--gray-secondary); border-radius: 5px; display: grid; grid-template-columns: min-content auto; diff --git a/packages/app/src/Element/Relay/Relay.tsx b/packages/app/src/Element/Relay/Relay.tsx index f0cfd41b..0cb3dbde 100644 --- a/packages/app/src/Element/Relay/Relay.tsx +++ b/packages/app/src/Element/Relay/Relay.tsx @@ -41,7 +41,7 @@ export default function Relay(props: RelayProps) { return ( <> -
+
diff --git a/packages/app/src/External/SnortApi.ts b/packages/app/src/External/SnortApi.ts index 0f3efc6a..ee451d3e 100644 --- a/packages/app/src/External/SnortApi.ts +++ b/packages/app/src/External/SnortApi.ts @@ -68,6 +68,16 @@ export interface TranslationResponse { }>; } +export interface RelayDistance { + url: string; + distance: number; + users: number; + country?: string; + city?: string; + is_paid?: boolean; + description?: string; +} + export default class SnortApi { #url: string; #publisher?: EventPublisher; @@ -121,6 +131,10 @@ export default class SnortApi { return this.#getJson("api/v1/translate", "POST", tx); } + closeRelays(lat: number, lon: number, count = 5) { + return this.#getJson>(`api/v1/relays?count=${count}`, "POST", { lat, lon }); + } + async #getJsonAuthd( path: string, method?: "GET" | string, diff --git a/packages/app/src/Login/Functions.ts b/packages/app/src/Login/Functions.ts index fcaf852e..4193b3cf 100644 --- a/packages/app/src/Login/Functions.ts +++ b/packages/app/src/Login/Functions.ts @@ -12,13 +12,14 @@ import { unixNowMs } from "@snort/shared"; import * as secp from "@noble/curves/secp256k1"; import * as utils from "@noble/curves/abstract/utils"; -import { DefaultRelays, SnortPubKey } from "@/Const"; +import { Blasters, SnortPubKey } from "@/Const"; import { LoginStore, UserPreferences, LoginSession, LoginSessionType, SnortAppData, Newest } from "@/Login"; import { generateBip39Entropy, entropyToPrivateKey } from "@/nip6"; -import { bech32ToHex, dedupeById, sanitizeRelayUrl, unwrap } from "@/SnortUtils"; +import { bech32ToHex, dedupeById, getCountry, sanitizeRelayUrl, unwrap } from "@/SnortUtils"; import { SubscriptionEvent } from "@/Subscription"; import { Chats, FollowsFeed, GiftsCache, Notifications } from "@/Cache"; import { Nip7OsSigner } from "./Nip7OsSigner"; +import SnortApi from "@/External/SnortApi"; export function setRelays(state: LoginSession, relays: Record, createdAt: number) { if (SINGLE_RELAY) { @@ -92,7 +93,22 @@ export async function generateNewLogin( const ent = generateBip39Entropy(); const entropy = utils.bytesToHex(ent); const privateKey = entropyToPrivateKey(ent); - const newRelays = Object.fromEntries(DefaultRelays.entries()); + const newRelays = {} as Record; + + // Use current timezone info to determine approx location + // use closest 5 relays + const country = getCountry(); + const api = new SnortApi(); + const closeRelays = await api.closeRelays(country.lat, country.lon, 20); + for (const cr of closeRelays.sort((a, b) => (a.distance > b.distance ? 1 : -1)).filter(a => !a.is_paid)) { + const rr = sanitizeRelayUrl(cr.url); + if (rr) { + newRelays[rr] = { read: true, write: true }; + if (Object.keys(newRelays).length >= 5) { + break; + } + } + } // connect to new relays await Promise.all(Object.entries(newRelays).map(([k, v]) => system.ConnectToRelay(k, v))); @@ -107,10 +123,12 @@ export async function generateNewLogin( // Create relay metadata event const ev2 = await publisher.relayList(newRelays); await system.BroadcastEvent(ev2); + await Promise.all(Blasters.map(a => system.WriteOnceToRelay(a, ev2))); // Publish new profile const ev3 = await publisher.metadata(profile); await system.BroadcastEvent(ev3); + await Promise.all(Blasters.map(a => system.WriteOnceToRelay(a, ev3))); LoginStore.loginWithPrivateKey(await pin(privateKey), entropy, newRelays); } diff --git a/packages/app/src/Pages/Notifications.tsx b/packages/app/src/Pages/Notifications.tsx index 10d09ac8..c10b9119 100644 --- a/packages/app/src/Pages/Notifications.tsx +++ b/packages/app/src/Pages/Notifications.tsx @@ -11,7 +11,7 @@ import { Bar, BarChart, Tooltip, XAxis, YAxis } from "recharts"; import useLogin from "@/Hooks/useLogin"; import { markNotificationsRead } from "@/Login"; import { Notifications } from "@/Cache"; -import { dedupe, findTag, orderAscending, orderDescending, getDisplayName } from "@/SnortUtils"; +import { dedupe, orderAscending, orderDescending, getDisplayName } from "@/SnortUtils"; import Icon from "@/Icons/Icon"; import ProfileImage from "@/Element/User/ProfileImage"; import useModeration from "@/Hooks/useModeration"; @@ -28,18 +28,17 @@ import { ShowMoreInView } from "@/Element/Event/ShowMore"; function notificationContext(ev: TaggedNostrEvent) { switch (ev.kind) { case EventKind.ZapReceipt: { - const aTag = findTag(ev, "a"); + const aTag = ev.tags.find(a => a[0] === "a"); if (aTag) { - const [kind, author, d] = aTag.split(":"); - return new NostrLink(NostrPrefix.Address, d, Number(kind), author); + return NostrLink.fromTag(aTag); } - const eTag = findTag(ev, "e"); + const eTag = ev.tags.find(a => a[0] === "e"); if (eTag) { - return new NostrLink(CONFIG.eventLinkPrefix, eTag); + return NostrLink.fromTag(eTag); } - const pTag = ev.tags.filter(a => a[0] === "p").slice(-1)?.[0]; + const pTag = ev.tags.find(a => a[0] === "p"); if (pTag) { - return new NostrLink(NostrPrefix.PublicKey, pTag[1]); + return NostrLink.fromTag(pTag); } break; } @@ -47,17 +46,14 @@ function notificationContext(ev: TaggedNostrEvent) { case EventKind.Reaction: { const thread = EventExt.extractThread(ev); const tag = unwrap(thread?.replyTo ?? thread?.root ?? { value: ev.id, key: "e" }); - if (tag.key === "e") { - return new NostrLink(CONFIG.eventLinkPrefix, unwrap(tag.value)); - } else if (tag.key === "a") { - const [kind, author, d] = unwrap(tag.value).split(":"); - return new NostrLink(NostrPrefix.Address, d, Number(kind), author); + if (tag.key === "e" || tag.key === "a") { + return NostrLink.fromThreadTag(tag); } else { throw new Error("Unknown thread context"); } } case EventKind.TextNote: { - return new NostrLink(NostrPrefix.Note, ev.id); + return NostrLink.fromEvent(ev); } } } diff --git a/packages/app/src/Pages/settings/Relays.tsx b/packages/app/src/Pages/settings/Relays.tsx index 8bb94bc6..4cc812a5 100644 --- a/packages/app/src/Pages/settings/Relays.tsx +++ b/packages/app/src/Pages/settings/Relays.tsx @@ -1,6 +1,6 @@ -import { useMemo, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { FormattedMessage } from "react-intl"; -import { unixNowMs } from "@snort/shared"; +import { unixNowMs, unwrap } from "@snort/shared"; import { EventPublisher, FullRelaySettings, RelaySettings, SystemInterface } from "@snort/system"; import Relay from "@/Element/Relay/Relay"; @@ -8,11 +8,13 @@ import useEventPublisher from "@/Hooks/useEventPublisher"; import useLogin from "@/Hooks/useLogin"; import { setRelays } from "@/Login"; import AsyncButton from "@/Element/AsyncButton"; +import SnortApi, { RelayDistance } from "@/External/SnortApi"; +import { getCountry, getRelayName, sanitizeRelayUrl } from "@/SnortUtils"; +import { formatShort } from "@/Number"; +import { Blasters } from "@/Const"; import messages from "./messages"; -const Blasters = ["wss://nostr.mutinywallet.com"]; - export async function saveRelays( system: SystemInterface, publisher: EventPublisher | undefined, @@ -88,6 +90,7 @@ const RelaySettingsPage = () => { {addRelay()} +

@@ -101,3 +104,89 @@ const RelaySettingsPage = () => { }; export default RelaySettingsPage; + +export function CloseRelays() { + const [relays, setRecommendedRelays] = useState>(); + const country = getCountry(); + const [location, setLocation] = useState<{ lat: number; lon: number }>(country); + const login = useLogin(); + const relayUrls = Object.keys(login.relays.item); + + async function loadRelays() { + const api = new SnortApi(); + setRecommendedRelays(await api.closeRelays(location.lat, location.lon, 10)); + } + + useEffect(() => { + loadRelays().catch(console.error); + }, [location]); + + return ( + <> +

+ +

+ {"geolocation" in navigator && ( + { + try { + const pos = await new Promise((resolve, reject) => { + navigator.geolocation.getCurrentPosition(resolve, reject); + }); + setLocation({ + lat: pos.coords.latitude, + lon: pos.coords.longitude, + }); + } catch (e) { + console.error(e); + } + }}> + + + )} + {relays + ?.filter(a => !relayUrls.includes(unwrap(sanitizeRelayUrl(a.url))) && !a.is_paid) + .sort((a, b) => (a.distance > b.distance ? 1 : -1)) + .map(a => ( +
+
+
{getRelayName(a.url)}
+ { + setRelays( + login, + { + ...login.relays.item, + [a.url]: { read: true, write: true }, + }, + unixNowMs(), + ); + }}> + + +
+
+ {a.description} + + + + + + +
+
+ ))} + + ); +} diff --git a/packages/app/src/SnortUtils/index.ts b/packages/app/src/SnortUtils/index.ts index 132ec586..2c99a5de 100644 --- a/packages/app/src/SnortUtils/index.ts +++ b/packages/app/src/SnortUtils/index.ts @@ -517,12 +517,15 @@ export function getDisplayNameOrPlaceHolder(user: UserMetadata | undefined, pubk export function getCountry() { const tz = Intl.DateTimeFormat().resolvedOptions(); const info = (TZ as Record | undefined>)[tz.timeZone]; - const [, lat, lon] = info?.[1].split(/[-+]/) ?? ["", "00", "000"]; + const pos = info?.[1]; + const sep = Number(pos?.slice(1).search(/[-+]/)) + 1; + const [lat, lon] = [pos?.slice(0, sep) ?? "00", pos?.slice(sep) ?? "000"]; return { zone: tz.timeZone, country: info?.[0], - lat: Number(lat) / Math.pow(10, lat.length - 2), - lon: Number(lon) / Math.pow(10, lon.length - 3), + lat: Number(lat) / Math.pow(10, lat.length - 3), + lon: Number(lon) / Math.pow(10, lon.length - 4), + info, }; } diff --git a/packages/app/src/lang.json b/packages/app/src/lang.json index d2a3009b..2829da58 100644 --- a/packages/app/src/lang.json +++ b/packages/app/src/lang.json @@ -66,6 +66,9 @@ "0BUTMv": { "defaultMessage": "Search..." }, + "0HFX0T": { + "defaultMessage": "Use Exact Location" + }, "0jOEtS": { "defaultMessage": "Invalid LNURL" }, @@ -81,6 +84,9 @@ "0yO7wF": { "defaultMessage": "{n} secs" }, + "1H4Keq": { + "defaultMessage": "{n} users" + }, "1Mo59U": { "defaultMessage": "Are you sure you want to remove this note from bookmarks?" }, @@ -834,6 +840,9 @@ "UrKTqQ": { "defaultMessage": "You have an active iris.to account" }, + "VL900k": { + "defaultMessage": "Recommended Relays" + }, "VN0+Fz": { "defaultMessage": "Balance: {amount} sats" }, @@ -1158,6 +1167,9 @@ "jMzO1S": { "defaultMessage": "Internal error: {msg}" }, + "jTrbGf": { + "defaultMessage": "{n} km - {location}" + }, "jfV8Wr": { "defaultMessage": "Back", "description": "Navigate back button on threads view" diff --git a/packages/app/src/translations/ar_SA.json b/packages/app/src/translations/ar_SA.json index b1e138d1..0b2dab05 100644 --- a/packages/app/src/translations/ar_SA.json +++ b/packages/app/src/translations/ar_SA.json @@ -21,11 +21,13 @@ "08zn6O": "مفاتيح التصدير", "0Azlrb": "إدارة", "0BUTMv": "بحث...", + "0HFX0T": "Use Exact Location", "0jOEtS": "عنوان LNURL غير صالح", "0mch2Y": "الاسم يحتوي على أحرف غير مسموح بها", "0siT4z": "السياسة", "0uoY11": "إظهار الحالة", "0yO7wF": "{n} ثانية", + "1H4Keq": "{n} users", "1Mo59U": "هل أنت متأكد من حذف هذا المنشور من المنشورات المرجعية؟", "1R43+L": "أدخل تكوين اتصال محفظة Nostr", "1c4YST": "متصل بـ: {node}🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "تسجيل الدخول", "Up5U7K": "حظر", "UrKTqQ": "لديك حساب iris.to نشط", + "VL900k": "Recommended Relays", "VN0+Fz": "الرصيد: {amount} ساتوشي", "VOjC1i": "اختر خدمة التحميل التي تريد رفع المرفقات إليها", "VR5eHw": "مفتاح عام (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "إنتهت صلاحية اشتراكك {site_name}", "jHa/ko": "تنظيف موجز الويب الخاص بك", "jMzO1S": "خطأ داخلي: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "الخلف", "jvo0vs": "حفظ", "jzgQ2z": "التفاعل {n}", diff --git a/packages/app/src/translations/az_AZ.json b/packages/app/src/translations/az_AZ.json index 5d2ede3c..6a26690f 100644 --- a/packages/app/src/translations/az_AZ.json +++ b/packages/app/src/translations/az_AZ.json @@ -21,11 +21,13 @@ "08zn6O": "Açarları ixrac edin", "0Azlrb": "İdarə et", "0BUTMv": "Axtar...", + "0HFX0T": "Use Exact Location", "0jOEtS": "Yanlış LNURL", "0mch2Y": "adda icazə verilməyən simvollar var", "0siT4z": "Politics", "0uoY11": "Show Status", "0yO7wF": "{n} saniyə", + "1H4Keq": "{n} users", "1Mo59U": "Bu qeydi əlfəcinlərdən silmək istədiyinizə əminsiniz?", "1R43+L": "Nostr Wallet Connect konfiqurasiyasını daxil edin", "1c4YST": "Qoşuldu: {node} 🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Sign In", "Up5U7K": "Block", "UrKTqQ": "You have an active iris.to account", + "VL900k": "Recommended Relays", "VN0+Fz": "Balance: {amount} sats", "VOjC1i": "Pick which upload service you want to upload attachments to", "VR5eHw": "Public key (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Your {site_name} subscription is expired", "jHa/ko": "Clean up your feed", "jMzO1S": "Internal error: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Back", "jvo0vs": "Save", "jzgQ2z": "{n} Reactions", diff --git a/packages/app/src/translations/de_DE.json b/packages/app/src/translations/de_DE.json index 91296093..6d3578d3 100644 --- a/packages/app/src/translations/de_DE.json +++ b/packages/app/src/translations/de_DE.json @@ -21,11 +21,13 @@ "08zn6O": "Schlüssel exportieren", "0Azlrb": "Verwalten", "0BUTMv": "Suche...", + "0HFX0T": "Exakten Standort verwenden", "0jOEtS": "Ungültige LNURL", "0mch2Y": "Der Name enthält unerlaubte Zeichen", "0siT4z": "Politik", "0uoY11": "Status anzeigen", "0yO7wF": "{n} Sek.", + "1H4Keq": "{n} Benutzer", "1Mo59U": "Bist du sicher, dass du diese Note aus deinen Lesezeichen entfernen möchtest?", "1R43+L": "Nostr Wallet Connect Konfiguration eingeben", "1c4YST": "Verbunden mit: {node}🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Anmelden", "Up5U7K": "Blockieren", "UrKTqQ": "Du hast ein aktives iris.to Konto", + "VL900k": "Empfohlene Relais", "VN0+Fz": "Guthaben: {amount} Sats", "VOjC1i": "Wähle einen Upload-Dienst für deine Anhänge", "VR5eHw": "Öffentlicher Schlüssel (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Dein {site_name} Abonnement ist abgelaufen", "jHa/ko": "Räume deinen Feed auf", "jMzO1S": "Interner Fehler: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Zurück", "jvo0vs": "Speichern", "jzgQ2z": "{n} Reaktionen", diff --git a/packages/app/src/translations/en.json b/packages/app/src/translations/en.json index 5441acd8..471fc1d5 100644 --- a/packages/app/src/translations/en.json +++ b/packages/app/src/translations/en.json @@ -21,11 +21,13 @@ "08zn6O": "Export Keys", "0Azlrb": "Manage", "0BUTMv": "Search...", + "0HFX0T": "Use Exact Location", "0jOEtS": "Invalid LNURL", "0mch2Y": "name has disallowed characters", "0siT4z": "Politics", "0uoY11": "Show Status", "0yO7wF": "{n} secs", + "1H4Keq": "{n} users", "1Mo59U": "Are you sure you want to remove this note from bookmarks?", "1R43+L": "Enter Nostr Wallet Connect config", "1c4YST": "Connected to: {node} 🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Sign In", "Up5U7K": "Block", "UrKTqQ": "You have an active iris.to account", + "VL900k": "Recommended Relays", "VN0+Fz": "Balance: {amount} sats", "VOjC1i": "Pick which upload service you want to upload attachments to", "VR5eHw": "Public key (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Your {site_name} subscription is expired", "jHa/ko": "Clean up your feed", "jMzO1S": "Internal error: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Back", "jvo0vs": "Save", "jzgQ2z": "{n} Reactions", diff --git a/packages/app/src/translations/es_ES.json b/packages/app/src/translations/es_ES.json index 08b2411a..71d1124e 100644 --- a/packages/app/src/translations/es_ES.json +++ b/packages/app/src/translations/es_ES.json @@ -21,11 +21,13 @@ "08zn6O": "Exportar claves", "0Azlrb": "Gestionar", "0BUTMv": "Buscar...", + "0HFX0T": "Use Exact Location", "0jOEtS": "LNURL inválida", "0mch2Y": "el nombre tiene caracteres inválidos", "0siT4z": "Política", "0uoY11": "Mostrar estado", "0yO7wF": "{n} seg", + "1H4Keq": "{n} users", "1Mo59U": "¿Estás seguro de que quieres eliminar esta nota de tus favoritos?", "1R43+L": "Introduzca la configuración de Nostr Wallet Connect", "1c4YST": "Conectado a: {node}🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Iniciar sesión", "Up5U7K": "Bloquear", "UrKTqQ": "Tienes una cuenta activa en iris.to", + "VL900k": "Recommended Relays", "VN0+Fz": "Saldo: {amount} sats", "VOjC1i": "Elige qué servicio de subida de ficheros quieres utilizar", "VR5eHw": "Clave pública (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Su suscripción a {site_name} ha caducado", "jHa/ko": "Limpie su alimentación", "jMzO1S": "Error interno: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Atrás", "jvo0vs": "Guardar", "jzgQ2z": "{n} Reacciones", diff --git a/packages/app/src/translations/fa_IR.json b/packages/app/src/translations/fa_IR.json index 7e91da91..d6a9ca5f 100644 --- a/packages/app/src/translations/fa_IR.json +++ b/packages/app/src/translations/fa_IR.json @@ -21,11 +21,13 @@ "08zn6O": "استخراج کلید", "0Azlrb": "مدیریت", "0BUTMv": "جستجو...", + "0HFX0T": "Use Exact Location", "0jOEtS": "LNURL نامعتبر", "0mch2Y": "نام دارای کاراکتر غیرمجاز است", "0siT4z": "سیاست", "0uoY11": "نمایش وضعیت", "0yO7wF": "{n} ثانیه", + "1H4Keq": "{n} users", "1Mo59U": "مطمئنید می خواهید این یادداشت را از نشانک ها خارج کنید؟", "1R43+L": "پیکربندی اتصال ناستر به کیف پول", "1c4YST": "متصل به:{node}🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "ورود", "Up5U7K": "مسدود کردن", "UrKTqQ": "شما یک حساب کاربری فعال iris.to دارید", + "VL900k": "Recommended Relays", "VN0+Fz": "تراز: {amount} ساتوشی", "VOjC1i": "انتخاب کنید درکدام خدمات بارگذاری فایل می خواهید پیوست ها را بارگذاری کنید", "VR5eHw": "کلید عمومی (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "عضویت شما در {site_name} منقضی شده است", "jHa/ko": "پاک سازی خبرنامه", "jMzO1S": "خطای داخلی: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "برگشت", "jvo0vs": "ذخیره", "jzgQ2z": "{n} واکنش", diff --git a/packages/app/src/translations/fi_FI.json b/packages/app/src/translations/fi_FI.json index 387c7fa4..f66cc57f 100644 --- a/packages/app/src/translations/fi_FI.json +++ b/packages/app/src/translations/fi_FI.json @@ -21,11 +21,13 @@ "08zn6O": "Vie avaimet", "0Azlrb": "Hallitse", "0BUTMv": "Etsi...", + "0HFX0T": "Use Exact Location", "0jOEtS": "Virheellinen LNURL", "0mch2Y": "nimi sisältää sallimattomia merkkejä", "0siT4z": "Politiikka", "0uoY11": "Näytä tila", "0yO7wF": "{n} sek", + "1H4Keq": "{n} users", "1Mo59U": "Haluatko varmasti poistaa tämän viestin kirjanmerkeistä?", "1R43+L": "Anna Nostr Wallet Connect asetukset", "1c4YST": "Yhdistetty: {node} 🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Kirjaudu sisään", "Up5U7K": "Estä", "UrKTqQ": "Sinulla on aktiivinen iris.to-tili", + "VL900k": "Recommended Relays", "VN0+Fz": "Saldo: {amount} satsia", "VOjC1i": "Valitse palvelu, johon haluat ladata liitteitä", "VR5eHw": "Julkinen avain (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "{site_name} tilauksesi on päättynyt", "jHa/ko": "Siivoa rehusi", "jMzO1S": "Sisäinen virhe: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Takaisin", "jvo0vs": "Tallenna", "jzgQ2z": "{n} Reaktiota", diff --git a/packages/app/src/translations/fr_FR.json b/packages/app/src/translations/fr_FR.json index 97c16b0d..c4a73f57 100644 --- a/packages/app/src/translations/fr_FR.json +++ b/packages/app/src/translations/fr_FR.json @@ -21,11 +21,13 @@ "08zn6O": "Exporter les clés", "0Azlrb": "Gérer", "0BUTMv": "Chercher...", + "0HFX0T": "Use Exact Location", "0jOEtS": "LNURL invalide", "0mch2Y": "le nom contient des caractères non autorisés", "0siT4z": "Politique", "0uoY11": "Afficher l'état", "0yO7wF": "{n} secondes", + "1H4Keq": "{n} users", "1Mo59U": "Êtes-vous sûr de vouloir supprimer cette note de vos favoris ?", "1R43+L": "Accéder à la configuration de Nostr Wallet Connect", "1c4YST": "Connecté à : {node} 🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "S'inscrire", "Up5U7K": "Bloquer", "UrKTqQ": "Vous avez un compte iris.to actif", + "VL900k": "Recommended Relays", "VN0+Fz": "Solde : {amount} sats", "VOjC1i": "Choisissez le service d'hébergement vers lequel vous souhaitez héberger les pièces jointes", "VR5eHw": "Clé publique (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Votre abonnement à {site_name} a expiré", "jHa/ko": "Nettoyez votre flux", "jMzO1S": "Erreur interne : {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Retourner", "jvo0vs": "Sauvegarder", "jzgQ2z": "{n} Réactions", diff --git a/packages/app/src/translations/hr_HR.json b/packages/app/src/translations/hr_HR.json index 4f1fc22a..c1b40aaf 100644 --- a/packages/app/src/translations/hr_HR.json +++ b/packages/app/src/translations/hr_HR.json @@ -21,11 +21,13 @@ "08zn6O": "Izvezi Ključeve", "0Azlrb": "Upravljaj", "0BUTMv": "Pretraga...", + "0HFX0T": "Use Exact Location", "0jOEtS": "Nevažeći LNURL", "0mch2Y": "ime sadrži nepodržane znakove", "0siT4z": "Politics", "0uoY11": "Show Status", "0yO7wF": "{n} sekundi", + "1H4Keq": "{n} users", "1Mo59U": "Jeste li sigurni da želite ukloniti ovu bilješku iz trake s oznakama?", "1R43+L": "Enter Nostr Wallet Connect config", "1c4YST": "Povezano s: {node} 🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Sign In", "Up5U7K": "Blokiraj", "UrKTqQ": "You have an active iris.to account", + "VL900k": "Recommended Relays", "VN0+Fz": "Iznos: {amount} sati", "VOjC1i": "Odaberite kroz koji servis želite učitati privitke", "VR5eHw": "Javni ključ (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Your {site_name} subscription is expired", "jHa/ko": "Clean up your feed", "jMzO1S": "Interna pogreška: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Natrag", "jvo0vs": "Spremi", "jzgQ2z": "{n} Reakcija", diff --git a/packages/app/src/translations/hu_HU.json b/packages/app/src/translations/hu_HU.json index 6e479a31..134c900d 100644 --- a/packages/app/src/translations/hu_HU.json +++ b/packages/app/src/translations/hu_HU.json @@ -21,11 +21,13 @@ "08zn6O": "Kulcsok exportálása", "0Azlrb": "Menedzselés", "0BUTMv": "Keresés...", + "0HFX0T": "Use Exact Location", "0jOEtS": "Érvénytelen LNURL", "0mch2Y": "név nem engedélyezett karaktereket tartalmaz", "0siT4z": "Politika", "0uoY11": "Státusz megjelenítése", "0yO7wF": "{n} másodperc", + "1H4Keq": "{n} users", "1Mo59U": "Biztos hogy a kedvencekből ezt a bejegyzést el akarod távolítani?", "1R43+L": "Írd be a Nostr Wallet Connect konfigurációt", "1c4YST": "Kapcsolódás a: {node} 🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Bejelentkezés", "Up5U7K": "Tiltás", "UrKTqQ": "Van aktív iris.to fiókod", + "VL900k": "Recommended Relays", "VN0+Fz": "Egyenleg: {amount} sats", "VOjC1i": "Válaszd ki mely szolgáltatóhoz legyenek a fájlok feltöltve", "VR5eHw": "Publikus kulcs (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "{site_name}-előfizetése lejárt", "jHa/ko": "Tisztítsa meg a takarmányt", "jMzO1S": "Belső hiba: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Vissza", "jvo0vs": "Mentés", "jzgQ2z": "{n} Reakció", diff --git a/packages/app/src/translations/id_ID.json b/packages/app/src/translations/id_ID.json index 585e2d50..ac28a3d5 100644 --- a/packages/app/src/translations/id_ID.json +++ b/packages/app/src/translations/id_ID.json @@ -21,11 +21,13 @@ "08zn6O": "Kunci Ekspor", "0Azlrb": "Mengelola", "0BUTMv": "Cari...", + "0HFX0T": "Use Exact Location", "0jOEtS": "LNURL Tidak valid", "0mch2Y": "nama memiliki karakter yang tidak diizinkan", "0siT4z": "Politik", "0uoY11": "Tampilkan Status", "0yO7wF": "{n} detik", + "1H4Keq": "{n} users", "1Mo59U": "Apa Anda yakin Anda ingin memindahkan catatan ini dari penanda buku?", "1R43+L": "Masukkan konfigurasi Nostr Wallet Connect", "1c4YST": "Terhubung ke: {node} 🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Masuk", "Up5U7K": "Blokir", "UrKTqQ": "Anda memiliki akun iris.to yang aktif", + "VL900k": "Recommended Relays", "VN0+Fz": "Saldo: {amount} sats", "VOjC1i": "Pilih layanan unggah mana yang ingin Anda unggahkan lampirannya", "VR5eHw": "Kunci publik (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Langganan {site_name} Anda telah kedaluwarsa", "jHa/ko": "Bersihkan feed Anda", "jMzO1S": "Kesalahan internal: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Kembali", "jvo0vs": "Simpan", "jzgQ2z": "{n} Reaksi", diff --git a/packages/app/src/translations/it_IT.json b/packages/app/src/translations/it_IT.json index aa56312f..ff1d54f0 100644 --- a/packages/app/src/translations/it_IT.json +++ b/packages/app/src/translations/it_IT.json @@ -21,11 +21,13 @@ "08zn6O": "Esporta Chiavi", "0Azlrb": "Gestisci", "0BUTMv": "Cerca...", + "0HFX0T": "Use Exact Location", "0jOEtS": "LNURL non valido", "0mch2Y": "il nome ha caratteri non ammessi", "0siT4z": "Politica", "0uoY11": "Mostra stato", "0yO7wF": "{n} sec", + "1H4Keq": "{n} users", "1Mo59U": "Vuoi davvero rimuovere questa nota dai preferiti?", "1R43+L": "Inserire la configurazione di Nostr Wallet Connect", "1c4YST": "Connessione a: {node}🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Accedi", "Up5U7K": "Blocca", "UrKTqQ": "Avete un account iris.to attivo", + "VL900k": "Recommended Relays", "VN0+Fz": "Saldo: {amount} sats", "VOjC1i": "Scegli quale servizio vuoi usare per caricare gli allegati", "VR5eHw": "Chiave pubblica (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "L'abbonamento a {site_name} è scaduto", "jHa/ko": "Pulite il vostro feed", "jMzO1S": "Errore interno: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Indietro", "jvo0vs": "Salva", "jzgQ2z": "{n} Reazioni", diff --git a/packages/app/src/translations/ja_JP.json b/packages/app/src/translations/ja_JP.json index 3026a38e..93b64350 100644 --- a/packages/app/src/translations/ja_JP.json +++ b/packages/app/src/translations/ja_JP.json @@ -21,11 +21,13 @@ "08zn6O": "鍵をエクスポート", "0Azlrb": "管理", "0BUTMv": "検索する", + "0HFX0T": "Use Exact Location", "0jOEtS": "無効なLNURL", "0mch2Y": "名前に使用できない文字が含まれています", "0siT4z": "政治", "0uoY11": "ステータス表示", "0yO7wF": "{n}秒", + "1H4Keq": "{n} users", "1Mo59U": "本当にこの投稿をブックマークから削除しますか?", "1R43+L": "Nostr Wallet Connectの設定値を入力", "1c4YST": "{node}に接続しました🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "サインイン", "Up5U7K": "ブロック", "UrKTqQ": "iris.toアカウントをお持ちの方", + "VL900k": "Recommended Relays", "VN0+Fz": "残高: {amount} sats", "VOjC1i": "添付ファイルをアップロードするためのサービスを選択してください", "VR5eHw": "公開鍵 (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "{site_name} 、有効期限が切れています。", "jHa/ko": "フィードをきれいにする", "jMzO1S": "内部エラー:{msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "戻る", "jvo0vs": "保存", "jzgQ2z": "{n} リアクション", diff --git a/packages/app/src/translations/nl_NL.json b/packages/app/src/translations/nl_NL.json index abe00d48..abf8ed6b 100644 --- a/packages/app/src/translations/nl_NL.json +++ b/packages/app/src/translations/nl_NL.json @@ -21,11 +21,13 @@ "08zn6O": "Sleutel exporteren", "0Azlrb": "Beheren", "0BUTMv": "Zoeken naar...", + "0HFX0T": "Use Exact Location", "0jOEtS": "Ongeldig LNURL", "0mch2Y": "naam heeft verboden tekens", "0siT4z": "Politiek", "0uoY11": "Toon status", "0yO7wF": "{n} seconden", + "1H4Keq": "{n} users", "1Mo59U": "Weet u zeker dat u deze notitie uit bladwijzers wilt verwijderen?", "1R43+L": "Voer Nostr Wallet Connect configuratie in", "1c4YST": "Verbonden met: {node}🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Aanmelden", "Up5U7K": "Blokkeren", "UrKTqQ": "Je hebt een actieve iris.to account", + "VL900k": "Recommended Relays", "VN0+Fz": "Saldo: {amount} sats", "VOjC1i": "Kies naar welke service u bijlagen wilt uploaden", "VR5eHw": "Publieke sleutel (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Uw {site_name} abonnement is verlopen", "jHa/ko": "Ruim je feed op", "jMzO1S": "Interne fout: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Terug", "jvo0vs": "Opslaan", "jzgQ2z": "{n} Reacties", diff --git a/packages/app/src/translations/pt_BR.json b/packages/app/src/translations/pt_BR.json index 194d3a2a..d8d58491 100644 --- a/packages/app/src/translations/pt_BR.json +++ b/packages/app/src/translations/pt_BR.json @@ -21,11 +21,13 @@ "08zn6O": "Exportar chaves", "0Azlrb": "Gerenciar", "0BUTMv": "Pesquisar...", + "0HFX0T": "Use Exact Location", "0jOEtS": "LNURL inválida", "0mch2Y": "o nome possui caracteres não permitidos", "0siT4z": "Política", "0uoY11": "Mostrar status", "0yO7wF": "{n} segundos", + "1H4Keq": "{n} users", "1Mo59U": "Tem certeza que deseja remover esta nota dos favoritos?", "1R43+L": "Insira a configuração da Nostr Wallet Connect", "1c4YST": "Conectado em: {node} 🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Entrar", "Up5U7K": "Bloquear", "UrKTqQ": "Você tem uma conta ativa no iris.to", + "VL900k": "Recommended Relays", "VN0+Fz": "Saldo: {amount} sats", "VOjC1i": "Escolha para qual serviço fazer upload dos arquivos", "VR5eHw": "Chave pública (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Sua assinatura do {site_name} expirou", "jHa/ko": "Limpe seu feed", "jMzO1S": "Erro interno: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Voltar", "jvo0vs": "Salvar", "jzgQ2z": "{n} Reações", diff --git a/packages/app/src/translations/ru_RU.json b/packages/app/src/translations/ru_RU.json index f57b1a9e..6f09eb7c 100644 --- a/packages/app/src/translations/ru_RU.json +++ b/packages/app/src/translations/ru_RU.json @@ -21,11 +21,13 @@ "08zn6O": "Экспортировать ключи", "0Azlrb": "Управление", "0BUTMv": "Поиск...", + "0HFX0T": "Use Exact Location", "0jOEtS": "Неверный LNURL", "0mch2Y": "имя содержит запрещенные символы", "0siT4z": "Политика", "0uoY11": "Показать статус", "0yO7wF": "{n} секунд", + "1H4Keq": "{n} users", "1Mo59U": "Вы уверены, что хотите удалить эту заметку из закладок?", "1R43+L": "Введите конфигурацию Nostr Wallet Connect", "1c4YST": "Подключен к: {node} 🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Войти", "Up5U7K": "Блок", "UrKTqQ": "У вас есть активная учетная запись iris.to", + "VL900k": "Recommended Relays", "VN0+Fz": "Баланс: {amount} сат", "VOjC1i": "Выберите каким сервисом Вы бы хотели пользоваться для загрузки медиа", "VR5eHw": "Публичный ключ (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Срок действия вашей подписки {site_name} истек", "jHa/ko": "Очистка корма", "jMzO1S": "Ошибка: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Назад", "jvo0vs": "Сохранить", "jzgQ2z": "{n} Реакции", diff --git a/packages/app/src/translations/sv_SE.json b/packages/app/src/translations/sv_SE.json index 2b76cfa4..fb17c071 100644 --- a/packages/app/src/translations/sv_SE.json +++ b/packages/app/src/translations/sv_SE.json @@ -21,11 +21,13 @@ "08zn6O": "Exportera nycklar", "0Azlrb": "Hantera", "0BUTMv": "Sök...", + "0HFX0T": "Use Exact Location", "0jOEtS": "Ogiltig LNURL", "0mch2Y": "namnet har otillåtna tecken", "0siT4z": "Politik", "0uoY11": "Visa status", "0yO7wF": "{n} secs", + "1H4Keq": "{n} users", "1Mo59U": "Är du säker på att du vill ta bort den här anteckningen från bokmärken?", "1R43+L": "Skriv in Nostr Wallet Connect konfiguration", "1c4YST": "Ansluten till: {node}🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Logga in", "Up5U7K": "Blockera", "UrKTqQ": "Du har ett aktivt iris.to konto", + "VL900k": "Recommended Relays", "VN0+Fz": "Saldo: {amount} sats", "VOjC1i": "Välj vilken uppladdningstjänst du vill ladda upp bilagor till", "VR5eHw": "Publik nyckel (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Ditt {site_name} abonnemang har löpt ut", "jHa/ko": "Städa upp i ditt flöde", "jMzO1S": "Internt fel: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Tillbaka", "jvo0vs": "Spara", "jzgQ2z": "{n} Reaktioner", diff --git a/packages/app/src/translations/sw_KE.json b/packages/app/src/translations/sw_KE.json index fd1a72bc..e1072d1d 100644 --- a/packages/app/src/translations/sw_KE.json +++ b/packages/app/src/translations/sw_KE.json @@ -21,11 +21,13 @@ "08zn6O": "Tuma Funguo", "0Azlrb": "Dhibiti", "0BUTMv": "Tafuta...", + "0HFX0T": "Use Exact Location", "0jOEtS": "LNURL Batili", "0mch2Y": "jina limekataza herufi", "0siT4z": "Politics", "0uoY11": "Show Status", "0yO7wF": "{n} sekundi", + "1H4Keq": "{n} users", "1Mo59U": "Je, una uhakika unataka kuondoa dokezo hili kutoka kwa vialamisho?", "1R43+L": "Ingiza usanidi wa Nostr Wallet Connect", "1c4YST": "Imeunganishwa kwa: {node} 🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Sign In", "Up5U7K": "Zuia", "UrKTqQ": "You have an active iris.to account", + "VL900k": "Recommended Relays", "VN0+Fz": "Salio: {amount} sats", "VOjC1i": "Chagua ni huduma gani ya upakiaji ungependa kupakia viambatisho", "VR5eHw": "Ufunguo wa umma (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Your {site_name} subscription is expired", "jHa/ko": "Clean up your feed", "jMzO1S": "Hitilafu ya ndani: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "Rudi", "jvo0vs": "Hifadhi", "jzgQ2z": "{n} Maoni", diff --git a/packages/app/src/translations/ta_IN.json b/packages/app/src/translations/ta_IN.json index 8100360b..019d11d4 100644 --- a/packages/app/src/translations/ta_IN.json +++ b/packages/app/src/translations/ta_IN.json @@ -7,9 +7,9 @@ "+vA//S": "உள்நுழைவுகள்", "+vIQlC": "பிற்காலத்தில் உங்களது கணக்கை நிர்வகிக்க, கீழே உள்ள கடவுச்சொல்லைத் தவறாமல் சேமிக்கவும்", "+vVZ/G": "இணை", - "+vj0U3": "edit", + "+vj0U3": "தொகு", "+xliwN": "{name} மறுபதிவு செய்தார்", - "/B8zwF": "Your space the way you want it 😌", + "/B8zwF": "நீங்கள் விரும்பியபடி உங்கள் இடம் 😌", "/GCoTA": "அழி", "/JE/X+": "கணக்கு உதவி", "/PCavi": "பொது", @@ -21,29 +21,31 @@ "08zn6O": "சாவிகளை ஏற்றுமதி செய்யவும்", "0Azlrb": "நிர்வகி", "0BUTMv": "தேடு...", + "0HFX0T": "Use Exact Location", "0jOEtS": "தவறான LNURL", "0mch2Y": "பெயர் அங்கீகரிக்கப்படாத எழுத்துக்களைக் கொண்டுள்ளது", - "0siT4z": "Politics", + "0siT4z": "அரசியல்", "0uoY11": "சமுதாய நிலையைக் காட்டு", "0yO7wF": "{n} வினாடிகள்", + "1H4Keq": "{n} users", "1Mo59U": "இந்தக் குறிப்பைப் புக்மார்க்குகளிலிருந்து அகற்ற நிச்சயமாக விரும்புகிறீர்களா?", "1R43+L": "நாஸ்டர் பணப்பை இணைப்புக் கட்டமைப்பை உள்ளிடவும்", "1c4YST": "{node} உடன் இணைக்கப் பட்டது 🎉", "1nYUGC": "{n} பின்தொடரப் படுவோர்", "1o2BgB": "கையெழுத்துக்களை சரிபார்", - "1ozeyg": "Nature", + "1ozeyg": "இயற்கை", "1udzha": "உரையாடல்கள்", "2/2yg+": "சேர்", "25V4l1": "பதாகை", - "25WwxF": "Don't have an account?", + "25WwxF": "கணக்கு இல்லையா?", "2IFGap": "நன்கொடை அளிக்க", "2LbrkB": "கடவுச்சொல்லை உள்ளிடுக", - "2O2sfp": "Finish", + "2O2sfp": "முடிக்க", "2a2YiP": "{n} புத்தகக் குறிகள்", "2k0Cv+": "விருப்பமின்மைகள் ({n})", "2ukA4d": "{n} மணித்துளிகள்", "2zJXeA": "சுயவிவரங்கள்", - "39AHJm": "Sign Up", + "39AHJm": "பதிவு செய்", "3KNMbJ": "கட்டுரைகள்", "3cc4Ct": "ஒளி", "3gOsZq": "மொழிபெயர்ப்பாளர்கள்", @@ -56,7 +58,7 @@ "4IPzdn": "முதன்மை உருவாக்கி", "4L2vUY": "உங்களது புதிய NIP-05 கணக்கு:", "4MBtMa": "பெயர் 1 முதல் 32 எழுத்துக்களைக் கொண்டிருக்க வேண்டும்", - "4MjsHk": "Life", + "4MjsHk": "வாழ்க்கை", "4OB335": "விருப்பமில்லை", "4Vmpt4": "Nostr Plebs முதல் NIP-05 வழங்குநர்களில் ஒன்றாகும். மேலும், இது நியாயமான விலையில் டொமைன்களின் நல்ல தொகுப்பை வழங்குகிறது", "4Z3t5i": "படங்களை சுருக்க imgproxy உபயோகிக்கவும்", @@ -69,7 +71,7 @@ "5ykRmX": "ஜாப் அனுப்பு", "6/SF6e": "

{n}

காஷூ சாட்கள்", "6/hB3S": "மறு ஓட்டத்தைப் பார்க்கவும்", - "62nsdy": "Retry", + "62nsdy": "மீண்டும் முயற்சிக்கவும்", "65BmHb": "{host} இல் இருந்து படத்தைப் பதிலி செய்ய முடியவில்லை, நேரடியாகப் பெற இங்கு கிளிக் செய்யவும்", "6OSOXl": "காரணம்: {reason}", "6TfgXX": "{site} என்பது ஆர்வமுள்ள மக்கள் தங்கள் ஓய்வு நேரத்தில் உருவாக்கிய திறந்த மூல திட்டம் ஆகும்", @@ -79,31 +81,31 @@ "7+Domh": "குறிப்புகள்", "712i26": "Proxy uses HODL invoices to forward the payment, which hides the pubkey of your node", "7BX/yC": "கணக்கு மாற்றி", - "7UOvbT": "Offline", + "7UOvbT": "அகல்நிலை", "7hp70g": "NIP-05", "8/vBbP": "மறுபதிவுகள் ({n})", "89q5wc": "மறுப்பதிவுகளை உறுதி செய்யவும்", "8ED/4u": "இவருக்கு பதிலளி", "8QDesP": "{n} ஸாட்கள் ஜாப் செய்", "8Rkoyb": "பெறுநர்", - "8Y6bZQ": "Invalid zap split: {input}", + "8Y6bZQ": "தவறான zap பிளவு: {input}", "8g2vyB": "பெயர் மிக நீளமாக உள்ளது", "8v1NN+": "ஜோடிக்கும் சொற்றொடர்", "9+Ddtu": "அடுத்து", "9HU8vw": "பதில்", "9SvQep": "பின்தொடர்வுகள் {n}", "9WRlF4": "அனுப்பு", - "9kSari": "Retry publishing", + "9kSari": "வெளியிட மீண்டும் முயற்சிக்கவும்", "9pMqYs": "நாஸ்டர் முகவரி", "9wO4wJ": "லைட்னிங் விலைப்பட்டியல்", "ABAQyo": "அரட்டைகள்", "ADmfQT": "பெற்றோர்", - "AIgmDy": "Add up to 4 hashtags", + "AIgmDy": "4 ஹேஷ்டேக்குகள் வரை சேர்க்கவும்", "AN0Z7Q": "முடக்கப்பட்ட வார்த்தைகள்", "ASRK0S": "இந்தப் பதிவாளர் முடக்கப் பட்டுள்ளார்", "Ai8VHU": "ஸ்நார்ட் ரிலேயில் வரம்பற்ற குறிப்புகளை வைத்திரு", "AkCxS/": "காரணம்", - "Am8glJ": "Game", + "Am8glJ": "விளையாட்டு", "AnLrRC": "ஜாப் அல்லாத", "AxDOiG": "மாதங்கள்", "AyGauy": "உள்நுழை", @@ -114,15 +116,15 @@ "BWpuKl": "புதுப்பி", "BjNwZW": "நாஸ்டர் முகவரி (nip05)", "C1LjMx": "லைட்னிங் நன்கொடை", - "C7642/": "Quote Repost", + "C7642/": "மேற்கோள் மறுபதிவு", "C81/uG": "வெளியேறு", "C8HhVE": "பரிந்துரைக்கப்படும் பயனர்கள்", "CHTbO3": "விலைப்பட்டியலை பெற முடியவில்லை", - "CVWeJ6": "Trending People", + "CVWeJ6": "டிரெண்டிங் நபர்கள்", "CmZ9ls": "{n} ஒலியடக்கப்பட்டவை", - "CsCUYo": "{n} sats", + "CsCUYo": "{n} சாட்ஸ்", "Cu/K85": "{lang} இல் இருந்து மொழிபெயர்க்கப் பட்டது", - "CzHZoc": "Social Graph", + "CzHZoc": "சமூக வரைபடம்", "D+KzKd": "கிடைக்கும் ஒவ்வொரு குறிப்புகளையும் தானாக ஜாப் செய்யவும்", "D3idYv": "அமைப்புகள்", "DBiVK1": "தேக்ககம்", @@ -132,21 +134,21 @@ "Dh3hbq": "தானாக ஜாப்", "Dn82AL": "நேரலை", "DtYelJ": "பரிமாற்றம்", - "Dx4ey3": "Toggle all", + "Dx4ey3": "அனைத்தையும் நிலைமாற்று", "EJbFi7": "குறிப்புகளைத் தேடு", "ELbg9p": "தரவு வழங்குநர்", - "EQKRE4": "Show badges on profile pages", + "EQKRE4": "சுயவிவரப் பக்கங்களில் பேட்ஜ்களைக் காட்டு", "EWyQH5": "முழுதளாவிய", "Ebl/B2": "{lang} இற்கு மொழிபெயர்க்கவும்", - "EcZF24": "Custom Relays", - "EcfIwB": "Username is available", + "EcZF24": "கஸ்டம் ரிலேஸ்", + "EcfIwB": "பயனர் பெயர் இருக்கிறது", "EcglP9": "சாவி", - "EjFyoR": "On-chain Donation Address", + "EjFyoR": "ஆன்-செயின் நன்கொடை முகவரி", "EnCOBJ": "வாங்கு", "F3l7xL": "கணக்கை சேர்", "FDguSC": "{n} ஜாப்கள்", - "FMfjrl": "Show status messages on profile pages", - "FSYL8G": "Trending Users", + "FMfjrl": "சுயவிவரப் பக்கங்களில் நிலை செய்திகளைக் காட்டு", + "FSYL8G": "பிரபலமான பயனர்கள்", "FcNSft": "Redirect issues HTTP redirect to the supplied lightning address", "FdhSU2": "இப்போது உரிமை கோரவும்", "FfYsOb": "ஓரு பிழை நேர்ந்துவிட்டது!", @@ -155,36 +157,36 @@ "G1BGCg": "பணப்பை தேர்வு", "GFOoEE": "உப்பு", "GL8aXW": "புக்மார்க்குகள் ({n})", - "GQPtfk": "Join Stream", - "GSye7T": "Lightning Address", + "GQPtfk": "ஸ்ட்ரீமில் சேரவும்", + "GSye7T": "லைட்னிங் முகவரி", "GUlSVG": "உங்கள் ஸ்நார்ட் நாஸ்டர் முகவரியைப் பெறவும்", "Gcn9NQ": "மேக்னெட் இணைப்பு", "GspYR7": "{n} விருப்பமின்மை", - "Gxcr08": "Broadcast Event", + "Gxcr08": "ஒளிபரப்பு நிகழ்வு", "H+vHiz": "ஹெக்ஸ் சாவி..", "H0JBH6": "வெளியேறு", "H6/kLh": "ஆர்டர் செலுத்தப்பட்டது!", "HAlOn1": "பெயர்", "HFls6j": "பெயர் பின்னர் கிடைக்கப் பெறும்", "HOzFdo": "ஒலியடக்கப்பட்டவை", - "HWbkEK": "Clear cache and reload", + "HWbkEK": "தற்காலிக சேமிப்பை அழித்து மீண்டும் ஏற்றவும்", "HbefNb": "திறந்த பணப்பை", - "HhcAVH": "You don't follow this person, click here to load media from {link}, or update your preferences to always load media from everybody.", + "HhcAVH": "நீங்கள் இவரைப் பின்தொடரவில்லை, மீடியாவை ஏற்ற இங்கே கிளிக் செய்யவும் {link}, அல்லது புதுப்பிக்கவும் உங்கள் விருப்பங்களை எல்லாரிடமிருந்தும் எப்போதும் மீடியாவை ஏற்றுவதற்கு.", "IEwZvs": "இந்தக் குறிப்பின் நிலையான பொறுத்தத்தை நிச்சயமாக நீக்க விரும்புகிறீர்களா?", "IKKHqV": "பின்தொடர்வுகள்", - "IVbtTS": "Zap all {n} sats", - "IWz1ta": "Auto Translate", - "Ig9/a1": "Sent {n} sats to {name}", - "IoQq+a": "Click here to load anyway", - "Ix8l+B": "Trending Notes", + "IVbtTS": "{n} சாட்கள் ஜாப் செய்", + "IWz1ta": "தானியங்கு மொழிபெயர்ப்பு", + "Ig9/a1": "{name} க்கு {n} சாட்ஸ் அனுப்பப்பட்டது", + "IoQq+a": "எப்படியும் ஏற்ற இங்கே கிளிக் செய்யவும்", + "Ix8l+B": "பிரபலமான குறிப்புகள்", "J+dIsA": "சந்தாக்கள்", - "J2HeQ+": "Use commas to separate words e.g. word1, word2, word3", + "J2HeQ+": "சொற்களைப் பிரிக்க காற்புள்ளிகளைப் பயன்படுத்தவும் எ.கா. சொல்1, சொல்2, சொல்3", "JCIgkj": "பயனர் பெயர்", - "JGrt9q": "Send sats to {name}", + "JGrt9q": "{name} க்கு சாட்களை அனுப்பு", "JHEHCk": "ஜாப்கள் ({n})", - "JIVWWA": "Sport", - "JPFYIM": "No lightning address", - "JSx7y9": "Subscribe to {site_name} {plan} for {price} and receive the following rewards", + "JIVWWA": "விளையாட்டு", + "JPFYIM": "லைட்னிங் முகவரி இல்லை", + "JSx7y9": "{price} க்கு {site_name} {plan} இல் குழுசேர்ந்து பின்வரும் வெகுமதிகளைப் பெறுங்கள்", "JeoS4y": "மறுபதிவு", "JjGgXI": "பயனர்களைத் தேடுக", "JkLHGw": "வலைத்தளம்", @@ -192,24 +194,24 @@ "K3r6DQ": "நீக்கு", "K7AkdL": "காண்பி", "KAhAcM": "LNDHub கட்டமைப்பை உள்ளிடவும்", - "KHK8B9": "Relay", + "KHK8B9": "ரிலே", "KQvWvD": "நீக்கப்பட்டது", "KahimY": "அறிந்திராத நிகழ்வு வகை: {kind}", - "KoFlZg": "Enter mint URL", - "KtsyO0": "Enter Pin", + "KoFlZg": "mint URL ஐ உள்ளிடவும்", + "KtsyO0": "பின்னை உள்ளிடவும்", "LF5kYT": "பிற இணைப்புகள்", - "LR1XjT": "Pin too short", + "LR1XjT": "பின் மிகவும் சிறியது", "LXxsbk": "பெயரிலா", "LgbKvU": "கருத்து", - "Lu5/Bj": "Open on Zapstr", - "Lw+I+J": "{n,plural,=0{{name} zapped} other{{name} & {n} others zapped}}", - "LwYmVi": "Zaps on this note will be split to the following users.", + "Lu5/Bj": "Zapstr இல் திறக்கவும்", + "Lw+I+J": "{n,plural,=0{{name} zapped} other{{{name} & {n} others zapped}}", + "LwYmVi": "இந்தக் குறிப்பில் உள்ள Zaps பின்வரும் பயனர்களுக்குப் பிரிக்கப்படும்.", "M3Oirc": "மெனுக்களை பிழை திருத்தவும்", "MBAYRO": "ஒவ்வொரு செய்தியிலும் சூழல் மெனுவில் \"IDஐ நகலெடு\" மற்றும் \"நிகழ்வு JSONஐ நகலெடு\" ஆகியவற்றைக் காட்டுகிறது", "MI2jkA": "கிடைக்கவில்லை:", "MP54GY": "பணப்பை கடவுச்சொல்", "MWTx65": "இயல்புநிலை பக்கம்", - "MiMipu": "Set as primary Nostr address (nip05)", + "MiMipu": "முதன்மை Nostr முகவரியாக அமைக்கவும் (nip05)", "Mrpkot": "சந்தாவுக்கு பணம் செலுத்துங்கள்", "MuVeKe": "Buy nostr address", "MzRYWH": "{item} வாங்கப் படுகிறது", @@ -274,6 +276,7 @@ "Ub+AGc": "Sign In", "Up5U7K": "முடக்கு", "UrKTqQ": "You have an active iris.to account", + "VL900k": "Recommended Relays", "VN0+Fz": "இருப்பு: {amount} ஸாட்கள்", "VOjC1i": "எந்தப் பதிவேற்ற சேவையில் இணைப்புகளைப் பதிவேற்ற விரும்புகிறீர்கள் என்பதைத் தேர்ந்தெடுக்கவும்", "VR5eHw": "பொது சாவி (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Your {site_name} subscription is expired", "jHa/ko": "Clean up your feed", "jMzO1S": "உள் பிழை: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "பின்", "jvo0vs": "சேமி", "jzgQ2z": "{n} எதிர்வினைகள்", diff --git a/packages/app/src/translations/th_TH.json b/packages/app/src/translations/th_TH.json index 225dfd76..236ca36c 100644 --- a/packages/app/src/translations/th_TH.json +++ b/packages/app/src/translations/th_TH.json @@ -21,11 +21,13 @@ "08zn6O": "ส่งออกกุญแจ", "0Azlrb": "จัดการ", "0BUTMv": "ค้นหา...", + "0HFX0T": "Use Exact Location", "0jOEtS": "LNURL ไม่ถูกต้อง", "0mch2Y": "ชื่อมีอักขระที่ไม่อนุญาตให้ใช้", "0siT4z": "Politics", "0uoY11": "Show Status", "0yO7wF": "{n} วินาที", + "1H4Keq": "{n} users", "1Mo59U": "คุณแน่ใจหรือว่าต้องการลบโน้ตนี้ออกจากบุ๊คมาร์ค?", "1R43+L": "ใส่ Nostr Wallet Connect config", "1c4YST": "เชื่อมต่อกับ: {node} 🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "Sign In", "Up5U7K": "บล็อก", "UrKTqQ": "You have an active iris.to account", + "VL900k": "Recommended Relays", "VN0+Fz": "คงเหลือ: {amount} sats", "VOjC1i": "เลือกบริการอัปโหลดที่คุณต้องการอัปโหลดไฟล์แนบ", "VR5eHw": "Public key (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "Your {site_name} subscription is expired", "jHa/ko": "Clean up your feed", "jMzO1S": "ข้อผิดพลาดภายใน: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "ย้อนกลับ", "jvo0vs": "บันทึก", "jzgQ2z": "{n} Reactions", diff --git a/packages/app/src/translations/zh_CN.json b/packages/app/src/translations/zh_CN.json index f54797c3..7996e29f 100644 --- a/packages/app/src/translations/zh_CN.json +++ b/packages/app/src/translations/zh_CN.json @@ -21,11 +21,13 @@ "08zn6O": "导出密钥", "0Azlrb": "管理", "0BUTMv": "搜索...", + "0HFX0T": "Use Exact Location", "0jOEtS": "LNURL无效", "0mch2Y": "名称中有禁用字符", "0siT4z": "政治", "0uoY11": "显示状态", "0yO7wF": "{n} 秒", + "1H4Keq": "{n} users", "1Mo59U": "是否确定要从收藏中移除此条笔记?", "1R43+L": "输入 Nostr Wallet Connect 配置", "1c4YST": "已连接到:{node}🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "登录", "Up5U7K": "屏蔽", "UrKTqQ": "你有一个活跃的 iris.to 帐户", + "VL900k": "Recommended Relays", "VN0+Fz": "余额: {amount} 聪", "VOjC1i": "选择你要将附件上传到哪个上传服务", "VR5eHw": "公钥 (npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "你的 {site_name} 订阅已过期", "jHa/ko": "清理你的订阅", "jMzO1S": "内部错误: {msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "返回", "jvo0vs": "保存", "jzgQ2z": "{n} 个回应", diff --git a/packages/app/src/translations/zh_TW.json b/packages/app/src/translations/zh_TW.json index 673730dd..710578b5 100644 --- a/packages/app/src/translations/zh_TW.json +++ b/packages/app/src/translations/zh_TW.json @@ -21,11 +21,13 @@ "08zn6O": "導出密鑰", "0Azlrb": "管理", "0BUTMv": "搜索...", + "0HFX0T": "Use Exact Location", "0jOEtS": "LNURL 無效", "0mch2Y": "名稱中有禁用字符", "0siT4z": "政治", "0uoY11": "顯示狀態", "0yO7wF": "{n} 秒", + "1H4Keq": "{n} users", "1Mo59U": "是否確定要從收藏中移除此條筆記?", "1R43+L": "輸入 Nostr Wallet Connect 配置", "1c4YST": "已連接到:{node} 🎉", @@ -274,6 +276,7 @@ "Ub+AGc": "登錄", "Up5U7K": "屏蔽", "UrKTqQ": "你有一個活躍的 iris.to 帳戶", + "VL900k": "Recommended Relays", "VN0+Fz": "餘額:{amount} 聰", "VOjC1i": "選擇你要將附件上傳到哪個上傳服務", "VR5eHw": "公鑰(npub/nprofile)", @@ -381,6 +384,7 @@ "jAmfGl": "你的 {site_name} 訂閱已過期了", "jHa/ko": "清理你的訂閱", "jMzO1S": "內部錯誤:{msg}", + "jTrbGf": "{n} km - {location}", "jfV8Wr": "返回", "jvo0vs": "保存", "jzgQ2z": "{n} 個回應", diff --git a/packages/shared/src/utils.ts b/packages/shared/src/utils.ts index 6976140d..aa075bc7 100644 --- a/packages/shared/src/utils.ts +++ b/packages/shared/src/utils.ts @@ -144,13 +144,9 @@ export function getPublicKey(privKey: string) { } export function bech32ToHex(str: string) { - try { - const nKey = bech32.decode(str, 1_000); - const buff = bech32.fromWords(nKey.words); - return utils.bytesToHex(Uint8Array.from(buff)); - } catch (e) { - return str; - } + const nKey = bech32.decode(str, 1_000); + const buff = bech32.fromWords(nKey.words); + return utils.bytesToHex(Uint8Array.from(buff)); } /** @@ -159,13 +155,9 @@ export function bech32ToHex(str: string) { * @returns */ export function bech32ToText(str: string) { - try { - const decoded = bech32.decode(str, 1000); - const buf = bech32.fromWords(decoded.words); - return new TextDecoder().decode(Uint8Array.from(buf)); - } catch { - return ""; - } + const decoded = bech32.decode(str, 1000); + const buf = bech32.fromWords(decoded.words); + return new TextDecoder().decode(Uint8Array.from(buf)); } export async function fetchNip05Pubkey(name: string, domain: string, timeout = 2_000): Promise { diff --git a/packages/system/src/nostr-link.ts b/packages/system/src/nostr-link.ts index ee47ad26..6e53c657 100644 --- a/packages/system/src/nostr-link.ts +++ b/packages/system/src/nostr-link.ts @@ -233,11 +233,16 @@ export function tryParseNostrLink(link: string, prefixHint?: NostrPrefix): Nostr } } -export function parseNostrLink(link: string, prefixHint?: NostrPrefix): NostrLink { +export function trimNostrLink(link: string) { let entity = link.startsWith("web+nostr:") || link.startsWith("nostr:") ? link.split(":")[1] : link; // trim any non-bech32 chars entity = entity.match(/(n(?:pub|profile|event|ote|addr|req)1[acdefghjklmnpqrstuvwxyz023456789]+)/)?.[0] ?? entity; + return entity; +} + +export function parseNostrLink(link: string, prefixHint?: NostrPrefix): NostrLink { + const entity = trimNostrLink(link); const isPrefix = (prefix: NostrPrefix) => { return entity.startsWith(prefix);