From 577547d40e7f2352df4826f4d9af16d3272e2f15 Mon Sep 17 00:00:00 2001 From: Joey Stanford Date: Fri, 31 Jul 2026 09:06:50 -0600 Subject: [PATCH 1/4] fix(reticulum): address CodeRabbit a11y and listener-off retry toast Darken the Remote pending-offer badge, align 99+ aria with the visible cap, add axe coverage, and toast listener-off distinctly when retry skips the enable modal. --- src/renderer/components/Sidebar.test.tsx | 35 +++++++++++++++++++ src/renderer/components/Sidebar.tsx | 8 ++--- .../remote/ChatDmRncpOfferBanner.test.tsx | 6 +++- .../remote/RemoteTransferSection.test.tsx | 4 +++ .../remote/RemoteTransferSection.tsx | 8 +++-- src/renderer/locales/cs/translation.json | 4 ++- src/renderer/locales/de/translation.json | 4 ++- src/renderer/locales/en/translation.json | 2 ++ src/renderer/locales/es/translation.json | 4 ++- src/renderer/locales/fr/translation.json | 4 ++- src/renderer/locales/id/translation.json | 4 ++- src/renderer/locales/it/translation.json | 4 ++- src/renderer/locales/ja/translation.json | 4 ++- src/renderer/locales/ko/translation.json | 4 ++- src/renderer/locales/nl/translation.json | 4 ++- src/renderer/locales/pl/translation.json | 4 ++- src/renderer/locales/pt-BR/translation.json | 4 ++- src/renderer/locales/ru/translation.json | 4 ++- src/renderer/locales/tr/translation.json | 4 ++- src/renderer/locales/uk/translation.json | 4 ++- src/renderer/locales/zh/translation.json | 4 ++- 21 files changed, 101 insertions(+), 22 deletions(-) diff --git a/src/renderer/components/Sidebar.test.tsx b/src/renderer/components/Sidebar.test.tsx index 92f076c27..a091c6130 100644 --- a/src/renderer/components/Sidebar.test.tsx +++ b/src/renderer/components/Sidebar.test.tsx @@ -271,6 +271,41 @@ describe('Sidebar', () => { expect(screen.queryByText('0')).not.toBeInTheDocument(); }); + it('caps Remote pending-offer badge at 99+ with matching aria', () => { + render( + , + ); + expect(screen.getByText('99+')).toBeInTheDocument(); + expect( + screen.getByRole('tab', { name: '99+ pending inbound file offers' }), + ).toBeInTheDocument(); + }); + + it('has no axe violations when Remote pending-offer badge shows', async () => { + render( + , + ); + const badge = screen.getByText('2'); + hydrateAxeThemeColors(badge); + expect(await axe(badge)).toHaveNoViolations(); + }); + it('hides RRC unread badge when rrcUnread is 0', () => { const onChange = vi.fn(); render( diff --git a/src/renderer/components/Sidebar.tsx b/src/renderer/components/Sidebar.tsx index f509aa838..c723c2408 100644 --- a/src/renderer/components/Sidebar.tsx +++ b/src/renderer/components/Sidebar.tsx @@ -80,9 +80,9 @@ export default function Sidebar({ const showBadge = showChatBadge || showRoomsBadge || showRrcBadge || showRemoteBadge; const tabAriaLabel = showBadge ? showRemoteBadge - ? t('reticulumRemote.transfer.pendingOffersBadgeAria', { - count: badgeCount > 99 ? 99 : badgeCount, - }) + ? badgeCount > 99 + ? t('reticulumRemote.transfer.pendingOffersBadgeAriaCapped') + : t('reticulumRemote.transfer.pendingOffersBadgeAria', { count: badgeCount }) : t('aria.tabWithUnread', { label: displayLabel, count: badgeCount > 99 ? '99+' : badgeCount, @@ -120,7 +120,7 @@ export default function Sidebar({ {showBadge && ( {badgeCount > 99 ? '99+' : badgeCount} diff --git a/src/renderer/components/remote/ChatDmRncpOfferBanner.test.tsx b/src/renderer/components/remote/ChatDmRncpOfferBanner.test.tsx index a3118cf8d..2cd80bc98 100644 --- a/src/renderer/components/remote/ChatDmRncpOfferBanner.test.tsx +++ b/src/renderer/components/remote/ChatDmRncpOfferBanner.test.tsx @@ -1,7 +1,9 @@ import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { axe } from 'vitest-axe'; +import { hydrateAxeThemeColors } from '@/renderer/lib/a11yTestHelpers'; import { useReticulumIdentityActivityStore } from '@/renderer/stores/reticulumIdentityActivityStore'; import { useRncpTransferStore } from '@/renderer/stores/rncpTransferStore'; @@ -52,11 +54,13 @@ describe('ChatDmRncpOfferBanner', () => { }); const user = userEvent.setup(); - render(); + const { container } = render(); expect(screen.getByText('Incoming file offers')).toBeInTheDocument(); expect(screen.getByText('photo.jpg')).toBeInTheDocument(); expect(screen.queryByText('other.txt')).not.toBeInTheDocument(); + hydrateAxeThemeColors(container); + expect(await axe(container)).toHaveNoViolations(); await user.click(screen.getByRole('button', { name: 'Accept photo.jpg' })); expect(window.electronAPI.reticulum.rncp.accept).toHaveBeenCalledWith({ transfer_id: 't1' }); diff --git a/src/renderer/components/remote/RemoteTransferSection.test.tsx b/src/renderer/components/remote/RemoteTransferSection.test.tsx index 2ba7e731b..7bcaeef37 100644 --- a/src/renderer/components/remote/RemoteTransferSection.test.tsx +++ b/src/renderer/components/remote/RemoteTransferSection.test.tsx @@ -273,6 +273,10 @@ describe('RemoteTransferSection', () => { expect(window.electronAPI.reticulum.rncp.send).not.toHaveBeenCalled(); expect(sendRncpRequestEnable).not.toHaveBeenCalled(); expect(useRncpTransferStore.getState().transfers.get('failed-2')?.retryCount).toBe(0); + expect(addToast).toHaveBeenCalledWith( + 'No path to their file receive destination; file receiving may be off. Send an enable request, then try again.', + 'error', + ); }); it('sends when the receive dest is reachable', async () => { diff --git a/src/renderer/components/remote/RemoteTransferSection.tsx b/src/renderer/components/remote/RemoteTransferSection.tsx index aca29b31a..2e85b9cc0 100644 --- a/src/renderer/components/remote/RemoteTransferSection.tsx +++ b/src/renderer/components/remote/RemoteTransferSection.tsx @@ -106,8 +106,12 @@ export function RemoteTransferSection({ lxmfPeerHash: resolveLxmfPeerHash(destinationHash), }); if (reach.status === 'reachable') return true; - if (reach.status === 'listenerLikelyOff' && opts.promptEnable) { - setEnableRequestConfirmOpen(true); + if (reach.status === 'listenerLikelyOff') { + if (opts.promptEnable) { + setEnableRequestConfirmOpen(true); + } else { + addToast(t('reticulumRemote.transfer.listenerLikelyOffToast'), 'error'); + } return false; } addToast(t('reticulumRemote.transfer.peerUnreachable'), 'error'); diff --git a/src/renderer/locales/cs/translation.json b/src/renderer/locales/cs/translation.json index b91b65396..e13a8fffd 100644 --- a/src/renderer/locales/cs/translation.json +++ b/src/renderer/locales/cs/translation.json @@ -4887,7 +4887,9 @@ "checkingReachability": "Kontrola dosažitelnosti…", "listenerLikelyOffTitle": "Příjem souborů může být vypnutý", "listenerLikelyOffBody": "Žádná cesta k cílovému umístění jejich souboru, ale hledají online chat. Požádejte je, aby povolili příjem souborů (Vzdálené → Nastavení → Nabídky příchozích souborů), a zkuste to znovu.", - "listenerLikelyOffConfirm": "Odeslat požadavek na povolení" + "listenerLikelyOffConfirm": "Odeslat požadavek na povolení", + "pendingOffersBadgeAriaCapped": "99+ čekajících nabídek příchozích souborů", + "listenerLikelyOffToast": "Žádná cesta k cíli příjmu jejich souboru; příjem souborů může být vypnutý. Odešlete žádost o povolení a zkuste to znovu." }, "enableRequest": { "title": "Povolit příjem souborů?", diff --git a/src/renderer/locales/de/translation.json b/src/renderer/locales/de/translation.json index 126dd4d34..5561c862e 100644 --- a/src/renderer/locales/de/translation.json +++ b/src/renderer/locales/de/translation.json @@ -4885,7 +4885,9 @@ "checkingReachability": "Erreichbarkeit prüfen…", "listenerLikelyOffTitle": "Möglicherweise ist der Dateiempfang deaktiviert", "listenerLikelyOffBody": "Kein Pfad zu ihrem Dateiempfangsziel, aber sie suchen online nach Chat. Bitten Sie sie, den Dateiempfang zu aktivieren (Remote → Einstellungen → Angebote für eingehende Dateien) und versuchen Sie es dann erneut.", - "listenerLikelyOffConfirm": "Aktivierungsanfrage senden" + "listenerLikelyOffConfirm": "Aktivierungsanfrage senden", + "pendingOffersBadgeAriaCapped": "Über 99 ausstehende Angebote für eingehende Dateien", + "listenerLikelyOffToast": "Kein Pfad zu ihrem Dateiempfangsziel; Der Dateiempfang ist möglicherweise deaktiviert. Senden Sie eine Aktivierungsanforderung und versuchen Sie es dann erneut." }, "enableRequest": { "title": "Dateiempfang aktivieren?", diff --git a/src/renderer/locales/en/translation.json b/src/renderer/locales/en/translation.json index 344af3718..c28aa9bb9 100644 --- a/src/renderer/locales/en/translation.json +++ b/src/renderer/locales/en/translation.json @@ -4685,6 +4685,7 @@ "pendingOffersTitle": "Pending inbound files", "pendingOffersBadgeAria_one": "{{count}} pending inbound file offer", "pendingOffersBadgeAria_other": "{{count}} pending inbound file offers", + "pendingOffersBadgeAriaCapped": "99+ pending inbound file offers", "offerLabel": "{{file}} ({{bytes}})", "acceptAria": "Accept {{file}}", "accept": "Accept", @@ -4746,6 +4747,7 @@ "listenerLikelyOffTitle": "File receiving may be off", "listenerLikelyOffBody": "No path to their file receive destination, but they look online for chat. Ask them to enable file receiving (Remote → Settings → Inbound file offers), then try again.", "listenerLikelyOffConfirm": "Send enable request", + "listenerLikelyOffToast": "No path to their file receive destination; file receiving may be off. Send an enable request, then try again.", "offerToast": "Incoming file offer: {{file}}", "copyInstructionsAria": "Copy instructions for enabling file receive", "copyInstructions": "Copy instructions", diff --git a/src/renderer/locales/es/translation.json b/src/renderer/locales/es/translation.json index a7f2958f7..4d7399269 100644 --- a/src/renderer/locales/es/translation.json +++ b/src/renderer/locales/es/translation.json @@ -4885,7 +4885,9 @@ "checkingReachability": "Comprobando accesibilidad...", "listenerLikelyOffTitle": "La recepción de archivos puede estar desactivada", "listenerLikelyOffBody": "No hay ruta al destino de recepción de su archivo, pero buscan chat en línea. Pídales que habiliten la recepción de archivos (Remoto → Configuración → Ofertas de archivos entrantes) y luego vuelva a intentarlo.", - "listenerLikelyOffConfirm": "Enviar solicitud de habilitación" + "listenerLikelyOffConfirm": "Enviar solicitud de habilitación", + "pendingOffersBadgeAriaCapped": "Más de 99 ofertas de archivos entrantes pendientes", + "listenerLikelyOffToast": "No hay ruta al destino de recepción de su archivo; La recepción de archivos puede estar desactivada. Envíe una solicitud de habilitación y vuelva a intentarlo." }, "enableRequest": { "title": "¿Habilitar la recepción de archivos?", diff --git a/src/renderer/locales/fr/translation.json b/src/renderer/locales/fr/translation.json index 5354a5413..a49098ebc 100644 --- a/src/renderer/locales/fr/translation.json +++ b/src/renderer/locales/fr/translation.json @@ -4885,7 +4885,9 @@ "checkingReachability": "Vérification de l'accessibilité…", "listenerLikelyOffTitle": "La réception de fichiers est peut-être désactivée", "listenerLikelyOffBody": "Aucun chemin vers la destination de réception de leur fichier, mais ils recherchent en ligne pour discuter. Demandez-leur d'activer la réception de fichiers (À distance → Paramètres → Offres de fichiers entrants), puis réessayez.", - "listenerLikelyOffConfirm": "Envoyer une demande d'activation" + "listenerLikelyOffConfirm": "Envoyer une demande d'activation", + "pendingOffersBadgeAriaCapped": "Plus de 99 offres de fichiers entrants en attente", + "listenerLikelyOffToast": "Aucun chemin vers leur destination de réception de fichier ; la réception du fichier est peut-être désactivée. Envoyez une demande d'activation, puis réessayez." }, "enableRequest": { "title": "Activer la réception de fichiers ?", diff --git a/src/renderer/locales/id/translation.json b/src/renderer/locales/id/translation.json index 66640ee78..6a2d95ef2 100644 --- a/src/renderer/locales/id/translation.json +++ b/src/renderer/locales/id/translation.json @@ -4885,7 +4885,9 @@ "checkingReachability": "Memeriksa jangkauan…", "listenerLikelyOffTitle": "Penerimaan file mungkin tidak aktif", "listenerLikelyOffBody": "Tidak ada jalur ke tujuan penerimaan file mereka, tetapi mereka mencari obrolan online. Minta mereka untuk mengaktifkan penerimaan file (Jarak Jauh → Pengaturan → Penawaran file masuk), lalu coba lagi.", - "listenerLikelyOffConfirm": "Kirim permintaan pengaktifan" + "listenerLikelyOffConfirm": "Kirim permintaan pengaktifan", + "pendingOffersBadgeAriaCapped": "99+ penawaran file masuk yang tertunda", + "listenerLikelyOffToast": "Tidak ada jalur ke tujuan penerimaan file mereka; penerimaan file mungkin tidak aktif. Kirim permintaan pengaktifan, lalu coba lagi." }, "enableRequest": { "title": "Aktifkan penerimaan file?", diff --git a/src/renderer/locales/it/translation.json b/src/renderer/locales/it/translation.json index 80cdecb37..300f683f2 100644 --- a/src/renderer/locales/it/translation.json +++ b/src/renderer/locales/it/translation.json @@ -4885,7 +4885,9 @@ "checkingReachability": "Verifica della raggiungibilità…", "listenerLikelyOffTitle": "La ricezione dei file potrebbe essere disattivata", "listenerLikelyOffBody": "Nessun percorso verso la destinazione di ricezione del file, ma cercano online la chat. Chiedi loro di abilitare la ricezione dei file (Telecomando → Impostazioni → Offerte di file in entrata), quindi riprova.", - "listenerLikelyOffConfirm": "Invia richiesta di abilitazione" + "listenerLikelyOffConfirm": "Invia richiesta di abilitazione", + "pendingOffersBadgeAriaCapped": "Oltre 99 offerte di file in entrata in sospeso", + "listenerLikelyOffToast": "Nessun percorso per la destinazione di ricezione del file; la ricezione dei file potrebbe essere disattivata. Invia una richiesta di abilitazione, quindi riprova." }, "enableRequest": { "title": "Abilitare la ricezione dei file?", diff --git a/src/renderer/locales/ja/translation.json b/src/renderer/locales/ja/translation.json index 7dbf02808..7735d5303 100644 --- a/src/renderer/locales/ja/translation.json +++ b/src/renderer/locales/ja/translation.json @@ -4885,7 +4885,9 @@ "checkingReachability": "到達可能性を確認しています…", "listenerLikelyOffTitle": "ファイル受信がオフになっている可能性があります", "listenerLikelyOffBody": "ファイルの受信先へのパスはありませんが、オンラインでチャットを探しています。ファイル受信を有効にするよう依頼して (リモート → 設定 → 受信ファイル オファー)、もう一度試してください。", - "listenerLikelyOffConfirm": "有効化リクエストを送信する" + "listenerLikelyOffConfirm": "有効化リクエストを送信する", + "pendingOffersBadgeAriaCapped": "99 件以上の保留中の受信ファイル オファー", + "listenerLikelyOffToast": "ファイルの受信先へのパスがありません。ファイル受信がオフになっている可能性があります。有効化リクエストを送信して、再試行してください。" }, "enableRequest": { "title": "ファイル受信を有効にしますか?", diff --git a/src/renderer/locales/ko/translation.json b/src/renderer/locales/ko/translation.json index c16711198..fa5bfb2d8 100644 --- a/src/renderer/locales/ko/translation.json +++ b/src/renderer/locales/ko/translation.json @@ -4885,7 +4885,9 @@ "checkingReachability": "연결 가능성 확인 중…", "listenerLikelyOffTitle": "파일 수신이 꺼져 있을 수 있습니다.", "listenerLikelyOffBody": "파일 수신 대상에 대한 경로가 없지만 온라인에서 채팅을 찾습니다. 파일 수신 활성화(원격 → 설정 → 인바운드 파일 제공)를 요청한 후 다시 시도하세요.", - "listenerLikelyOffConfirm": "활성화 요청 보내기" + "listenerLikelyOffConfirm": "활성화 요청 보내기", + "pendingOffersBadgeAriaCapped": "99개 이상의 대기 중인 인바운드 파일 제안", + "listenerLikelyOffToast": "파일 수신 대상에 대한 경로가 없습니다. 파일 수신이 꺼져 있을 수 있습니다. 활성화 요청을 보낸 후 다시 시도하세요." }, "enableRequest": { "title": "파일 수신을 활성화하시겠습니까?", diff --git a/src/renderer/locales/nl/translation.json b/src/renderer/locales/nl/translation.json index 18f7bc39e..b9baafc03 100644 --- a/src/renderer/locales/nl/translation.json +++ b/src/renderer/locales/nl/translation.json @@ -4885,7 +4885,9 @@ "checkingReachability": "Bereikbaarheid controleren...", "listenerLikelyOffTitle": "Het ontvangen van bestanden is mogelijk uitgeschakeld", "listenerLikelyOffBody": "Er is geen pad naar de bestemming van hun bestand, maar ze zoeken online naar chat. Vraag hen om het ontvangen van bestanden in te schakelen (Op afstand → Instellingen → Inkomende bestandsaanbiedingen) en probeer het vervolgens opnieuw.", - "listenerLikelyOffConfirm": "Inschakelverzoek verzenden" + "listenerLikelyOffConfirm": "Inschakelverzoek verzenden", + "pendingOffersBadgeAriaCapped": "99+ openstaande aanbiedingen voor inkomende bestanden", + "listenerLikelyOffToast": "Geen pad naar hun bestandsontvangstbestemming; Het ontvangen van bestanden is mogelijk uitgeschakeld. Stuur een inschakelverzoek en probeer het opnieuw." }, "enableRequest": { "title": "Bestandsontvangst inschakelen?", diff --git a/src/renderer/locales/pl/translation.json b/src/renderer/locales/pl/translation.json index 13d8ce3b3..9df542330 100644 --- a/src/renderer/locales/pl/translation.json +++ b/src/renderer/locales/pl/translation.json @@ -4889,7 +4889,9 @@ "checkingReachability": "Sprawdzam osiągalność…", "listenerLikelyOffTitle": "Odbieranie plików może być wyłączone", "listenerLikelyOffBody": "Brak ścieżki do miejsca docelowego odbioru pliku, ale szukają czatu w Internecie. Poproś o włączenie odbierania plików (Zdalne → Ustawienia → Oferty plików przychodzących), a następnie spróbuj ponownie.", - "listenerLikelyOffConfirm": "Wyślij prośbę o włączenie" + "listenerLikelyOffConfirm": "Wyślij prośbę o włączenie", + "pendingOffersBadgeAriaCapped": "Ponad 99 oczekujących ofert plików przychodzących", + "listenerLikelyOffToast": "Brak ścieżki do miejsca docelowego odbioru pliku; odbieranie plików może być wyłączone. Wyślij prośbę o włączenie i spróbuj ponownie." }, "enableRequest": { "title": "Włączyć odbiór plików?", diff --git a/src/renderer/locales/pt-BR/translation.json b/src/renderer/locales/pt-BR/translation.json index ebb1870f7..200fdb424 100644 --- a/src/renderer/locales/pt-BR/translation.json +++ b/src/renderer/locales/pt-BR/translation.json @@ -4885,7 +4885,9 @@ "checkingReachability": "Verificando acessibilidade…", "listenerLikelyOffTitle": "O recebimento de arquivos pode estar desativado", "listenerLikelyOffBody": "Nenhum caminho para o destino de recebimento do arquivo, mas eles procuram bate-papo on-line. Peça-lhes para ativar o recebimento de arquivos (Remoto → Configurações → Ofertas de arquivos de entrada) e tente novamente.", - "listenerLikelyOffConfirm": "Enviar solicitação de ativação" + "listenerLikelyOffConfirm": "Enviar solicitação de ativação", + "pendingOffersBadgeAriaCapped": "Mais de 99 ofertas pendentes de arquivos de entrada", + "listenerLikelyOffToast": "Nenhum caminho para o destino de recebimento do arquivo; o recebimento de arquivos pode estar desativado. Envie uma solicitação de ativação e tente novamente." }, "enableRequest": { "title": "Habilitar recebimento de arquivos?", diff --git a/src/renderer/locales/ru/translation.json b/src/renderer/locales/ru/translation.json index f9578c1aa..814b5ad7a 100644 --- a/src/renderer/locales/ru/translation.json +++ b/src/renderer/locales/ru/translation.json @@ -4887,7 +4887,9 @@ "checkingReachability": "Проверка доступности…", "listenerLikelyOffTitle": "Прием файлов может быть отключен", "listenerLikelyOffBody": "Нет пути к месту назначения их файла, но они ищут чат в Интернете. Попросите их включить получение файлов (Удаленное управление → Настройки → Предложения входящих файлов), а затем повторите попытку.", - "listenerLikelyOffConfirm": "Отправить запрос на включение" + "listenerLikelyOffConfirm": "Отправить запрос на включение", + "pendingOffersBadgeAriaCapped": "Более 99 ожидающих предложений по входящим файлам", + "listenerLikelyOffToast": "Нет пути к месту назначения файла; прием файлов может быть отключен. Отправьте запрос на включение и повторите попытку." }, "enableRequest": { "title": "Включить получение файлов?", diff --git a/src/renderer/locales/tr/translation.json b/src/renderer/locales/tr/translation.json index 89b6e06e1..4c324a858 100644 --- a/src/renderer/locales/tr/translation.json +++ b/src/renderer/locales/tr/translation.json @@ -4885,7 +4885,9 @@ "checkingReachability": "Erişilebilirlik kontrol ediliyor…", "listenerLikelyOffTitle": "Dosya alma kapalı olabilir", "listenerLikelyOffBody": "Dosyalarının varış noktasına giden yolu yok, ancak sohbet için çevrimiçi görünüyorlar. Dosya almayı etkinleştirmelerini isteyin (Uzak → Ayarlar → Gelen dosya teklifleri), ardından tekrar deneyin.", - "listenerLikelyOffConfirm": "Etkinleştirme isteği gönder" + "listenerLikelyOffConfirm": "Etkinleştirme isteği gönder", + "pendingOffersBadgeAriaCapped": "99'dan fazla bekleyen gelen dosya teklifi", + "listenerLikelyOffToast": "Dosya alma hedefine giden yol yok; dosya alma kapalı olabilir. Etkinleştirme isteği gönderin ve tekrar deneyin." }, "enableRequest": { "title": "Dosya alımı etkinleştirilsin mi?", diff --git a/src/renderer/locales/uk/translation.json b/src/renderer/locales/uk/translation.json index 55c736d56..9b6f6098a 100644 --- a/src/renderer/locales/uk/translation.json +++ b/src/renderer/locales/uk/translation.json @@ -4887,7 +4887,9 @@ "checkingReachability": "Перевірка доступності…", "listenerLikelyOffTitle": "Отримання файлів може бути вимкнено", "listenerLikelyOffBody": "Немає шляху до пункту призначення файлу, але вони шукають онлайн-чат. Попросіть їх увімкнути отримання файлів (Віддалене → Налаштування → Пропозиції вхідних файлів), а потім повторіть спробу.", - "listenerLikelyOffConfirm": "Надіслати запит на ввімкнення" + "listenerLikelyOffConfirm": "Надіслати запит на ввімкнення", + "pendingOffersBadgeAriaCapped": "99+ пропозицій щодо вхідних файлів, що очікують на розгляд", + "listenerLikelyOffToast": "Немає шляху до місця призначення файлу; отримання файлів може бути вимкнено. Надішліть запит на ввімкнення та повторіть спробу." }, "enableRequest": { "title": "Увімкнути прийом файлів?", diff --git a/src/renderer/locales/zh/translation.json b/src/renderer/locales/zh/translation.json index 4dc9bfee8..b0dfa5e08 100644 --- a/src/renderer/locales/zh/translation.json +++ b/src/renderer/locales/zh/translation.json @@ -4885,7 +4885,9 @@ "checkingReachability": "检查可达性...", "listenerLikelyOffTitle": "文件接收可能已关闭", "listenerLikelyOffBody": "没有通往文件接收目的地的路径,但他们在网上查找聊天内容。要求他们启用文件接收(远程 → 设置 → 入站文件提供),然后重试。", - "listenerLikelyOffConfirm": "发送启用请求" + "listenerLikelyOffConfirm": "发送启用请求", + "pendingOffersBadgeAriaCapped": "超过 99 个待处理的入站文件优惠", + "listenerLikelyOffToast": "没有文件接收目的地的路径;文件接收可能已关闭。发送启用请求,然后重试。" }, "enableRequest": { "title": "启用文件接收?", From 8fa7bb67e1f45c943772251fc102accf60f47edc Mon Sep 17 00:00:00 2001 From: Joey Stanford Date: Fri, 31 Jul 2026 09:26:49 -0600 Subject: [PATCH 2/4] fix(reticulum): make RNCP enable-request copy app-agnostic Drop mesh-client UI paths and the request-enable sentinel from outbound LXMF so Sideband/Nomad peers get a clear human ask for their rncp receive hash. --- .../remote/RemoteTransferSection.test.tsx | 2 +- src/renderer/lib/sendRncpRequestEnable.test.ts | 8 ++++++-- src/renderer/locales/cs/translation.json | 8 ++++---- src/renderer/locales/de/translation.json | 8 ++++---- src/renderer/locales/en/translation.json | 8 ++++---- src/renderer/locales/es/translation.json | 8 ++++---- src/renderer/locales/fr/translation.json | 8 ++++---- src/renderer/locales/id/translation.json | 8 ++++---- src/renderer/locales/it/translation.json | 8 ++++---- src/renderer/locales/ja/translation.json | 8 ++++---- src/renderer/locales/ko/translation.json | 8 ++++---- src/renderer/locales/nl/translation.json | 8 ++++---- src/renderer/locales/pl/translation.json | 8 ++++---- src/renderer/locales/pt-BR/translation.json | 8 ++++---- src/renderer/locales/ru/translation.json | 8 ++++---- src/renderer/locales/tr/translation.json | 8 ++++---- src/renderer/locales/uk/translation.json | 8 ++++---- src/renderer/locales/zh/translation.json | 8 ++++---- src/shared/rncpRequestEnable.test.ts | 9 +++++---- src/shared/rncpRequestEnable.ts | 15 +++++++++------ 20 files changed, 85 insertions(+), 77 deletions(-) diff --git a/src/renderer/components/remote/RemoteTransferSection.test.tsx b/src/renderer/components/remote/RemoteTransferSection.test.tsx index 7bcaeef37..a0ef17439 100644 --- a/src/renderer/components/remote/RemoteTransferSection.test.tsx +++ b/src/renderer/components/remote/RemoteTransferSection.test.tsx @@ -274,7 +274,7 @@ describe('RemoteTransferSection', () => { expect(sendRncpRequestEnable).not.toHaveBeenCalled(); expect(useRncpTransferStore.getState().transfers.get('failed-2')?.retryCount).toBe(0); expect(addToast).toHaveBeenCalledWith( - 'No path to their file receive destination; file receiving may be off. Send an enable request, then try again.', + 'No path to their file receive destination; file receiving may be off. Ask them to enable rncp receive and send their hash, then try again.', 'error', ); }); diff --git a/src/renderer/lib/sendRncpRequestEnable.test.ts b/src/renderer/lib/sendRncpRequestEnable.test.ts index 067efcf1b..a204d3735 100644 --- a/src/renderer/lib/sendRncpRequestEnable.test.ts +++ b/src/renderer/lib/sendRncpRequestEnable.test.ts @@ -26,13 +26,17 @@ describe('sendRncpRequestEnable', () => { expect(window.electronAPI.reticulum.proxyPost).not.toHaveBeenCalled(); }); - it('posts destination_hash and text (sidecar field name) with sentinel', async () => { + it('posts destination_hash and human enable-request text', async () => { const hash = 'ab'.repeat(16); await expect(sendRncpRequestEnable(hash)).resolves.toEqual({ ok: true }); expect(window.electronAPI.reticulum.proxyPost).toHaveBeenCalledWith('/api/v1/lxmf/send', { destination_hash: hash, - text: expect.stringContaining(RNCP_REQUEST_ENABLE_SENTINEL), + text: 'reticulumRemote.enableRequest.lxmfBody', }); + const text = ( + vi.mocked(window.electronAPI.reticulum.proxyPost).mock.calls[0]?.[1] as { text: string } + ).text; + expect(text).not.toContain(RNCP_REQUEST_ENABLE_SENTINEL); }); it('rate-limits a second send to the same peer within the cooldown', async () => { diff --git a/src/renderer/locales/cs/translation.json b/src/renderer/locales/cs/translation.json index e13a8fffd..29671af0c 100644 --- a/src/renderer/locales/cs/translation.json +++ b/src/renderer/locales/cs/translation.json @@ -4886,10 +4886,10 @@ "peerUnreachable": "Žádná cesta k tomuto cíli. Partner může být offline.", "checkingReachability": "Kontrola dosažitelnosti…", "listenerLikelyOffTitle": "Příjem souborů může být vypnutý", - "listenerLikelyOffBody": "Žádná cesta k cílovému umístění jejich souboru, ale hledají online chat. Požádejte je, aby povolili příjem souborů (Vzdálené → Nastavení → Nabídky příchozích souborů), a zkuste to znovu.", "listenerLikelyOffConfirm": "Odeslat požadavek na povolení", "pendingOffersBadgeAriaCapped": "99+ čekajících nabídek příchozích souborů", - "listenerLikelyOffToast": "Žádná cesta k cíli příjmu jejich souboru; příjem souborů může být vypnutý. Odešlete žádost o povolení a zkuste to znovu." + "listenerLikelyOffBody": "Žádná cesta k cílovému umístění jejich souboru, ale hledají online chat. Požádejte je, aby povolili příjem souborů rncp a odeslali svůj hash pro příjem rncp, pak to zkuste znovu.", + "listenerLikelyOffToast": "Žádná cesta k cíli příjmu jejich souboru; příjem souborů může být vypnutý. Požádejte je, aby povolili rncp přijímat a odesílat svůj hash, a zkuste to znovu." }, "enableRequest": { "title": "Povolit příjem souborů?", @@ -4906,9 +4906,9 @@ "enableFailed": "Nelze povolit příjem souboru: {{error}}", "saveDirRequired": "Chcete-li povolit příjem, vyberte složku pro uložení.", "identityUnknown": "Hash identity tohoto peera se zatím nepodařilo zjistit — příchozí dotazování je povoleno, ale peer nebyl přidán na seznam povolených. Zkuste to znovu, až dorazí cesta nebo oznámení.", - "lxmfShareBody": "Příjem souborů je povolen. Zde je můj rncp receive destination (mesh-client jej pro vás uloží).", "shareDestWarning": "Pokud povolíte, mesh-client odešle váš cíl příjmu rncp tomuto partnerovi, aby mohl automaticky vyplnit soubor.", - "lxmfBody": "Povolte příjem rncp (Vzdálené → Nastavení → Nabídky příchozích souborů) a pošlete mi svůj hash pro příjem rncp." + "lxmfBody": "Povolte příjem souboru rncp a odpovězte pomocí cílového hash pro příjem rncp.", + "lxmfShareBody": "Příjem souborů je povolen. Můj rncp přijímá cílový hash:" }, "saved": { "labelPlaceholder": "Označení", diff --git a/src/renderer/locales/de/translation.json b/src/renderer/locales/de/translation.json index 5561c862e..14821e0a4 100644 --- a/src/renderer/locales/de/translation.json +++ b/src/renderer/locales/de/translation.json @@ -4884,10 +4884,10 @@ "peerUnreachable": "Kein Weg zu diesem Ziel. Der Peer ist möglicherweise offline.", "checkingReachability": "Erreichbarkeit prüfen…", "listenerLikelyOffTitle": "Möglicherweise ist der Dateiempfang deaktiviert", - "listenerLikelyOffBody": "Kein Pfad zu ihrem Dateiempfangsziel, aber sie suchen online nach Chat. Bitten Sie sie, den Dateiempfang zu aktivieren (Remote → Einstellungen → Angebote für eingehende Dateien) und versuchen Sie es dann erneut.", "listenerLikelyOffConfirm": "Aktivierungsanfrage senden", "pendingOffersBadgeAriaCapped": "Über 99 ausstehende Angebote für eingehende Dateien", - "listenerLikelyOffToast": "Kein Pfad zu ihrem Dateiempfangsziel; Der Dateiempfang ist möglicherweise deaktiviert. Senden Sie eine Aktivierungsanforderung und versuchen Sie es dann erneut." + "listenerLikelyOffBody": "Kein Pfad zu ihrem Dateiempfangsziel, aber sie suchen online nach Chat. Bitten Sie sie, den Empfang von RNCP-Dateien zu aktivieren und ihren RNCP-Empfangs-Hash zu senden, und versuchen Sie es dann erneut.", + "listenerLikelyOffToast": "Kein Pfad zu ihrem Dateiempfangsziel; Der Dateiempfang ist möglicherweise deaktiviert. Bitten Sie sie, den RNCP-Empfang und das Senden ihres Hashs zu aktivieren, und versuchen Sie es dann erneut." }, "enableRequest": { "title": "Dateiempfang aktivieren?", @@ -4904,9 +4904,9 @@ "enableFailed": "Dateiempfang konnte nicht aktiviert werden: {{error}}", "saveDirRequired": "Wählen Sie einen Speicherordner aus, um den Empfang zu aktivieren.", "identityUnknown": "Der Identitäts-Hash dieses Peers konnte noch nicht aufgelöst werden — eingehendes Nachfragen ist aktiviert, aber der Peer wurde nicht zur Erlaubnisliste hinzugefügt. Versuche es erneut, sobald ein Pfad oder ein Announce eintrifft.", - "lxmfShareBody": "Dateiempfang ist aktiviert. Hier ist mein rncp-Empfangsziel (mesh-client speichert es für Sie).", "shareDestWarning": "Wenn Sie diese Option aktivieren, sendet der Mesh-Client Ihr RNCP-Empfangsziel an diesen Peer, damit dieser den Dateiversand automatisch ausfüllen kann.", - "lxmfBody": "Bitte aktivieren Sie den rncp-Empfang (Remote → Einstellungen → Angebote für eingehende Dateien) und senden Sie mir Ihren rncp-Empfangs-Hash." + "lxmfBody": "Bitte aktivieren Sie den Empfang von RNCP-Dateien und antworten Sie mit Ihrem RNCP-Empfangsziel-Hash.", + "lxmfShareBody": "Der Dateiempfang ist aktiviert. Mein RNCP-Empfangsziel-Hash:" }, "saved": { "labelPlaceholder": "Etikett", diff --git a/src/renderer/locales/en/translation.json b/src/renderer/locales/en/translation.json index c28aa9bb9..1b27708d6 100644 --- a/src/renderer/locales/en/translation.json +++ b/src/renderer/locales/en/translation.json @@ -4745,9 +4745,9 @@ "peerUnreachable": "No path to that destination. The peer may be offline.", "checkingReachability": "Checking reachability…", "listenerLikelyOffTitle": "File receiving may be off", - "listenerLikelyOffBody": "No path to their file receive destination, but they look online for chat. Ask them to enable file receiving (Remote → Settings → Inbound file offers), then try again.", + "listenerLikelyOffBody": "No path to their file receive destination, but they look online for chat. Ask them to enable rncp file receiving and send their rncp receive hash, then try again.", "listenerLikelyOffConfirm": "Send enable request", - "listenerLikelyOffToast": "No path to their file receive destination; file receiving may be off. Send an enable request, then try again.", + "listenerLikelyOffToast": "No path to their file receive destination; file receiving may be off. Ask them to enable rncp receive and send their hash, then try again.", "offerToast": "Incoming file offer: {{file}}", "copyInstructionsAria": "Copy instructions for enabling file receive", "copyInstructions": "Copy instructions", @@ -4771,8 +4771,8 @@ "enableFailed": "Could not enable file receiving: {{error}}", "saveDirRequired": "Choose a save folder to enable receiving.", "identityUnknown": "Could not resolve this peer's identity hash yet — inbound Ask is enabled, but they were not added to the allow list. Try again after a path or announce arrives.", - "lxmfBody": "Please enable rncp receive (Remote → Settings → Inbound file offers) and send me your rncp receive hash.", - "lxmfShareBody": "File receiving is enabled. Here is my rncp receive destination (mesh-client will save it for you)." + "lxmfBody": "Please enable rncp file receiving and reply with your rncp receive destination hash.", + "lxmfShareBody": "File receiving is enabled. My rncp receive destination hash:" }, "saved": { "labelPlaceholder": "Label", diff --git a/src/renderer/locales/es/translation.json b/src/renderer/locales/es/translation.json index 4d7399269..8360d01b5 100644 --- a/src/renderer/locales/es/translation.json +++ b/src/renderer/locales/es/translation.json @@ -4884,10 +4884,10 @@ "peerUnreachable": "No hay camino hacia ese destino. Es posible que el interlocutor esté desconectado.", "checkingReachability": "Comprobando accesibilidad...", "listenerLikelyOffTitle": "La recepción de archivos puede estar desactivada", - "listenerLikelyOffBody": "No hay ruta al destino de recepción de su archivo, pero buscan chat en línea. Pídales que habiliten la recepción de archivos (Remoto → Configuración → Ofertas de archivos entrantes) y luego vuelva a intentarlo.", "listenerLikelyOffConfirm": "Enviar solicitud de habilitación", "pendingOffersBadgeAriaCapped": "Más de 99 ofertas de archivos entrantes pendientes", - "listenerLikelyOffToast": "No hay ruta al destino de recepción de su archivo; La recepción de archivos puede estar desactivada. Envíe una solicitud de habilitación y vuelva a intentarlo." + "listenerLikelyOffBody": "No hay ruta al destino de recepción de su archivo, pero buscan chat en línea. Pídales que habiliten la recepción de archivos rncp y envíen su hash de recepción rncp, luego vuelva a intentarlo.", + "listenerLikelyOffToast": "No hay ruta al destino de recepción de su archivo; La recepción de archivos puede estar desactivada. Pídales que habiliten rncp para recibir y enviar su hash, luego intente nuevamente." }, "enableRequest": { "title": "¿Habilitar la recepción de archivos?", @@ -4904,9 +4904,9 @@ "enableFailed": "No se ha podido habilitar la recepción de archivos: {{error}}", "saveDirRequired": "Elija una carpeta de guardado para habilitar la recepción.", "identityUnknown": "Aún no se pudo resolver el hash de identidad de este par — el modo Preguntar está activado, pero no se añadió a la lista de permitidos. Inténtalo de nuevo cuando llegue una ruta o un anuncio.", - "lxmfShareBody": "La recepción de archivos está habilitada. Aquí está mi destino de recepción rncp (mesh-client lo guardará para usted).", "shareDestWarning": "Si lo habilita, mesh-client enviará su destino de recepción rncp a este par para que pueda completar automáticamente el envío del archivo.", - "lxmfBody": "Habilite la recepción de rncp (Remoto → Configuración → Ofertas de archivos entrantes) y envíeme su hash de recepción de rncp." + "lxmfBody": "Habilite la recepción de archivos rncp y responda con su hash de destino de recepción rncp.", + "lxmfShareBody": "La recepción de archivos está habilitada. Mi rncp recibe el hash de destino:" }, "saved": { "labelPlaceholder": "Designación", diff --git a/src/renderer/locales/fr/translation.json b/src/renderer/locales/fr/translation.json index a49098ebc..d6bd291e0 100644 --- a/src/renderer/locales/fr/translation.json +++ b/src/renderer/locales/fr/translation.json @@ -4884,10 +4884,10 @@ "peerUnreachable": "Aucun chemin vers cette destination. L'homologue est peut-être hors ligne.", "checkingReachability": "Vérification de l'accessibilité…", "listenerLikelyOffTitle": "La réception de fichiers est peut-être désactivée", - "listenerLikelyOffBody": "Aucun chemin vers la destination de réception de leur fichier, mais ils recherchent en ligne pour discuter. Demandez-leur d'activer la réception de fichiers (À distance → Paramètres → Offres de fichiers entrants), puis réessayez.", "listenerLikelyOffConfirm": "Envoyer une demande d'activation", "pendingOffersBadgeAriaCapped": "Plus de 99 offres de fichiers entrants en attente", - "listenerLikelyOffToast": "Aucun chemin vers leur destination de réception de fichier ; la réception du fichier est peut-être désactivée. Envoyez une demande d'activation, puis réessayez." + "listenerLikelyOffBody": "Aucun chemin vers la destination de réception de leur fichier, mais ils recherchent en ligne pour discuter. Demandez-leur d'activer la réception de fichiers rncp et d'envoyer leur hachage de réception rncp, puis réessayez.", + "listenerLikelyOffToast": "Aucun chemin vers leur destination de réception de fichier ; la réception du fichier est peut-être désactivée. Demandez-leur d'activer la réception et l'envoi de leur hachage par RNCP, puis réessayez." }, "enableRequest": { "title": "Activer la réception de fichiers ?", @@ -4904,9 +4904,9 @@ "enableFailed": "Impossible d'activer la réception du fichier : {{error}}", "saveDirRequired": "Choisissez un dossier de sauvegarde pour activer la réception.", "identityUnknown": "Impossible de résoudre le hachage d'identité de ce pair pour le moment — le mode Demander est activé, mais il n'a pas été ajouté à la liste d'autorisation. Réessayez après l'arrivée d'un chemin ou d'une annonce.", - "lxmfShareBody": "La réception de fichiers est activée. Voici ma destination de réception rncp (mesh-client l'enregistrera pour vous).", "shareDestWarning": "Si vous l'activez, mesh-client enverra votre destination de réception rncp à cet homologue afin qu'il puisse remplir automatiquement l'envoi de fichiers.", - "lxmfBody": "Veuillez activer la réception rncp (À distance → Paramètres → Offres de fichiers entrants) et envoyez-moi votre hachage de réception rncp." + "lxmfBody": "Veuillez activer la réception de fichiers RNCP et répondre avec votre hachage de destination de réception RNCP.", + "lxmfShareBody": "La réception de fichiers est activée. Mon rncp reçoit le hachage de destination :" }, "saved": { "labelPlaceholder": "Dénomination", diff --git a/src/renderer/locales/id/translation.json b/src/renderer/locales/id/translation.json index 6a2d95ef2..07517d131 100644 --- a/src/renderer/locales/id/translation.json +++ b/src/renderer/locales/id/translation.json @@ -4884,10 +4884,10 @@ "peerUnreachable": "Tidak ada jalan menuju tujuan itu. Rekan tersebut mungkin sedang offline.", "checkingReachability": "Memeriksa jangkauan…", "listenerLikelyOffTitle": "Penerimaan file mungkin tidak aktif", - "listenerLikelyOffBody": "Tidak ada jalur ke tujuan penerimaan file mereka, tetapi mereka mencari obrolan online. Minta mereka untuk mengaktifkan penerimaan file (Jarak Jauh → Pengaturan → Penawaran file masuk), lalu coba lagi.", "listenerLikelyOffConfirm": "Kirim permintaan pengaktifan", "pendingOffersBadgeAriaCapped": "99+ penawaran file masuk yang tertunda", - "listenerLikelyOffToast": "Tidak ada jalur ke tujuan penerimaan file mereka; penerimaan file mungkin tidak aktif. Kirim permintaan pengaktifan, lalu coba lagi." + "listenerLikelyOffBody": "Tidak ada jalur ke tujuan penerimaan file mereka, tetapi mereka mencari obrolan online. Minta mereka untuk mengaktifkan penerimaan file rncp dan mengirimkan hash penerimaan rncp mereka, lalu coba lagi.", + "listenerLikelyOffToast": "Tidak ada jalur ke tujuan penerimaan file mereka; penerimaan file mungkin tidak aktif. Minta mereka untuk mengaktifkan rncp menerima dan mengirim hash mereka, lalu coba lagi." }, "enableRequest": { "title": "Aktifkan penerimaan file?", @@ -4904,9 +4904,9 @@ "enableFailed": "Tidak dapat mengaktifkan penerimaan file: {{error}}", "saveDirRequired": "Pilih folder penyimpanan untuk mengaktifkan penerimaan.", "identityUnknown": "Hash identitas peer ini belum dapat ditentukan — mode Tanya untuk file masuk sudah aktif, tetapi peer belum ditambahkan ke daftar izin. Coba lagi setelah jalur atau pengumuman diterima.", - "lxmfShareBody": "Penerimaan file diaktifkan. Ini tujuan penerimaan rncp saya (mesh-client akan menyimpannya untuk Anda).", "shareDestWarning": "Jika Anda mengaktifkannya, mesh-client akan mengirimkan tujuan penerimaan rncp Anda ke rekan ini sehingga mereka dapat mengisi otomatis pengiriman file.", - "lxmfBody": "Harap aktifkan penerimaan rncp (Jarak Jauh → Pengaturan → Penawaran file masuk) dan kirimkan saya hash penerimaan rncp Anda." + "lxmfBody": "Harap aktifkan penerimaan file rncp dan balas dengan hash tujuan penerimaan rncp Anda.", + "lxmfShareBody": "Penerimaan file diaktifkan. Rncp saya menerima hash tujuan:" }, "saved": { "labelPlaceholder": "Label", diff --git a/src/renderer/locales/it/translation.json b/src/renderer/locales/it/translation.json index 300f683f2..e91d37e8f 100644 --- a/src/renderer/locales/it/translation.json +++ b/src/renderer/locales/it/translation.json @@ -4884,10 +4884,10 @@ "peerUnreachable": "Nessun percorso per quella destinazione. Il peer potrebbe essere offline.", "checkingReachability": "Verifica della raggiungibilità…", "listenerLikelyOffTitle": "La ricezione dei file potrebbe essere disattivata", - "listenerLikelyOffBody": "Nessun percorso verso la destinazione di ricezione del file, ma cercano online la chat. Chiedi loro di abilitare la ricezione dei file (Telecomando → Impostazioni → Offerte di file in entrata), quindi riprova.", "listenerLikelyOffConfirm": "Invia richiesta di abilitazione", "pendingOffersBadgeAriaCapped": "Oltre 99 offerte di file in entrata in sospeso", - "listenerLikelyOffToast": "Nessun percorso per la destinazione di ricezione del file; la ricezione dei file potrebbe essere disattivata. Invia una richiesta di abilitazione, quindi riprova." + "listenerLikelyOffBody": "Nessun percorso verso la destinazione di ricezione del file, ma cercano online la chat. Chiedi loro di abilitare la ricezione di file rncp e di inviare l'hash di ricezione rncp, quindi riprova.", + "listenerLikelyOffToast": "Nessun percorso per la destinazione di ricezione del file; la ricezione dei file potrebbe essere disattivata. Chiedi loro di abilitare la ricezione rncp e di inviare il loro hash, quindi riprova." }, "enableRequest": { "title": "Abilitare la ricezione dei file?", @@ -4904,9 +4904,9 @@ "enableFailed": "Impossibile abilitare la ricezione dei file: {{error}}", "saveDirRequired": "Scegli una cartella di salvataggio per abilitare la ricezione.", "identityUnknown": "Non è stato ancora possibile risolvere l'hash di identità di questo peer — la modalità Chiedi è attiva, ma il peer non è stato aggiunto alla lista dei consentiti. Riprova dopo l'arrivo di un percorso o di un annuncio.", - "lxmfShareBody": "La ricezione file è abilitata. Ecco la mia destinazione di ricezione rncp (mesh-client la salverà per te).", "shareDestWarning": "Se abiliti, mesh-client invierà la destinazione di ricezione rncp a questo peer in modo che possa compilare automaticamente l'invio del file.", - "lxmfBody": "Abilita la ricezione rncp (Telecomando → Impostazioni → Offerte file in entrata) e inviami il tuo hash di ricezione rncp." + "lxmfBody": "Abilita la ricezione di file rncp e rispondi con l'hash di destinazione di ricezione rncp.", + "lxmfShareBody": "La ricezione dei file è abilitata. Il mio rncp riceve l'hash di destinazione:" }, "saved": { "labelPlaceholder": "Label", diff --git a/src/renderer/locales/ja/translation.json b/src/renderer/locales/ja/translation.json index 7735d5303..ee8e7f475 100644 --- a/src/renderer/locales/ja/translation.json +++ b/src/renderer/locales/ja/translation.json @@ -4884,10 +4884,10 @@ "peerUnreachable": "その目的地への道はありません。ピアがオフラインである可能性があります。", "checkingReachability": "到達可能性を確認しています…", "listenerLikelyOffTitle": "ファイル受信がオフになっている可能性があります", - "listenerLikelyOffBody": "ファイルの受信先へのパスはありませんが、オンラインでチャットを探しています。ファイル受信を有効にするよう依頼して (リモート → 設定 → 受信ファイル オファー)、もう一度試してください。", "listenerLikelyOffConfirm": "有効化リクエストを送信する", "pendingOffersBadgeAriaCapped": "99 件以上の保留中の受信ファイル オファー", - "listenerLikelyOffToast": "ファイルの受信先へのパスがありません。ファイル受信がオフになっている可能性があります。有効化リクエストを送信して、再試行してください。" + "listenerLikelyOffBody": "ファイルの受信先へのパスはありませんが、オンラインでチャットを探しています。 rncp ファイル受信を有効にし、rncp 受信ハッシュを送信してから、再試行するように依頼してください。", + "listenerLikelyOffToast": "ファイルの受信先へのパスがありません。ファイル受信がオフになっている可能性があります。 rncp のハッシュの送受信を有効にするよう依頼してから、再試行してください。" }, "enableRequest": { "title": "ファイル受信を有効にしますか?", @@ -4904,9 +4904,9 @@ "enableFailed": "ファイル受信を有効にできませんでした: {{error}}", "saveDirRequired": "受信を有効にする保存フォルダを選択します。", "identityUnknown": "このピアのIDハッシュをまだ解決できませんでした。受信時の確認は有効になりましたが、許可リストには追加されていません。パスまたはアナウンスの到着後にもう一度お試しください。", - "lxmfShareBody": "ファイル受信が有効です。これが私の rncp 受信先です(mesh-client が保存します)。", "shareDestWarning": "有効にすると、mesh-client は rncp 受信宛先をこのピアに送信し、ファイル送信を自動入力できるようになります。", - "lxmfBody": "rncp 受信を有効にして (リモート → 設定 → インバウンド ファイル オファー)、rncp 受信ハッシュを送信してください。" + "lxmfBody": "rncp ファイル受信を有効にし、rncp 受信宛先ハッシュを返信してください。", + "lxmfShareBody": "ファイル受信が有効になっています。私のrncp受信宛先ハッシュ:" }, "saved": { "labelPlaceholder": "ラベル", diff --git a/src/renderer/locales/ko/translation.json b/src/renderer/locales/ko/translation.json index fa5bfb2d8..1fdc73ecf 100644 --- a/src/renderer/locales/ko/translation.json +++ b/src/renderer/locales/ko/translation.json @@ -4884,10 +4884,10 @@ "peerUnreachable": "해당 목적지까지의 경로가 없습니다. 피어가 오프라인일 수 있습니다.", "checkingReachability": "연결 가능성 확인 중…", "listenerLikelyOffTitle": "파일 수신이 꺼져 있을 수 있습니다.", - "listenerLikelyOffBody": "파일 수신 대상에 대한 경로가 없지만 온라인에서 채팅을 찾습니다. 파일 수신 활성화(원격 → 설정 → 인바운드 파일 제공)를 요청한 후 다시 시도하세요.", "listenerLikelyOffConfirm": "활성화 요청 보내기", "pendingOffersBadgeAriaCapped": "99개 이상의 대기 중인 인바운드 파일 제안", - "listenerLikelyOffToast": "파일 수신 대상에 대한 경로가 없습니다. 파일 수신이 꺼져 있을 수 있습니다. 활성화 요청을 보낸 후 다시 시도하세요." + "listenerLikelyOffBody": "파일 수신 대상에 대한 경로가 없지만 온라인에서 채팅을 찾습니다. rncp 파일 수신을 활성화하고 rncp 수신 해시를 보낸 후 다시 시도하세요.", + "listenerLikelyOffToast": "파일 수신 대상에 대한 경로가 없습니다. 파일 수신이 꺼져 있을 수 있습니다. rncp 수신 및 해시 전송을 활성화하도록 요청한 후 다시 시도하세요." }, "enableRequest": { "title": "파일 수신을 활성화하시겠습니까?", @@ -4904,9 +4904,9 @@ "enableFailed": "파일 수신을 활성화할 수 없습니다: {{error}}", "saveDirRequired": "수신을 활성화하려면 저장 폴더를 선택하세요.", "identityUnknown": "이 피어의 신원 해시를 아직 확인할 수 없습니다 — 수신 확인은 활성화되었지만 허용 목록에는 추가되지 않았습니다. 경로나 알림이 도착한 후 다시 시도하세요.", - "lxmfShareBody": "파일 수신이 활성화되었습니다. 제 rncp 수신 대상입니다(mesh-client가 저장합니다).", "shareDestWarning": "활성화하면 mesh-client는 rncp 수신 대상을 이 피어에 보내 파일 보내기를 자동 채울 수 있습니다.", - "lxmfBody": "rncp 수신을 활성화하고(원격 → 설정 → 인바운드 파일 제공) rncp 수신 해시를 보내주세요." + "lxmfBody": "rncp 파일 수신을 활성화하고 rncp 수신 대상 해시로 응답하세요.", + "lxmfShareBody": "파일 수신이 활성화되었습니다. 내 rncp 수신 대상 해시:" }, "saved": { "labelPlaceholder": "상표", diff --git a/src/renderer/locales/nl/translation.json b/src/renderer/locales/nl/translation.json index b9baafc03..a72d505c7 100644 --- a/src/renderer/locales/nl/translation.json +++ b/src/renderer/locales/nl/translation.json @@ -4884,10 +4884,10 @@ "peerUnreachable": "Geen pad naar die bestemming. De peer is mogelijk offline.", "checkingReachability": "Bereikbaarheid controleren...", "listenerLikelyOffTitle": "Het ontvangen van bestanden is mogelijk uitgeschakeld", - "listenerLikelyOffBody": "Er is geen pad naar de bestemming van hun bestand, maar ze zoeken online naar chat. Vraag hen om het ontvangen van bestanden in te schakelen (Op afstand → Instellingen → Inkomende bestandsaanbiedingen) en probeer het vervolgens opnieuw.", "listenerLikelyOffConfirm": "Inschakelverzoek verzenden", "pendingOffersBadgeAriaCapped": "99+ openstaande aanbiedingen voor inkomende bestanden", - "listenerLikelyOffToast": "Geen pad naar hun bestandsontvangstbestemming; Het ontvangen van bestanden is mogelijk uitgeschakeld. Stuur een inschakelverzoek en probeer het opnieuw." + "listenerLikelyOffBody": "Er is geen pad naar de bestemming van hun bestand, maar ze zoeken online naar chat. Vraag hen om het ontvangen van rncp-bestanden in te schakelen en hun rncp-ontvangst-hash te verzenden, en probeer het vervolgens opnieuw.", + "listenerLikelyOffToast": "Geen pad naar hun bestandsontvangstbestemming; Het ontvangen van bestanden is mogelijk uitgeschakeld. Vraag hen om rncp het ontvangen en verzenden van hun hash in te schakelen en probeer het vervolgens opnieuw." }, "enableRequest": { "title": "Bestandsontvangst inschakelen?", @@ -4904,9 +4904,9 @@ "enableFailed": "Kon het ontvangen van bestanden niet inschakelen: {{error}}", "saveDirRequired": "Kies een opslagmap om ontvangst in te schakelen.", "identityUnknown": "De identiteitshash van deze peer kon nog niet worden bepaald — inkomend vragen is ingeschakeld, maar de peer is niet aan de toestaanlijst toegevoegd. Probeer het opnieuw nadat een pad of aankondiging is ontvangen.", - "lxmfShareBody": "Bestandsontvangst is ingeschakeld. Dit is mijn rncp-ontvangstbestemming (mesh-client bewaart dit voor u).", "shareDestWarning": "Als u dit inschakelt, zal mesh-client uw rncp-ontvangstbestemming naar deze peer sturen, zodat zij het verzenden van bestanden automatisch kunnen aanvullen.", - "lxmfBody": "Schakel rncp-ontvangst in (Op afstand → Instellingen → Inkomende bestandsaanbiedingen) en stuur mij uw rncp-ontvangst-hash." + "lxmfBody": "Schakel het ontvangen van rncp-bestanden in en antwoord met de hash van uw rncp-ontvangstbestemming.", + "lxmfShareBody": "Bestandsontvangst is ingeschakeld. Mijn rncp ontvangt bestemmingshash:" }, "saved": { "labelPlaceholder": "Label", diff --git a/src/renderer/locales/pl/translation.json b/src/renderer/locales/pl/translation.json index 9df542330..51f10ef56 100644 --- a/src/renderer/locales/pl/translation.json +++ b/src/renderer/locales/pl/translation.json @@ -4888,10 +4888,10 @@ "peerUnreachable": "Żadnej drogi do tego celu. Partner może być offline.", "checkingReachability": "Sprawdzam osiągalność…", "listenerLikelyOffTitle": "Odbieranie plików może być wyłączone", - "listenerLikelyOffBody": "Brak ścieżki do miejsca docelowego odbioru pliku, ale szukają czatu w Internecie. Poproś o włączenie odbierania plików (Zdalne → Ustawienia → Oferty plików przychodzących), a następnie spróbuj ponownie.", "listenerLikelyOffConfirm": "Wyślij prośbę o włączenie", "pendingOffersBadgeAriaCapped": "Ponad 99 oczekujących ofert plików przychodzących", - "listenerLikelyOffToast": "Brak ścieżki do miejsca docelowego odbioru pliku; odbieranie plików może być wyłączone. Wyślij prośbę o włączenie i spróbuj ponownie." + "listenerLikelyOffBody": "Brak ścieżki do miejsca docelowego odbioru pliku, ale szukają czatu w Internecie. Poproś ich o włączenie odbierania plików rncp i wysłanie skrótu odbioru rncp, a następnie spróbuj ponownie.", + "listenerLikelyOffToast": "Brak ścieżki do miejsca docelowego odbioru pliku; odbieranie plików może być wyłączone. Poproś ich, aby umożliwili rncp odbieranie i wysyłanie skrótu, a następnie spróbuj ponownie." }, "enableRequest": { "title": "Włączyć odbiór plików?", @@ -4908,9 +4908,9 @@ "enableFailed": "Nie można włączyć odbierania plików: {{error}}", "saveDirRequired": "Wybierz folder zapisu, aby włączyć odbiór.", "identityUnknown": "Nie udało się jeszcze ustalić skrótu tożsamości tego peera — tryb pytania jest włączony, ale nie dodano go do listy dozwolonych. Spróbuj ponownie, gdy nadejdzie ścieżka lub ogłoszenie.", - "lxmfShareBody": "Odbieranie plików jest włączone. Oto moje miejsce docelowe odbioru rncp (mesh-client zapisze je dla Ciebie).", "shareDestWarning": "Jeśli włączysz, mesh-client wyśle miejsce docelowe odbioru rncp do tego partnera, aby mógł automatycznie wypełnić wysyłanie pliku.", - "lxmfBody": "Włącz odbieranie rncp (Zdalne → Ustawienia → Oferty plików przychodzących) i wyślij mi swój skrót odbierania rncp." + "lxmfBody": "Włącz odbieranie pliku rncp i odpowiedz, podając hash miejsca docelowego odbioru rncp.", + "lxmfShareBody": "Odbieranie plików jest włączone. Mój rncp odbiera docelowy skrót:" }, "saved": { "labelPlaceholder": "Oznaczenie", diff --git a/src/renderer/locales/pt-BR/translation.json b/src/renderer/locales/pt-BR/translation.json index 200fdb424..7251507ca 100644 --- a/src/renderer/locales/pt-BR/translation.json +++ b/src/renderer/locales/pt-BR/translation.json @@ -4884,10 +4884,10 @@ "peerUnreachable": "Nenhum caminho para esse destino. O par pode estar offline.", "checkingReachability": "Verificando acessibilidade…", "listenerLikelyOffTitle": "O recebimento de arquivos pode estar desativado", - "listenerLikelyOffBody": "Nenhum caminho para o destino de recebimento do arquivo, mas eles procuram bate-papo on-line. Peça-lhes para ativar o recebimento de arquivos (Remoto → Configurações → Ofertas de arquivos de entrada) e tente novamente.", "listenerLikelyOffConfirm": "Enviar solicitação de ativação", "pendingOffersBadgeAriaCapped": "Mais de 99 ofertas pendentes de arquivos de entrada", - "listenerLikelyOffToast": "Nenhum caminho para o destino de recebimento do arquivo; o recebimento de arquivos pode estar desativado. Envie uma solicitação de ativação e tente novamente." + "listenerLikelyOffBody": "Nenhum caminho para o destino de recebimento do arquivo, mas eles procuram bate-papo on-line. Peça-lhes para ativar o recebimento do arquivo rncp e enviar o hash de recebimento do rncp e, em seguida, tente novamente.", + "listenerLikelyOffToast": "Nenhum caminho para o destino de recebimento do arquivo; o recebimento de arquivos pode estar desativado. Peça-lhes para ativar o recebimento e envio do rncp e tente novamente." }, "enableRequest": { "title": "Habilitar recebimento de arquivos?", @@ -4904,9 +4904,9 @@ "enableFailed": "Não foi possível ativar o recebimento de arquivos: {{error}}", "saveDirRequired": "Escolha uma pasta de salvamento para ativar o recebimento.", "identityUnknown": "Ainda não foi possível resolver o hash de identidade deste par — o modo Perguntar foi ativado, mas ele não foi adicionado à lista de permitidos. Tente novamente quando um caminho ou anúncio chegar.", - "lxmfShareBody": "O recebimento de arquivos está ativado. Aqui está meu destino de recebimento rncp (mesh-client salvará para você).", "shareDestWarning": "Se você ativar, o mesh-client enviará seu destino de recebimento rncp para esse par para que eles possam preencher automaticamente o envio do arquivo.", - "lxmfBody": "Ative o recebimento do rncp (Remoto → Configurações → Ofertas de arquivos de entrada) e envie-me seu hash de recebimento do rncp." + "lxmfBody": "Ative o recebimento do arquivo rncp e responda com seu hash de destino de recebimento do rncp.", + "lxmfShareBody": "O recebimento de arquivos está habilitado. Meu rncp recebe hash de destino:" }, "saved": { "labelPlaceholder": "Etiqueta", diff --git a/src/renderer/locales/ru/translation.json b/src/renderer/locales/ru/translation.json index 814b5ad7a..53c37a419 100644 --- a/src/renderer/locales/ru/translation.json +++ b/src/renderer/locales/ru/translation.json @@ -4886,10 +4886,10 @@ "peerUnreachable": "Нет пути к этому месту назначения. Узел может быть отключен от сети.", "checkingReachability": "Проверка доступности…", "listenerLikelyOffTitle": "Прием файлов может быть отключен", - "listenerLikelyOffBody": "Нет пути к месту назначения их файла, но они ищут чат в Интернете. Попросите их включить получение файлов (Удаленное управление → Настройки → Предложения входящих файлов), а затем повторите попытку.", "listenerLikelyOffConfirm": "Отправить запрос на включение", "pendingOffersBadgeAriaCapped": "Более 99 ожидающих предложений по входящим файлам", - "listenerLikelyOffToast": "Нет пути к месту назначения файла; прием файлов может быть отключен. Отправьте запрос на включение и повторите попытку." + "listenerLikelyOffBody": "Нет пути к месту назначения их файла, но они ищут чат в Интернете. Попросите их включить получение файлов rncp и отправить хэш получения rncp, а затем повторите попытку.", + "listenerLikelyOffToast": "Нет пути к месту назначения файла; прием файлов может быть отключен. Попросите их включить получение и отправку хэша по rncp, а затем повторите попытку." }, "enableRequest": { "title": "Включить получение файлов?", @@ -4906,9 +4906,9 @@ "enableFailed": "Не удалось включить получение файлов: {{error}}", "saveDirRequired": "Выберите папку сохранения, чтобы включить получение.", "identityUnknown": "Пока не удалось определить хеш личности этого пира — режим «Спрашивать» включён, но пир не добавлен в список разрешённых. Повторите попытку после получения пути или анонса.", - "lxmfShareBody": "Приём файлов включён. Вот моё rncp-назначение приёма (mesh-client сохранит его для вас).", "shareDestWarning": "Если вы включите этот параметр, mesh-client отправит пункт назначения получения rncp этому узлу, чтобы он мог автоматически заполнить файл для отправки.", - "lxmfBody": "Пожалуйста, включите получение rncp (Удаленное управление → Настройки → Предложения входящих файлов) и пришлите мне хэш получения rncp." + "lxmfBody": "Пожалуйста, включите получение файлов rncp и ответьте, указав хэш получателя rncp.", + "lxmfShareBody": "Прием файлов включен. Мой rncp получает хеш назначения:" }, "saved": { "labelPlaceholder": "Ярлык", diff --git a/src/renderer/locales/tr/translation.json b/src/renderer/locales/tr/translation.json index 4c324a858..aa9dd1f84 100644 --- a/src/renderer/locales/tr/translation.json +++ b/src/renderer/locales/tr/translation.json @@ -4884,10 +4884,10 @@ "peerUnreachable": "O hedefe giden yol yok. Eş çevrimdışı olabilir.", "checkingReachability": "Erişilebilirlik kontrol ediliyor…", "listenerLikelyOffTitle": "Dosya alma kapalı olabilir", - "listenerLikelyOffBody": "Dosyalarının varış noktasına giden yolu yok, ancak sohbet için çevrimiçi görünüyorlar. Dosya almayı etkinleştirmelerini isteyin (Uzak → Ayarlar → Gelen dosya teklifleri), ardından tekrar deneyin.", "listenerLikelyOffConfirm": "Etkinleştirme isteği gönder", "pendingOffersBadgeAriaCapped": "99'dan fazla bekleyen gelen dosya teklifi", - "listenerLikelyOffToast": "Dosya alma hedefine giden yol yok; dosya alma kapalı olabilir. Etkinleştirme isteği gönderin ve tekrar deneyin." + "listenerLikelyOffBody": "Dosyalarının varış noktasına giden yolu yok, ancak sohbet için çevrimiçi görünüyorlar. Onlardan rncp dosyası almayı etkinleştirmelerini ve rncp alma karmalarını göndermelerini isteyin, ardından tekrar deneyin.", + "listenerLikelyOffToast": "Dosya alma hedefine giden yol yok; dosya alma kapalı olabilir. Onlardan rncp'nin karmalarını almasını ve göndermesini etkinleştirmelerini isteyin, ardından tekrar deneyin." }, "enableRequest": { "title": "Dosya alımı etkinleştirilsin mi?", @@ -4904,9 +4904,9 @@ "enableFailed": "Dosya alımı etkinleştirilemedi: {{error}}", "saveDirRequired": "Alımı etkinleştirmek için bir kaydetme klasörü seçin.", "identityUnknown": "Bu eşin kimlik karması henüz çözülemedi — gelen Sor modu etkinleştirildi ancak eş izin listesine eklenmedi. Bir yol veya duyuru geldikten sonra tekrar deneyin.", - "lxmfShareBody": "Dosya alma etkinleştirildi. İşte rncp alma hedefim (mesh-client sizin için kaydedecek).", "shareDestWarning": "Etkinleştirirseniz mesh-client, dosya gönderimini otomatik olarak doldurabilmeleri için rncp alma hedefinizi bu eşe gönderecektir.", - "lxmfBody": "Lütfen rncp alımını etkinleştirin (Uzak → Ayarlar → Gelen dosya teklifleri) ve bana rncp alma karmanızı gönderin." + "lxmfBody": "Lütfen rncp dosya alımını etkinleştirin ve rncp alma hedefi karmanızla yanıtlayın.", + "lxmfShareBody": "Dosya alma etkinleştirildi. Benim rncp alma hedefi karması:" }, "saved": { "labelPlaceholder": "Etiket", diff --git a/src/renderer/locales/uk/translation.json b/src/renderer/locales/uk/translation.json index 9b6f6098a..3b98ba9db 100644 --- a/src/renderer/locales/uk/translation.json +++ b/src/renderer/locales/uk/translation.json @@ -4886,10 +4886,10 @@ "peerUnreachable": "Немає шляху до цього пункту призначення. Одноранговий пристрій може бути офлайн.", "checkingReachability": "Перевірка доступності…", "listenerLikelyOffTitle": "Отримання файлів може бути вимкнено", - "listenerLikelyOffBody": "Немає шляху до пункту призначення файлу, але вони шукають онлайн-чат. Попросіть їх увімкнути отримання файлів (Віддалене → Налаштування → Пропозиції вхідних файлів), а потім повторіть спробу.", "listenerLikelyOffConfirm": "Надіслати запит на ввімкнення", "pendingOffersBadgeAriaCapped": "99+ пропозицій щодо вхідних файлів, що очікують на розгляд", - "listenerLikelyOffToast": "Немає шляху до місця призначення файлу; отримання файлів може бути вимкнено. Надішліть запит на ввімкнення та повторіть спробу." + "listenerLikelyOffBody": "Немає шляху до пункту призначення файлу, але вони шукають онлайн-чат. Попросіть їх увімкнути отримання файлів rncp і надіслати свій хеш отримання rncp, а потім повторіть спробу.", + "listenerLikelyOffToast": "Немає шляху до місця призначення файлу; отримання файлів може бути вимкнено. Попросіть їх увімкнути rncp отримувати та надсилати свій хеш, а потім повторіть спробу." }, "enableRequest": { "title": "Увімкнути прийом файлів?", @@ -4906,9 +4906,9 @@ "enableFailed": "Не вдалося увімкнути отримання файлу: {{error}}", "saveDirRequired": "Виберіть папку збереження, щоб увімкнути отримання.", "identityUnknown": "Поки не вдалося визначити хеш особи цього піра — режим «Запитувати» увімкнено, але піра не додано до списку дозволених. Спробуйте ще раз після надходження шляху або анонсу.", - "lxmfShareBody": "Прийом файлів увімкнено. Ось мій rncp destination прийому (mesh-client збереже його для вас).", "shareDestWarning": "Якщо ввімкнути, mesh-client надсилатиме ваш адресат отримання rncp цьому вузлу, щоб він міг автоматично заповнювати надсилання файлів.", - "lxmfBody": "Будь ласка, увімкніть отримання rncp (Віддалений → Налаштування → Пропозиції вхідних файлів) і надішліть мені свій хеш отримання rncp." + "lxmfBody": "Будь ласка, увімкніть отримання файлу rncp і надішліть відповідь, вказавши свій хеш призначення rncp.", + "lxmfShareBody": "Отримання файлів увімкнено. Мій rncp отримує хеш призначення:" }, "saved": { "labelPlaceholder": "Мітка", diff --git a/src/renderer/locales/zh/translation.json b/src/renderer/locales/zh/translation.json index b0dfa5e08..0adf5765e 100644 --- a/src/renderer/locales/zh/translation.json +++ b/src/renderer/locales/zh/translation.json @@ -4884,10 +4884,10 @@ "peerUnreachable": "没有通往那个目的地的路。对等方可能离线。", "checkingReachability": "检查可达性...", "listenerLikelyOffTitle": "文件接收可能已关闭", - "listenerLikelyOffBody": "没有通往文件接收目的地的路径,但他们在网上查找聊天内容。要求他们启用文件接收(远程 → 设置 → 入站文件提供),然后重试。", "listenerLikelyOffConfirm": "发送启用请求", "pendingOffersBadgeAriaCapped": "超过 99 个待处理的入站文件优惠", - "listenerLikelyOffToast": "没有文件接收目的地的路径;文件接收可能已关闭。发送启用请求,然后重试。" + "listenerLikelyOffBody": "没有通往文件接收目的地的路径,但他们在网上查找聊天内容。要求他们启用 rncp 文件接收并发送其 rncp 接收哈希,然后重试。", + "listenerLikelyOffToast": "没有文件接收目的地的路径;文件接收可能已关闭。要求他们启用 rncp 接收和发送哈希值,然后重试。" }, "enableRequest": { "title": "启用文件接收?", @@ -4904,9 +4904,9 @@ "enableFailed": "无法启用文件接收: {{error}}", "saveDirRequired": "选择一个保存文件夹以启用接收。", "identityUnknown": "暂时无法解析此对等节点的身份哈希 — 已启用来件询问,但未将其加入允许列表。等路径或公告到达后再试一次。", - "lxmfShareBody": "文件接收已启用。这是我的 rncp 接收目的地(mesh-client 将为您保存)。", "shareDestWarning": "如果启用,mesh-client 会将您的 rncp 接收目标发送到该对等方,以便他们可以自动填充文件发送。", - "lxmfBody": "请启用 rncp 接收(远程 → 设置 → 入站文件提供)并向我发送您的 rncp 接收哈希值。" + "lxmfBody": "请启用 rncp 文件接收并回复您的 rncp 接收目标哈希。", + "lxmfShareBody": "文件接收已启用。我的 rncp 接收目标哈希值:" }, "saved": { "labelPlaceholder": "标号", diff --git a/src/shared/rncpRequestEnable.test.ts b/src/shared/rncpRequestEnable.test.ts index f3dbed0ab..6b5d94a31 100644 --- a/src/shared/rncpRequestEnable.test.ts +++ b/src/shared/rncpRequestEnable.test.ts @@ -10,10 +10,10 @@ import { } from './rncpRequestEnable'; describe('rncpRequestEnable', () => { - it('embeds sentinel after human instructions', () => { + it('returns human instructions only (no mesh-client sentinel)', () => { const body = buildRncpRequestEnableMessageBody('Please enable file receiving.'); - expect(body).toContain('Please enable file receiving.'); - expect(body).toContain(RNCP_REQUEST_ENABLE_SENTINEL); + expect(body).toBe('Please enable file receiving.'); + expect(body).not.toContain(RNCP_REQUEST_ENABLE_SENTINEL); }); it('detects sentinel in inbound body', () => { @@ -22,9 +22,10 @@ describe('rncpRequestEnable', () => { expect(lxmfBodyContainsRncpRequestEnable(null)).toBe(false); }); - it('builds and parses receive-dest share bodies', () => { + it('builds and parses receive-dest share bodies with a plain hash line', () => { const hash = 'ab'.repeat(16); const body = buildRncpReceiveDestShareBody('Here is my rncp receive destination.', hash); + expect(body).toContain(`Here is my rncp receive destination.\n${hash}`); expect(body).toContain(RNCP_RECEIVE_DEST_SHARE_PREFIX + hash); expect(parseRncpReceiveDestShare(body)).toBe(hash); }); diff --git a/src/shared/rncpRequestEnable.ts b/src/shared/rncpRequestEnable.ts index 7797def23..9717135fa 100644 --- a/src/shared/rncpRequestEnable.ts +++ b/src/shared/rncpRequestEnable.ts @@ -1,7 +1,9 @@ /** * LXMF control sentinels for mesh-client rncp receive enable / dest sharing. - * Ordinary LXMF DM bodies always include human-readable instructions; mesh-client - * peers additionally parse these sentinels for UI automation. + * Human-readable LXMF bodies must stay app-agnostic (Sideband, Nomad, etc.). + * mesh-client still recognizes these sentinels when present for UI automation; + * request-enable outbound text is human-only so non-mesh-client peers are not + * shown opaque mesh-client tokens. */ export const RNCP_REQUEST_ENABLE_SENTINEL = 'mesh-client:request-rncp-receive:v1'; @@ -14,19 +16,20 @@ export const RNCP_REQUEST_ENABLE_COOLDOWN_MS = 10 * 60 * 1000; const DEST_HASH_RE = /^[0-9a-f]{32}$/; +/** Human-only enable request body (no mesh-client sentinel). */ export function buildRncpRequestEnableMessageBody(instructions: string): string { - const trimmed = instructions.trim(); - return `${trimmed}\n\n${RNCP_REQUEST_ENABLE_SENTINEL}`; + return instructions.trim(); } export function lxmfBodyContainsRncpRequestEnable(body: string | null | undefined): boolean { if (!body) return false; + // Legacy outbound bodies from older mesh-client builds still include the sentinel. return body.includes(RNCP_REQUEST_ENABLE_SENTINEL); } /** * Build an LXMF body that shares this client's rncp.receive destination with a peer - * who requested enable (human line + machine-readable sentinel). + * who requested enable (plain hash for any LXMF client + mesh-client sentinel). */ export function buildRncpReceiveDestShareBody(instructions: string, receiveHash: string): string { const hash = receiveHash.replace(/[^0-9a-f]/gi, '').toLowerCase(); @@ -34,7 +37,7 @@ export function buildRncpReceiveDestShareBody(instructions: string, receiveHash: throw new Error('invalid_rncp_receive_hash'); } const trimmed = instructions.trim(); - return `${trimmed}\n\n${RNCP_RECEIVE_DEST_SHARE_PREFIX}${hash}`; + return `${trimmed}\n${hash}\n\n${RNCP_RECEIVE_DEST_SHARE_PREFIX}${hash}`; } /** From d9ba2582134484859f4c5c802d23a88e81be733f Mon Sep 17 00:00:00 2001 From: Joey Stanford Date: Fri, 31 Jul 2026 09:29:41 -0600 Subject: [PATCH 3/4] fix(reticulum): keep enable-request sentinel for mesh-client popup Restore the trailing mesh-client sentinel so receivers still open the enable/share modal, while leaving the human LXMF line app-agnostic. --- src/renderer/lib/sendRncpRequestEnable.test.ts | 8 ++------ src/shared/rncpRequestEnable.test.ts | 5 ++--- src/shared/rncpRequestEnable.ts | 15 +++++++++------ 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/renderer/lib/sendRncpRequestEnable.test.ts b/src/renderer/lib/sendRncpRequestEnable.test.ts index a204d3735..68acc7de4 100644 --- a/src/renderer/lib/sendRncpRequestEnable.test.ts +++ b/src/renderer/lib/sendRncpRequestEnable.test.ts @@ -26,17 +26,13 @@ describe('sendRncpRequestEnable', () => { expect(window.electronAPI.reticulum.proxyPost).not.toHaveBeenCalled(); }); - it('posts destination_hash and human enable-request text', async () => { + it('posts destination_hash and text with human body plus sentinel', async () => { const hash = 'ab'.repeat(16); await expect(sendRncpRequestEnable(hash)).resolves.toEqual({ ok: true }); expect(window.electronAPI.reticulum.proxyPost).toHaveBeenCalledWith('/api/v1/lxmf/send', { destination_hash: hash, - text: 'reticulumRemote.enableRequest.lxmfBody', + text: `reticulumRemote.enableRequest.lxmfBody\n\n${RNCP_REQUEST_ENABLE_SENTINEL}`, }); - const text = ( - vi.mocked(window.electronAPI.reticulum.proxyPost).mock.calls[0]?.[1] as { text: string } - ).text; - expect(text).not.toContain(RNCP_REQUEST_ENABLE_SENTINEL); }); it('rate-limits a second send to the same peer within the cooldown', async () => { diff --git a/src/shared/rncpRequestEnable.test.ts b/src/shared/rncpRequestEnable.test.ts index 6b5d94a31..e34528f98 100644 --- a/src/shared/rncpRequestEnable.test.ts +++ b/src/shared/rncpRequestEnable.test.ts @@ -10,10 +10,9 @@ import { } from './rncpRequestEnable'; describe('rncpRequestEnable', () => { - it('returns human instructions only (no mesh-client sentinel)', () => { + it('appends mesh-client sentinel after human instructions for receiver automation', () => { const body = buildRncpRequestEnableMessageBody('Please enable file receiving.'); - expect(body).toBe('Please enable file receiving.'); - expect(body).not.toContain(RNCP_REQUEST_ENABLE_SENTINEL); + expect(body).toBe(`Please enable file receiving.\n\n${RNCP_REQUEST_ENABLE_SENTINEL}`); }); it('detects sentinel in inbound body', () => { diff --git a/src/shared/rncpRequestEnable.ts b/src/shared/rncpRequestEnable.ts index 9717135fa..fc51c1669 100644 --- a/src/shared/rncpRequestEnable.ts +++ b/src/shared/rncpRequestEnable.ts @@ -1,9 +1,8 @@ /** * LXMF control sentinels for mesh-client rncp receive enable / dest sharing. * Human-readable LXMF bodies must stay app-agnostic (Sideband, Nomad, etc.). - * mesh-client still recognizes these sentinels when present for UI automation; - * request-enable outbound text is human-only so non-mesh-client peers are not - * shown opaque mesh-client tokens. + * mesh-client peers additionally parse these sentinels for UI automation + * (enable-request modal + receive-dest autofill). */ export const RNCP_REQUEST_ENABLE_SENTINEL = 'mesh-client:request-rncp-receive:v1'; @@ -16,14 +15,18 @@ export const RNCP_REQUEST_ENABLE_COOLDOWN_MS = 10 * 60 * 1000; const DEST_HASH_RE = /^[0-9a-f]{32}$/; -/** Human-only enable request body (no mesh-client sentinel). */ +/** + * Enable-request LXMF body: app-agnostic human instructions, then the mesh-client + * sentinel so receiving mesh-client builds can open the enable/share modal. + * Other LXMF apps show the sentinel as an extra line they can ignore. + */ export function buildRncpRequestEnableMessageBody(instructions: string): string { - return instructions.trim(); + const trimmed = instructions.trim(); + return `${trimmed}\n\n${RNCP_REQUEST_ENABLE_SENTINEL}`; } export function lxmfBodyContainsRncpRequestEnable(body: string | null | undefined): boolean { if (!body) return false; - // Legacy outbound bodies from older mesh-client builds still include the sentinel. return body.includes(RNCP_REQUEST_ENABLE_SENTINEL); } From 9a2c05e1e2c2eb9f667705492c460fb2d1da33c9 Mon Sep 17 00:00:00 2001 From: Joey Stanford Date: Fri, 31 Jul 2026 09:36:06 -0600 Subject: [PATCH 4/4] fix(reticulum): stop sticky RNCP enable modal and clarify allow-list miss Auto-dismiss repeat enable-requests when already listening, broaden identity resolve before Always allow, and soften the toast when Ask enables without an identity hash yet. --- .../remote/RncpEnableRequestModal.test.tsx | 67 +++++++++++++++++++ .../remote/RncpEnableRequestModal.tsx | 54 ++++++++++----- src/renderer/locales/cs/translation.json | 4 +- src/renderer/locales/de/translation.json | 4 +- src/renderer/locales/en/translation.json | 2 +- src/renderer/locales/es/translation.json | 4 +- src/renderer/locales/fr/translation.json | 4 +- src/renderer/locales/id/translation.json | 4 +- src/renderer/locales/it/translation.json | 4 +- src/renderer/locales/ja/translation.json | 4 +- src/renderer/locales/ko/translation.json | 4 +- src/renderer/locales/nl/translation.json | 4 +- src/renderer/locales/pl/translation.json | 4 +- src/renderer/locales/pt-BR/translation.json | 4 +- src/renderer/locales/ru/translation.json | 4 +- src/renderer/locales/tr/translation.json | 4 +- src/renderer/locales/uk/translation.json | 4 +- src/renderer/locales/zh/translation.json | 4 +- 18 files changed, 137 insertions(+), 46 deletions(-) diff --git a/src/renderer/components/remote/RncpEnableRequestModal.test.tsx b/src/renderer/components/remote/RncpEnableRequestModal.test.tsx index 5a1a73ca5..cc83e1937 100644 --- a/src/renderer/components/remote/RncpEnableRequestModal.test.tsx +++ b/src/renderer/components/remote/RncpEnableRequestModal.test.tsx @@ -14,6 +14,10 @@ vi.mock('@/renderer/components/Toast', () => ({ useToast: () => ({ addToast }), })); +vi.mock('@/renderer/lib/reticulum/reticulumSidecarReads', () => ({ + probeReticulumPeer: vi.fn().mockResolvedValue({ ok: false }), +})); + describe('RncpEnableRequestModal', () => { beforeEach(() => { addToast.mockReset(); @@ -108,4 +112,67 @@ describe('RncpEnableRequestModal', () => { }); expect(useRncpEnableRequestStore.getState().prompts).toHaveLength(0); }); + + it('auto-dismisses a repeat enable-request while already listening', async () => { + vi.mocked(window.electronAPI.reticulum.rncp.getListener).mockResolvedValue({ + enabled: true, + inbound_mode: 'ask', + allowed: [], + blocked: [], + }); + const { rerender } = render(); + await waitFor(() => { + expect(useRncpEnableRequestStore.getState().prompts).toHaveLength(0); + }); + + useRncpEnableRequestStore.getState().enqueue({ + peerHash: 'a'.repeat(32), + peerLabel: 'Alice', + receivedAt: Date.now(), + }); + rerender(); + await waitFor(() => { + expect(useRncpEnableRequestStore.getState().prompts).toHaveLength(0); + }); + expect( + vi.mocked(window.electronAPI.reticulum.proxyPost).mock.calls.length, + ).toBeGreaterThanOrEqual(2); + }); + + it('enables Ask and still shares when Always allow cannot resolve identity', async () => { + vi.mocked(window.electronAPI.reticulum.rncp.getListener) + .mockResolvedValueOnce({ + enabled: false, + inbound_mode: 'off', + allowed: [], + blocked: [], + }) + .mockResolvedValue({ + enabled: true, + inbound_mode: 'ask', + allowed: [], + blocked: [], + }); + const user = userEvent.setup(); + render(); + await user.click( + screen.getByRole('button', { + name: 'Enable inbound file offers and allow this sender', + }), + ); + await waitFor(() => { + expect(addToast).toHaveBeenCalledWith('File receiving is enabled.', 'success'); + }); + expect(addToast).toHaveBeenCalledWith( + expect.stringContaining('identity hash is not known yet'), + 'info', + ); + await waitFor(() => { + expect(window.electronAPI.reticulum.proxyPost).toHaveBeenCalledWith('/api/v1/lxmf/send', { + destination_hash: 'a'.repeat(32), + text: expect.stringContaining(`${RNCP_RECEIVE_DEST_SHARE_PREFIX}${'c'.repeat(32)}`), + }); + }); + expect(useRncpEnableRequestStore.getState().prompts).toHaveLength(0); + }); }); diff --git a/src/renderer/components/remote/RncpEnableRequestModal.tsx b/src/renderer/components/remote/RncpEnableRequestModal.tsx index d110bae6a..49b809776 100644 --- a/src/renderer/components/remote/RncpEnableRequestModal.tsx +++ b/src/renderer/components/remote/RncpEnableRequestModal.tsx @@ -1,12 +1,14 @@ -import { useCallback, useEffect, useRef } from 'react'; +import { useCallback, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useToast } from '@/renderer/components/Toast'; import { errLikeToLogString } from '@/renderer/lib/errLikeToLogString'; import { rememberRncpListenerDirs } from '@/renderer/lib/pushRncpListenerPolicy'; +import { probeReticulumPeer } from '@/renderer/lib/reticulum/reticulumSidecarReads'; import { policiesToRncpLists } from '@/renderer/lib/rncpInboundPolicyLists'; import { useReticulumIdentityActivityStore } from '@/renderer/stores/reticulumIdentityActivityStore'; import { useReticulumInboundPolicyStore } from '@/renderer/stores/reticulumInboundPolicyStore'; +import { useReticulumRemoteAddressStore } from '@/renderer/stores/reticulumRemoteAddressStore'; import { useRncpEnableRequestStore } from '@/renderer/stores/rncpEnableRequestStore'; import { useRncpTransferStore } from '@/renderer/stores/rncpTransferStore'; import { canonicalizeReticulumDestinationHash } from '@/shared/reticulumDestinationHash'; @@ -16,19 +18,40 @@ import { buildRncpReceiveDestShareBody } from '@/shared/rncpRequestEnable'; * Resolve a Reticulum **identity** hash for an LXMF delivery destination hash. * rncp LinkIdentify gates on identity_hash, which is not the LXMF sender dest. */ -async function resolveIdentityHashForLxmfPeer(peerDestHash: string): Promise { +export async function resolveIdentityHashForLxmfPeer(peerDestHash: string): Promise { const dest = canonicalizeReticulumDestinationHash(peerDestHash); if (!dest) return null; + + const fromRows = (rows: { identity_hash?: string | null }[]): string | null => { + for (const row of rows) { + const id = row.identity_hash ? canonicalizeReticulumDestinationHash(row.identity_hash) : null; + if (id) return id; + } + return null; + }; + const store = useReticulumIdentityActivityStore.getState(); let rows = store.getActivity(dest); if (rows.length === 0) { rows = await store.loadForDestination(dest); } - for (const row of rows) { - const id = row.identity_hash ? canonicalizeReticulumDestinationHash(row.identity_hash) : null; + const fromActivity = fromRows(rows); + if (fromActivity) return fromActivity; + + const saved = useReticulumRemoteAddressStore.getState().findByLxmfPeer(dest); + if (saved?.identity_hash) { + const id = canonicalizeReticulumDestinationHash(saved.identity_hash); if (id) return id; } - return null; + + // Path/probe can surface announce identity for peers we have only chatted with. + try { + await probeReticulumPeer(dest); + } catch { + // catch-no-log-ok probe is best-effort before allow-list upsert + } + rows = await store.loadForDestination(dest); + return fromRows(rows); } /** @@ -92,14 +115,12 @@ export function RncpEnableRequestModal() { const setListener = useRncpTransferStore((s) => s.setListener); const current = prompts[0] ?? null; - const autoSharedPeerRef = useRef(null); - // If inbound rncp is already enabled, re-share our receive dest immediately so the - // requester does not stay empty when the peer thinks they are "already enabled". + // Already listening: re-share dest and clear the prompt so repeat enable-requests + // from the same peer do not leave a sticky modal (do not latch a one-shot peer ref). useEffect(() => { if (!current) return; const peerHash = current.peerHash; - if (autoSharedPeerRef.current === peerHash) return; let cancelled = false; void (async () => { try { @@ -107,18 +128,20 @@ export function RncpEnableRequestModal() { if (cancelled) return; setListener(status); if (!status?.enabled) return; - autoSharedPeerRef.current = peerHash; - const shareResult = await shareRncpReceiveDestWithPeer( + await shareRncpReceiveDestWithPeer( peerHash, t('reticulumRemote.enableRequest.lxmfShareBody'), ); - if (!cancelled && shareResult === 'shared') { + if (!cancelled) { dismiss(peerHash, false); } } catch (e) { console.debug( '[RncpEnableRequestModal] already-enabled auto-share ' + errLikeToLogString(e), ); + if (!cancelled) { + dismiss(peerHash, false); + } } })(); return () => { @@ -139,9 +162,7 @@ export function RncpEnableRequestModal() { let identityHash: string | null = null; if (allowIdentity) { identityHash = await resolveIdentityHashForLxmfPeer(current.peerHash); - if (!identityHash) { - addToast(t('reticulumRemote.enableRequest.identityUnknown'), 'info'); - } else { + if (identityHash) { await upsertPolicy({ identity_hash: identityHash, decision: 'allow', @@ -177,6 +198,9 @@ export function RncpEnableRequestModal() { const listener = await window.electronAPI.reticulum.rncp.getListener(); useRncpTransferStore.getState().setListener(listener); addToast(t('reticulumRemote.enableRequest.enabled'), 'success'); + if (allowIdentity && !identityHash) { + addToast(t('reticulumRemote.enableRequest.identityUnknown'), 'info'); + } const peerHash = current.peerHash; dismiss(peerHash, false); // Best-effort: tell the requester our rncp.receive dest so they can autofill. diff --git a/src/renderer/locales/cs/translation.json b/src/renderer/locales/cs/translation.json index 29671af0c..37c03e7b9 100644 --- a/src/renderer/locales/cs/translation.json +++ b/src/renderer/locales/cs/translation.json @@ -4905,10 +4905,10 @@ "enabled": "Příjem souboru je povolen.", "enableFailed": "Nelze povolit příjem souboru: {{error}}", "saveDirRequired": "Chcete-li povolit příjem, vyberte složku pro uložení.", - "identityUnknown": "Hash identity tohoto peera se zatím nepodařilo zjistit — příchozí dotazování je povoleno, ale peer nebyl přidán na seznam povolených. Zkuste to znovu, až dorazí cesta nebo oznámení.", "shareDestWarning": "Pokud povolíte, mesh-client odešle váš cíl příjmu rncp tomuto partnerovi, aby mohl automaticky vyplnit soubor.", "lxmfBody": "Povolte příjem souboru rncp a odpovězte pomocí cílového hash pro příjem rncp.", - "lxmfShareBody": "Příjem souborů je povolen. Můj rncp přijímá cílový hash:" + "lxmfShareBody": "Příjem souborů je povolen. Můj rncp přijímá cílový hash:", + "identityUnknown": "Příchozí dotaz je zapnutý, ale hash identity tohoto partnera zatím není znám, takže nebyl přidán do Vždy povolit. Před každým souborem budete stále dotázáni; zkuste Vždy znovu povolit po příchodu cesty nebo oznámení." }, "saved": { "labelPlaceholder": "Označení", diff --git a/src/renderer/locales/de/translation.json b/src/renderer/locales/de/translation.json index 14821e0a4..eafa1a885 100644 --- a/src/renderer/locales/de/translation.json +++ b/src/renderer/locales/de/translation.json @@ -4903,10 +4903,10 @@ "enabled": "Der Dateiempfang ist aktiviert.", "enableFailed": "Dateiempfang konnte nicht aktiviert werden: {{error}}", "saveDirRequired": "Wählen Sie einen Speicherordner aus, um den Empfang zu aktivieren.", - "identityUnknown": "Der Identitäts-Hash dieses Peers konnte noch nicht aufgelöst werden — eingehendes Nachfragen ist aktiviert, aber der Peer wurde nicht zur Erlaubnisliste hinzugefügt. Versuche es erneut, sobald ein Pfad oder ein Announce eintrifft.", "shareDestWarning": "Wenn Sie diese Option aktivieren, sendet der Mesh-Client Ihr RNCP-Empfangsziel an diesen Peer, damit dieser den Dateiversand automatisch ausfüllen kann.", "lxmfBody": "Bitte aktivieren Sie den Empfang von RNCP-Dateien und antworten Sie mit Ihrem RNCP-Empfangsziel-Hash.", - "lxmfShareBody": "Der Dateiempfang ist aktiviert. Mein RNCP-Empfangsziel-Hash:" + "lxmfShareBody": "Der Dateiempfang ist aktiviert. Mein RNCP-Empfangsziel-Hash:", + "identityUnknown": "„Eingehende Anfragen“ ist aktiviert, aber der Identitäts-Hash dieses Peers ist noch nicht bekannt, sodass er nicht zu „Immer zulassen“ hinzugefügt wurde. Sie werden weiterhin vor jeder Datei gefragt; Versuchen Sie „Immer zulassen“ erneut, nachdem ein Pfad oder eine Ankündigung eintrifft." }, "saved": { "labelPlaceholder": "Etikett", diff --git a/src/renderer/locales/en/translation.json b/src/renderer/locales/en/translation.json index 1b27708d6..24287d448 100644 --- a/src/renderer/locales/en/translation.json +++ b/src/renderer/locales/en/translation.json @@ -4770,7 +4770,7 @@ "enabled": "File receiving is enabled.", "enableFailed": "Could not enable file receiving: {{error}}", "saveDirRequired": "Choose a save folder to enable receiving.", - "identityUnknown": "Could not resolve this peer's identity hash yet — inbound Ask is enabled, but they were not added to the allow list. Try again after a path or announce arrives.", + "identityUnknown": "Inbound Ask is on, but this peer's identity hash is not known yet so they were not added to Always allow. You will still be asked before each file; try Always allow again after a path or announce arrives.", "lxmfBody": "Please enable rncp file receiving and reply with your rncp receive destination hash.", "lxmfShareBody": "File receiving is enabled. My rncp receive destination hash:" }, diff --git a/src/renderer/locales/es/translation.json b/src/renderer/locales/es/translation.json index 8360d01b5..caebb1ea1 100644 --- a/src/renderer/locales/es/translation.json +++ b/src/renderer/locales/es/translation.json @@ -4903,10 +4903,10 @@ "enabled": "La recepción de archivos está habilitada.", "enableFailed": "No se ha podido habilitar la recepción de archivos: {{error}}", "saveDirRequired": "Elija una carpeta de guardado para habilitar la recepción.", - "identityUnknown": "Aún no se pudo resolver el hash de identidad de este par — el modo Preguntar está activado, pero no se añadió a la lista de permitidos. Inténtalo de nuevo cuando llegue una ruta o un anuncio.", "shareDestWarning": "Si lo habilita, mesh-client enviará su destino de recepción rncp a este par para que pueda completar automáticamente el envío del archivo.", "lxmfBody": "Habilite la recepción de archivos rncp y responda con su hash de destino de recepción rncp.", - "lxmfShareBody": "La recepción de archivos está habilitada. Mi rncp recibe el hash de destino:" + "lxmfShareBody": "La recepción de archivos está habilitada. Mi rncp recibe el hash de destino:", + "identityUnknown": "La pregunta entrante está activada, pero aún no se conoce el hash de identidad de este par, por lo que no se agregaron a Permitir siempre. Aún se le preguntará antes de cada archivo; Intente Permitir siempre nuevamente después de que llegue una ruta o un anuncio." }, "saved": { "labelPlaceholder": "Designación", diff --git a/src/renderer/locales/fr/translation.json b/src/renderer/locales/fr/translation.json index d6bd291e0..91cdd051f 100644 --- a/src/renderer/locales/fr/translation.json +++ b/src/renderer/locales/fr/translation.json @@ -4903,10 +4903,10 @@ "enabled": "La réception de fichiers est activée.", "enableFailed": "Impossible d'activer la réception du fichier : {{error}}", "saveDirRequired": "Choisissez un dossier de sauvegarde pour activer la réception.", - "identityUnknown": "Impossible de résoudre le hachage d'identité de ce pair pour le moment — le mode Demander est activé, mais il n'a pas été ajouté à la liste d'autorisation. Réessayez après l'arrivée d'un chemin ou d'une annonce.", "shareDestWarning": "Si vous l'activez, mesh-client enverra votre destination de réception rncp à cet homologue afin qu'il puisse remplir automatiquement l'envoi de fichiers.", "lxmfBody": "Veuillez activer la réception de fichiers RNCP et répondre avec votre hachage de destination de réception RNCP.", - "lxmfShareBody": "La réception de fichiers est activée. Mon rncp reçoit le hachage de destination :" + "lxmfShareBody": "La réception de fichiers est activée. Mon rncp reçoit le hachage de destination :", + "identityUnknown": "La demande entrante est activée, mais le hachage d'identité de cet homologue n'est pas encore connu et n'a donc pas été ajouté à Toujours autoriser. Il vous sera toujours demandé avant chaque dossier ; essayez Toujours autoriser à nouveau après l'arrivée d'un chemin ou d'une annonce." }, "saved": { "labelPlaceholder": "Dénomination", diff --git a/src/renderer/locales/id/translation.json b/src/renderer/locales/id/translation.json index 07517d131..91304c0df 100644 --- a/src/renderer/locales/id/translation.json +++ b/src/renderer/locales/id/translation.json @@ -4903,10 +4903,10 @@ "enabled": "Penerimaan file diaktifkan.", "enableFailed": "Tidak dapat mengaktifkan penerimaan file: {{error}}", "saveDirRequired": "Pilih folder penyimpanan untuk mengaktifkan penerimaan.", - "identityUnknown": "Hash identitas peer ini belum dapat ditentukan — mode Tanya untuk file masuk sudah aktif, tetapi peer belum ditambahkan ke daftar izin. Coba lagi setelah jalur atau pengumuman diterima.", "shareDestWarning": "Jika Anda mengaktifkannya, mesh-client akan mengirimkan tujuan penerimaan rncp Anda ke rekan ini sehingga mereka dapat mengisi otomatis pengiriman file.", "lxmfBody": "Harap aktifkan penerimaan file rncp dan balas dengan hash tujuan penerimaan rncp Anda.", - "lxmfShareBody": "Penerimaan file diaktifkan. Rncp saya menerima hash tujuan:" + "lxmfShareBody": "Penerimaan file diaktifkan. Rncp saya menerima hash tujuan:", + "identityUnknown": "Tanya Masuk aktif, namun hash identitas rekan ini belum diketahui sehingga tidak ditambahkan ke Selalu izinkan. Anda masih akan ditanya sebelum setiap file; coba Selalu izinkan lagi setelah jalur atau pengumuman tiba." }, "saved": { "labelPlaceholder": "Label", diff --git a/src/renderer/locales/it/translation.json b/src/renderer/locales/it/translation.json index e91d37e8f..d24f63d03 100644 --- a/src/renderer/locales/it/translation.json +++ b/src/renderer/locales/it/translation.json @@ -4903,10 +4903,10 @@ "enabled": "La ricezione dei file è abilitata.", "enableFailed": "Impossibile abilitare la ricezione dei file: {{error}}", "saveDirRequired": "Scegli una cartella di salvataggio per abilitare la ricezione.", - "identityUnknown": "Non è stato ancora possibile risolvere l'hash di identità di questo peer — la modalità Chiedi è attiva, ma il peer non è stato aggiunto alla lista dei consentiti. Riprova dopo l'arrivo di un percorso o di un annuncio.", "shareDestWarning": "Se abiliti, mesh-client invierà la destinazione di ricezione rncp a questo peer in modo che possa compilare automaticamente l'invio del file.", "lxmfBody": "Abilita la ricezione di file rncp e rispondi con l'hash di destinazione di ricezione rncp.", - "lxmfShareBody": "La ricezione dei file è abilitata. Il mio rncp riceve l'hash di destinazione:" + "lxmfShareBody": "La ricezione dei file è abilitata. Il mio rncp riceve l'hash di destinazione:", + "identityUnknown": "La richiesta in entrata è attiva, ma l'hash dell'identità di questo peer non è ancora noto, quindi non è stato aggiunto a Consenti sempre. Ti verrà comunque chiesto prima di ogni file; prova Consenti sempre di nuovo dopo l'arrivo di un percorso o di un annuncio." }, "saved": { "labelPlaceholder": "Label", diff --git a/src/renderer/locales/ja/translation.json b/src/renderer/locales/ja/translation.json index ee8e7f475..42aa62cb8 100644 --- a/src/renderer/locales/ja/translation.json +++ b/src/renderer/locales/ja/translation.json @@ -4903,10 +4903,10 @@ "enabled": "ファイル受信が有効になっています。", "enableFailed": "ファイル受信を有効にできませんでした: {{error}}", "saveDirRequired": "受信を有効にする保存フォルダを選択します。", - "identityUnknown": "このピアのIDハッシュをまだ解決できませんでした。受信時の確認は有効になりましたが、許可リストには追加されていません。パスまたはアナウンスの到着後にもう一度お試しください。", "shareDestWarning": "有効にすると、mesh-client は rncp 受信宛先をこのピアに送信し、ファイル送信を自動入力できるようになります。", "lxmfBody": "rncp ファイル受信を有効にし、rncp 受信宛先ハッシュを返信してください。", - "lxmfShareBody": "ファイル受信が有効になっています。私のrncp受信宛先ハッシュ:" + "lxmfShareBody": "ファイル受信が有効になっています。私のrncp受信宛先ハッシュ:", + "identityUnknown": "Inbound Ask はオンですが、このピアの ID ハッシュがまだ不明であるため、常に許可には追加されませんでした。各ファイルの前に引き続き質問されます。 try パスまたはアナウンスが到着した後は、常に再度許可します。" }, "saved": { "labelPlaceholder": "ラベル", diff --git a/src/renderer/locales/ko/translation.json b/src/renderer/locales/ko/translation.json index 1fdc73ecf..95decf1ce 100644 --- a/src/renderer/locales/ko/translation.json +++ b/src/renderer/locales/ko/translation.json @@ -4903,10 +4903,10 @@ "enabled": "파일 수신이 활성화되었습니다.", "enableFailed": "파일 수신을 활성화할 수 없습니다: {{error}}", "saveDirRequired": "수신을 활성화하려면 저장 폴더를 선택하세요.", - "identityUnknown": "이 피어의 신원 해시를 아직 확인할 수 없습니다 — 수신 확인은 활성화되었지만 허용 목록에는 추가되지 않았습니다. 경로나 알림이 도착한 후 다시 시도하세요.", "shareDestWarning": "활성화하면 mesh-client는 rncp 수신 대상을 이 피어에 보내 파일 보내기를 자동 채울 수 있습니다.", "lxmfBody": "rncp 파일 수신을 활성화하고 rncp 수신 대상 해시로 응답하세요.", - "lxmfShareBody": "파일 수신이 활성화되었습니다. 내 rncp 수신 대상 해시:" + "lxmfShareBody": "파일 수신이 활성화되었습니다. 내 rncp 수신 대상 해시:", + "identityUnknown": "인바운드 요청이 켜져 있지만 이 피어의 ID 해시가 아직 알려지지 않았기 때문에 항상 허용에 추가되지 않았습니다. 각 파일 앞에는 여전히 질문이 표시됩니다. 경로나 알림이 도착한 후에는 항상 다시 허용해 보세요." }, "saved": { "labelPlaceholder": "상표", diff --git a/src/renderer/locales/nl/translation.json b/src/renderer/locales/nl/translation.json index a72d505c7..75d9e7b0a 100644 --- a/src/renderer/locales/nl/translation.json +++ b/src/renderer/locales/nl/translation.json @@ -4903,10 +4903,10 @@ "enabled": "Bestandsontvangst is ingeschakeld.", "enableFailed": "Kon het ontvangen van bestanden niet inschakelen: {{error}}", "saveDirRequired": "Kies een opslagmap om ontvangst in te schakelen.", - "identityUnknown": "De identiteitshash van deze peer kon nog niet worden bepaald — inkomend vragen is ingeschakeld, maar de peer is niet aan de toestaanlijst toegevoegd. Probeer het opnieuw nadat een pad of aankondiging is ontvangen.", "shareDestWarning": "Als u dit inschakelt, zal mesh-client uw rncp-ontvangstbestemming naar deze peer sturen, zodat zij het verzenden van bestanden automatisch kunnen aanvullen.", "lxmfBody": "Schakel het ontvangen van rncp-bestanden in en antwoord met de hash van uw rncp-ontvangstbestemming.", - "lxmfShareBody": "Bestandsontvangst is ingeschakeld. Mijn rncp ontvangt bestemmingshash:" + "lxmfShareBody": "Bestandsontvangst is ingeschakeld. Mijn rncp ontvangt bestemmingshash:", + "identityUnknown": "Inkomend vragen is ingeschakeld, maar de identiteitshash van deze peer is nog niet bekend, dus deze is niet toegevoegd aan Altijd toestaan. U wordt nog steeds vóór elk bestand gevraagd; probeer Altijd opnieuw toestaan ​​nadat een pad of aankondiging binnenkomt." }, "saved": { "labelPlaceholder": "Label", diff --git a/src/renderer/locales/pl/translation.json b/src/renderer/locales/pl/translation.json index 51f10ef56..ce1abe4da 100644 --- a/src/renderer/locales/pl/translation.json +++ b/src/renderer/locales/pl/translation.json @@ -4907,10 +4907,10 @@ "enabled": "Odbiór plików jest włączony.", "enableFailed": "Nie można włączyć odbierania plików: {{error}}", "saveDirRequired": "Wybierz folder zapisu, aby włączyć odbiór.", - "identityUnknown": "Nie udało się jeszcze ustalić skrótu tożsamości tego peera — tryb pytania jest włączony, ale nie dodano go do listy dozwolonych. Spróbuj ponownie, gdy nadejdzie ścieżka lub ogłoszenie.", "shareDestWarning": "Jeśli włączysz, mesh-client wyśle miejsce docelowe odbioru rncp do tego partnera, aby mógł automatycznie wypełnić wysyłanie pliku.", "lxmfBody": "Włącz odbieranie pliku rncp i odpowiedz, podając hash miejsca docelowego odbioru rncp.", - "lxmfShareBody": "Odbieranie plików jest włączone. Mój rncp odbiera docelowy skrót:" + "lxmfShareBody": "Odbieranie plików jest włączone. Mój rncp odbiera docelowy skrót:", + "identityUnknown": "Zapytanie przychodzące jest włączone, ale skrót tożsamości tego partnera nie jest jeszcze znany, dlatego nie został on dodany do opcji Zawsze zezwalaj. Nadal będziesz pytany przed każdym plikiem; spróbuj Zawsze zezwalaj ponownie po nadejściu ścieżki lub ogłoszenia." }, "saved": { "labelPlaceholder": "Oznaczenie", diff --git a/src/renderer/locales/pt-BR/translation.json b/src/renderer/locales/pt-BR/translation.json index 7251507ca..536a5f59d 100644 --- a/src/renderer/locales/pt-BR/translation.json +++ b/src/renderer/locales/pt-BR/translation.json @@ -4903,10 +4903,10 @@ "enabled": "O recebimento de arquivos está ativado.", "enableFailed": "Não foi possível ativar o recebimento de arquivos: {{error}}", "saveDirRequired": "Escolha uma pasta de salvamento para ativar o recebimento.", - "identityUnknown": "Ainda não foi possível resolver o hash de identidade deste par — o modo Perguntar foi ativado, mas ele não foi adicionado à lista de permitidos. Tente novamente quando um caminho ou anúncio chegar.", "shareDestWarning": "Se você ativar, o mesh-client enviará seu destino de recebimento rncp para esse par para que eles possam preencher automaticamente o envio do arquivo.", "lxmfBody": "Ative o recebimento do arquivo rncp e responda com seu hash de destino de recebimento do rncp.", - "lxmfShareBody": "O recebimento de arquivos está habilitado. Meu rncp recebe hash de destino:" + "lxmfShareBody": "O recebimento de arquivos está habilitado. Meu rncp recebe hash de destino:", + "identityUnknown": "A solicitação de entrada está ativada, mas o hash de identidade desse peer ainda não é conhecido, portanto, eles não foram adicionados a Sempre permitir. Você ainda será questionado antes de cada arquivo; tente Sempre permitir novamente após a chegada de um caminho ou anúncio." }, "saved": { "labelPlaceholder": "Etiqueta", diff --git a/src/renderer/locales/ru/translation.json b/src/renderer/locales/ru/translation.json index 53c37a419..dcca8baaa 100644 --- a/src/renderer/locales/ru/translation.json +++ b/src/renderer/locales/ru/translation.json @@ -4905,10 +4905,10 @@ "enabled": "Получение файлов включено.", "enableFailed": "Не удалось включить получение файлов: {{error}}", "saveDirRequired": "Выберите папку сохранения, чтобы включить получение.", - "identityUnknown": "Пока не удалось определить хеш личности этого пира — режим «Спрашивать» включён, но пир не добавлен в список разрешённых. Повторите попытку после получения пути или анонса.", "shareDestWarning": "Если вы включите этот параметр, mesh-client отправит пункт назначения получения rncp этому узлу, чтобы он мог автоматически заполнить файл для отправки.", "lxmfBody": "Пожалуйста, включите получение файлов rncp и ответьте, указав хэш получателя rncp.", - "lxmfShareBody": "Прием файлов включен. Мой rncp получает хеш назначения:" + "lxmfShareBody": "Прием файлов включен. Мой rncp получает хеш назначения:", + "identityUnknown": "Входящий запрос включен, но хэш идентификатора этого узла еще не известен, поэтому он не был добавлен в список «Всегда разрешать». Вас по-прежнему будут спрашивать перед каждым файлом; попробуйте Всегда разрешать снова после поступления пути или объявления." }, "saved": { "labelPlaceholder": "Ярлык", diff --git a/src/renderer/locales/tr/translation.json b/src/renderer/locales/tr/translation.json index aa9dd1f84..1edf7fb49 100644 --- a/src/renderer/locales/tr/translation.json +++ b/src/renderer/locales/tr/translation.json @@ -4903,10 +4903,10 @@ "enabled": "Dosya alma etkinleştirildi.", "enableFailed": "Dosya alımı etkinleştirilemedi: {{error}}", "saveDirRequired": "Alımı etkinleştirmek için bir kaydetme klasörü seçin.", - "identityUnknown": "Bu eşin kimlik karması henüz çözülemedi — gelen Sor modu etkinleştirildi ancak eş izin listesine eklenmedi. Bir yol veya duyuru geldikten sonra tekrar deneyin.", "shareDestWarning": "Etkinleştirirseniz mesh-client, dosya gönderimini otomatik olarak doldurabilmeleri için rncp alma hedefinizi bu eşe gönderecektir.", "lxmfBody": "Lütfen rncp dosya alımını etkinleştirin ve rncp alma hedefi karmanızla yanıtlayın.", - "lxmfShareBody": "Dosya alma etkinleştirildi. Benim rncp alma hedefi karması:" + "lxmfShareBody": "Dosya alma etkinleştirildi. Benim rncp alma hedefi karması:", + "identityUnknown": "Gelen Sor açık ancak bu eşin kimlik karması henüz bilinmediğinden Her zaman izin ver'e eklenmedi. Yine de her dosyadan önce size sorulacaktır; Bir yol veya duyuru geldiğinde Her zaman izin ver'i tekrar deneyin." }, "saved": { "labelPlaceholder": "Etiket", diff --git a/src/renderer/locales/uk/translation.json b/src/renderer/locales/uk/translation.json index 3b98ba9db..79a42b9eb 100644 --- a/src/renderer/locales/uk/translation.json +++ b/src/renderer/locales/uk/translation.json @@ -4905,10 +4905,10 @@ "enabled": "Отримання файлів увімкнено.", "enableFailed": "Не вдалося увімкнути отримання файлу: {{error}}", "saveDirRequired": "Виберіть папку збереження, щоб увімкнути отримання.", - "identityUnknown": "Поки не вдалося визначити хеш особи цього піра — режим «Запитувати» увімкнено, але піра не додано до списку дозволених. Спробуйте ще раз після надходження шляху або анонсу.", "shareDestWarning": "Якщо ввімкнути, mesh-client надсилатиме ваш адресат отримання rncp цьому вузлу, щоб він міг автоматично заповнювати надсилання файлів.", "lxmfBody": "Будь ласка, увімкніть отримання файлу rncp і надішліть відповідь, вказавши свій хеш призначення rncp.", - "lxmfShareBody": "Отримання файлів увімкнено. Мій rncp отримує хеш призначення:" + "lxmfShareBody": "Отримання файлів увімкнено. Мій rncp отримує хеш призначення:", + "identityUnknown": "Вхідний запит увімкнено, але хеш-ідентифікатор цього однорангового вузла ще невідомий, тому його не було додано до Завжди дозволяти. Вас все одно запитуватимуть перед кожним файлом; спробуйте Завжди дозволяти знову після надходження шляху або оголошення." }, "saved": { "labelPlaceholder": "Мітка", diff --git a/src/renderer/locales/zh/translation.json b/src/renderer/locales/zh/translation.json index 0adf5765e..7f1e5960c 100644 --- a/src/renderer/locales/zh/translation.json +++ b/src/renderer/locales/zh/translation.json @@ -4903,10 +4903,10 @@ "enabled": "文件接收已启用。", "enableFailed": "无法启用文件接收: {{error}}", "saveDirRequired": "选择一个保存文件夹以启用接收。", - "identityUnknown": "暂时无法解析此对等节点的身份哈希 — 已启用来件询问,但未将其加入允许列表。等路径或公告到达后再试一次。", "shareDestWarning": "如果启用,mesh-client 会将您的 rncp 接收目标发送到该对等方,以便他们可以自动填充文件发送。", "lxmfBody": "请启用 rncp 文件接收并回复您的 rncp 接收目标哈希。", - "lxmfShareBody": "文件接收已启用。我的 rncp 接收目标哈希值:" + "lxmfShareBody": "文件接收已启用。我的 rncp 接收目标哈希值:", + "identityUnknown": "入站询问已打开,但该对等方的身份哈希尚不清楚,因此它们未添加到始终允许中。每个文件之前仍会询问您;尝试在路径或公告到达后再次始终允许。" }, "saved": { "labelPlaceholder": "标号",