diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index de39d7e4..6f22c5e2 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -959,7 +959,12 @@ class MeshCoreConnector extends ChangeNotifier { if (!isConnected) return; if (_batteryRequested && !force) return; _batteryRequested = true; - await sendFrame(buildGetBattAndStorageFrame()); + try { + await sendFrame(buildGetBattAndStorageFrame()); + } catch (e) { + // Connection likely lost - trigger disconnection handling + _handleDisconnection(); + } } void _startBatteryPolling() { diff --git a/lib/connector/meshcore_protocol.dart b/lib/connector/meshcore_protocol.dart index f9241e88..470b795d 100644 --- a/lib/connector/meshcore_protocol.dart +++ b/lib/connector/meshcore_protocol.dart @@ -18,6 +18,10 @@ class BufferReader { return data; } + void skipBytes(int count) { + _pointer += count; + } + Uint8List readRemainingBytes() => readBytes(remaining); String readString() => @@ -127,6 +131,7 @@ const int cmdSendStatusReq = 27; const int cmdGetContactByKey = 30; const int cmdGetChannel = 31; const int cmdSetChannel = 32; +const int cmdSendTracePath = 36; const int cmdGetRadioSettings = 57; const int cmdGetTelemetryReq = 39; const int cmdGetCustomVar = 40; @@ -176,6 +181,7 @@ const int pushCodeLoginSuccess = 0x85; const int pushCodeLoginFail = 0x86; const int pushCodeStatusResponse = 0x87; const int pushCodeLogRxData = 0x88; +const int pushCodeTraceData = 0x89; const int pushCodeNewAdvert = 0x8A; const int pushCodeTelemetryResponse = 0x8B; const int pushCodeBinaryResponse = 0x8C; @@ -708,3 +714,18 @@ Uint8List buildSendBinaryReq(Uint8List repeaterPubKey, {Uint8List? payload}) { } return writer.toBytes(); } + +//Build a trace request frame +//[cmd][tag x4][auth x4][flag][payload] +Uint8List buildTraceReq(int tag, int auth, int flag, {Uint8List? payload}) +{ + final writer = BufferWriter(); + writer.writeByte(cmdSendTracePath); + writer.writeUInt32LE(tag); + writer.writeUInt32LE(auth); + writer.writeByte(flag); + if (payload != null && payload.isNotEmpty) { + writer.writeBytes(payload); + } + return writer.toBytes(); +} \ No newline at end of file diff --git a/lib/l10n/app_bg.arb b/lib/l10n/app_bg.arb index e5f40f38..958d9633 100644 --- a/lib/l10n/app_bg.arb +++ b/lib/l10n/app_bg.arb @@ -1533,5 +1533,24 @@ "community_regenerate": "Регенерация", "community_updateSecret": "Актуализирай тайна", "community_scanToUpdateSecret": "Сканьорвайте новия QR код, за да актуализирате секрета за \"{name}\"", - "community_secretUpdated": "Секретно обновено за \"{name}\"" + "community_secretUpdated": "Секретно обновено за \"{name}\"", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_you": "Вие", + "pathTrace_notAvailable": "Пътека за проследяване не е достъпна.", + "contacts_pathTrace": "Пътен проследяване", + "pathTrace_refreshTooltip": "Обнови Path Trace.", + "pathTrace_failed": "Пътят за проследяване не успя.", + "contacts_repeaterPing": "Пингване на повторителя", + "contacts_repeaterPathTrace": "Трасировка до повторител", + "contacts_ping": "Пинг", + "contacts_chatTraceRoute": "Трасиране на път", + "contacts_roomPathTrace": "Трасиране на път до съ", + "contacts_roomPing": "Ping на сървъра на стаята", + "contacts_pathTraceTo": "Проследи маршрут към {name}" } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 3aba6e50..2586877c 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -1533,5 +1533,24 @@ "community_regenerateSecret": "Neugenerierung des Schlüssels", "community_secretUpdated": "Schlüssel für \"{name}\" aktualisiert", "community_scanToUpdateSecret": "Scannen Sie den neuen QR-Code, um das Geheimnis für \"{name}\" zu aktualisieren.", - "community_updateSecret": "Aktualisieren Sie den Schlüssel" + "community_updateSecret": "Aktualisieren Sie den Schlüssel", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_refreshTooltip": "Path Trace aktualisieren.", + "pathTrace_you": "Du", + "pathTrace_failed": "Pfadverfolgung fehlgeschlagen.", + "pathTrace_notAvailable": "Pfadverfolgung nicht verfügbar.", + "contacts_pathTrace": "Pfadverfolgung", + "contacts_ping": "Pingen", + "contacts_repeaterPathTrace": "Pfadverfolgung zum Repeater", + "contacts_repeaterPing": "Repeater pingen", + "contacts_roomPathTrace": "Pfadverfolgung zum Raumserver", + "contacts_roomPing": "Raumserver anpingen", + "contacts_pathTraceTo": "Route nach {name} verfolgen", + "contacts_chatTraceRoute": "Pfadverfolgungsroute" } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 56cb1cc1..d191370a 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1308,5 +1308,24 @@ "listFilter_repeaters": "Repeaters", "listFilter_roomServers": "Room servers", "listFilter_unreadOnly": "Unread only", - "listFilter_newGroup": "New group" + "listFilter_newGroup": "New group", + + "pathTrace_you": "You", + "pathTrace_failed": "Path trace failed.", + "pathTrace_notAvailable": "Path trace not available.", + "pathTrace_refreshTooltip": "Refresh Path Trace.", + "contacts_pathTrace": "Path Trace", + "contacts_ping": "Ping", + "contacts_repeaterPathTrace": "Path trace to repeater", + "contacts_repeaterPing": "Ping repeater", + "contacts_roomPathTrace": "Path trace to room server", + "contacts_roomPing": "Ping room server", + "contacts_chatTraceRoute": "Path trace route", + "contacts_pathTraceTo": "Trace route to {name}", + "@contacts_pathTraceTo": { + "placeholders": { + "name": {"type": "String"} + } + } + } diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 4b6b5262..1cdfb7bc 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -1533,5 +1533,24 @@ "community_regenerate": "Regenerar", "community_secretUpdated": "Confidencialidad actualizada para \"{name}\"", "community_scanToUpdateSecret": "Escanear el nuevo código QR para actualizar el secreto de \"{name}\"", - "community_updateSecret": "Actualizar Contraseña" + "community_updateSecret": "Actualizar Contraseña", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_you": "Tú", + "pathTrace_failed": "El trazado de ruta falló.", + "pathTrace_refreshTooltip": "Actualizar Path Trace", + "contacts_pathTrace": "Rastreo de caminos", + "contacts_repeaterPathTrace": "Rastrear ruta al repetidor", + "contacts_repeaterPing": "Pingar repetidor", + "contacts_ping": "Ping", + "pathTrace_notAvailable": "El trazado de ruta no está disponible.", + "contacts_roomPing": "Pingar servidor de sala", + "contacts_roomPathTrace": "Rastreo de ruta al servidor de la habitación", + "contacts_pathTraceTo": "Rastrear ruta a {name}", + "contacts_chatTraceRoute": "Ruta de trazado" } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 1b695405..88c65d61 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -1533,5 +1533,24 @@ "community_secretRegenerated": "Mot de passe secret régénéré pour \"{name}\"", "community_scanToUpdateSecret": "Scanner le nouveau code QR pour mettre à jour le mot de passe pour \"{name}\"", "community_updateSecret": "Mettre à jour le secret", - "community_secretUpdated": "Modification secrète mise à jour pour \"{name}\"" + "community_secretUpdated": "Modification secrète mise à jour pour \"{name}\"", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_you": "Vous", + "pathTrace_refreshTooltip": "Actualiser Path Trace", + "pathTrace_failed": "Traçage du chemin échoué.", + "pathTrace_notAvailable": "Tracé de chemin non disponible.", + "contacts_pathTrace": "Traçage de chemin", + "contacts_repeaterPathTrace": "Tracer le chemin vers le répéteur", + "contacts_repeaterPing": "Pinguer le répéteur", + "contacts_roomPathTrace": "Traçage du chemin vers le serveur de la salle", + "contacts_chatTraceRoute": "Tracer le chemin", + "contacts_pathTraceTo": "Tracer l'itinéraire vers {name}", + "contacts_ping": "Ping", + "contacts_roomPing": "Pinguer le serveur de la salle" } diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index cd031fbf..acd440b8 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -1533,5 +1533,24 @@ "community_secretRegenerated": "Codice segreto rigenerato per \"{name}\"", "community_updateSecret": "Aggiorna Segreto", "community_secretUpdated": "Segreto aggiornato per \"{name}\"", - "community_scanToUpdateSecret": "Scansiona il nuovo codice QR per aggiornare il segreto di \"{name}\"" + "community_scanToUpdateSecret": "Scansiona il nuovo codice QR per aggiornare il segreto di \"{name}\"", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_failed": "Tracciamento del percorso fallito.", + "pathTrace_you": "Tu", + "pathTrace_notAvailable": "Tracciamento del percorso non disponibile.", + "pathTrace_refreshTooltip": "Aggiorna Path Trace.", + "contacts_ping": "Ping", + "contacts_repeaterPathTrace": "Traccia percorso al ripetitore", + "contacts_roomPathTrace": "Traccia del percorso al server della stanza", + "contacts_pathTrace": "Traccia Percorso", + "contacts_repeaterPing": "Ripetitore ping", + "contacts_pathTraceTo": "Traccia percorso verso {name}", + "contacts_roomPing": "Ping al server della stanza", + "contacts_chatTraceRoute": "Traccia percorso path" } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index d40c7918..ec047bdd 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -4687,6 +4687,78 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'New group'** String get listFilter_newGroup; + + /// No description provided for @pathTrace_you. + /// + /// In en, this message translates to: + /// **'You'** + String get pathTrace_you; + + /// No description provided for @pathTrace_failed. + /// + /// In en, this message translates to: + /// **'Path trace failed.'** + String get pathTrace_failed; + + /// No description provided for @pathTrace_notAvailable. + /// + /// In en, this message translates to: + /// **'Path trace not available.'** + String get pathTrace_notAvailable; + + /// No description provided for @pathTrace_refreshTooltip. + /// + /// In en, this message translates to: + /// **'Refresh Path Trace.'** + String get pathTrace_refreshTooltip; + + /// No description provided for @contacts_pathTrace. + /// + /// In en, this message translates to: + /// **'Path Trace'** + String get contacts_pathTrace; + + /// No description provided for @contacts_ping. + /// + /// In en, this message translates to: + /// **'Ping'** + String get contacts_ping; + + /// No description provided for @contacts_repeaterPathTrace. + /// + /// In en, this message translates to: + /// **'Path trace to repeater'** + String get contacts_repeaterPathTrace; + + /// No description provided for @contacts_repeaterPing. + /// + /// In en, this message translates to: + /// **'Ping repeater'** + String get contacts_repeaterPing; + + /// No description provided for @contacts_roomPathTrace. + /// + /// In en, this message translates to: + /// **'Path trace to room server'** + String get contacts_roomPathTrace; + + /// No description provided for @contacts_roomPing. + /// + /// In en, this message translates to: + /// **'Ping room server'** + String get contacts_roomPing; + + /// No description provided for @contacts_chatTraceRoute. + /// + /// In en, this message translates to: + /// **'Path trace route'** + String get contacts_chatTraceRoute; + + /// No description provided for @contacts_pathTraceTo. + /// + /// In en, this message translates to: + /// **'Trace route to {name}'** + String contacts_pathTraceTo(String name); } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_bg.dart b/lib/l10n/app_localizations_bg.dart index 9b70d9c4..520b00d4 100644 --- a/lib/l10n/app_localizations_bg.dart +++ b/lib/l10n/app_localizations_bg.dart @@ -2676,4 +2676,42 @@ class AppLocalizationsBg extends AppLocalizations { @override String get listFilter_newGroup => 'Нова група'; + + @override + String get pathTrace_you => 'Вие'; + + @override + String get pathTrace_failed => 'Пътят за проследяване не успя.'; + + @override + String get pathTrace_notAvailable => 'Пътека за проследяване не е достъпна.'; + + @override + String get pathTrace_refreshTooltip => 'Обнови Path Trace.'; + + @override + String get contacts_pathTrace => 'Пътен проследяване'; + + @override + String get contacts_ping => 'Пинг'; + + @override + String get contacts_repeaterPathTrace => 'Трасировка до повторител'; + + @override + String get contacts_repeaterPing => 'Пингване на повторителя'; + + @override + String get contacts_roomPathTrace => 'Трасиране на път до съ'; + + @override + String get contacts_roomPing => 'Ping на сървъра на стаята'; + + @override + String get contacts_chatTraceRoute => 'Трасиране на път'; + + @override + String contacts_pathTraceTo(String name) { + return 'Проследи маршрут към $name'; + } } diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 53bec5e5..905792f8 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -2680,4 +2680,42 @@ class AppLocalizationsDe extends AppLocalizations { @override String get listFilter_newGroup => 'Neue Gruppe'; + + @override + String get pathTrace_you => 'Du'; + + @override + String get pathTrace_failed => 'Pfadverfolgung fehlgeschlagen.'; + + @override + String get pathTrace_notAvailable => 'Pfadverfolgung nicht verfügbar.'; + + @override + String get pathTrace_refreshTooltip => 'Path Trace aktualisieren.'; + + @override + String get contacts_pathTrace => 'Pfadverfolgung'; + + @override + String get contacts_ping => 'Pingen'; + + @override + String get contacts_repeaterPathTrace => 'Pfadverfolgung zum Repeater'; + + @override + String get contacts_repeaterPing => 'Repeater pingen'; + + @override + String get contacts_roomPathTrace => 'Pfadverfolgung zum Raumserver'; + + @override + String get contacts_roomPing => 'Raumserver anpingen'; + + @override + String get contacts_chatTraceRoute => 'Pfadverfolgungsroute'; + + @override + String contacts_pathTraceTo(String name) { + return 'Route nach $name verfolgen'; + } } diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 86f18ba2..9a1634ff 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -2636,4 +2636,42 @@ class AppLocalizationsEn extends AppLocalizations { @override String get listFilter_newGroup => 'New group'; + + @override + String get pathTrace_you => 'You'; + + @override + String get pathTrace_failed => 'Path trace failed.'; + + @override + String get pathTrace_notAvailable => 'Path trace not available.'; + + @override + String get pathTrace_refreshTooltip => 'Refresh Path Trace.'; + + @override + String get contacts_pathTrace => 'Path Trace'; + + @override + String get contacts_ping => 'Ping'; + + @override + String get contacts_repeaterPathTrace => 'Path trace to repeater'; + + @override + String get contacts_repeaterPing => 'Ping repeater'; + + @override + String get contacts_roomPathTrace => 'Path trace to room server'; + + @override + String get contacts_roomPing => 'Ping room server'; + + @override + String get contacts_chatTraceRoute => 'Path trace route'; + + @override + String contacts_pathTraceTo(String name) { + return 'Trace route to $name'; + } } diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index 908c88c8..7f2f4898 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -2675,4 +2675,43 @@ class AppLocalizationsEs extends AppLocalizations { @override String get listFilter_newGroup => 'Nuevo grupo'; + + @override + String get pathTrace_you => 'Tú'; + + @override + String get pathTrace_failed => 'El trazado de ruta falló.'; + + @override + String get pathTrace_notAvailable => 'El trazado de ruta no está disponible.'; + + @override + String get pathTrace_refreshTooltip => 'Actualizar Path Trace'; + + @override + String get contacts_pathTrace => 'Rastreo de caminos'; + + @override + String get contacts_ping => 'Ping'; + + @override + String get contacts_repeaterPathTrace => 'Rastrear ruta al repetidor'; + + @override + String get contacts_repeaterPing => 'Pingar repetidor'; + + @override + String get contacts_roomPathTrace => + 'Rastreo de ruta al servidor de la habitación'; + + @override + String get contacts_roomPing => 'Pingar servidor de sala'; + + @override + String get contacts_chatTraceRoute => 'Ruta de trazado'; + + @override + String contacts_pathTraceTo(String name) { + return 'Rastrear ruta a $name'; + } } diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 07ec4c89..fbc797f3 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -2692,4 +2692,43 @@ class AppLocalizationsFr extends AppLocalizations { @override String get listFilter_newGroup => 'Nouveau groupe'; + + @override + String get pathTrace_you => 'Vous'; + + @override + String get pathTrace_failed => 'Traçage du chemin échoué.'; + + @override + String get pathTrace_notAvailable => 'Tracé de chemin non disponible.'; + + @override + String get pathTrace_refreshTooltip => 'Actualiser Path Trace'; + + @override + String get contacts_pathTrace => 'Traçage de chemin'; + + @override + String get contacts_ping => 'Ping'; + + @override + String get contacts_repeaterPathTrace => 'Tracer le chemin vers le répéteur'; + + @override + String get contacts_repeaterPing => 'Pinguer le répéteur'; + + @override + String get contacts_roomPathTrace => + 'Traçage du chemin vers le serveur de la salle'; + + @override + String get contacts_roomPing => 'Pinguer le serveur de la salle'; + + @override + String get contacts_chatTraceRoute => 'Tracer le chemin'; + + @override + String contacts_pathTraceTo(String name) { + return 'Tracer l\'itinéraire vers $name'; + } } diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart index 83010d8d..b5b100a6 100644 --- a/lib/l10n/app_localizations_it.dart +++ b/lib/l10n/app_localizations_it.dart @@ -2675,4 +2675,44 @@ class AppLocalizationsIt extends AppLocalizations { @override String get listFilter_newGroup => 'Nuovo gruppo'; + + @override + String get pathTrace_you => 'Tu'; + + @override + String get pathTrace_failed => 'Tracciamento del percorso fallito.'; + + @override + String get pathTrace_notAvailable => + 'Tracciamento del percorso non disponibile.'; + + @override + String get pathTrace_refreshTooltip => 'Aggiorna Path Trace.'; + + @override + String get contacts_pathTrace => 'Traccia Percorso'; + + @override + String get contacts_ping => 'Ping'; + + @override + String get contacts_repeaterPathTrace => 'Traccia percorso al ripetitore'; + + @override + String get contacts_repeaterPing => 'Ripetitore ping'; + + @override + String get contacts_roomPathTrace => + 'Traccia del percorso al server della stanza'; + + @override + String get contacts_roomPing => 'Ping al server della stanza'; + + @override + String get contacts_chatTraceRoute => 'Traccia percorso path'; + + @override + String contacts_pathTraceTo(String name) { + return 'Traccia percorso verso $name'; + } } diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index ce60a8f8..3ca198c3 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -2666,4 +2666,42 @@ class AppLocalizationsNl extends AppLocalizations { @override String get listFilter_newGroup => 'Nieuwe groep'; + + @override + String get pathTrace_you => 'Jij'; + + @override + String get pathTrace_failed => 'Padtrace mislukt.'; + + @override + String get pathTrace_notAvailable => 'Padtrace niet beschikbaar.'; + + @override + String get pathTrace_refreshTooltip => 'Path Trace vernieuwen.'; + + @override + String get contacts_pathTrace => 'Pad Traceren'; + + @override + String get contacts_ping => 'Pingen'; + + @override + String get contacts_repeaterPathTrace => 'Pad traceren naar repeater'; + + @override + String get contacts_repeaterPing => 'Ping repeater'; + + @override + String get contacts_roomPathTrace => 'Padtrace naar room server'; + + @override + String get contacts_roomPing => 'Ping kamer server'; + + @override + String get contacts_chatTraceRoute => 'Route traceren'; + + @override + String contacts_pathTraceTo(String name) { + return 'Trace route to $name'; + } } diff --git a/lib/l10n/app_localizations_pl.dart b/lib/l10n/app_localizations_pl.dart index 13fbeb0a..491f76dd 100644 --- a/lib/l10n/app_localizations_pl.dart +++ b/lib/l10n/app_localizations_pl.dart @@ -2674,4 +2674,43 @@ class AppLocalizationsPl extends AppLocalizations { @override String get listFilter_newGroup => 'Nowa grupa'; + + @override + String get pathTrace_you => 'Ty'; + + @override + String get pathTrace_failed => 'Śledzenie ścieżki nie powiodło się.'; + + @override + String get pathTrace_notAvailable => 'Ścieżka śledzenia niedostępna.'; + + @override + String get pathTrace_refreshTooltip => 'Odśwież ścieżkę.'; + + @override + String get contacts_pathTrace => 'Śledzenie Ścieżek'; + + @override + String get contacts_ping => 'Pingować'; + + @override + String get contacts_repeaterPathTrace => 'Śledzenie ścieżki do repeatera'; + + @override + String get contacts_repeaterPing => 'Repeater pingowy'; + + @override + String get contacts_roomPathTrace => + 'Śledzenie ścieżki do serwera pokojowego'; + + @override + String get contacts_roomPing => 'Pinguj serwer pokoju'; + + @override + String get contacts_chatTraceRoute => 'Śledź trasę promienia'; + + @override + String contacts_pathTraceTo(String name) { + return 'Śledź trasę do $name'; + } } diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index 3f54001f..f88a4970 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -2677,4 +2677,42 @@ class AppLocalizationsPt extends AppLocalizations { @override String get listFilter_newGroup => 'Novo grupo'; + + @override + String get pathTrace_you => 'Você'; + + @override + String get pathTrace_failed => 'Falha no rastreamento de caminho.'; + + @override + String get pathTrace_notAvailable => 'Traçado de caminho não disponível.'; + + @override + String get pathTrace_refreshTooltip => 'Atualizar Path Trace.'; + + @override + String get contacts_pathTrace => 'Traçado de Caminho'; + + @override + String get contacts_ping => 'Pingar'; + + @override + String get contacts_repeaterPathTrace => 'Traçar caminho para repetidor'; + + @override + String get contacts_repeaterPing => 'Pingar repetidor'; + + @override + String get contacts_roomPathTrace => 'Traçar caminho para o servidor da sala'; + + @override + String get contacts_roomPing => 'Pingar servidor da sala'; + + @override + String get contacts_chatTraceRoute => 'Rastrear rota do caminho'; + + @override + String contacts_pathTraceTo(String name) { + return 'Rastrear rota para $name'; + } } diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index ae784e49..72da35c9 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -2679,4 +2679,42 @@ class AppLocalizationsRu extends AppLocalizations { @override String get listFilter_newGroup => 'Новая группа'; + + @override + String get pathTrace_you => 'Вы'; + + @override + String get pathTrace_failed => 'Путь трассировки не выполнен.'; + + @override + String get pathTrace_notAvailable => 'Трассировка пути недоступна.'; + + @override + String get pathTrace_refreshTooltip => 'Обновить Path Trace'; + + @override + String get contacts_pathTrace => 'Трассировка пути'; + + @override + String get contacts_ping => 'Пинговать'; + + @override + String get contacts_repeaterPathTrace => 'Отследить путь к ретранслятору'; + + @override + String get contacts_repeaterPing => 'Пинговать повторитель'; + + @override + String get contacts_roomPathTrace => 'Трассировка пути к серверу комнаты'; + + @override + String get contacts_roomPing => 'Пинговать сервер комнаты'; + + @override + String get contacts_chatTraceRoute => 'Трассировка маршрута'; + + @override + String contacts_pathTraceTo(String name) { + return 'Показать маршрут к $name'; + } } diff --git a/lib/l10n/app_localizations_sk.dart b/lib/l10n/app_localizations_sk.dart index 75d46549..23e3f1af 100644 --- a/lib/l10n/app_localizations_sk.dart +++ b/lib/l10n/app_localizations_sk.dart @@ -2662,4 +2662,42 @@ class AppLocalizationsSk extends AppLocalizations { @override String get listFilter_newGroup => 'Nová skupina'; + + @override + String get pathTrace_you => 'Vy'; + + @override + String get pathTrace_failed => 'Sledovanie cesty zlyhalo.'; + + @override + String get pathTrace_notAvailable => 'Path trace nie je k dispozícii.'; + + @override + String get pathTrace_refreshTooltip => 'Obnoviť Path Trace.'; + + @override + String get contacts_pathTrace => 'Sledovanie lúčov'; + + @override + String get contacts_ping => 'Pingovať'; + + @override + String get contacts_repeaterPathTrace => 'Sledovanie cesty k opakovaču'; + + @override + String get contacts_repeaterPing => 'Pingovať opakovač'; + + @override + String get contacts_roomPathTrace => 'Sledovanie cesty k serveru miestnosti'; + + @override + String get contacts_roomPing => 'Ping server miestnosti'; + + @override + String get contacts_chatTraceRoute => 'Sledovať trasu lúča'; + + @override + String contacts_pathTraceTo(String name) { + return 'Sledovať trasu k $name'; + } } diff --git a/lib/l10n/app_localizations_sl.dart b/lib/l10n/app_localizations_sl.dart index be9556f3..4ad59e87 100644 --- a/lib/l10n/app_localizations_sl.dart +++ b/lib/l10n/app_localizations_sl.dart @@ -12,7 +12,7 @@ class AppLocalizationsSl extends AppLocalizations { String get appTitle => 'MeshCore Open'; @override - String get nav_contacts => 'Kontakti'; + String get nav_contacts => 'Stiki'; @override String get nav_channels => 'Kanali'; @@ -144,7 +144,7 @@ class AppLocalizationsSl extends AppLocalizations { String get scanner_scan => 'Skeniraj'; @override - String get device_quickSwitch => 'Hitro preklopiti'; + String get device_quickSwitch => 'Hitro preklop'; @override String get device_meshcore => 'MeshCore'; @@ -163,16 +163,16 @@ class AppLocalizationsSl extends AppLocalizations { 'Obveščanja, sporoščanje in zemljevidi.'; @override - String get settings_nodeSettings => 'Nastavitve časa'; + String get settings_nodeSettings => 'Nastavitev časa'; @override - String get settings_nodeName => 'Ime omrežno mesto'; + String get settings_nodeName => 'Ime node-a'; @override - String get settings_nodeNameNotSet => 'Nezavedeno'; + String get settings_nodeNameNotSet => 'Ni nastavljeno'; @override - String get settings_nodeNameHint => 'Vnesite ime časa'; + String get settings_nodeNameHint => 'Vnesite ime node-a'; @override String get settings_nodeNameUpdated => 'Ime posodobljeno'; @@ -182,7 +182,7 @@ class AppLocalizationsSl extends AppLocalizations { @override String get settings_radioSettingsSubtitle => - 'Frekvenca, moč, razširni faktor'; + 'Frekvenca, moč, razširitveni faktor'; @override String get settings_radioSettingsUpdated => 'Radio nastavitve posodobljene'; @@ -201,7 +201,7 @@ class AppLocalizationsSl extends AppLocalizations { @override String get settings_locationInvalid => - 'Neveljna zemeljska širina ali dolžina.'; + 'Neveljavna zemeljska širina ali dolžina.'; @override String get settings_locationGPSEnable => 'Omogoči GPS'; @@ -224,7 +224,7 @@ class AppLocalizationsSl extends AppLocalizations { String get settings_longitude => 'Dolžina'; @override - String get settings_privacyMode => 'Mod podjetja'; + String get settings_privacyMode => 'Zasebnost'; @override String get settings_privacyModeSubtitle => 'Skrita imena/lokacije v oglasih'; @@ -234,10 +234,10 @@ class AppLocalizationsSl extends AppLocalizations { 'Omogoči način zasebnosti, da skrijemo tvoje ime in lokacijo v oglasih.'; @override - String get settings_privacyModeEnabled => 'Privatni režim je omogočen.'; + String get settings_privacyModeEnabled => 'Privatni način je omogočen.'; @override - String get settings_privacyModeDisabled => 'Privatni režim je onemogočen.'; + String get settings_privacyModeDisabled => 'Privatni način je onemogočen.'; @override String get settings_actions => 'Akcije'; @@ -253,47 +253,46 @@ class AppLocalizationsSl extends AppLocalizations { String get settings_advertisementSent => 'Oglas poslan'; @override - String get settings_syncTime => 'Ugasniti čas'; + String get settings_syncTime => 'Nastavi uro'; @override - String get settings_syncTimeSubtitle => 'Nastavi uro naprave v čas telefona'; + String get settings_syncTimeSubtitle => 'Nastavi uro naprave na čas telefona'; @override - String get settings_timeSynchronized => 'Sinhronizirano po času'; + String get settings_timeSynchronized => 'Ura sinhronizirana'; @override String get settings_refreshContacts => 'Ponovno obišči kontakte'; @override String get settings_refreshContactsSubtitle => - 'Ponovno naloži seznam kontaktov iz naprave'; + 'Ponovno naloži seznam stikov v napravi'; @override - String get settings_rebootDevice => 'Restart Naprave'; + String get settings_rebootDevice => 'Ponovni zagon naprave'; @override - String get settings_rebootDeviceSubtitle => - 'Ponovite zažetek naprave MeshCore'; + String get settings_rebootDeviceSubtitle => 'Ponovno zaženi MeshCore napravo'; @override String get settings_rebootDeviceConfirm => - 'Ste prepričani, da želite ponovno zagon napravke? Boste odvisni od omrežja.'; + 'Ste prepričani, da želite ponovno zagnati napravo? Povezava bo prekinjena.'; @override - String get settings_debug => 'Napravi popravek'; + String get settings_debug => 'Debug'; @override - String get settings_bleDebugLog => 'Logarjev zapis BLE'; + String get settings_bleDebugLog => 'BLE debug log (razhroščevanje)'; @override String get settings_bleDebugLogSubtitle => - 'Navodila BLE, odgovori in surovo podatkovno'; + 'BLE ukazi, odgovori in surovi podatki'; @override - String get settings_appDebugLog => 'Log zapiske aplikacije'; + String get settings_appDebugLog => 'Logi aplikacije'; @override - String get settings_appDebugLogSubtitle => 'Prijavni sporočila aplikacije'; + String get settings_appDebugLogSubtitle => 'Debug sporočila aplikacije'; @override String get settings_about => 'Oglejte si'; @@ -304,11 +303,11 @@ class AppLocalizationsSl extends AppLocalizations { } @override - String get settings_aboutLegalese => 'MeshCore Odprtokodni Projekt 2024'; + String get settings_aboutLegalese => 'Odprtokodni projekt MeshCore 2024'; @override String get settings_aboutDescription => - 'Odprtokodni Flutter kličnik za naprave za LoRa mrežo MeshCore.'; + 'Odprtokodni Flutter klient za naprave za LoRa omrežje MeshCore.'; @override String get settings_infoName => 'Ime'; @@ -323,10 +322,10 @@ class AppLocalizationsSl extends AppLocalizations { String get settings_infoBattery => 'Baterija'; @override - String get settings_infoPublicKey => 'Ključ javnega tipa'; + String get settings_infoPublicKey => 'Javni ključ'; @override - String get settings_infoContactsCount => 'Število kontaktov'; + String get settings_infoContactsCount => 'Število stikov'; @override String get settings_infoChannelCount => 'Število kanalov'; @@ -350,7 +349,7 @@ class AppLocalizationsSl extends AppLocalizations { String get settings_frequencyHelper => '300,00 - 2500,00'; @override - String get settings_frequencyInvalid => 'Neveljčna frekvenca (300-2500 MHz)'; + String get settings_frequencyInvalid => 'Neveljavna frekvenca (300-2500 MHz)'; @override String get settings_bandwidth => 'Pasovna širina'; @@ -368,13 +367,13 @@ class AppLocalizationsSl extends AppLocalizations { String get settings_txPowerHelper => '0 - 22'; @override - String get settings_txPowerInvalid => 'Neveljaven TX moč (0-22 dBm)'; + String get settings_txPowerInvalid => 'Neveljavna TX moč (0-22 dBm)'; @override - String get settings_longRange => 'Dolenje območje'; + String get settings_longRange => 'DDolg doseg'; @override - String get settings_fastSpeed => 'Hitra hitrost'; + String get settings_fastSpeed => 'Visoka hitrost'; @override String settings_error(String message) { @@ -391,10 +390,10 @@ class AppLocalizationsSl extends AppLocalizations { String get appSettings_theme => 'Tema'; @override - String get appSettings_themeSystem => 'Predpomnilnik sistema'; + String get appSettings_themeSystem => 'Sistemska tema'; @override - String get appSettings_themeLight => 'Luč'; + String get appSettings_themeLight => 'Svetlo'; @override String get appSettings_themeDark => 'Temno'; @@ -445,10 +444,10 @@ class AppLocalizationsSl extends AppLocalizations { String get appSettings_languageBg => 'Български'; @override - String get appSettings_notifications => 'Obveščanja'; + String get appSettings_notifications => 'Obvestila'; @override - String get appSettings_enableNotifications => 'Omogoči obveščanje'; + String get appSettings_enableNotifications => 'Omogoči obvestila'; @override String get appSettings_enableNotificationsSubtitle => @@ -484,7 +483,7 @@ class AppLocalizationsSl extends AppLocalizations { @override String get appSettings_advertisementNotificationsSubtitle => - 'Pokaži obvestilo, ko so novi vozlišči odkrivljeni.'; + 'Pokaži obvestilo, ko so najdene nove naprave.'; @override String get appSettings_messaging => 'Komuniciranje'; @@ -499,18 +498,19 @@ class AppLocalizationsSl extends AppLocalizations { @override String get appSettings_pathsWillBeCleared => - 'Potnice bodo očiščene po 5 neuspešnih poskusih.'; + 'Počisti pot po 5 neuspešnih poskusih.'; @override String get appSettings_pathsWillNotBeCleared => - 'Potniški poti ne bodo samodejno čiščeni.'; + 'Poti ne bodo samodejno čiščene.'; @override - String get appSettings_autoRouteRotation => 'Avtomatsko Občutke in Rotacije'; + String get appSettings_autoRouteRotation => + 'Avtomatsko rotacija prenosne poti'; @override String get appSettings_autoRouteRotationSubtitle => - 'Med spreminjanjem med najboljšimi potmi in plovilnim načinom'; + 'Menjaj med boljšo potjo in flood načinom'; @override String get appSettings_autoRouteRotationEnabled => @@ -524,16 +524,16 @@ class AppLocalizationsSl extends AppLocalizations { String get appSettings_battery => 'Baterija'; @override - String get appSettings_batteryChemistry => 'Razem z možnostmi'; + String get appSettings_batteryChemistry => 'Kemija baterije'; @override String appSettings_batteryChemistryPerDevice(String deviceName) { - return 'Nastavitve za naprave ($deviceName)'; + return 'Nastavitev za napravo ($deviceName)'; } @override String get appSettings_batteryChemistryConnectFirst => - 'Povežite se z napravo za izbiro'; + 'Za izbiro se poveži z napravo'; @override String get appSettings_batteryNmc => '18650 NMC (3,0-4,2V)'; @@ -545,52 +545,51 @@ class AppLocalizationsSl extends AppLocalizations { String get appSettings_batteryLipo => 'LiPo (3,0-4,2V)'; @override - String get appSettings_mapDisplay => 'Prikaz zemljevide'; + String get appSettings_mapDisplay => 'Prikaz zemljevida'; @override - String get appSettings_showRepeaters => 'Prikaži ponovitve'; + String get appSettings_showRepeaters => 'Prikaži repetitorje'; @override - String get appSettings_showRepeatersSubtitle => - 'Prikaži ponovljalne notranjosti na zemljeploscu'; + String get appSettings_showRepeatersSubtitle => 'Prikaži repetitorje na mapi'; @override - String get appSettings_showChatNodes => 'Prikaži čakalne notranjosti'; + String get appSettings_showChatNodes => 'Prikaži naprave za klepet'; @override String get appSettings_showChatNodesSubtitle => - 'Prikaži pogovorni pike na zemljeploscu'; + 'Prikaži naprave na zemljevidu'; @override - String get appSettings_showOtherNodes => 'Pokaži druge vozlišča'; + String get appSettings_showOtherNodes => 'Pokaži druge naprave'; @override String get appSettings_showOtherNodesSubtitle => - 'Pokaži druge vrste notranjih elementov na zemljevalu.'; + 'Pokaži druge vrste naprav na zemljevidu.'; @override - String get appSettings_timeFilter => 'Filtri po času'; + String get appSettings_timeFilter => 'Filter po času'; @override - String get appSettings_timeFilterShowAll => 'Pokaži vse notranje elemente'; + String get appSettings_timeFilterShowAll => 'Pokaži vse naprave'; @override String appSettings_timeFilterShowLast(int hours) { - return 'Pokaži notranjosti iz zadnjih $hours ur'; + return 'Pokaži naprave v zadnjih $hours urah'; } @override - String get appSettings_mapTimeFilter => 'Filtri časa zemljevida'; + String get appSettings_mapTimeFilter => 'Filter časa na zemljevidu'; @override String get appSettings_showNodesDiscoveredWithin => - 'Pokaži notranje čepke, odkrivene v:'; + 'Pokaži naprave odkrite v:'; @override - String get appSettings_allTime => 'Vse čase'; + String get appSettings_allTime => 'Brez omejitev'; @override - String get appSettings_lastHour => 'Minuto nazaj'; + String get appSettings_lastHour => 'V zadnji uri'; @override String get appSettings_last6Hours => 'Zadnjih 6 ur'; @@ -599,13 +598,13 @@ class AppLocalizationsSl extends AppLocalizations { String get appSettings_last24Hours => 'Zadnjih 24 ur'; @override - String get appSettings_lastWeek => 'Lepošno'; + String get appSettings_lastWeek => 'Prejšnji teden'; @override - String get appSettings_offlineMapCache => 'Omrezni Poudni Arhiv'; + String get appSettings_offlineMapCache => 'Shramba zemljevidov brez povezave'; @override - String get appSettings_noAreaSelected => 'Nizkana označena površina'; + String get appSettings_noAreaSelected => 'Območje ni izbrano'; @override String appSettings_areaSelectedZoom(int minZoom, int maxZoom) { @@ -613,79 +612,78 @@ class AppLocalizationsSl extends AppLocalizations { } @override - String get appSettings_debugCard => 'Napravi popravek'; + String get appSettings_debugCard => 'Razhroščevanje'; @override - String get appSettings_appDebugLogging => 'Programski Log'; + String get appSettings_appDebugLogging => 'Programski dnevnik'; @override String get appSettings_appDebugLoggingSubtitle => - 'Log aplikacijske debug sporočila za odpravljanje težav'; + 'Dnevnik debug sporočil za odpravljanje težav'; @override String get appSettings_appDebugLoggingEnabled => - 'Omogočeno zaznamovanje napak v aplikaciji'; + 'Beleženje napak v aplikaciji omogočeno'; @override String get appSettings_appDebugLoggingDisabled => - 'Programski logi aplikacije so onemogočeni.'; + 'Beleženje napak v aplikacije onemogočeno.'; @override - String get contacts_title => 'Kontakti'; + String get contacts_title => 'Stiki'; @override - String get contacts_noContacts => 'Še ni kontaktov.'; + String get contacts_noContacts => 'Ni stikov.'; @override String get contacts_contactsWillAppear => - 'Kontakti se bodo prikazali, ko naprave oglasijo.'; + 'Stiki se bodo prikazali, ko se naprave oglasijo.'; @override - String get contacts_searchContacts => 'Iskanje kontaktov...'; + String get contacts_searchContacts => 'Iskanje stikov...'; @override - String get contacts_noUnreadContacts => 'Nerešeno kontaktov.'; + String get contacts_noUnreadContacts => 'Ne prebrani stiki.'; @override - String get contacts_noContactsFound => - 'Niti ena oseba ali skupine ni najdena.'; + String get contacts_noContactsFound => 'Stiki niso najdeni.'; @override - String get contacts_deleteContact => 'Izbrisati Kontakt'; + String get contacts_deleteContact => 'Izbriši stik'; @override String contacts_removeConfirm(String contactName) { - return 'Izbrisati $contactName iz kontaktov?'; + return 'Izbrišem $contactName iz stikov?'; } @override - String get contacts_manageRepeater => 'Upravljajte Ponovitve'; + String get contacts_manageRepeater => 'Upravljaj Ponovitve'; @override String get contacts_manageRoom => 'Upravljajte strežnik sobe'; @override - String get contacts_roomLogin => 'Vnos v sobo'; + String get contacts_roomLogin => 'Prijava v sobo'; @override - String get contacts_openChat => 'Odprta kleta'; + String get contacts_openChat => 'Odpri klepet'; @override - String get contacts_editGroup => 'Uredi Skupino'; + String get contacts_editGroup => 'Uredi skupino'; @override - String get contacts_deleteGroup => 'Izbrisati Skupino'; + String get contacts_deleteGroup => 'Izbriši skupino'; @override String contacts_deleteGroupConfirm(String groupName) { - return 'Odpovedati $groupName?'; + return 'Izbriši $groupName?'; } @override - String get contacts_newGroup => 'Novo skupino'; + String get contacts_newGroup => 'Nova skupina'; @override - String get contacts_groupName => 'Skupina imena'; + String get contacts_groupName => 'Ime skupine'; @override String get contacts_groupNameRequired => 'Ime skupine je obvezno.'; @@ -696,53 +694,53 @@ class AppLocalizationsSl extends AppLocalizations { } @override - String get contacts_filterContacts => 'Filtri kontakt\\,...'; + String get contacts_filterContacts => 'Filtriraj stik\\,...'; @override String get contacts_noContactsMatchFilter => - 'Niti ena oseba ne ustreza vašemu kriteriju.'; + 'Noben stik ne ustreza vašemu kriteriju.'; @override - String get contacts_noMembers => 'Nič članov.'; + String get contacts_noMembers => 'Ni članov.'; @override - String get contacts_lastSeenNow => 'Datum zadnjega vpisa zdaj'; + String get contacts_lastSeenNow => 'Nazadnje viden zdaj'; @override String contacts_lastSeenMinsAgo(int minutes) { - return 'Zadnjič videti $minutes minut nazaj'; + return 'Zadnjič viden pred $minutes minutami'; } @override - String get contacts_lastSeenHourAgo => 'Zadnjič ogledan pred 1 uro.'; + String get contacts_lastSeenHourAgo => 'Zadnjič viden pred 1 uro.'; @override String contacts_lastSeenHoursAgo(int hours) { - return 'Zadnjič videti $hours ur nazaj'; + return 'Zadnjič viden pred $hours urami'; } @override - String get contacts_lastSeenDayAgo => 'Zadnjič ogledan pred 1 dnem'; + String get contacts_lastSeenDayAgo => 'Zadnjič viden pred 1 dnem'; @override String contacts_lastSeenDaysAgo(int days) { - return 'Zadnjič videti $days dni nazaj'; + return 'Zadnjič viden pred $days dnem'; } @override String get channels_title => 'Kanali'; @override - String get channels_noChannelsConfigured => 'Nekonfigurirane kanale'; + String get channels_noChannelsConfigured => 'Kanali še niso konfigurirani'; @override - String get channels_addPublicChannel => 'Dodaj Objavni Kanal'; + String get channels_addPublicChannel => 'Dodaj javni kanal'; @override String get channels_searchChannels => 'Poišči kanale...'; @override - String get channels_noChannelsFound => 'Niti kanalov najti ni.'; + String get channels_noChannelsFound => 'Ne najdem kanalov.'; @override String channels_channelIndex(int index) { @@ -753,16 +751,16 @@ class AppLocalizationsSl extends AppLocalizations { String get channels_hashtagChannel => 'Hashtag kanal'; @override - String get channels_public => 'javno'; + String get channels_public => 'Javni'; @override - String get channels_private => 'Zasebno'; + String get channels_private => 'Zasebni'; @override - String get channels_publicChannel => 'Ogljišna skupina'; + String get channels_publicChannel => 'Javni kanal'; @override - String get channels_privateChannel => 'Zatemniščen kanal'; + String get channels_privateChannel => 'Zasebni kanal'; @override String get channels_editChannel => 'Uredi kanal'; @@ -772,7 +770,7 @@ class AppLocalizationsSl extends AppLocalizations { @override String channels_deleteChannelConfirm(String name) { - return 'Izbrisati \"$name\"? To se ne da povrniti.'; + return 'Izbrišem \"$name\"? To se ne da povrniti.'; } @override @@ -912,21 +910,21 @@ class AppLocalizationsSl extends AppLocalizations { } @override - String get chat_typeMessage => 'Vnesite sporočilo...'; + String get chat_typeMessage => 'Vnesi sporočilo...'; @override String chat_messageTooLong(int maxBytes) { - return 'Pošiljanje sporočila je onemogočeno, saj je preveliko (maksimalno $maxBytes bajt).'; + return 'Pošiljanje sporočila je onemogočeno, saj je preveliko (maksimalno $maxBytes byte-ov).'; } @override - String get chat_messageCopied => 'Pošljeno sporočilo'; + String get chat_messageCopied => 'Sporočilo poslano'; @override - String get chat_messageDeleted => 'Pošiljanje sporočila izbrisano'; + String get chat_messageDeleted => 'Sporočilo izbrisano'; @override - String get chat_retryingMessage => 'Ponovna poskus.'; + String get chat_retryingMessage => 'Ponovni poskus.'; @override String chat_retryCount(int current, int max) { @@ -937,10 +935,10 @@ class AppLocalizationsSl extends AppLocalizations { String get chat_sendGif => 'Pošlji GIF'; @override - String get chat_reply => 'Odpošlji'; + String get chat_reply => 'Odgovori'; @override - String get chat_addReaction => 'Dodaj Reakcijo'; + String get chat_addReaction => 'Dodaj reakcijo'; @override String get chat_me => 'jaz'; @@ -961,19 +959,19 @@ class AppLocalizationsSl extends AppLocalizations { String get gifPicker_title => 'Izberi GIF'; @override - String get gifPicker_searchHint => 'Iskalite GIF-e...'; + String get gifPicker_searchHint => 'Išči GIF-e...'; @override - String get gifPicker_poweredBy => 'Naprodno z GIPHY'; + String get gifPicker_poweredBy => 'Napredno z GIPHY'; @override - String get gifPicker_noGifsFound => 'Niti GIF-jev najti ni.'; + String get gifPicker_noGifsFound => 'Ne najdem GIF-ov.'; @override - String get gifPicker_failedLoad => 'Neuspešno je naložilo GIF-e'; + String get gifPicker_failedLoad => 'Neuspešno nalaganje GIF-a'; @override - String get gifPicker_failedSearch => 'Posodobit neuspešno.'; + String get gifPicker_failedSearch => 'Iskanje neuspešno.'; @override String get gifPicker_noInternet => 'Ni internetne povezave'; @@ -982,35 +980,35 @@ class AppLocalizationsSl extends AppLocalizations { String get debugLog_appTitle => 'Log zapiske aplikacije'; @override - String get debugLog_bleTitle => 'Logarjev zapis BLE'; + String get debugLog_bleTitle => 'Log zapis BLE'; @override - String get debugLog_copyLog => 'Kopiraj zapiske'; + String get debugLog_copyLog => 'Kopiraj dnevnik'; @override - String get debugLog_clearLog => 'Pasters log'; + String get debugLog_clearLog => 'Briši log'; @override - String get debugLog_copied => 'Kopirana belež poteka.'; + String get debugLog_copied => 'Beležka kopirana.'; @override - String get debugLog_bleCopied => 'Kopirana beležke iz BLE'; + String get debugLog_bleCopied => 'Kopirana beležka iz BLE'; @override - String get debugLog_noEntries => 'Še ni ustvarjenih debug zapisov.'; + String get debugLog_noEntries => 'Ni ustvarjenih debug zapisov.'; @override String get debugLog_enableInSettings => - 'Omogoči beleženje napak v aplikaciji v nastavitvah'; + 'Omogoči beleženje napak v nastavitvah aplikacije'; @override - String get debugLog_frames => 'Okna'; + String get debugLog_frames => 'Okvirji'; @override String get debugLog_rawLogRx => 'Svež Log-RX'; @override - String get debugLog_noBleActivity => 'Šele začnite z aktivnostjo BLE.'; + String get debugLog_noBleActivity => 'Ni BLE aktivnosti.'; @override String debugFrame_length(int count) { @@ -1079,10 +1077,10 @@ class AppLocalizationsSl extends AppLocalizations { 'Zapiske o poti so popolni. Izbriši vnose, da dodaš nove.'; @override - String get chat_hopSingular => 'skoč'; + String get chat_hopSingular => 'skok'; @override - String get chat_hopPlural => 'škrabec'; + String get chat_hopPlural => 'skokov'; @override String chat_hopsCount(int count) { @@ -1103,7 +1101,7 @@ class AppLocalizationsSl extends AppLocalizations { @override String get chat_noPathHistoryYet => - 'Še ni shranjenih poti.\nPošlji sporočilo za odkrivanje poti.'; + 'Ni shranjenih poti.\nPošlji sporočilo za odkrivanje poti.'; @override String get chat_pathActions => 'Potni ukazi:'; @@ -1115,7 +1113,7 @@ class AppLocalizationsSl extends AppLocalizations { String get chat_setCustomPathSubtitle => 'Ročno določite potniško pot.'; @override - String get chat_clearPath => 'Čista pot'; + String get chat_clearPath => 'Počisti pot'; @override String get chat_clearPathSubtitle => 'Ob naslednji pošiljanju znova zbrati.'; @@ -1133,7 +1131,7 @@ class AppLocalizationsSl extends AppLocalizations { 'Narejena je bila omrežna modaliteta. Vklopi jo znova preko ikone v meniju aplikacije.'; @override - String get chat_fullPath => 'Polni pot'; + String get chat_fullPath => 'Polna pot'; @override String get chat_pathDetailsNotAvailable => @@ -2012,13 +2010,13 @@ class AppLocalizationsSl extends AppLocalizations { } @override - String get repeater_cliQuickGetName => 'Dobiti ime'; + String get repeater_cliQuickGetName => 'Pridobi ime'; @override String get repeater_cliQuickGetRadio => 'Dobiti Radiopravo'; @override - String get repeater_cliQuickGetTx => 'Dobiti TX'; + String get repeater_cliQuickGetTx => 'Pridobi TX'; @override String get repeater_cliQuickNeighbors => 'Sosedi'; @@ -2030,7 +2028,7 @@ class AppLocalizationsSl extends AppLocalizations { String get repeater_cliQuickAdvertise => 'Oglasite'; @override - String get repeater_cliQuickClock => 'Urnik'; + String get repeater_cliQuickClock => 'Ura'; @override String get repeater_cliHelpAdvert => 'Pošlje paket oglasov'; @@ -2153,7 +2151,7 @@ class AppLocalizationsSl extends AppLocalizations { @override String get repeater_cliHelpSetPerm => - 'Modificira ACL. Odstrani ustreznu vnos (po predponi pubkeyja), če je \"permissions\" enako nič. Dodaja nov vnos, če je pubkey-hex v celoti in trenutno ni v ACL. Posodobi vnos po ustreznem predponi pubkeyja. Bitje dovoljenj se razlikuje glede na firmware vlogo, vendar so prvi dve bitki: 0 (Gost), 1 (Lezenje samo), 2 (Lezenje in pisanje), 3 (Administrator).'; + 'Modificira ACL. Odstrani ustrezen vnos (po predponi pubkeyja), če je \"permissions\" enako nič. Dodaja nov vnos, če je pubkey-hex v celoti in trenutno ni v ACL. Posodobi vnos po ustreznem predponi pubkeyja. Bitje dovoljenj se razlikuje glede na firmware vlogo, vendar so prvi dve bitki: 0 (Gost), 1 (Lezenje samo), 2 (Lezenje in pisanje), 3 (Administrator).'; @override String get repeater_cliHelpGetBridgeType => @@ -2261,11 +2259,11 @@ class AppLocalizationsSl extends AppLocalizations { String get repeater_logging => 'Logiranje'; @override - String get repeater_neighborsRepeaterOnly => 'Sosedi (le za ponovitelja)'; + String get repeater_neighborsRepeaterOnly => 'Sosedi (le za repetitorje)'; @override String get repeater_regionManagementRepeaterOnly => - 'Upravljanje regij (zgolj za ponovitve)'; + 'Upravljanje regij (zgolj za repetitorje)'; @override String get repeater_regionNote => @@ -2380,13 +2378,13 @@ class AppLocalizationsSl extends AppLocalizations { String get channelPath_messageDetails => 'Podrobnosti sporočila'; @override - String get channelPath_senderLabel => 'Pošiljalec'; + String get channelPath_senderLabel => 'Pošiljatelj'; @override - String get channelPath_timeLabel => 'Čas'; + String get channelPath_timeLabel => 'Ura'; @override - String get channelPath_repeatsLabel => 'Ponovi'; + String get channelPath_repeatsLabel => 'Ponovitve'; @override String channelPath_pathLabel(int index) { @@ -2551,17 +2549,17 @@ class AppLocalizationsSl extends AppLocalizations { @override String get community_scanOrCreate => - 'Skenirajte QR kodo ali ustvarite skupnost za začetek.'; + 'Skeniraj QR kodo ali ustvari skupnost za začetek.'; @override - String get community_manageCommunities => 'Upravljajte skupnosti'; + String get community_manageCommunities => 'Upravljanje skupnosti'; @override String get community_delete => 'Opusti skupnost'; @override String community_deleteConfirm(String name) { - return 'Zapustiti \"$name\"?'; + return 'Zapusti \"$name\"?'; } @override @@ -2575,7 +2573,7 @@ class AppLocalizationsSl extends AppLocalizations { } @override - String get community_regenerateSecret => 'Preberi nov tajni kôd'; + String get community_regenerateSecret => 'Ponovno ustvari geslo'; @override String community_regenerateSecretConfirm(String name) { @@ -2587,11 +2585,11 @@ class AppLocalizationsSl extends AppLocalizations { @override String community_secretRegenerated(String name) { - return 'Tajna za \"$name\" ponovno ustvarjena'; + return 'Geslo za \"$name\" ponovno ustvarjeno'; } @override - String get community_updateSecret => 'Ažurniraj tajno'; + String get community_updateSecret => 'Ažuriraj ključ'; @override String community_secretUpdated(String name) { @@ -2600,11 +2598,11 @@ class AppLocalizationsSl extends AppLocalizations { @override String community_scanToUpdateSecret(String name) { - return 'Skeniraj nov kôd QR za posodabljanje tajne za $name'; + return 'Skeniraj novo QR kodo za posodabljanje ključa za $name'; } @override - String get community_addHashtagChannel => 'Dodaj Oznako Obštnine'; + String get community_addHashtagChannel => 'Dodaj hashtag kanal'; @override String get community_addHashtagChannelDesc => @@ -2618,7 +2616,7 @@ class AppLocalizationsSl extends AppLocalizations { @override String get community_regularHashtagDesc => - 'javna oznaka (kateri koli lahko sodelujejo)'; + 'javna oznaka (kdorkoli lahko sodeluje)'; @override String get community_communityHashtag => 'Skupnostni hashtag'; @@ -2667,4 +2665,42 @@ class AppLocalizationsSl extends AppLocalizations { @override String get listFilter_newGroup => 'Nova skupina'; + + @override + String get pathTrace_you => 'Ti'; + + @override + String get pathTrace_failed => 'Sledenje poti ni uspelo.'; + + @override + String get pathTrace_notAvailable => 'Potni sled ni na voljo.'; + + @override + String get pathTrace_refreshTooltip => 'Osveži Path Trace.'; + + @override + String get contacts_pathTrace => 'Sledenje poti'; + + @override + String get contacts_ping => 'Pingati'; + + @override + String get contacts_repeaterPathTrace => 'Sledi poti do ponavljalnika'; + + @override + String get contacts_repeaterPing => 'Pinguj ponavljalnik'; + + @override + String get contacts_roomPathTrace => 'Sledenje poti do strežnika sobe'; + + @override + String get contacts_roomPing => 'Ping strežnik sobe'; + + @override + String get contacts_chatTraceRoute => 'Slediti poti žarkov'; + + @override + String contacts_pathTraceTo(String name) { + return 'Trace route to $name'; + } } diff --git a/lib/l10n/app_localizations_sv.dart b/lib/l10n/app_localizations_sv.dart index 34b54b46..885d7d67 100644 --- a/lib/l10n/app_localizations_sv.dart +++ b/lib/l10n/app_localizations_sv.dart @@ -2650,4 +2650,42 @@ class AppLocalizationsSv extends AppLocalizations { @override String get listFilter_newGroup => 'Ny grupp'; + + @override + String get pathTrace_you => 'Du'; + + @override + String get pathTrace_failed => 'Sökvägsföljning misslyckades.'; + + @override + String get pathTrace_notAvailable => 'Path trace ej tillgänglig.'; + + @override + String get pathTrace_refreshTooltip => 'Uppdatera Path Trace'; + + @override + String get contacts_pathTrace => 'Path Trace'; + + @override + String get contacts_ping => 'Ping'; + + @override + String get contacts_repeaterPathTrace => 'Vägspårning till repeater'; + + @override + String get contacts_repeaterPing => 'Ping-repeater'; + + @override + String get contacts_roomPathTrace => 'Vägspårning till rumserver'; + + @override + String get contacts_roomPing => 'Ping rumsserver'; + + @override + String get contacts_chatTraceRoute => 'Spåra rutt'; + + @override + String contacts_pathTraceTo(String name) { + return 'Spåra rutt till $name'; + } } diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index bc431eae..9f223da3 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -2686,4 +2686,42 @@ class AppLocalizationsUk extends AppLocalizations { @override String get listFilter_newGroup => 'Нова група'; + + @override + String get pathTrace_you => 'Ви'; + + @override + String get pathTrace_failed => 'Відстеження шляху не вдалося.'; + + @override + String get pathTrace_notAvailable => 'Трасування шляху недоступне.'; + + @override + String get pathTrace_refreshTooltip => 'Оновити Path Trace'; + + @override + String get contacts_pathTrace => 'Трасування шляхів'; + + @override + String get contacts_ping => 'Пінгувати'; + + @override + String get contacts_repeaterPathTrace => 'Трасування шляху до повторювача'; + + @override + String get contacts_repeaterPing => 'Пінгувати повторювач'; + + @override + String get contacts_roomPathTrace => 'Трасування шляху до серверу кімнати'; + + @override + String get contacts_roomPing => 'Пінг сервера кімнати'; + + @override + String get contacts_chatTraceRoute => 'Трасування шляху'; + + @override + String contacts_pathTraceTo(String name) { + return 'Відстежити маршрут до $name'; + } } diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index cd9c3be8..fc8d78ba 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -2531,4 +2531,42 @@ class AppLocalizationsZh extends AppLocalizations { @override String get listFilter_newGroup => '新组'; + + @override + String get pathTrace_you => '你'; + + @override + String get pathTrace_failed => '路径追踪失败。'; + + @override + String get pathTrace_notAvailable => '路径追踪不可用'; + + @override + String get pathTrace_refreshTooltip => '刷新路径追踪'; + + @override + String get contacts_pathTrace => '路径追踪'; + + @override + String get contacts_ping => 'ping'; + + @override + String get contacts_repeaterPathTrace => '路径追踪到中继器'; + + @override + String get contacts_repeaterPing => 'Ping 中继器'; + + @override + String get contacts_roomPathTrace => '路径追踪至房间服务器'; + + @override + String get contacts_roomPing => 'Ping 房间服务器'; + + @override + String get contacts_chatTraceRoute => '路径追踪'; + + @override + String contacts_pathTraceTo(String name) { + return '追踪路由到 $name'; + } } diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index 48ef3ddd..b28d668a 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -1533,5 +1533,24 @@ "community_regenerate": "Regeneer", "community_updateSecret": "Bijwerken Geheime", "community_secretUpdated": "Geheim gewijzigd voor \"{name}\"", - "community_scanToUpdateSecret": "Scan de nieuwe QR-code om het geheim voor \"{name}\" bij te werken" + "community_scanToUpdateSecret": "Scan de nieuwe QR-code om het geheim voor \"{name}\" bij te werken", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_you": "Jij", + "pathTrace_failed": "Padtrace mislukt.", + "pathTrace_notAvailable": "Padtrace niet beschikbaar.", + "pathTrace_refreshTooltip": "Path Trace vernieuwen.", + "contacts_pathTrace": "Pad Traceren", + "contacts_ping": "Pingen", + "contacts_repeaterPathTrace": "Pad traceren naar repeater", + "contacts_repeaterPing": "Ping repeater", + "contacts_roomPathTrace": "Padtrace naar room server", + "contacts_roomPing": "Ping kamer server", + "contacts_chatTraceRoute": "Route traceren", + "contacts_pathTraceTo": "Trace route to {name}" } diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 823bba1e..8070ac31 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -1533,5 +1533,24 @@ "community_regenerateSecretConfirm": "Regeneruj tajny klucz dla \"{name}\"? Wszyscy członkowie będą musieli zeskanować nowy kod QR, aby kontynuować komunikację.", "community_scanToUpdateSecret": "Skanuj nowy kod QR, aby zaktualizować sekret dla \"{name}\"", "community_secretUpdated": "Hasło zaktualizowane dla \"{name}\"", - "community_updateSecret": "Zaktualizuj tajny klucz" + "community_updateSecret": "Zaktualizuj tajny klucz", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_you": "Ty", + "pathTrace_failed": "Śledzenie ścieżki nie powiodło się.", + "pathTrace_notAvailable": "Ścieżka śledzenia niedostępna.", + "contacts_pathTrace": "Śledzenie Ścieżek", + "contacts_ping": "Pingować", + "contacts_repeaterPathTrace": "Śledzenie ścieżki do repeatera", + "contacts_roomPathTrace": "Śledzenie ścieżki do serwera pokojowego", + "contacts_roomPing": "Pinguj serwer pokoju", + "pathTrace_refreshTooltip": "Odśwież ścieżkę.", + "contacts_repeaterPing": "Repeater pingowy", + "contacts_pathTraceTo": "Śledź trasę do {name}", + "contacts_chatTraceRoute": "Śledź trasę promienia" } diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index b48db37b..6994bea0 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -1533,5 +1533,24 @@ "community_regenerate": "Regenerar", "community_secretUpdated": "Segredo atualizado para \"{name}\"", "community_scanToUpdateSecret": "Scanar o novo código QR para atualizar o segredo para \"{name}\"\n\n\n+++++", - "community_updateSecret": "Atualizar Segredo" + "community_updateSecret": "Atualizar Segredo", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_you": "Você", + "pathTrace_failed": "Falha no rastreamento de caminho.", + "pathTrace_notAvailable": "Traçado de caminho não disponível.", + "pathTrace_refreshTooltip": "Atualizar Path Trace.", + "contacts_pathTrace": "Traçado de Caminho", + "contacts_ping": "Pingar", + "contacts_repeaterPathTrace": "Traçar caminho para repetidor", + "contacts_repeaterPing": "Pingar repetidor", + "contacts_roomPathTrace": "Traçar caminho para o servidor da sala", + "contacts_roomPing": "Pingar servidor da sala", + "contacts_chatTraceRoute": "Rastrear rota do caminho", + "contacts_pathTraceTo": "Rastrear rota para {name}" } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index e0c2cbe0..f007aa7c 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -774,5 +774,24 @@ "chat_openLink": "Открыть ссылку?", "chat_openLinkConfirmation": "Хотите открыть эту ссылку в вашем браузере?", "neighbors_heardAgo": "Слушал(а): {time} назад", - "chat_invalidLink": "Неправильный формат ссылки" + "chat_invalidLink": "Неправильный формат ссылки", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_you": "Вы", + "pathTrace_failed": "Путь трассировки не выполнен.", + "pathTrace_notAvailable": "Трассировка пути недоступна.", + "pathTrace_refreshTooltip": "Обновить Path Trace", + "contacts_pathTrace": "Трассировка пути", + "contacts_ping": "Пинговать", + "contacts_repeaterPathTrace": "Отследить путь к ретранслятору", + "contacts_repeaterPing": "Пинговать повторитель", + "contacts_roomPathTrace": "Трассировка пути к серверу комнаты", + "contacts_roomPing": "Пинговать сервер комнаты", + "contacts_chatTraceRoute": "Трассировка маршрута", + "contacts_pathTraceTo": "Показать маршрут к {name}" } diff --git a/lib/l10n/app_sk.arb b/lib/l10n/app_sk.arb index 71871d16..4e66af0a 100644 --- a/lib/l10n/app_sk.arb +++ b/lib/l10n/app_sk.arb @@ -1533,5 +1533,24 @@ "community_regenerateSecret": "Zobraziť nový tajný kód", "community_scanToUpdateSecret": "Skáňte nový QR kód na aktualizáciu tajného hesla pre \"{name}\"", "community_updateSecret": "Aktualizovať tajné heslo", - "community_secretUpdated": "Zmena tajnej slova pre \"{name}\"" + "community_secretUpdated": "Zmena tajnej slova pre \"{name}\"", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_you": "Vy", + "pathTrace_failed": "Sledovanie cesty zlyhalo.", + "pathTrace_notAvailable": "Path trace nie je k dispozícii.", + "pathTrace_refreshTooltip": "Obnoviť Path Trace.", + "contacts_pathTrace": "Sledovanie lúčov", + "contacts_ping": "Pingovať", + "contacts_repeaterPathTrace": "Sledovanie cesty k opakovaču", + "contacts_repeaterPing": "Pingovať opakovač", + "contacts_roomPathTrace": "Sledovanie cesty k serveru miestnosti", + "contacts_roomPing": "Ping server miestnosti", + "contacts_chatTraceRoute": "Sledovať trasu lúča", + "contacts_pathTraceTo": "Sledovať trasu k {name}" } diff --git a/lib/l10n/app_sl.arb b/lib/l10n/app_sl.arb index 977f29cd..805621b6 100644 --- a/lib/l10n/app_sl.arb +++ b/lib/l10n/app_sl.arb @@ -1,7 +1,7 @@ { "@@locale": "sl", "appTitle": "MeshCore Open", - "nav_contacts": "Kontakti", + "nav_contacts": "Stiki", "nav_channels": "Kanali", "nav_map": "Karta", "common_cancel": "Prekliči", @@ -69,49 +69,49 @@ }, "scanner_stop": "Prekliči", "scanner_scan": "Skeniraj", - "device_quickSwitch": "Hitro preklopiti", + "device_quickSwitch": "Hitro preklop", "device_meshcore": "MeshCore", "settings_title": "Nastavitve", "settings_deviceInfo": "Informacije o napravei", "settings_appSettings": "Nastavitve aplikacije", "settings_appSettingsSubtitle": "Obveščanja, sporoščanje in zemljevidi.", - "settings_nodeSettings": "Nastavitve časa", - "settings_nodeName": "Ime omrežno mesto", - "settings_nodeNameNotSet": "Nezavedeno", - "settings_nodeNameHint": "Vnesite ime časa", + "settings_nodeSettings": "Nastavitev časa", + "settings_nodeName": "Ime node-a", + "settings_nodeNameNotSet": "Ni nastavljeno", + "settings_nodeNameHint": "Vnesite ime node-a", "settings_nodeNameUpdated": "Ime posodobljeno", "settings_radioSettings": "Nastavitve radija", - "settings_radioSettingsSubtitle": "Frekvenca, moč, razširni faktor", + "settings_radioSettingsSubtitle": "Frekvenca, moč, razširitveni faktor", "settings_radioSettingsUpdated": "Radio nastavitve posodobljene", "settings_location": "Lokacija", "settings_locationSubtitle": "GPS koordinate", "settings_locationUpdated": "Lokacija posodobljena", "settings_locationBothRequired": "Vnesite širino in dolžino.", - "settings_locationInvalid": "Neveljna zemeljska širina ali dolžina.", + "settings_locationInvalid": "Neveljavna zemeljska širina ali dolžina.", "settings_latitude": "Širina", "settings_longitude": "Dolžina", - "settings_privacyMode": "Mod podjetja", + "settings_privacyMode": "Zasebnost", "settings_privacyModeSubtitle": "Skrita imena/lokacije v oglasih", "settings_privacyModeToggle": "Omogoči način zasebnosti, da skrijemo tvoje ime in lokacijo v oglasih.", - "settings_privacyModeEnabled": "Privatni režim je omogočen.", - "settings_privacyModeDisabled": "Privatni režim je onemogočen.", + "settings_privacyModeEnabled": "Privatni način je omogočen.", + "settings_privacyModeDisabled": "Privatni način je onemogočen.", "settings_actions": "Akcije", "settings_sendAdvertisement": "Pošlji Oglas", "settings_sendAdvertisementSubtitle": "Trenutna prisotnost v oddajah", "settings_advertisementSent": "Oglas poslan", - "settings_syncTime": "Ugasniti čas", - "settings_syncTimeSubtitle": "Nastavi uro naprave v čas telefona", - "settings_timeSynchronized": "Sinhronizirano po času", + "settings_syncTime": "Nastavi uro", + "settings_syncTimeSubtitle": "Nastavi uro naprave na čas telefona", + "settings_timeSynchronized": "Ura sinhronizirana", "settings_refreshContacts": "Ponovno obišči kontakte", - "settings_refreshContactsSubtitle": "Ponovno naloži seznam kontaktov iz naprave", - "settings_rebootDevice": "Restart Naprave", - "settings_rebootDeviceSubtitle": "Ponovite zažetek naprave MeshCore", - "settings_rebootDeviceConfirm": "Ste prepričani, da želite ponovno zagon napravke? Boste odvisni od omrežja.", - "settings_debug": "Napravi popravek", - "settings_bleDebugLog": "Logarjev zapis BLE", - "settings_bleDebugLogSubtitle": "Navodila BLE, odgovori in surovo podatkovno", - "settings_appDebugLog": "Log zapiske aplikacije", - "settings_appDebugLogSubtitle": "Prijavni sporočila aplikacije", + "settings_refreshContactsSubtitle": "Ponovno naloži seznam stikov v napravi", + "settings_rebootDevice": "Ponovni zagon naprave", + "settings_rebootDeviceSubtitle": "Ponovno zaženi MeshCore napravo", + "settings_rebootDeviceConfirm": "Ste prepričani, da želite ponovno zagnati napravo? Povezava bo prekinjena.", + "settings_debug": "Debug", + "settings_bleDebugLog": "BLE debug log (razhroščevanje)", + "settings_bleDebugLogSubtitle": "BLE ukazi, odgovori in surovi podatki", + "settings_appDebugLog": "Logi aplikacije", + "settings_appDebugLogSubtitle": "Debug sporočila aplikacije", "settings_about": "Oglejte si", "settings_aboutVersion": "MeshCore Open v{version}", "@settings_aboutVersion": { @@ -121,14 +121,14 @@ } } }, - "settings_aboutLegalese": "MeshCore Odprtokodni Projekt 2024", - "settings_aboutDescription": "Odprtokodni Flutter kličnik za naprave za LoRa mrežo MeshCore.", + "settings_aboutLegalese": "Odprtokodni projekt MeshCore 2024", + "settings_aboutDescription": "Odprtokodni Flutter klient za naprave za LoRa omrežje MeshCore.", "settings_infoName": "Ime", "settings_infoId": "ID", "settings_infoStatus": "Status", "settings_infoBattery": "Baterija", - "settings_infoPublicKey": "Ključ javnega tipa", - "settings_infoContactsCount": "Število kontaktov", + "settings_infoPublicKey": "Javni ključ", + "settings_infoContactsCount": "Število stikov", "settings_infoChannelCount": "Število kanalov", "settings_presets": "Prednastavitve", "settings_preset915Mhz": "915 MHz", @@ -136,15 +136,15 @@ "settings_preset433Mhz": "433 MHz", "settings_frequency": "Frekvenca (MHz)", "settings_frequencyHelper": "300,00 - 2500,00", - "settings_frequencyInvalid": "Neveljčna frekvenca (300-2500 MHz)", + "settings_frequencyInvalid": "Neveljavna frekvenca (300-2500 MHz)", "settings_bandwidth": "Pasovna širina", "settings_spreadingFactor": "Razširitveni faktor", "settings_codingRate": "Programska hitrost", "settings_txPower": "TX Moč (dBm)", "settings_txPowerHelper": "0 - 22", - "settings_txPowerInvalid": "Neveljaven TX moč (0-22 dBm)", - "settings_longRange": "Dolenje območje", - "settings_fastSpeed": "Hitra hitrost", + "settings_txPowerInvalid": "Neveljavna TX moč (0-22 dBm)", + "settings_longRange": "DDolg doseg", + "settings_fastSpeed": "Visoka hitrost", "settings_error": "Napaka: {message}", "@settings_error": { "placeholders": { @@ -156,8 +156,8 @@ "appSettings_title": "Nastavitve aplikacije", "appSettings_appearance": "Prikaži", "appSettings_theme": "Tema", - "appSettings_themeSystem": "Predpomnilnik sistema", - "appSettings_themeLight": "Luč", + "appSettings_themeSystem": "Sistemska tema", + "appSettings_themeLight": "Svetlo", "appSettings_themeDark": "Temno", "appSettings_language": "Jezik", "appSettings_languageSystem": "Sistemska privzeta vrednost", @@ -174,8 +174,8 @@ "appSettings_languageNl": "Nederlands", "appSettings_languageSk": "Slovenčina", "appSettings_languageBg": "Български", - "appSettings_notifications": "Obveščanja", - "appSettings_enableNotifications": "Omogoči obveščanje", + "appSettings_notifications": "Obvestila", + "appSettings_enableNotifications": "Omogoči obvestila", "appSettings_enableNotificationsSubtitle": "Prejmite obvestila o sporočilih in oglasih", "appSettings_notificationPermissionDenied": "Odobritev obvestila zavrnjena", "appSettings_notificationsEnabled": "Obvestila omogočena", @@ -185,19 +185,19 @@ "appSettings_channelMessageNotifications": "Obvestila o sporočilih kanala", "appSettings_channelMessageNotificationsSubtitle": "Pokaži obvestilo ob prejemanju sporočil kanala", "appSettings_advertisementNotifications": "Opozorila o oglasih", - "appSettings_advertisementNotificationsSubtitle": "Pokaži obvestilo, ko so novi vozlišči odkrivljeni.", + "appSettings_advertisementNotificationsSubtitle": "Pokaži obvestilo, ko so najdene nove naprave.", "appSettings_messaging": "Komuniciranje", "appSettings_clearPathOnMaxRetry": "Ponovite pot do cilja na največjem štetju", "appSettings_clearPathOnMaxRetrySubtitle": "Ponovi pot zimske obveščevalne poti po 5 neuspešnih poskusih pošiljanja", - "appSettings_pathsWillBeCleared": "Potnice bodo očiščene po 5 neuspešnih poskusih.", - "appSettings_pathsWillNotBeCleared": "Potniški poti ne bodo samodejno čiščeni.", - "appSettings_autoRouteRotation": "Avtomatsko Občutke in Rotacije", - "appSettings_autoRouteRotationSubtitle": "Med spreminjanjem med najboljšimi potmi in plovilnim načinom", + "appSettings_pathsWillBeCleared": "Počisti pot po 5 neuspešnih poskusih.", + "appSettings_pathsWillNotBeCleared": "Poti ne bodo samodejno čiščene.", + "appSettings_autoRouteRotation": "Avtomatsko rotacija prenosne poti", + "appSettings_autoRouteRotationSubtitle": "Menjaj med boljšo potjo in flood načinom", "appSettings_autoRouteRotationEnabled": "Samodejno krmilno rotiranje omogočeno", "appSettings_autoRouteRotationDisabled": "Samodejno krmilno rotiranje je onemogočeno", "appSettings_battery": "Baterija", - "appSettings_batteryChemistry": "Razem z možnostmi", - "appSettings_batteryChemistryPerDevice": "Nastavitve za naprave ({deviceName})", + "appSettings_batteryChemistry": "Kemija baterije", + "appSettings_batteryChemistryPerDevice": "Nastavitev za napravo ({deviceName})", "@appSettings_batteryChemistryPerDevice": { "placeholders": { "deviceName": { @@ -205,20 +205,20 @@ } } }, - "appSettings_batteryChemistryConnectFirst": "Povežite se z napravo za izbiro", + "appSettings_batteryChemistryConnectFirst": "Za izbiro se poveži z napravo", "appSettings_batteryNmc": "18650 NMC (3,0-4,2V)", "appSettings_batteryLifepo4": "LiFePO4 (2,6–3,65 V)", "appSettings_batteryLipo": "LiPo (3,0-4,2V)", - "appSettings_mapDisplay": "Prikaz zemljevide", - "appSettings_showRepeaters": "Prikaži ponovitve", - "appSettings_showRepeatersSubtitle": "Prikaži ponovljalne notranjosti na zemljeploscu", - "appSettings_showChatNodes": "Prikaži čakalne notranjosti", - "appSettings_showChatNodesSubtitle": "Prikaži pogovorni pike na zemljeploscu", - "appSettings_showOtherNodes": "Pokaži druge vozlišča", - "appSettings_showOtherNodesSubtitle": "Pokaži druge vrste notranjih elementov na zemljevalu.", - "appSettings_timeFilter": "Filtri po času", - "appSettings_timeFilterShowAll": "Pokaži vse notranje elemente", - "appSettings_timeFilterShowLast": "Pokaži notranjosti iz zadnjih {hours} ur", + "appSettings_mapDisplay": "Prikaz zemljevida", + "appSettings_showRepeaters": "Prikaži repetitorje", + "appSettings_showRepeatersSubtitle": "Prikaži repetitorje na mapi", + "appSettings_showChatNodes": "Prikaži naprave za klepet", + "appSettings_showChatNodesSubtitle": "Prikaži naprave na zemljevidu", + "appSettings_showOtherNodes": "Pokaži druge naprave", + "appSettings_showOtherNodesSubtitle": "Pokaži druge vrste naprav na zemljevidu.", + "appSettings_timeFilter": "Filter po času", + "appSettings_timeFilterShowAll": "Pokaži vse naprave", + "appSettings_timeFilterShowLast": "Pokaži naprave v zadnjih {hours} urah", "@appSettings_timeFilterShowLast": { "placeholders": { "hours": { @@ -226,15 +226,15 @@ } } }, - "appSettings_mapTimeFilter": "Filtri časa zemljevida", - "appSettings_showNodesDiscoveredWithin": "Pokaži notranje čepke, odkrivene v:", - "appSettings_allTime": "Vse čase", - "appSettings_lastHour": "Minuto nazaj", + "appSettings_mapTimeFilter": "Filter časa na zemljevidu", + "appSettings_showNodesDiscoveredWithin": "Pokaži naprave odkrite v:", + "appSettings_allTime": "Brez omejitev", + "appSettings_lastHour": "V zadnji uri", "appSettings_last6Hours": "Zadnjih 6 ur", "appSettings_last24Hours": "Zadnjih 24 ur", - "appSettings_lastWeek": "Lepošno", - "appSettings_offlineMapCache": "Omrezni Poudni Arhiv", - "appSettings_noAreaSelected": "Nizkana označena površina", + "appSettings_lastWeek": "Prejšnji teden", + "appSettings_offlineMapCache": "Shramba zemljevidov brez povezave", + "appSettings_noAreaSelected": "Območje ni izbrano", "appSettings_areaSelectedZoom": "Izbrano območje (povečava {minZoom}-{maxZoom})", "@appSettings_areaSelectedZoom": { "placeholders": { @@ -246,19 +246,19 @@ } } }, - "appSettings_debugCard": "Napravi popravek", - "appSettings_appDebugLogging": "Programski Log", - "appSettings_appDebugLoggingSubtitle": "Log aplikacijske debug sporočila za odpravljanje težav", - "appSettings_appDebugLoggingEnabled": "Omogočeno zaznamovanje napak v aplikaciji", - "appSettings_appDebugLoggingDisabled": "Programski logi aplikacije so onemogočeni.", - "contacts_title": "Kontakti", - "contacts_noContacts": "Še ni kontaktov.", - "contacts_contactsWillAppear": "Kontakti se bodo prikazali, ko naprave oglasijo.", - "contacts_searchContacts": "Iskanje kontaktov...", - "contacts_noUnreadContacts": "Nerešeno kontaktov.", - "contacts_noContactsFound": "Niti ena oseba ali skupine ni najdena.", - "contacts_deleteContact": "Izbrisati Kontakt", - "contacts_removeConfirm": "Izbrisati {contactName} iz kontaktov?", + "appSettings_debugCard": "Razhroščevanje", + "appSettings_appDebugLogging": "Programski dnevnik", + "appSettings_appDebugLoggingSubtitle": "Dnevnik debug sporočil za odpravljanje težav", + "appSettings_appDebugLoggingEnabled": "Beleženje napak v aplikaciji omogočeno", + "appSettings_appDebugLoggingDisabled": "Beleženje napak v aplikacije onemogočeno.", + "contacts_title": "Stiki", + "contacts_noContacts": "Ni stikov.", + "contacts_contactsWillAppear": "Stiki se bodo prikazali, ko se naprave oglasijo.", + "contacts_searchContacts": "Iskanje stikov...", + "contacts_noUnreadContacts": "Ne prebrani stiki.", + "contacts_noContactsFound": "Stiki niso najdeni.", + "contacts_deleteContact": "Izbriši stik", + "contacts_removeConfirm": "Izbrišem {contactName} iz stikov?", "@contacts_removeConfirm": { "placeholders": { "contactName": { @@ -266,12 +266,12 @@ } } }, - "contacts_manageRepeater": "Upravljajte Ponovitve", - "contacts_roomLogin": "Vnos v sobo", - "contacts_openChat": "Odprta kleta", - "contacts_editGroup": "Uredi Skupino", - "contacts_deleteGroup": "Izbrisati Skupino", - "contacts_deleteGroupConfirm": "Odpovedati {groupName}?", + "contacts_manageRepeater": "Upravljaj Ponovitve", + "contacts_roomLogin": "Prijava v sobo", + "contacts_openChat": "Odpri klepet", + "contacts_editGroup": "Uredi skupino", + "contacts_deleteGroup": "Izbriši skupino", + "contacts_deleteGroupConfirm": "Izbriši {groupName}?", "@contacts_deleteGroupConfirm": { "placeholders": { "groupName": { @@ -279,8 +279,8 @@ } } }, - "contacts_newGroup": "Novo skupino", - "contacts_groupName": "Skupina imena", + "contacts_newGroup": "Nova skupina", + "contacts_groupName": "Ime skupine", "contacts_groupNameRequired": "Ime skupine je obvezno.", "contacts_groupAlreadyExists": "Skupina \"{name}\" že obstaja", "@contacts_groupAlreadyExists": { @@ -290,11 +290,11 @@ } } }, - "contacts_filterContacts": "Filtri kontakt\\,...", - "contacts_noContactsMatchFilter": "Niti ena oseba ne ustreza vašemu kriteriju.", - "contacts_noMembers": "Nič članov.", - "contacts_lastSeenNow": "Datum zadnjega vpisa zdaj", - "contacts_lastSeenMinsAgo": "Zadnjič videti {minutes} minut nazaj", + "contacts_filterContacts": "Filtriraj stik\\,...", + "contacts_noContactsMatchFilter": "Noben stik ne ustreza vašemu kriteriju.", + "contacts_noMembers": "Ni članov.", + "contacts_lastSeenNow": "Nazadnje viden zdaj", + "contacts_lastSeenMinsAgo": "Zadnjič viden pred {minutes} minutami", "@contacts_lastSeenMinsAgo": { "placeholders": { "minutes": { @@ -302,8 +302,8 @@ } } }, - "contacts_lastSeenHourAgo": "Zadnjič ogledan pred 1 uro.", - "contacts_lastSeenHoursAgo": "Zadnjič videti {hours} ur nazaj", + "contacts_lastSeenHourAgo": "Zadnjič viden pred 1 uro.", + "contacts_lastSeenHoursAgo": "Zadnjič viden pred {hours} urami", "@contacts_lastSeenHoursAgo": { "placeholders": { "hours": { @@ -311,8 +311,8 @@ } } }, - "contacts_lastSeenDayAgo": "Zadnjič ogledan pred 1 dnem", - "contacts_lastSeenDaysAgo": "Zadnjič videti {days} dni nazaj", + "contacts_lastSeenDayAgo": "Zadnjič viden pred 1 dnem", + "contacts_lastSeenDaysAgo": "Zadnjič viden pred {days} dnem", "@contacts_lastSeenDaysAgo": { "placeholders": { "days": { @@ -321,10 +321,10 @@ } }, "channels_title": "Kanali", - "channels_noChannelsConfigured": "Nekonfigurirane kanale", - "channels_addPublicChannel": "Dodaj Objavni Kanal", + "channels_noChannelsConfigured": "Kanali še niso konfigurirani", + "channels_addPublicChannel": "Dodaj javni kanal", "channels_searchChannels": "Poišči kanale...", - "channels_noChannelsFound": "Niti kanalov najti ni.", + "channels_noChannelsFound": "Ne najdem kanalov.", "channels_channelIndex": "Kanal {index}", "@channels_channelIndex": { "placeholders": { @@ -334,13 +334,13 @@ } }, "channels_hashtagChannel": "Hashtag kanal", - "channels_public": "javno", - "channels_private": "Zasebno", - "channels_publicChannel": "Ogljišna skupina", - "channels_privateChannel": "Zatemniščen kanal", + "channels_public": "Javni", + "channels_private": "Zasebni", + "channels_publicChannel": "Javni kanal", + "channels_privateChannel": "Zasebni kanal", "channels_editChannel": "Uredi kanal", "channels_deleteChannel": "Pošlji kanal", - "channels_deleteChannelConfirm": "Izbrisati \"{name}\"? To se ne da povrniti.", + "channels_deleteChannelConfirm": "Izbrišem \"{name}\"? To se ne da povrniti.", "@channels_deleteChannelConfirm": { "placeholders": { "name": { @@ -424,8 +424,8 @@ } } }, - "chat_typeMessage": "Vnesite sporočilo...", - "chat_messageTooLong": "Pošiljanje sporočila je onemogočeno, saj je preveliko (maksimalno {maxBytes} bajt).", + "chat_typeMessage": "Vnesi sporočilo...", + "chat_messageTooLong": "Pošiljanje sporočila je onemogočeno, saj je preveliko (maksimalno {maxBytes} byte-ov).", "@chat_messageTooLong": { "placeholders": { "maxBytes": { @@ -433,9 +433,9 @@ } } }, - "chat_messageCopied": "Pošljeno sporočilo", - "chat_messageDeleted": "Pošiljanje sporočila izbrisano", - "chat_retryingMessage": "Ponovna poskus.", + "chat_messageCopied": "Sporočilo poslano", + "chat_messageDeleted": "Sporočilo izbrisano", + "chat_retryingMessage": "Ponovni poskus.", "chat_retryCount": "Ponovit {current}/{max}", "@chat_retryCount": { "placeholders": { @@ -448,31 +448,31 @@ } }, "chat_sendGif": "Pošlji GIF", - "chat_reply": "Odpošlji", - "chat_addReaction": "Dodaj Reakcijo", + "chat_reply": "Odgovori", + "chat_addReaction": "Dodaj reakcijo", "chat_me": "jaz", "emojiCategorySmileys": "Emoji", "emojiCategoryGestures": "Gestikulacije", "emojiCategoryHearts": "Srce", "emojiCategoryObjects": "Predmeti", "gifPicker_title": "Izberi GIF", - "gifPicker_searchHint": "Iskalite GIF-e...", - "gifPicker_poweredBy": "Naprodno z GIPHY", - "gifPicker_noGifsFound": "Niti GIF-jev najti ni.", - "gifPicker_failedLoad": "Neuspešno je naložilo GIF-e", - "gifPicker_failedSearch": "Posodobit neuspešno.", + "gifPicker_searchHint": "Išči GIF-e...", + "gifPicker_poweredBy": "Napredno z GIPHY", + "gifPicker_noGifsFound": "Ne najdem GIF-ov.", + "gifPicker_failedLoad": "Neuspešno nalaganje GIF-a", + "gifPicker_failedSearch": "Iskanje neuspešno.", "gifPicker_noInternet": "Ni internetne povezave", "debugLog_appTitle": "Log zapiske aplikacije", - "debugLog_bleTitle": "Logarjev zapis BLE", - "debugLog_copyLog": "Kopiraj zapiske", - "debugLog_clearLog": "Pasters log", - "debugLog_copied": "Kopirana belež poteka.", - "debugLog_bleCopied": "Kopirana beležke iz BLE", - "debugLog_noEntries": "Še ni ustvarjenih debug zapisov.", - "debugLog_enableInSettings": "Omogoči beleženje napak v aplikaciji v nastavitvah", - "debugLog_frames": "Okna", + "debugLog_bleTitle": "Log zapis BLE", + "debugLog_copyLog": "Kopiraj dnevnik", + "debugLog_clearLog": "Briši log", + "debugLog_copied": "Beležka kopirana.", + "debugLog_bleCopied": "Kopirana beležka iz BLE", + "debugLog_noEntries": "Ni ustvarjenih debug zapisov.", + "debugLog_enableInSettings": "Omogoči beleženje napak v nastavitvah aplikacije", + "debugLog_frames": "Okvirji", "debugLog_rawLogRx": "Svež Log-RX", - "debugLog_noBleActivity": "Šele začnite z aktivnostjo BLE.", + "debugLog_noBleActivity": "Ni BLE aktivnosti.", "debugFrame_length": "Izhodni rob: {count} bajtov", "@debugFrame_length": { "placeholders": { @@ -542,8 +542,8 @@ "chat_forceFloodMode": "Nasilje obvezati v način", "chat_recentAckPaths": "Nedavni poti ACK (tap za uporabo):", "chat_pathHistoryFull": "Zapiske o poti so popolni. Izbriši vnose, da dodaš nove.", - "chat_hopSingular": "skoč", - "chat_hopPlural": "škrabec", + "chat_hopSingular": "skok", + "chat_hopPlural": "skokov", "chat_hopsCount": "{count} {count, plural, =1{hop} other{hops}}", "@chat_hopsCount": { "placeholders": { @@ -554,16 +554,16 @@ }, "chat_successes": "Uspešni", "chat_removePath": "Izbriši pot", - "chat_noPathHistoryYet": "Še ni shranjenih poti.\nPošlji sporočilo za odkrivanje poti.", + "chat_noPathHistoryYet": "Ni shranjenih poti.\nPošlji sporočilo za odkrivanje poti.", "chat_pathActions": "Potni ukazi:", "chat_setCustomPath": "Nastavi Prilozeno Pot", "chat_setCustomPathSubtitle": "Ročno določite potniško pot.", - "chat_clearPath": "Čista pot", + "chat_clearPath": "Počisti pot", "chat_clearPathSubtitle": "Ob naslednji pošiljanju znova zbrati.", "chat_pathCleared": "Pot je očiščena. Naslednje sporočilo bo ponovno odkril pot.", "chat_floodModeSubtitle": "Uporabi tipko usmerjevanja v meniju aplikacije.", "chat_floodModeEnabled": "Narejena je bila omrežna modaliteta. Vklopi jo znova preko ikone v meniju aplikacije.", - "chat_fullPath": "Polni pot", + "chat_fullPath": "Polna pot", "chat_pathDetailsNotAvailable": "Podrobnosti poti zaenkrat niso na voljo. Poskusite poslati sporočilo za osvežitev.", "chat_pathSetHops": "Pot nastavljen: {hopCount} {hopCount, plural, =1{hop} other{hops}} - {status}", "@chat_pathSetHops": { @@ -1104,13 +1104,13 @@ } } }, - "repeater_cliQuickGetName": "Dobiti ime", + "repeater_cliQuickGetName": "Pridobi ime", "repeater_cliQuickGetRadio": "Dobiti Radiopravo", - "repeater_cliQuickGetTx": "Dobiti TX", + "repeater_cliQuickGetTx": "Pridobi TX", "repeater_cliQuickNeighbors": "Sosedi", "repeater_cliQuickVersion": "Različica", "repeater_cliQuickAdvertise": "Oglasite", - "repeater_cliQuickClock": "Urnik", + "repeater_cliQuickClock": "Ura", "repeater_cliHelpAdvert": "Pošlje paket oglasov", "repeater_cliHelpReboot": "Ponastavi naprave. (Opomba, lahko pride do 'Timeouta', kar je normalno)", "repeater_cliHelpClock": "Prikaže trenutno uro po uri naprave.", @@ -1142,7 +1142,7 @@ "repeater_cliHelpSetBridgeSecret": "Nastavi skrivni dostop za mostove ESPNOW.", "repeater_cliHelpSetAdcMultiplier": "Nastavi prilagoditev faktorja za prilagoditev poravnalnega napetosti baterije (podprt le na izbranih ploščah).", "repeater_cliHelpTempRadio": "Nastavi začasne radio parametre za določeno časovno obdobje, kar po preteku časa vrne originalne radio parametre. (ne shranjuje v preferencije).", - "repeater_cliHelpSetPerm": "Modificira ACL. Odstrani ustreznu vnos (po predponi pubkeyja), če je \"permissions\" enako nič. Dodaja nov vnos, če je pubkey-hex v celoti in trenutno ni v ACL. Posodobi vnos po ustreznem predponi pubkeyja. Bitje dovoljenj se razlikuje glede na firmware vlogo, vendar so prvi dve bitki: 0 (Gost), 1 (Lezenje samo), 2 (Lezenje in pisanje), 3 (Administrator).", + "repeater_cliHelpSetPerm": "Modificira ACL. Odstrani ustrezen vnos (po predponi pubkeyja), če je \"permissions\" enako nič. Dodaja nov vnos, če je pubkey-hex v celoti in trenutno ni v ACL. Posodobi vnos po ustreznem predponi pubkeyja. Bitje dovoljenj se razlikuje glede na firmware vlogo, vendar so prvi dve bitki: 0 (Gost), 1 (Lezenje samo), 2 (Lezenje in pisanje), 3 (Administrator).", "repeater_cliHelpGetBridgeType": "Dobrodošli pri izbiri vrste mostu: brez, rs232, espnow", "repeater_cliHelpLogStart": "Začnete beleženje paketov v datotekovni sistem.", "repeater_cliHelpLogStop": "Ustavite beleženje paketov v datotečno sistem.", @@ -1171,8 +1171,8 @@ "repeater_settingsCategory": "Nastavitve", "repeater_bridge": "Most", "repeater_logging": "Logiranje", - "repeater_neighborsRepeaterOnly": "Sosedi (le za ponovitelja)", - "repeater_regionManagementRepeaterOnly": "Upravljanje regij (zgolj za ponovitve)", + "repeater_neighborsRepeaterOnly": "Sosedi (le za repetitorje)", + "repeater_regionManagementRepeaterOnly": "Upravljanje regij (zgolj za repetitorje)", "repeater_regionNote": "Regionske ukazi so bili uvedeni za upravljanje z regijskimi definicijami in dovolili.", "repeater_gpsManagement": "Upravljanje GPS", "repeater_gpsNote": "GPS ukaz je bil uveden za upravljanje z vprašanji, povezanimi z lokacijo.", @@ -1244,9 +1244,9 @@ "channelPath_repeaterHops": "Skoki ponovitelja", "channelPath_noHopDetails": "Podrobnosti o paketu za dostavo niso navedene.", "channelPath_messageDetails": "Podrobnosti sporočila", - "channelPath_senderLabel": "Pošiljalec", - "channelPath_timeLabel": "Čas", - "channelPath_repeatsLabel": "Ponovi", + "channelPath_senderLabel": "Pošiljatelj", + "channelPath_timeLabel": "Ura", + "channelPath_repeatsLabel": "Ponovitve", "channelPath_pathLabel": "Pot {index}", "channelPath_observedLabel": "Opazovani", "channelPath_observedPathTitle": "Opazovana pot {index} • {hops}", @@ -1478,10 +1478,10 @@ "community_addPublicChannel": "Dodaj Objavni Kanal Komunitarja", "community_addPublicChannelHint": "Samodejno dodaj javni kanal za to skupnost.", "community_noCommunities": "Še nobena skupnost se ni pridružila.", - "community_scanOrCreate": "Skenirajte QR kodo ali ustvarite skupnost za začetek.", - "community_manageCommunities": "Upravljajte skupnosti", + "community_scanOrCreate": "Skeniraj QR kodo ali ustvari skupnost za začetek.", + "community_manageCommunities": "Upravljanje skupnosti", "community_delete": "Opusti skupnost", - "community_deleteConfirm": "Zapustiti \"{name}\"?", + "community_deleteConfirm": "Zapusti \"{name}\"?", "community_deleteChannelsWarning": "To bo izbrisalo tudi {count} kanal/kanalov in njihova sporočila.", "@community_deleteChannelsWarning": { "placeholders": { @@ -1491,11 +1491,11 @@ } }, "community_deleted": "Zapustil skupnost \"{name}\"", - "community_addHashtagChannel": "Dodaj Oznako Obštnine", + "community_addHashtagChannel": "Dodaj hashtag kanal", "community_addHashtagChannelDesc": "Dodajte hashtag kanal za to skupnost.", "community_selectCommunity": "Izberi skupnost", "community_regularHashtag": "Oznaka s hashtagom", - "community_regularHashtagDesc": "javna oznaka (kateri koli lahko sodelujejo)", + "community_regularHashtagDesc": "javna oznaka (kdorkoli lahko sodeluje)", "community_communityHashtag": "Skupnostni hashtag", "community_communityHashtagDesc": "Izključeno za uporabnike skupnosti", "community_forCommunity": "Za {name}", @@ -1527,11 +1527,30 @@ } } }, - "community_secretRegenerated": "Tajna za \"{name}\" ponovno ustvarjena", - "community_regenerateSecret": "Preberi nov tajni kôd", + "community_secretRegenerated": "Geslo za \"{name}\" ponovno ustvarjeno", + "community_regenerateSecret": "Ponovno ustvari geslo", "community_regenerateSecretConfirm": "Preberite novo tajno geslo za \"{name}\"? Vsi članici morajo prebrati novo QR kodo, da lahko nadaljujejo s komunikacijo.", "community_regenerate": "Preberi znova", - "community_scanToUpdateSecret": "Skeniraj nov kôd QR za posodabljanje tajne za {name}", - "community_updateSecret": "Ažurniraj tajno", - "community_secretUpdated": "Skrivnostno spremembo za \"{name}\"" + "community_scanToUpdateSecret": "Skeniraj novo QR kodo za posodabljanje ključa za {name}", + "community_updateSecret": "Ažuriraj ključ", + "community_secretUpdated": "Skrivnostno spremembo za \"{name}\"", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_you": "Ti", + "pathTrace_failed": "Sledenje poti ni uspelo.", + "pathTrace_notAvailable": "Potni sled ni na voljo.", + "pathTrace_refreshTooltip": "Osveži Path Trace.", + "contacts_pathTrace": "Sledenje poti", + "contacts_ping": "Pingati", + "contacts_repeaterPathTrace": "Sledi poti do ponavljalnika", + "contacts_repeaterPing": "Pinguj ponavljalnik", + "contacts_roomPathTrace": "Sledenje poti do strežnika sobe", + "contacts_roomPing": "Ping strežnik sobe", + "contacts_chatTraceRoute": "Slediti poti žarkov", + "contacts_pathTraceTo": "Trace route to {name}" } diff --git a/lib/l10n/app_sv.arb b/lib/l10n/app_sv.arb index f1da7c8b..da017bed 100644 --- a/lib/l10n/app_sv.arb +++ b/lib/l10n/app_sv.arb @@ -1533,5 +1533,24 @@ "community_regenerateSecret": "Regenerera hemlig kod", "community_scanToUpdateSecret": "Skanna den nya QR-koden för att uppdatera hemligheten för \"{name}\"", "community_secretUpdated": "Hemlighet uppdaterad för \"{name}\"", - "community_updateSecret": "Uppdatera hemlighet" + "community_updateSecret": "Uppdatera hemlighet", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_you": "Du", + "pathTrace_failed": "Sökvägsföljning misslyckades.", + "pathTrace_notAvailable": "Path trace ej tillgänglig.", + "pathTrace_refreshTooltip": "Uppdatera Path Trace", + "contacts_pathTrace": "Path Trace", + "contacts_ping": "Ping", + "contacts_repeaterPathTrace": "Vägspårning till repeater", + "contacts_repeaterPing": "Ping-repeater", + "contacts_roomPathTrace": "Vägspårning till rumserver", + "contacts_roomPing": "Ping rumsserver", + "contacts_chatTraceRoute": "Spåra rutt", + "contacts_pathTraceTo": "Spåra rutt till {name}" } diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb index 492805ec..85ce4a26 100644 --- a/lib/l10n/app_uk.arb +++ b/lib/l10n/app_uk.arb @@ -1534,5 +1534,24 @@ "community_secretRegenerated": "Секретний пароль для «{name}» перегенеровано", "community_scanToUpdateSecret": "Відскануйте новий QR-код, щоб оновити пароль для «{name}»", "community_updateSecret": "Оновити секрет", - "community_secretUpdated": "Зміну секрету для «{name}» оновлено" -} \ No newline at end of file + "community_secretUpdated": "Зміну секрету для «{name}» оновлено", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_you": "Ви", + "pathTrace_failed": "Відстеження шляху не вдалося.", + "pathTrace_notAvailable": "Трасування шляху недоступне.", + "pathTrace_refreshTooltip": "Оновити Path Trace", + "contacts_pathTrace": "Трасування шляхів", + "contacts_ping": "Пінгувати", + "contacts_repeaterPathTrace": "Трасування шляху до повторювача", + "contacts_repeaterPing": "Пінгувати повторювач", + "contacts_roomPathTrace": "Трасування шляху до серверу кімнати", + "contacts_roomPing": "Пінг сервера кімнати", + "contacts_chatTraceRoute": "Трасування шляху", + "contacts_pathTraceTo": "Відстежити маршрут до {name}" +} diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index ae10f604..5f0c7977 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -1533,5 +1533,24 @@ "community_regenerateSecretConfirm": "重新生成“{name}”的秘密密钥?所有成员将需要扫描新的二维码才能继续沟通。", "community_scanToUpdateSecret": "扫描新的二维码更新\"{name}\"的密码", "community_updateSecret": "更新密钥", - "community_secretUpdated": "密码已更新为“{name}”" + "community_secretUpdated": "密码已更新为“{name}”", + "@contacts_pathTraceTo": { + "placeholders": { + "name": { + "type": "String" + } + } + }, + "pathTrace_you": "你", + "pathTrace_failed": "路径追踪失败。", + "pathTrace_notAvailable": "路径追踪不可用", + "pathTrace_refreshTooltip": "刷新路径追踪", + "contacts_pathTrace": "路径追踪", + "contacts_ping": "ping", + "contacts_repeaterPathTrace": "路径追踪到中继器", + "contacts_repeaterPing": "Ping 中继器", + "contacts_roomPathTrace": "路径追踪至房间服务器", + "contacts_roomPing": "Ping 房间服务器", + "contacts_chatTraceRoute": "路径追踪", + "contacts_pathTraceTo": "追踪路由到 {name}" } diff --git a/lib/models/contact.dart b/lib/models/contact.dart index 364defff..c9e40ab7 100644 --- a/lib/models/contact.dart +++ b/lib/models/contact.dart @@ -102,6 +102,46 @@ class Contact { return parts.join(','); } + String get shortPubKeyHex { + return "<${publicKeyHex.substring(0, 8)}...${publicKeyHex.substring(publicKeyHex.length - 8)}>"; + } + + Uint8List? get traceRouteBytes { + final pathBytes = _pathBytesForDisplay; + Uint8List? traceBytes; + + if(pathLength <= 0) { + traceBytes = Uint8List(1); + traceBytes[0] = publicKey[0]; + return traceBytes; + } + + if(type == advTypeRepeater || type == advTypeRoom) { + final len = (pathBytes.length + pathBytes.length + 1); + traceBytes = Uint8List(len); + traceBytes[pathBytes.length] = publicKey[0]; + for (int i = 0; i < pathBytes.length; i++) { + traceBytes[i] = pathBytes[i]; + if (i < pathBytes.length) { + traceBytes[len-1-i] = pathBytes[i]; + } + } + } else { + if(pathBytes.length < 2) { + return pathBytes[0] == 0 ? null : pathBytes; + } + final len = (pathBytes.length + pathBytes.length-1); + traceBytes = Uint8List(len); + for (int i = 0; i < pathBytes.length; i++) { + traceBytes[i] = pathBytes[i]; + if (i < pathBytes.length-1) { + traceBytes[len-1-i] = pathBytes[i]; + } + } + } + return traceBytes; + } + Uint8List get _pathBytesForDisplay { if (pathOverride != null) { if (pathOverride! < 0) return Uint8List(0); diff --git a/lib/screens/contacts_screen.dart b/lib/screens/contacts_screen.dart index 54f819c6..d12abb07 100644 --- a/lib/screens/contacts_screen.dart +++ b/lib/screens/contacts_screen.dart @@ -1,6 +1,8 @@ import 'dart:async'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:meshcore_open/widgets/path_trace_dialog.dart'; import 'package:provider/provider.dart'; import '../connector/meshcore_connector.dart'; @@ -51,7 +53,7 @@ class _ContactsScreenState extends State final ContactGroupStore _groupStore = ContactGroupStore(); List _groups = []; Timer? _searchDebounce; - + @override void initState() { super.initState(); @@ -760,7 +762,19 @@ class _ContactsScreenState extends State child: Column( mainAxisSize: MainAxisSize.min, children: [ - if (isRepeater) + if (isRepeater) ...[ + ListTile( + leading: const Icon(Icons.radar, color: Colors.green), + title: contact.pathLength > 0 ? Text(context.l10n.contacts_pathTrace) : Text(context.l10n.contacts_ping), + onTap: () { + showDialog(context: context, builder: (context) { + return PathTraceDialog( + title: contact.pathLength > 0 ? context.l10n.contacts_repeaterPathTrace : context.l10n.contacts_repeaterPing, + path: contact.traceRouteBytes ?? Uint8List(0), + ); + }); + } + ), ListTile( leading: const Icon(Icons.cell_tower, color: Colors.orange), title: Text(context.l10n.contacts_manageRepeater), @@ -769,7 +783,19 @@ class _ContactsScreenState extends State _showRepeaterLogin(context, contact); }, ) - else if (isRoom) ...[ + ]else if (isRoom) ...[ + ListTile( + leading: const Icon(Icons.radar, color: Colors.green), + title: contact.pathLength > 0 ? Text(context.l10n.contacts_pathTrace) : Text(context.l10n.contacts_ping), + onTap: () { + showDialog(context: context, builder: (context) { + return PathTraceDialog( + title: contact.pathLength > 0 ? context.l10n.contacts_roomPathTrace : context.l10n.contacts_roomPing, + path: contact.traceRouteBytes ?? Uint8List(0), + ); + }); + } + ), ListTile( leading: const Icon(Icons.room, color: Colors.blue), title: Text(context.l10n.contacts_roomLogin), @@ -786,7 +812,20 @@ class _ContactsScreenState extends State _showRoomLogin(context, contact, RoomLoginDestination.management); }, ), - ] else + ] else ...[ + if(contact.pathLength > 0) + ListTile( + leading: const Icon(Icons.radar, color: Colors.green), + title: Text(context.l10n.contacts_chatTraceRoute), + onTap: () { + showDialog(context: context, builder: (context) { + return PathTraceDialog( + title: context.l10n.contacts_pathTraceTo(contact.name), + path: contact.traceRouteBytes ?? Uint8List(0), + ); + }); + } + ), ListTile( leading: const Icon(Icons.chat), title: Text(context.l10n.contacts_openChat), @@ -806,6 +845,7 @@ class _ContactsScreenState extends State _confirmDelete(context, connector, contact); }, ), + ], ], ), ), @@ -860,8 +900,6 @@ class _ContactTile extends StatelessWidget { @override Widget build(BuildContext context) { - final shotPublicKey = - "<${contact.publicKeyHex.substring(0, 8)}...${contact.publicKeyHex.substring(contact.publicKeyHex.length - 8)}>"; return ListTile( leading: CircleAvatar( backgroundColor: _getTypeColor(contact.type), @@ -869,7 +907,7 @@ class _ContactTile extends StatelessWidget { ), title: Text(contact.name), subtitle: Text( - '${contact.typeLabel} • ${contact.pathLabel} $shotPublicKey', + '${contact.typeLabel} • ${contact.pathLabel} ${contact.shortPubKeyHex}', ), // Clamp text scaling in trailing section to prevent overflow while // maintaining accessibility. Primary content (title/subtitle) scales normally. diff --git a/lib/screens/repeater_hub_screen.dart b/lib/screens/repeater_hub_screen.dart index 5a545f37..903f89e6 100644 --- a/lib/screens/repeater_hub_screen.dart +++ b/lib/screens/repeater_hub_screen.dart @@ -73,7 +73,7 @@ class RepeaterHubScreen extends StatelessWidget { ), const SizedBox(height: 8), Text( - '<${repeater.publicKeyHex.substring(0, 8)}...${repeater.publicKeyHex.substring(repeater.publicKeyHex.length - 8)}>', + repeater.shortPubKeyHex, style: TextStyle(fontSize: 14, color: Colors.grey[600]), ), const SizedBox(height: 8), diff --git a/lib/screens/scanner_screen.dart b/lib/screens/scanner_screen.dart index 63f4a3c0..0d38d98b 100644 --- a/lib/screens/scanner_screen.dart +++ b/lib/screens/scanner_screen.dart @@ -8,9 +8,47 @@ import '../widgets/device_tile.dart'; import 'contacts_screen.dart'; /// Screen for scanning and connecting to MeshCore devices -class ScannerScreen extends StatelessWidget { +class ScannerScreen extends StatefulWidget { const ScannerScreen({super.key}); + @override + State createState() => _ScannerScreenState(); +} + +class _ScannerScreenState extends State { + bool _changedNavigation = false; + late final VoidCallback _connectionListener; + + @override + void initState() { + super.initState(); + final connector = Provider.of(context, listen: false); + + _connectionListener = () { + if (connector.state == MeshCoreConnectionState.disconnected) { + _changedNavigation = false; + } else if (connector.state == MeshCoreConnectionState.connected && !_changedNavigation) { + _changedNavigation = true; + if (mounted) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const ContactsScreen(), + ), + ); + } + } + }; + + connector.addListener(_connectionListener); + } + + @override + void dispose() { + final connector = Provider.of(context, listen: false); + connector.removeListener(_connectionListener); + super.dispose(); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -161,15 +199,6 @@ final l10n = context.l10n; ? result.device.platformName : result.advertisementData.advName; await connector.connect(result.device, displayName: name); - - if (context.mounted && connector.isConnected) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const ContactsScreen(), - ), - ); - } } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( diff --git a/lib/services/ble_debug_log_service.dart b/lib/services/ble_debug_log_service.dart index a53ad5d9..07ac6899 100644 --- a/lib/services/ble_debug_log_service.dart +++ b/lib/services/ble_debug_log_service.dart @@ -156,6 +156,8 @@ class BleDebugLogService extends ChangeNotifier { return 'CMD_GET_RADIO_SETTINGS'; case cmdSetCustomVar: return 'CMD_SET_CUSTOM_VAR'; + case cmdSendTracePath: + return 'CMD_SEND_TRACE_PATH'; default: return null; } @@ -195,6 +197,8 @@ class BleDebugLogService extends ChangeNotifier { return 'RESP_CODE_CHANNEL_INFO'; case respCodeRadioSettings: return 'RESP_CODE_RADIO_SETTINGS'; + case pushCodeTraceData: + return 'PUSH_CODE_TRACE_DATA'; default: return null; } diff --git a/lib/widgets/path_trace_dialog.dart b/lib/widgets/path_trace_dialog.dart new file mode 100644 index 00000000..958258bc --- /dev/null +++ b/lib/widgets/path_trace_dialog.dart @@ -0,0 +1,226 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import '../connector/meshcore_connector.dart'; +import '../connector/meshcore_protocol.dart'; +import '../models/contact.dart'; +import '../widgets/snr_indicator.dart'; +import '../l10n/l10n.dart'; +class PathTraceDialog extends StatefulWidget { + + const PathTraceDialog({ + super.key, + required this.title, + required this.path, + }); + + final String title; + final Uint8List path; + + @override + State createState() => _PathTraceDialogState(); +} + +class _PathTraceDialogState extends State { + StreamSubscription? _frameSubscription; + Timer? _timeoutTimer; + + bool _isLoading = false; + bool _failed2Loaded = false; + bool _hasData = false; + Uint8List _pathData = Uint8List(0); + Uint8List _snrData = Uint8List(0) ; + Map _pathContacts = {}; + + @override + void initState() { + super.initState(); + _setupFrameListener(); + _doPathTrace(); + } + + @override + void dispose() { + _frameSubscription?.cancel(); + _timeoutTimer?.cancel(); + super.dispose(); + } + + Future _doPathTrace() async { + if(mounted) { + setState(() { + _isLoading = true; + _failed2Loaded = false; + }); + } + + final connector = Provider.of(context, listen: false); + final frame = buildTraceReq( + DateTime.now().millisecondsSinceEpoch ~/ 1000, + 0, //flags + 0, //auth + payload: widget.path, + ); + connector.sendFrame(frame); + } + + void _setupFrameListener() { + final connector = Provider.of(context, listen: false); + Uint8List tagData = Uint8List(4); + // Listen for incoming text messages from the repeater + _frameSubscription = connector.receivedFrames.listen((frame) { + if (frame.isEmpty) return; + final frameBuffer = BufferReader(frame); + final code = frameBuffer.readUInt8(); + + if (code == respCodeSent) { + frameBuffer.skipBytes(1); //reserved + tagData = frameBuffer.readBytes(4); + final timeoutSeconds = frameBuffer.readUInt32LE(); + + // Start timeout timer for trace response + _timeoutTimer?.cancel(); + _timeoutTimer = Timer(Duration(milliseconds: timeoutSeconds), () { + if (!mounted) return; + setState(() { + _isLoading = false; + _failed2Loaded = true; + }); + }); + } + + // Check if it's a binary response + if (code == pushCodeTraceData && listEquals(frame.sublist(4, 8), tagData)) { + _timeoutTimer?.cancel(); + if (!mounted) return; + frameBuffer.skipBytes(3); //reserved + path length + flag + if(listEquals(frameBuffer.readBytes(4), tagData)){ + _handleTraceResponse(frame); + } + } + }); + } + + Future _handleTraceResponse(Uint8List frame)async { + final connector = Provider.of(context, listen: false); + + final buffer = BufferReader(frame); + buffer.skipBytes(2); // Skip push code and reserved byte + int pathLength = buffer.readUInt8(); + buffer.skipBytes(5); // Skip Flag byte and tag data + buffer.skipBytes(4); // Skip auth code + Uint8List pathData = buffer.readBytes(pathLength); + Uint8List snrData = buffer.readRemainingBytes(); + + Map pathContacts = {}; + + connector.contacts.where((c) => c.type != advTypeChat).forEach(( + repeater, + ) { + for (var neighbourData in pathData) { + if (listEquals( + repeater.publicKey.sublist(0, 1), + Uint8List.fromList([neighbourData]), + )) { + pathContacts[neighbourData] = repeater; + } + } + }); + + setState(() { + _isLoading = false; + _hasData = true; + _pathData = pathData; + _snrData = snrData; + _pathContacts = pathContacts; + }); + } + + String formatDirectionText(int index) { + if (index == 0 || index == _snrData.length - 1) { + if (index == 0) { + return context.l10n.pathTrace_you; + } else { + return _pathContacts[_pathData[_pathData.length - 1]]?.name ?? "0x${_pathData[_pathData.length - 1].toRadixString(16).toUpperCase()}"; + } + } else { + return _pathContacts[_pathData[index-1]]?.name ?? "0x${_pathData[index-1].toRadixString(16).toUpperCase()}"; + } + } + String formatDirectionSubText(int index) { + if (index == 0 || index == _snrData.length - 1) { + if (index == 0) { + return _pathContacts[_pathData[0]]?.name ?? "0x${_pathData[0].toRadixString(16).toUpperCase()}"; + } else { + return context.l10n.pathTrace_you; + } + } else { + return _pathContacts[_pathData[index]]?.name ?? "0x${_pathData[index].toRadixString(16).toUpperCase()}"; + } + } + + @override + Widget build(BuildContext context) { + final l10n = context.l10n; + return AlertDialog( + title: Column( children: [ + FittedBox(fit: BoxFit.scaleDown, child: Text(widget.title, style: const TextStyle(fontSize: 24))), + if(_failed2Loaded) + Text(l10n.pathTrace_failed, style: TextStyle(fontSize: 14, color: Theme.of(context).colorScheme.error),), + ], + ), + content: SafeArea( + child: RefreshIndicator( + onRefresh: _doPathTrace, + child: !_hasData + ? Center( + child: Text(l10n.pathTrace_notAvailable), + ) + : ListView.builder( + itemCount: _snrData.length, + itemBuilder: (context, index) { + return Column( + children: [ + ListTile( + leading: index >= _snrData.length / 2 ? Icon(Icons.call_received) : Icon(Icons.call_made), + title: Text( + formatDirectionText(index), style: const TextStyle(fontSize: 14), + ), + subtitle: Text( + formatDirectionSubText(index), + style: const TextStyle(fontSize: 14), + ), + trailing: SNRIcon(snr: _snrData[index].toSigned(8) / 4.0), + onTap: () { + // Handle item tap + }, + ), + if (index < _snrData.length - 1) const Divider(height: 0.0), + ], + ); + }, + ), + ), + ), + actions: [ + IconButton( + icon: _isLoading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator(strokeWidth: 2), + ) + : const Icon(Icons.refresh), + onPressed: _isLoading ? null : _doPathTrace, + tooltip: l10n.pathTrace_refreshTooltip, + ), + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: Text(l10n.common_close), + ), + ], + ); + } +} diff --git a/lib/widgets/repeater_login_dialog.dart b/lib/widgets/repeater_login_dialog.dart index 54c01504..1f767f6c 100644 --- a/lib/widgets/repeater_login_dialog.dart +++ b/lib/widgets/repeater_login_dialog.dart @@ -322,7 +322,9 @@ class _RepeaterLoginDialogState extends State { } }, onSubmitted: (_) => _handleLogin(), - autofocus: _passwordController.text.isEmpty, + autofocus: !(defaultTargetPlatform == TargetPlatform.android || + defaultTargetPlatform == TargetPlatform.iOS) && + _passwordController.text.isEmpty, ), const SizedBox(height: 12), CheckboxListTile( diff --git a/lib/widgets/room_login_dialog.dart b/lib/widgets/room_login_dialog.dart index 838ecf8c..1d2554df 100644 --- a/lib/widgets/room_login_dialog.dart +++ b/lib/widgets/room_login_dialog.dart @@ -261,7 +261,8 @@ class _RoomLoginDialogState extends State { child: CircularProgressIndicator(), ), ) - : Column( + : SingleChildScrollView( + child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -292,7 +293,9 @@ class _RoomLoginDialogState extends State { ), ), onSubmitted: (_) => _handleLogin(), - autofocus: _passwordController.text.isEmpty, + autofocus: !(defaultTargetPlatform == TargetPlatform.android || + defaultTargetPlatform == TargetPlatform.iOS) && + _passwordController.text.isEmpty, ), const SizedBox(height: 12), CheckboxListTile( @@ -382,6 +385,7 @@ class _RoomLoginDialogState extends State { ), ], ), + ), actions: [ TextButton( onPressed: () => Navigator.pop(context), diff --git a/tools/translate.py b/tools/translate.py index 06a95f29..84d172a8 100644 --- a/tools/translate.py +++ b/tools/translate.py @@ -466,7 +466,7 @@ def fmt_duration(seconds: float) -> str: def find_missing_keys(source_data: Dict[str, Any], target_data: Dict[str, Any]) -> List[str]: - """Find keys that are in source but not in target (excluding metadata keys).""" + """Find keys that are in source but not in target, or have empty values (excluding metadata keys).""" missing = [] for key in source_data: if key == "@@locale": @@ -475,6 +475,9 @@ def find_missing_keys(source_data: Dict[str, Any], target_data: Dict[str, Any]) continue if key not in target_data: missing.append(key) + elif isinstance(target_data.get(key), str) and target_data[key].strip() == "": + # Also include keys with empty string values + missing.append(key) return missing