feat(mobile): hidden connection log panel for device-only diagnostics

Connection lifecycle events (probes, transport failures, resume decisions)
are mirrored into an in-memory trail that resets on every launch. A long
press on the connect-screen logo or the instances list opens a panel that
renders the trail with one-tap copy, so release builds can report the exact
probe sequence without a tethered debugger. Details reuse the already-masked
log payloads — no tokens or secrets are captured.
This commit is contained in:
Bohdan Triapitsyn
2026-08-13 00:06:51 +03:00
parent 4074986112
commit dc9c5f8e3e
15 changed files with 235 additions and 3 deletions
+5
View File
@@ -76,6 +76,11 @@ export const dict = {
'mobile.instances.status.connectedDirect': 'Verbunden · Lokales Netzwerk',
'mobile.instances.status.connectedRelay': 'Verbunden · Privater Relay',
'mobile.instances.saveEdit': 'Änderungen speichern',
'mobile.connectionDebug.title': 'Verbindungsprotokoll',
'mobile.connectionDebug.copy': 'Kopieren',
'mobile.connectionDebug.copied': 'Kopiert',
'mobile.connectionDebug.close': 'Schließen',
'mobile.connectionDebug.empty': 'Noch keine Verbindungsereignisse.',
'mobile.nav.changes': 'Änderungen',
'mobile.nav.settings': 'Einstellungen',
'mobile.surface.closeAria': 'Schließen',
+5
View File
@@ -88,6 +88,11 @@ export const dict = {
'mobile.instances.status.connectedDirect': 'Connected · Local network',
'mobile.instances.status.connectedRelay': 'Connected · Private relay',
'mobile.instances.saveEdit': 'Save changes',
'mobile.connectionDebug.title': 'Connection log',
'mobile.connectionDebug.copy': 'Copy',
'mobile.connectionDebug.copied': 'Copied',
'mobile.connectionDebug.close': 'Close',
'mobile.connectionDebug.empty': 'No connection events yet.',
'mobile.nav.changes': 'Changes',
'mobile.nav.settings': 'Settings',
'mobile.surface.closeAria': 'Close',
+5
View File
@@ -86,6 +86,11 @@ export const dict: Record<I18nKey, string> = {
"mobile.instances.label.label": "Nombre",
"mobile.instances.label.placeholder": "Nombre para mostrar (opcional)",
"mobile.instances.saveNew": "Guardar instancia",
"mobile.connectionDebug.title": "Registro de conexión",
"mobile.connectionDebug.copy": "Copiar",
"mobile.connectionDebug.copied": "Copiado",
"mobile.connectionDebug.close": "Cerrar",
"mobile.connectionDebug.empty": "Aún no hay eventos de conexión.",
"mobile.instances.status.connectedDirect": "Conectado · Red local",
"mobile.instances.status.connectedRelay": "Conectado · Relay privado",
"mobile.instances.saveEdit": "Guardar cambios",
+5
View File
@@ -2738,6 +2738,11 @@ export const dict = {
'mobile.instances.status.connectedDirect': 'Connecté · Réseau local',
'mobile.instances.status.connectedRelay': 'Connecté · Relais privé',
'mobile.instances.saveEdit': 'Enregistrer les modifications',
'mobile.connectionDebug.title': 'Journal de connexion',
'mobile.connectionDebug.copy': 'Copier',
'mobile.connectionDebug.copied': 'Copié',
'mobile.connectionDebug.close': 'Fermer',
'mobile.connectionDebug.empty': 'Aucun événement de connexion pour le moment.',
'mobile.nav.changes': 'Modifications',
'mobile.nav.settings': 'Paramètres',
'mobile.surface.closeAria': 'Fermer',
+5
View File
@@ -86,6 +86,11 @@ export const dict: Record<I18nKey, string> = {
'mobile.instances.status.connectedDirect': '接続中 · ローカルネットワーク',
'mobile.instances.status.connectedRelay': '接続中 · プライベートリレー',
'mobile.instances.saveEdit': '変更を保存',
'mobile.connectionDebug.title': '接続ログ',
'mobile.connectionDebug.copy': 'コピー',
'mobile.connectionDebug.copied': 'コピーしました',
'mobile.connectionDebug.close': '閉じる',
'mobile.connectionDebug.empty': '接続イベントはまだありません。',
'mobile.instances.cancelEdit': 'キャンセル',
'mobile.instances.edit': '編集',
'mobile.instances.delete': '削除',
+5
View File
@@ -89,6 +89,11 @@ export const dict: Record<I18nKey, string> = {
'mobile.instances.status.connectedDirect': '연결됨 · 로컬 네트워크',
'mobile.instances.status.connectedRelay': '연결됨 · 비공개 릴레이',
'mobile.instances.saveEdit': '변경 사항 저장',
'mobile.connectionDebug.title': '연결 로그',
'mobile.connectionDebug.copy': '복사',
'mobile.connectionDebug.copied': '복사됨',
'mobile.connectionDebug.close': '닫기',
'mobile.connectionDebug.empty': '아직 연결 이벤트가 없습니다.',
'mobile.nav.changes': '변경사항',
'mobile.nav.settings': '설정',
'mobile.surface.closeAria': '닫기',
+5
View File
@@ -90,6 +90,11 @@ export const dict: Record<I18nKey, string> = {
'mobile.instances.status.connectedDirect': 'Połączono · Sieć lokalna',
'mobile.instances.status.connectedRelay': 'Połączono · Prywatny relay',
'mobile.instances.saveEdit': 'Zapisz zmiany',
'mobile.connectionDebug.title': 'Dziennik połączenia',
'mobile.connectionDebug.copy': 'Kopiuj',
'mobile.connectionDebug.copied': 'Skopiowano',
'mobile.connectionDebug.close': 'Zamknij',
'mobile.connectionDebug.empty': 'Brak zdarzeń połączenia.',
'mobile.nav.changes': 'Zmiany',
'mobile.nav.settings': 'Ustawienia',
'mobile.surface.closeAria': 'Zamknij',
@@ -86,6 +86,11 @@ export const dict: Record<I18nKey, string> = {
"mobile.instances.label.label": "Nome",
"mobile.instances.label.placeholder": "Nome de exibição opcional",
"mobile.instances.saveNew": "Salvar instância",
"mobile.connectionDebug.title": "Registro de conexão",
"mobile.connectionDebug.copy": "Copiar",
"mobile.connectionDebug.copied": "Copiado",
"mobile.connectionDebug.close": "Fechar",
"mobile.connectionDebug.empty": "Ainda não há eventos de conexão.",
"mobile.instances.status.connectedDirect": "Conectado · Rede local",
"mobile.instances.status.connectedRelay": "Conectado · Relay privado",
"mobile.instances.saveEdit": "Salvar alterações",
+5
View File
@@ -86,6 +86,11 @@ export const dict: Record<I18nKey, string> = {
"mobile.instances.label.label": "Назва",
"mobile.instances.label.placeholder": "Необовʼязкова назва",
"mobile.instances.saveNew": "Зберегти інстанс",
"mobile.connectionDebug.title": "Журнал з'єднання",
"mobile.connectionDebug.copy": "Копіювати",
"mobile.connectionDebug.copied": "Скопійовано",
"mobile.connectionDebug.close": "Закрити",
"mobile.connectionDebug.empty": "Поки немає подій з'єднання.",
"mobile.instances.status.connectedDirect": "Підключено · Локальна мережа",
"mobile.instances.status.connectedRelay": "Підключено · Приватний relay",
"mobile.instances.saveEdit": "Зберегти зміни",
@@ -89,6 +89,11 @@ export const dict: Record<I18nKey, string> = {
'mobile.instances.status.connectedDirect': '已连接 · 局域网',
'mobile.instances.status.connectedRelay': '已连接 · 私有中继',
'mobile.instances.saveEdit': '保存更改',
'mobile.connectionDebug.title': '连接日志',
'mobile.connectionDebug.copy': '复制',
'mobile.connectionDebug.copied': '已复制',
'mobile.connectionDebug.close': '关闭',
'mobile.connectionDebug.empty': '暂无连接事件。',
'mobile.nav.changes': '更改',
'mobile.nav.settings': '设置',
'mobile.surface.closeAria': '关闭',
@@ -89,6 +89,11 @@ export const dict: Record<I18nKey, string> = {
'mobile.instances.status.connectedDirect': '已連線 · 區域網路',
'mobile.instances.status.connectedRelay': '已連線 · 私人中繼',
'mobile.instances.saveEdit': '儲存變更',
'mobile.connectionDebug.title': '連線日誌',
'mobile.connectionDebug.copy': '複製',
'mobile.connectionDebug.copied': '已複製',
'mobile.connectionDebug.close': '關閉',
'mobile.connectionDebug.empty': '尚無連線事件。',
'mobile.nav.changes': '變更',
'mobile.nav.settings': '設定',
'mobile.surface.closeAria': '關閉',