From f0d0ca0b27dcb50a6f48cab1d2ced93db4fdb9a0 Mon Sep 17 00:00:00 2001 From: Strycher Date: Wed, 29 Jul 2026 19:53:38 -0400 Subject: [PATCH] feat(#420): remove Smaz send-side compression (Phase 1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Smaz is a client-side text convention with no MeshCore protocol or firmware support (findings: GH-315). When enabled it compressed ordinary prose into `s:`+base64, which any non-lineage client renders as garbage — the same cross-client interop failure as the old `g:` GIF token. Phase 1 of the Smaz-removal epic (GH-314): stop sending Smaz and remove the user-facing surface, while KEEPING decode so messages from lineage peers still on Smaz, and any legacy compressed rows, keep rendering. Decode removal is deferred to Phase 2 (GH-421). Removed: the Smaz branch in prepareContact/ChannelOutboundText (Cyr2Lat branch and the structured-payload guard preserved); connector state/API (the enabled maps, is*/set*SmazEnabled, ensureContactSmazSettingLoaded, the warm-up and channel loaders); the per-channel and per-contact toggles plus their mutual-exclusion; loadSmazEnabled/saveSmazEnabled and the `*_smaz_` key prefixes (stores kept, they also hold Cyr2Lat); l10n `channels_smazCompression` and the orphaned `chat_compressOutgoingMessages` across 18 locales (+ regenerated app_localizations). Retained for Phase 2: the 5 Smaz.tryDecodePrefixed decode sites and helpers/smaz.dart. Safety (verified): no storage migration, the app already persists plaintext (receive decodes before store; send stores the pre-compression text), so the `s:` form was wire-only. ACK matching is unaffected, the expected hash derives from prepare*'s output, so dropping compression keeps both sides hashing plaintext. Behavior change: the composer byte-counter now reflects raw size, so anyone who had Smaz on can type slightly fewer chars per message. Tests: gif_url_outbound_guard_test rewritten to pin plaintext passthrough and decode retention. Full suite green, analyze clean. Co-Authored-By: Claude Opus 4.8 --- lib/connector/meshcore_connector.dart | 56 +------------------ lib/l10n/app_bg.arb | 4 +- lib/l10n/app_de.arb | 4 +- lib/l10n/app_en.arb | 2 - lib/l10n/app_es.arb | 4 +- lib/l10n/app_fr.arb | 4 +- lib/l10n/app_hu.arb | 4 +- lib/l10n/app_it.arb | 4 +- lib/l10n/app_ja.arb | 4 +- lib/l10n/app_ko.arb | 4 +- lib/l10n/app_localizations.dart | 12 ---- lib/l10n/app_localizations_bg.dart | 7 --- lib/l10n/app_localizations_de.dart | 7 --- lib/l10n/app_localizations_en.dart | 6 -- lib/l10n/app_localizations_es.dart | 6 -- lib/l10n/app_localizations_fr.dart | 7 --- lib/l10n/app_localizations_hu.dart | 6 -- lib/l10n/app_localizations_it.dart | 6 -- lib/l10n/app_localizations_ja.dart | 6 -- lib/l10n/app_localizations_ko.dart | 6 -- lib/l10n/app_localizations_nl.dart | 7 --- lib/l10n/app_localizations_pl.dart | 6 -- lib/l10n/app_localizations_pt.dart | 6 -- lib/l10n/app_localizations_ru.dart | 6 -- lib/l10n/app_localizations_sk.dart | 6 -- lib/l10n/app_localizations_sl.dart | 6 -- lib/l10n/app_localizations_sv.dart | 6 -- lib/l10n/app_localizations_uk.dart | 6 -- lib/l10n/app_localizations_zh.dart | 6 -- lib/l10n/app_nl.arb | 4 +- lib/l10n/app_pl.arb | 4 +- lib/l10n/app_pt.arb | 4 +- lib/l10n/app_ru.arb | 4 +- lib/l10n/app_sk.arb | 4 +- lib/l10n/app_sl.arb | 4 +- lib/l10n/app_sv.arb | 4 +- lib/l10n/app_uk.arb | 4 +- lib/l10n/app_zh.arb | 4 +- lib/screens/channel_chat_screen.dart | 9 +-- lib/screens/channels_screen.dart | 19 ------- lib/screens/chat_screen.dart | 9 +-- lib/storage/channel_settings_store.dart | 44 --------------- lib/storage/contact_settings_store.dart | 44 --------------- lib/widgets/contact_settings_dialog.dart | 28 +--------- .../gif_url_outbound_guard_test.dart | 50 ++++++++++------- 45 files changed, 55 insertions(+), 398 deletions(-) diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index 9f4e53b..387dcfd 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -407,12 +407,10 @@ class MeshCoreConnector extends ChangeNotifier { final ChannelStore _channelStore = ChannelStore(); final UnreadStore _unreadStore = UnreadStore(); List _cachedChannels = []; - final Map _channelSmazEnabled = {}; final Map _channelCyr2LatEnabled = {}; final Map _channelCyr2LatProfileId = {}; bool _lastSentWasCliCommand = false; // Track if last sent message was a CLI command - final Map _contactSmazEnabled = {}; final Map _contactCyr2LatEnabled = {}; final Map _contactCyr2LatProfileId = {}; final Set _knownContactKeys = {}; @@ -939,18 +937,6 @@ class MeshCoreConnector extends ChangeNotifier { ); } - bool isChannelSmazEnabled(int channelIndex) { - return _channelSmazEnabled[channelIndex] ?? false; - } - - bool isContactSmazEnabled(String contactKeyHex) { - return _contactSmazEnabled[contactKeyHex] ?? false; - } - - void ensureContactSmazSettingLoaded(String contactKeyHex) { - _ensureContactSmazSettingLoaded(contactKeyHex); - } - bool isChannelCyr2LatEnabled(int channelIndex) { _ensureChannelCyr2LatSettingLoaded(channelIndex); return _channelCyr2LatEnabled[channelIndex] ?? false; @@ -1081,28 +1067,8 @@ class MeshCoreConnector extends ChangeNotifier { } } - Future setChannelSmazEnabled(int channelIndex, bool enabled) async { - _channelSmazEnabled[channelIndex] = enabled; - if (enabled) { - _channelCyr2LatEnabled[channelIndex] = false; - await _channelSettingsStore.saveCyr2LatEnabled(channelIndex, false); - } - await _channelSettingsStore.saveSmazEnabled(channelIndex, enabled); - notifyListeners(); - } - - Future setContactSmazEnabled(String contactKeyHex, bool enabled) async { - _contactSmazEnabled[contactKeyHex] = enabled; - await _contactSettingsStore.saveSmazEnabled(contactKeyHex, enabled); - notifyListeners(); - } - Future setChannelCyr2LatEnabled(int channelIndex, bool enabled) async { _channelCyr2LatEnabled[channelIndex] = enabled; - if (enabled) { - _channelSmazEnabled[channelIndex] = false; - await _channelSettingsStore.saveSmazEnabled(channelIndex, false); - } await _channelSettingsStore.saveCyr2LatEnabled(channelIndex, enabled); notifyListeners(); } @@ -1261,7 +1227,6 @@ class MeshCoreConnector extends ChangeNotifier { // contact list, which is what stalled the UI for ~44s on connect. await Future.wait([ for (final contact in cached) ...[ - _ensureContactSmazSettingLoaded(contact.publicKeyHex, notify: false), _ensureContactCyr2LatSettingLoaded(contact.publicKeyHex, notify: false), ], ]); @@ -1276,11 +1241,9 @@ class MeshCoreConnector extends ChangeNotifier { } Future loadChannelSettings({int? maxChannels}) async { - _channelSmazEnabled.clear(); _channelCyr2LatEnabled.clear(); final channelCount = maxChannels ?? _maxChannels; for (int i = 0; i < channelCount; i++) { - _channelSmazEnabled[i] = await _channelSettingsStore.loadSmazEnabled(i); _channelCyr2LatEnabled[i] = await _channelSettingsStore .loadCyr2LatEnabled(i); } @@ -6041,17 +6004,6 @@ class MeshCoreConnector extends ChangeNotifier { /// Notifying per contact rebuilds the whole tree once per contact, and each /// rebuild itself walks the contact list, so a large address book turns this /// into O(contacts^2) work on the UI isolate. - Future _ensureContactSmazSettingLoaded( - String contactKeyHex, { - bool notify = true, - }) async { - if (_contactSmazEnabled.containsKey(contactKeyHex)) return; - final enabled = await _contactSettingsStore.loadSmazEnabled(contactKeyHex); - if (_contactSmazEnabled[contactKeyHex] == enabled) return; - _contactSmazEnabled[contactKeyHex] = enabled; - if (notify) notifyListeners(); - } - Future _ensureContactCyr2LatSettingLoaded( String contactKeyHex, { bool notify = true, @@ -6131,9 +6083,7 @@ class MeshCoreConnector extends ChangeNotifier { trimmed.startsWith('m:') || trimmed.startsWith('V1|'); if (!isStructuredPayload) { - if (isContactSmazEnabled(contact.publicKeyHex)) { - return Smaz.encodeIfSmaller(text); - } else if (isContactCyr2LatEnabled(contact.publicKeyHex)) { + if (isContactCyr2LatEnabled(contact.publicKeyHex)) { final profileId = getContactCyr2LatProfileId(contact.publicKeyHex); final profile = profileId != null && _appSettingsService != null ? _appSettingsService!.getCyr2LatProfileById(profileId) @@ -6159,9 +6109,7 @@ class MeshCoreConnector extends ChangeNotifier { final isStructuredPayload = trimmed.startsWith('g:') || trimmed.startsWith('m:'); if (!isStructuredPayload) { - if (isChannelSmazEnabled(channelIndex)) { - return Smaz.encodeIfSmaller(text); - } else if (isChannelCyr2LatEnabled(channelIndex)) { + if (isChannelCyr2LatEnabled(channelIndex)) { final profileId = getChannelCyr2LatProfileId(channelIndex); final profile = profileId != null && _appSettingsService != null ? _appSettingsService!.getCyr2LatProfileById(profileId) diff --git a/lib/l10n/app_bg.arb b/lib/l10n/app_bg.arb index 75450f0..3e5a27e 100644 --- a/lib/l10n/app_bg.arb +++ b/lib/l10n/app_bg.arb @@ -390,7 +390,6 @@ } } }, - "channels_smazCompression": "Компресия SMAZ", "channels_cyr2latCompression": "Компресия Cyr2Lat", "channels_cyr2latCompressionDscr": "Заменя някои кирилични символи с латиница при изпращане.", "channels_cyr2latSettingsHeading": "Настройки на Cyr2Lat", @@ -607,7 +606,6 @@ "chat_type": "Въведете", "chat_path": "Пътекино", "chat_publicKey": "Публичен ключ", - "chat_compressOutgoingMessages": "Компресиране на изходящи съобщения", "chat_floodForced": "Потоп (принуден)", "chat_directForced": "Директно (принудително)", "chat_hopsForced": "{count} скока (принудително)", @@ -1318,7 +1316,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Брой заявки", "telemetry_error": "Неуспешно получаване на данни", "telemetry_noData": "Няма налични данни за телеметрията.", diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index e03c340..126068f 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -390,7 +390,6 @@ } } }, - "channels_smazCompression": "SMAZ-Komprimierung", "channels_cyr2latCompression": "Cyr2Lat-Komprimierung", "channels_cyr2latCompressionDscr": "Ersetzt einige kyrillische Zeichen durch lateinische Zeichen, wenn sie gesendet werden.", "channels_cyr2latSettingsHeading": "Cyr2Lat-Einstellungen", @@ -607,7 +606,6 @@ "chat_type": "Gebe ein", "chat_path": "Pfad", "chat_publicKey": "Öffentlicher Schlüssel", - "chat_compressOutgoingMessages": "Komprimieren ausgehender Nachrichten", "chat_floodForced": "Geflutet (erzwungen)", "chat_directForced": "Direkt (erzwungen)", "chat_hopsForced": "{count} Sprünge (erzwungen)", @@ -1318,7 +1316,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Anzahl der Anfragen", "telemetry_error": "Daten konnten nicht abgerufen werden", "telemetry_noData": "Keine Telemetriedaten verfügbar.", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a319bf2..5a740d8 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -629,7 +629,6 @@ } } }, - "channels_smazCompression": "SMAZ compression", "channels_cyr2latCompression": "Cyr2Lat compression", "channels_cyr2latCompressionDscr": "Replaces some Cyrillic characters with Latin characters when sending.", "channels_cyr2latSettingsHeading": "Cyr2Lat Setup", @@ -888,7 +887,6 @@ "chat_type": "Type", "chat_path": "Path", "chat_publicKey": "Public Key", - "chat_compressOutgoingMessages": "Compress outgoing messages", "chat_floodForced": "Flood (forced)", "chat_directForced": "Direct (forced)", "chat_hopsForced": "{count} hops (forced)", diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 58417d8..d182945 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -390,7 +390,6 @@ } } }, - "channels_smazCompression": "Compresión SMAZ", "channels_cyr2latCompression": "Compresión Cyr2Lat", "channels_cyr2latCompressionDscr": "Reemplaza algunos caracteres cirílicos con caracteres latinos al enviar.", "channels_cyr2latSettingsHeading": "Configuración de Cyr2Lat", @@ -607,7 +606,6 @@ "chat_type": "Escribe", "chat_path": "Ruta", "chat_publicKey": "Clave Pública", - "chat_compressOutgoingMessages": "Comprimir mensajes salientes", "chat_floodForced": "Inundación (forzada)", "chat_directForced": "Directo (forzado)", "chat_hopsForced": "{count} saltos (forzados)", @@ -1318,7 +1316,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Número de solicitudes", "telemetry_error": "No se pudieron obtener los datos", "telemetry_noData": "No hay datos de telemetría disponibles.", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index d32f029..dc4c258 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -390,7 +390,6 @@ } } }, - "channels_smazCompression": "Compression SMAZ", "channels_cyr2latCompression": "Compression Cyr2Lat", "channels_cyr2latCompressionDscr": "Remplace certains caractères cyrilliques par des caractères latins lors de l'envoi.", "channels_cyr2latSettingsHeading": "Paramètres Cyr2Lat", @@ -607,7 +606,6 @@ "chat_type": "Saisir", "chat_path": "Chemin", "chat_publicKey": "Clé Publique", - "chat_compressOutgoingMessages": "Compresser les messages sortants", "chat_floodForced": "Tout le réseau (forcée)", "chat_directForced": "Direct (forcé)", "chat_hopsForced": "{count} sauts (forcés)", @@ -1318,7 +1316,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Nombre de requêtes", "telemetry_error": "Impossible de récupérer les données", "telemetry_noData": "Aucune donnée de télémétrie disponible.", diff --git a/lib/l10n/app_hu.arb b/lib/l10n/app_hu.arb index 51cc7c6..ab33d7a 100644 --- a/lib/l10n/app_hu.arb +++ b/lib/l10n/app_hu.arb @@ -550,7 +550,6 @@ } } }, - "channels_smazCompression": "SMAZ kompresszió", "channels_cyr2latCompression": "Cyr2Lat kompresszió", "channels_cyr2latCompressionDscr": "Néhány Cirill betűt Latin betűkkel helyettesít küldéskor.", "channels_cyr2latSettingsHeading": "Cyr2Lat beállítások", @@ -780,7 +779,6 @@ "chat_type": "Típus", "chat_path": "Út", "chat_publicKey": "Nyelvkönyv", - "chat_compressOutgoingMessages": "A küldött üzenetek tömörítése", "chat_floodForced": "Áradás (kényszerített)", "chat_directForced": "Közvetlen (erélyes)", "chat_hopsForced": "{count} ánusz (erővel)", @@ -1504,7 +1502,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Kérések száma", "telemetry_error": "Nem sikerült lekérni az adatokat", "telemetry_noData": "Nincsenek elérhető telemetriadatok.", diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index 6fd027a..cdde5fe 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -390,7 +390,6 @@ } } }, - "channels_smazCompression": "Compressione SMAZ", "channels_cyr2latCompression": "Compressione Cyr2Lat", "channels_cyr2latCompressionDscr": "Sostituisce alcuni caratteri cirillici con caratteri latini durante l'invio.", "channels_cyr2latSettingsHeading": "Impostazioni Cyr2Lat", @@ -607,7 +606,6 @@ "chat_type": "Digita", "chat_path": "Percorso", "chat_publicKey": "Chiave Pubblica", - "chat_compressOutgoingMessages": "Comprimi messaggi in uscita", "chat_floodForced": "Inondazione (forzata)", "chat_directForced": "Riavvia (forzato)", "chat_hopsForced": "{count} salti (forzati)", @@ -1318,7 +1316,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Numero di richieste", "telemetry_error": "Impossibile recuperare i dati", "telemetry_noData": "Nessun dato di telemetria disponibile.", diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index 88ac881..477c683 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -550,7 +550,6 @@ } } }, - "channels_smazCompression": "SMAZ 圧縮", "channels_cyr2latCompression": "Cyr2Lat 圧縮", "channels_cyr2latCompressionDscr": "送信時に一部のキリル文字をラテン文字に置き換えます。", "channels_cyr2latSettingsHeading": "cyr2latの設定", @@ -780,7 +779,6 @@ "chat_type": "種類", "chat_path": "道", "chat_publicKey": "公開鍵", - "chat_compressOutgoingMessages": "送信されるメッセージを圧縮する", "chat_floodForced": "洪水(強制的な)", "chat_directForced": "直接的な(強制的な)", "chat_hopsForced": "{count} 本のホップ(強制的に採取)", @@ -1504,7 +1502,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "リクエスト数", "telemetry_error": "データを取得できません", "telemetry_noData": "テレメトリデータは利用できません。", diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb index d9ba986..d47f527 100644 --- a/lib/l10n/app_ko.arb +++ b/lib/l10n/app_ko.arb @@ -550,7 +550,6 @@ } } }, - "channels_smazCompression": "SMAZ 압축", "channels_cyr2latCompression": "Cyr2Lat 압축", "channels_cyr2latCompressionDscr": "보낼 때 일부 키릴 문자를 라틴 문자로 바꿉니다.", "channels_cyr2latSettingsHeading": "Cyr2Lat 설정", @@ -780,7 +779,6 @@ "chat_type": "종류", "chat_path": "경로", "chat_publicKey": "공개 키", - "chat_compressOutgoingMessages": "전송되는 메시지 압축", "chat_floodForced": "홍수 (강제)", "chat_directForced": "직접적인 (강제적인)", "chat_hopsForced": "{count}번 띄우기 (강제)", @@ -1504,7 +1502,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "요청 수", "telemetry_error": "데이터를 가져올 수 없습니다", "telemetry_noData": "텔레메트리 데이터는 제공되지 않습니다.", diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 3e2c821..08b3617 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -2380,12 +2380,6 @@ abstract class AppLocalizations { /// **'Edit Channel {index}'** String channels_editChannelTitle(int index); - /// No description provided for @channels_smazCompression. - /// - /// In en, this message translates to: - /// **'SMAZ compression'** - String get channels_smazCompression; - /// No description provided for @channels_cyr2latCompression. /// /// In en, this message translates to: @@ -3136,12 +3130,6 @@ abstract class AppLocalizations { /// **'Public Key'** String get chat_publicKey; - /// No description provided for @chat_compressOutgoingMessages. - /// - /// In en, this message translates to: - /// **'Compress outgoing messages'** - String get chat_compressOutgoingMessages; - /// No description provided for @chat_floodForced. /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_bg.dart b/lib/l10n/app_localizations_bg.dart index 391b15a..32db1ee 100644 --- a/lib/l10n/app_localizations_bg.dart +++ b/lib/l10n/app_localizations_bg.dart @@ -1286,9 +1286,6 @@ class AppLocalizationsBg extends AppLocalizations { return 'Редактирай Канал $index'; } - @override - String get channels_smazCompression => 'Компресия SMAZ'; - @override String get channels_cyr2latCompression => 'Компресия Cyr2Lat'; @@ -1737,10 +1734,6 @@ class AppLocalizationsBg extends AppLocalizations { @override String get chat_publicKey => 'Публичен ключ'; - @override - String get chat_compressOutgoingMessages => - 'Компресиране на изходящи съобщения'; - @override String get chat_floodForced => 'Потоп (принуден)'; diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index d25a0d3..8f7156c 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -1281,9 +1281,6 @@ class AppLocalizationsDe extends AppLocalizations { return 'Bearbeiteter Kanal $index'; } - @override - String get channels_smazCompression => 'SMAZ-Komprimierung'; - @override String get channels_cyr2latCompression => 'Cyr2Lat-Komprimierung'; @@ -1733,10 +1730,6 @@ class AppLocalizationsDe extends AppLocalizations { @override String get chat_publicKey => 'Öffentlicher Schlüssel'; - @override - String get chat_compressOutgoingMessages => - 'Komprimieren ausgehender Nachrichten'; - @override String get chat_floodForced => 'Geflutet (erzwungen)'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index e667496..41dac4f 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -1260,9 +1260,6 @@ class AppLocalizationsEn extends AppLocalizations { return 'Edit Channel $index'; } - @override - String get channels_smazCompression => 'SMAZ compression'; - @override String get channels_cyr2latCompression => 'Cyr2Lat compression'; @@ -1701,9 +1698,6 @@ class AppLocalizationsEn extends AppLocalizations { @override String get chat_publicKey => 'Public Key'; - @override - String get chat_compressOutgoingMessages => 'Compress outgoing messages'; - @override String get chat_floodForced => 'Flood (forced)'; diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index d8e3b54..3f9179f 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -1282,9 +1282,6 @@ class AppLocalizationsEs extends AppLocalizations { return 'Editar Canal $index'; } - @override - String get channels_smazCompression => 'Compresión SMAZ'; - @override String get channels_cyr2latCompression => 'Compresión Cyr2Lat'; @@ -1732,9 +1729,6 @@ class AppLocalizationsEs extends AppLocalizations { @override String get chat_publicKey => 'Clave Pública'; - @override - String get chat_compressOutgoingMessages => 'Comprimir mensajes salientes'; - @override String get chat_floodForced => 'Inundación (forzada)'; diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index b511813..e0ae5ed 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -1287,9 +1287,6 @@ class AppLocalizationsFr extends AppLocalizations { return 'Modifier le Canal $index'; } - @override - String get channels_smazCompression => 'Compression SMAZ'; - @override String get channels_cyr2latCompression => 'Compression Cyr2Lat'; @@ -1740,10 +1737,6 @@ class AppLocalizationsFr extends AppLocalizations { @override String get chat_publicKey => 'Clé Publique'; - @override - String get chat_compressOutgoingMessages => - 'Compresser les messages sortants'; - @override String get chat_floodForced => 'Tout le réseau (forcée)'; diff --git a/lib/l10n/app_localizations_hu.dart b/lib/l10n/app_localizations_hu.dart index db701b4..9b94203 100644 --- a/lib/l10n/app_localizations_hu.dart +++ b/lib/l10n/app_localizations_hu.dart @@ -1288,9 +1288,6 @@ class AppLocalizationsHu extends AppLocalizations { return 'Módosítsd a csatornát $index'; } - @override - String get channels_smazCompression => 'SMAZ kompresszió'; - @override String get channels_cyr2latCompression => 'Cyr2Lat kompresszió'; @@ -1743,9 +1740,6 @@ class AppLocalizationsHu extends AppLocalizations { @override String get chat_publicKey => 'Nyelvkönyv'; - @override - String get chat_compressOutgoingMessages => 'A küldött üzenetek tömörítése'; - @override String get chat_floodForced => 'Áradás (kényszerített)'; diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart index 71fad96..c9d7061 100644 --- a/lib/l10n/app_localizations_it.dart +++ b/lib/l10n/app_localizations_it.dart @@ -1283,9 +1283,6 @@ class AppLocalizationsIt extends AppLocalizations { return 'Modifica Canale $index'; } - @override - String get channels_smazCompression => 'Compressione SMAZ'; - @override String get channels_cyr2latCompression => 'Compressione Cyr2Lat'; @@ -1735,9 +1732,6 @@ class AppLocalizationsIt extends AppLocalizations { @override String get chat_publicKey => 'Chiave Pubblica'; - @override - String get chat_compressOutgoingMessages => 'Comprimi messaggi in uscita'; - @override String get chat_floodForced => 'Inondazione (forzata)'; diff --git a/lib/l10n/app_localizations_ja.dart b/lib/l10n/app_localizations_ja.dart index cabb6aa..d73a21f 100644 --- a/lib/l10n/app_localizations_ja.dart +++ b/lib/l10n/app_localizations_ja.dart @@ -1229,9 +1229,6 @@ class AppLocalizationsJa extends AppLocalizations { return 'チャンネル $index の編集'; } - @override - String get channels_smazCompression => 'SMAZ 圧縮'; - @override String get channels_cyr2latCompression => 'Cyr2Lat 圧縮'; @@ -1663,9 +1660,6 @@ class AppLocalizationsJa extends AppLocalizations { @override String get chat_publicKey => '公開鍵'; - @override - String get chat_compressOutgoingMessages => '送信されるメッセージを圧縮する'; - @override String get chat_floodForced => '洪水(強制的な)'; diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index 36c1335..0431e60 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -1224,9 +1224,6 @@ class AppLocalizationsKo extends AppLocalizations { return '채널 $index 편집'; } - @override - String get channels_smazCompression => 'SMAZ 압축'; - @override String get channels_cyr2latCompression => 'Cyr2Lat 압축'; @@ -1659,9 +1656,6 @@ class AppLocalizationsKo extends AppLocalizations { @override String get chat_publicKey => '공개 키'; - @override - String get chat_compressOutgoingMessages => '전송되는 메시지 압축'; - @override String get chat_floodForced => '홍수 (강제)'; diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index 5e0cb3c..dc97d1e 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -1273,9 +1273,6 @@ class AppLocalizationsNl extends AppLocalizations { return 'Bewerk Kanaal $index'; } - @override - String get channels_smazCompression => 'SMAZ compressie'; - @override String get channels_cyr2latCompression => 'Cyr2Lat compressie'; @@ -1721,10 +1718,6 @@ class AppLocalizationsNl extends AppLocalizations { @override String get chat_publicKey => 'Openbare Sleutel'; - @override - String get chat_compressOutgoingMessages => - 'Verzenden van uitgaande berichten comprimeren'; - @override String get chat_floodForced => 'Flood (afgedwongen)'; diff --git a/lib/l10n/app_localizations_pl.dart b/lib/l10n/app_localizations_pl.dart index 261f538..e848f8f 100644 --- a/lib/l10n/app_localizations_pl.dart +++ b/lib/l10n/app_localizations_pl.dart @@ -1292,9 +1292,6 @@ class AppLocalizationsPl extends AppLocalizations { return 'Edytuj Kanał $index'; } - @override - String get channels_smazCompression => 'Kompresja SMAZ'; - @override String get channels_cyr2latCompression => 'Kompresja Cyr2Lat'; @@ -1747,9 +1744,6 @@ class AppLocalizationsPl extends AppLocalizations { @override String get chat_publicKey => 'Klucz Publiczny'; - @override - String get chat_compressOutgoingMessages => 'Kompresuj wychodzące wiadomości'; - @override String get chat_floodForced => 'Zalew (wymuszony)'; diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index c131e8b..9b2c381 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -1282,9 +1282,6 @@ class AppLocalizationsPt extends AppLocalizations { return 'Editar Canal $index'; } - @override - String get channels_smazCompression => 'Compressão SMAZ'; - @override String get channels_cyr2latCompression => 'Compressão Cyr2Lat'; @@ -1731,9 +1728,6 @@ class AppLocalizationsPt extends AppLocalizations { @override String get chat_publicKey => 'Chave Pública'; - @override - String get chat_compressOutgoingMessages => 'Comprimir mensagens enviadas'; - @override String get chat_floodForced => 'Inundação (forçada)'; diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 9abac0b..e169fca 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -1283,9 +1283,6 @@ class AppLocalizationsRu extends AppLocalizations { return 'Изменить канал $index'; } - @override - String get channels_smazCompression => 'Сжатие SMAZ'; - @override String get channels_cyr2latCompression => 'Сжатие Cyr2Lat'; @@ -1736,9 +1733,6 @@ class AppLocalizationsRu extends AppLocalizations { @override String get chat_publicKey => 'Публичный ключ'; - @override - String get chat_compressOutgoingMessages => 'Сжимать исходящие сообщения'; - @override String get chat_floodForced => 'Рассылка (принудительно)'; diff --git a/lib/l10n/app_localizations_sk.dart b/lib/l10n/app_localizations_sk.dart index 771f252..48acee5 100644 --- a/lib/l10n/app_localizations_sk.dart +++ b/lib/l10n/app_localizations_sk.dart @@ -1273,9 +1273,6 @@ class AppLocalizationsSk extends AppLocalizations { return 'Upraviť kanál $index'; } - @override - String get channels_smazCompression => 'Odstránenie kompresie SMAZ'; - @override String get channels_cyr2latCompression => 'Odstránenie kompresie Cyr2Lat'; @@ -1724,9 +1721,6 @@ class AppLocalizationsSk extends AppLocalizations { @override String get chat_publicKey => 'Verejný kľúč'; - @override - String get chat_compressOutgoingMessages => 'Komprimovať odoslané správy'; - @override String get chat_floodForced => 'Povodňová (nutená)'; diff --git a/lib/l10n/app_localizations_sl.dart b/lib/l10n/app_localizations_sl.dart index 4a6ab6f..d73d0e6 100644 --- a/lib/l10n/app_localizations_sl.dart +++ b/lib/l10n/app_localizations_sl.dart @@ -1270,9 +1270,6 @@ class AppLocalizationsSl extends AppLocalizations { return 'Uredi Kanal $index'; } - @override - String get channels_smazCompression => 'Kompresija SMAZ'; - @override String get channels_cyr2latCompression => 'Kompresija Cyr2Lat'; @@ -1718,9 +1715,6 @@ class AppLocalizationsSl extends AppLocalizations { @override String get chat_publicKey => 'Ključ javnega tipa'; - @override - String get chat_compressOutgoingMessages => 'Stisnite izhodne sporočila'; - @override String get chat_floodForced => 'Porolni (nasilje).'; diff --git a/lib/l10n/app_localizations_sv.dart b/lib/l10n/app_localizations_sv.dart index df159d4..e448b38 100644 --- a/lib/l10n/app_localizations_sv.dart +++ b/lib/l10n/app_localizations_sv.dart @@ -1263,9 +1263,6 @@ class AppLocalizationsSv extends AppLocalizations { return 'Redigera Kanal $index'; } - @override - String get channels_smazCompression => 'SMAZ-komprimering'; - @override String get channels_cyr2latCompression => 'Cyr2Lat-komprimering'; @@ -1712,9 +1709,6 @@ class AppLocalizationsSv extends AppLocalizations { @override String get chat_publicKey => 'Allmänt nyckel'; - @override - String get chat_compressOutgoingMessages => 'Kryptera utgående meddelanden'; - @override String get chat_floodForced => 'Översvämning (tvingad)'; diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index 8d72e0d..f24414b 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -1278,9 +1278,6 @@ class AppLocalizationsUk extends AppLocalizations { return 'Редагувати канал $index'; } - @override - String get channels_smazCompression => 'Стиснення SMAZ'; - @override String get channels_cyr2latCompression => 'Стиснення Cyr2Lat'; @@ -1731,9 +1728,6 @@ class AppLocalizationsUk extends AppLocalizations { @override String get chat_publicKey => 'Відкритий ключ'; - @override - String get chat_compressOutgoingMessages => 'Стискати вихідні повідомлення'; - @override String get chat_floodForced => 'Через всю мережу (примусово)'; diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index 6e75415..aa6fa6f 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -1210,9 +1210,6 @@ class AppLocalizationsZh extends AppLocalizations { return '编辑频道 $index'; } - @override - String get channels_smazCompression => 'SMAZ 压缩'; - @override String get channels_cyr2latCompression => 'Cyr2Lat 压缩'; @@ -1630,9 +1627,6 @@ class AppLocalizationsZh extends AppLocalizations { @override String get chat_publicKey => '公钥'; - @override - String get chat_compressOutgoingMessages => '压缩发送的消息'; - @override String get chat_floodForced => '泛洪(强制)'; diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index fba0902..74c1619 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -390,7 +390,6 @@ } } }, - "channels_smazCompression": "SMAZ compressie", "channels_cyr2latCompression": "Cyr2Lat compressie", "channels_cyr2latCompressionDscr": "Vervangt sommige Cyrillische tekens door Latijnse tekens bij het verzenden.", "channels_cyr2latSettingsHeading": "Instellingen Cyr2Lat", @@ -607,7 +606,6 @@ "chat_type": "Typen", "chat_path": "Pad", "chat_publicKey": "Openbare Sleutel", - "chat_compressOutgoingMessages": "Verzenden van uitgaande berichten comprimeren", "chat_floodForced": "Flood (afgedwongen)", "chat_directForced": "Direct (afgedwongen)", "chat_hopsForced": "{count} hops (afgedwongen)", @@ -1318,7 +1316,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Aantal aanvragen", "telemetry_error": "Kan gegevens niet ophalen", "telemetry_noData": "Geen telemetriedata beschikbaar.", diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 128ed5e..65eb6dd 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -400,7 +400,6 @@ } } }, - "channels_smazCompression": "Kompresja SMAZ", "channels_cyr2latCompression": "Kompresja Cyr2Lat", "channels_cyr2latCompressionDscr": "Zastępuje niektóre znaki cyrylicy alfabetem łacińskim podczas wysyłania.", "channels_cyr2latSettingsHeading": "Ustawienia Cyr2Lat", @@ -617,7 +616,6 @@ "chat_type": "Typ", "chat_path": "Ścieżka", "chat_publicKey": "Klucz Publiczny", - "chat_compressOutgoingMessages": "Kompresuj wychodzące wiadomości", "chat_floodForced": "Zalew (wymuszony)", "chat_directForced": "Bezpośrednio (wymuszono)", "chat_hopsForced": "{count} skoków (wymuszonych)", @@ -1328,7 +1326,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Liczba żądań", "telemetry_error": "Nie udało się pobrać danych", "telemetry_noData": "Brak dostępnych danych telemetrycznych.", diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index 4e7418b..ff41163 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -390,7 +390,6 @@ } } }, - "channels_smazCompression": "Compressão SMAZ", "channels_cyr2latCompression": "Compressão Cyr2Lat", "channels_cyr2latCompressionDscr": "Substitui alguns caracteres cirílicos por caracteres latinos ao enviar.", "channels_cyr2latSettingsHeading": "Configuração do Cyr2Lat", @@ -607,7 +606,6 @@ "chat_type": "Digite", "chat_path": "Caminho", "chat_publicKey": "Chave Pública", - "chat_compressOutgoingMessages": "Comprimir mensagens enviadas", "chat_floodForced": "Inundação (forçada)", "chat_directForced": "Direto (forçado)", "chat_hopsForced": "{count} saltos (forçado)", @@ -1318,7 +1316,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Número de solicitações", "telemetry_error": "Não foi possível obter os dados", "telemetry_noData": "Não estão disponíveis dados de telemetria.", diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index ee0bb29..f1b9089 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -254,7 +254,6 @@ "channels_pskMustBe32Hex": "PSK должен содержать 32 шестнадцатеричных символа", "channels_channelAdded": "Канал \"{name}\" добавлен", "channels_editChannelTitle": "Изменить канал {index}", - "channels_smazCompression": "Сжатие SMAZ", "channels_cyr2latCompression": "Сжатие Cyr2Lat", "channels_cyr2latCompressionDscr": "Заменяет некоторые кириллические символы на латиницу при отправке.", "channels_cyr2latSettingsHeading": "Настройка Cyr2Lat", @@ -369,7 +368,6 @@ "chat_type": "Тип", "chat_path": "Маршрут", "chat_publicKey": "Публичный ключ", - "chat_compressOutgoingMessages": "Сжимать исходящие сообщения", "chat_floodForced": "Рассылка (принудительно)", "chat_directForced": "Прямой (принудительно)", "chat_hopsForced": "{count} хоп(ов) (принудительно)", @@ -724,7 +722,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Количество запросов", "telemetry_error": "Не удалось получить данные", "neighbors_receivedData": "Полученные данные о соседях", diff --git a/lib/l10n/app_sk.arb b/lib/l10n/app_sk.arb index 3a6e386..c1c03df 100644 --- a/lib/l10n/app_sk.arb +++ b/lib/l10n/app_sk.arb @@ -390,7 +390,6 @@ } } }, - "channels_smazCompression": "Odstránenie kompresie SMAZ", "channels_cyr2latCompression": "Odstránenie kompresie Cyr2Lat", "channels_cyr2latCompressionDscr": "Pri odosielaní nahradí niektoré znaky cyriliky latinskými znakmi.", "channels_cyr2latSettingsHeading": "Nastavenia Cyr2Lat", @@ -607,7 +606,6 @@ "chat_type": "Napište", "chat_path": "Cesta", "chat_publicKey": "Verejný kľúč", - "chat_compressOutgoingMessages": "Komprimovať odoslané správy", "chat_floodForced": "Povodňová (nutená)", "chat_directForced": "Priame (donútené)", "chat_hopsForced": "{count} skokov (nutené)", @@ -1318,7 +1316,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Počet požiadaviek", "telemetry_error": "Nepodarilo sa získať údaje", "telemetry_noData": "Nejsú dostupné žiadne údaje z telemetrie.", diff --git a/lib/l10n/app_sl.arb b/lib/l10n/app_sl.arb index fc943d6..31621a8 100644 --- a/lib/l10n/app_sl.arb +++ b/lib/l10n/app_sl.arb @@ -390,7 +390,6 @@ } } }, - "channels_smazCompression": "Kompresija SMAZ", "channels_cyr2latCompression": "Kompresija Cyr2Lat", "channels_cyr2latCompressionDscr": "Pri pošiljanju nekatere cirilice nadomesti z latiničnimi.", "channels_cyr2latSettingsHeading": "Nastavitve Cyr2Lat", @@ -607,7 +606,6 @@ "chat_type": "Vnesite", "chat_path": "Pot", "chat_publicKey": "Ključ javnega tipa", - "chat_compressOutgoingMessages": "Stisnite izhodne sporočila", "chat_floodForced": "Porolni (nasilje).", "chat_directForced": "Nezglašen (nasilje)", "chat_hopsForced": "{count} skoki (nasilje)", @@ -1318,7 +1316,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Število zahtev", "telemetry_error": "Podatkov ni bilo mogoče pridobiti", "telemetry_noData": "Niso na voljo podatki o telemetriji.", diff --git a/lib/l10n/app_sv.arb b/lib/l10n/app_sv.arb index 44f87ce..8eac1fd 100644 --- a/lib/l10n/app_sv.arb +++ b/lib/l10n/app_sv.arb @@ -390,7 +390,6 @@ } } }, - "channels_smazCompression": "SMAZ-komprimering", "channels_cyr2latCompression": "Cyr2Lat-komprimering", "channels_cyr2latCompressionDscr": "Ersätter vissa kyrilliska tecken med latinska tecken när du skickar.", "channels_cyr2latSettingsHeading": "Inställningar för Cyr2Lat", @@ -607,7 +606,6 @@ "chat_type": "Skriv", "chat_path": "Sökväg", "chat_publicKey": "Allmänt nyckel", - "chat_compressOutgoingMessages": "Kryptera utgående meddelanden", "chat_floodForced": "Översvämning (tvingad)", "chat_directForced": "Direkt (tvingad)", "chat_hopsForced": "{count} hopp (tvingat)", @@ -1318,7 +1316,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Antal förfrågningar", "telemetry_error": "Det gick inte att hämta data", "telemetry_noData": "Inga telemetridata tillgängliga.", diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb index 94e41e4..61081eb 100644 --- a/lib/l10n/app_uk.arb +++ b/lib/l10n/app_uk.arb @@ -393,7 +393,6 @@ } } }, - "channels_smazCompression": "Стиснення SMAZ", "channels_cyr2latCompression": "Стиснення Cyr2Lat", "channels_cyr2latCompressionDscr": "Замінює деякі кириличні символи на латиницю при відправці.", "channels_cyr2latSettingsHeading": "Налаштування Cyr2Lat", @@ -611,7 +610,6 @@ "chat_type": "Ввід", "chat_path": "Шлях", "chat_publicKey": "Відкритий ключ", - "chat_compressOutgoingMessages": "Стискати вихідні повідомлення", "chat_floodForced": "Через всю мережу (примусово)", "chat_directForced": "Напряму (примусово)", "chat_hopsForced": "{count} переходів (примусово)", @@ -1329,7 +1327,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "Кількість запитів", "telemetry_error": "Не вдалося отримати дані", "telemetry_noData": "Дані телеметрії недоступні.", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index fada6c3..17f96e0 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -405,7 +405,6 @@ } } }, - "channels_smazCompression": "SMAZ 压缩", "channels_cyr2latCompression": "Cyr2Lat 压缩", "channels_cyr2latCompressionDscr": "发送时将一些西里尔字符替换为拉丁字符。", "channels_cyr2latSettingsHeading": "Cyr2Lat 設定", @@ -634,7 +633,6 @@ "chat_type": "类型", "chat_path": "路径", "chat_publicKey": "公钥", - "chat_compressOutgoingMessages": "压缩发送的消息", "chat_floodForced": "泛洪(强制)", "chat_directForced": "直连(强制)", "chat_hopsForced": "{count} 跳(强制)", @@ -1348,7 +1346,7 @@ "telemetry_directionValue": "{degrees}°", "telemetry_concentrationValue": "{ppm} ppm", "telemetry_percentageValue": "{percent}%", - "telemetry_analogValue": "{value}", + "telemetry_analogValue": "{value}", "telemetry_autoFetchQuantity": "请求次数", "telemetry_error": "无法获取数据", "telemetry_noData": "暂无遥测数据", diff --git a/lib/screens/channel_chat_screen.dart b/lib/screens/channel_chat_screen.dart index 1007fa3..0a54cb4 100644 --- a/lib/screens/channel_chat_screen.dart +++ b/lib/screens/channel_chat_screen.dart @@ -1254,12 +1254,9 @@ class _ChannelChatScreenState extends State { hintText: context.l10n.chat_typeMessage, onSubmitted: (_) => _sendMessage(), encoder: - (connector.isChannelSmazEnabled( - _currentChannel.index, - ) || - connector.isChannelCyr2LatEnabled( - _currentChannel.index, - )) + connector.isChannelCyr2LatEnabled( + _currentChannel.index, + ) ? (text) => connector.prepareChannelOutboundText( _currentChannel.index, text, diff --git a/lib/screens/channels_screen.dart b/lib/screens/channels_screen.dart index 5d91ffd..3268e1c 100644 --- a/lib/screens/channels_screen.dart +++ b/lib/screens/channels_screen.dart @@ -1385,7 +1385,6 @@ class _ChannelsScreenState extends State ); final nameController = TextEditingController(text: channel.name); final pskController = TextEditingController(text: channel.pskHex); - bool smazEnabled = connector.isChannelSmazEnabled(channel.index); bool cyr2latEnabled = connector.isChannelCyr2LatEnabled(channel.index); String? selectedCyr2LatProfileId = connector.getChannelCyr2LatProfileId( channel.index, @@ -1431,17 +1430,6 @@ class _ChannelsScreenState extends State ), ), const SizedBox(height: 16), - SwitchListTile( - contentPadding: EdgeInsets.zero, - title: Text(dialogContext.l10n.channels_smazCompression), - value: smazEnabled, - onChanged: (value) => setState(() { - smazEnabled = value; - if (smazEnabled) { - cyr2latEnabled = false; - } - }), - ), SwitchListTile( contentPadding: EdgeInsets.zero, title: Text(dialogContext.l10n.channels_cyr2latCompression), @@ -1451,9 +1439,6 @@ class _ChannelsScreenState extends State value: cyr2latEnabled, onChanged: (value) => setState(() { cyr2latEnabled = value; - if (cyr2latEnabled) { - smazEnabled = false; - } }), ), if (cyr2latEnabled) ...[ @@ -1508,10 +1493,6 @@ class _ChannelsScreenState extends State Navigator.pop(dialogContext); try { await connector.setChannel(channel.index, name, psk); - await connector.setChannelSmazEnabled( - channel.index, - smazEnabled, - ); await connector.setChannelCyr2LatEnabled( channel.index, cyr2latEnabled, diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index 8710592..773e8df 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -674,12 +674,9 @@ class _ChatScreenState extends State { hintText: context.l10n.chat_typeMessage, onSubmitted: (_) => _sendMessage(connector), encoder: - (connector.isContactSmazEnabled( - widget.contact.publicKeyHex, - ) || - connector.isContactCyr2LatEnabled( - widget.contact.publicKeyHex, - )) + connector.isContactCyr2LatEnabled( + widget.contact.publicKeyHex, + ) ? (text) => connector.prepareContactOutboundText( widget.contact, text, diff --git a/lib/storage/channel_settings_store.dart b/lib/storage/channel_settings_store.dart index e6af56b..6c3c39c 100644 --- a/lib/storage/channel_settings_store.dart +++ b/lib/storage/channel_settings_store.dart @@ -2,58 +2,14 @@ import '../utils/app_logger.dart'; import 'prefs_manager.dart'; class ChannelSettingsStore { - static const String _keyPrefix = 'channel_smaz_'; static const String _cyr2latKeyPrefix = 'channel_cyr2lat_'; String publicKeyHex = ''; set setPublicKeyHex(String value) => publicKeyHex = value.length > 10 ? value.substring(0, 10) : ''; - String get keyFor => '$_keyPrefix$publicKeyHex'; String get keyForCyr2Lat => '$_cyr2latKeyPrefix$publicKeyHex'; - Future loadSmazEnabled(int channelIndex) async { - if (publicKeyHex.isEmpty) { - appLogger.warn( - 'Public key hex is not set. Cannot load channel settings.', - ); - return false; - } - final prefs = PrefsManager.instance; - final key = '$keyFor$channelIndex'; - final oldKey = '$_keyPrefix$channelIndex'; - bool? enabled = prefs.getBool(key); - if (enabled == null) { - // Attempt migration from legacy unscoped key on first load - // Only touch storage when a legacy key actually exists. This ran - // unconditionally, and on Windows shared_preferences re-serialises and - // rewrites the WHOLE prefs file on every mutation, so removing a key - // that was never there still cost a full multi-MB write. Repeated per - // channel/contact on connect, that blocked the UI isolate for ~38s. - enabled = prefs.getBool(oldKey); - if (enabled != null) { - appLogger.info( - 'Migrating channel settings from legacy key $oldKey to scoped key $key', - ); - await prefs.setBool(key, enabled); - await prefs.remove(oldKey); - } - } - return enabled ?? false; - } - - Future saveSmazEnabled(int channelIndex, bool enabled) async { - if (publicKeyHex.isEmpty) { - appLogger.warn( - 'Public key hex is not set. Cannot save channel settings.', - ); - return; - } - final prefs = PrefsManager.instance; - final key = '$keyFor$channelIndex'; - await prefs.setBool(key, enabled); - } - Future loadCyr2LatEnabled(int channelIndex) async { if (publicKeyHex.isEmpty) { appLogger.warn( diff --git a/lib/storage/contact_settings_store.dart b/lib/storage/contact_settings_store.dart index 109f5eb..1783258 100644 --- a/lib/storage/contact_settings_store.dart +++ b/lib/storage/contact_settings_store.dart @@ -2,58 +2,14 @@ import '../utils/app_logger.dart'; import 'prefs_manager.dart'; class ContactSettingsStore { - static const String _keyPrefix = 'contact_smaz_'; static const String _cyr2latKeyPrefix = 'contact_cyr2lat_'; String publicKeyHex = ''; set setPublicKeyHex(String value) => publicKeyHex = value.length > 10 ? value.substring(0, 10) : ''; - String get keyFor => '$_keyPrefix$publicKeyHex'; String get keyForCyr2Lat => '$_cyr2latKeyPrefix$publicKeyHex'; - Future loadSmazEnabled(String contactKeyHex) async { - if (publicKeyHex.isEmpty) { - appLogger.warn( - 'Public key hex is not set. Cannot load contact settings.', - ); - return false; - } - final prefs = PrefsManager.instance; - final key = '$keyFor$contactKeyHex'; - final oldKey = '$_keyPrefix$contactKeyHex'; - bool? enabled = prefs.getBool(key); - if (enabled == null) { - // Attempt migration from legacy unscoped key on first load - // Only touch storage when a legacy key actually exists. This ran - // unconditionally, and on Windows shared_preferences re-serialises and - // rewrites the WHOLE prefs file on every mutation, so removing a key - // that was never there still cost a full multi-MB write. Repeated per - // channel/contact on connect, that blocked the UI isolate for ~38s. - enabled = prefs.getBool(oldKey); - if (enabled != null) { - appLogger.info( - 'Migrating contact settings from legacy key $oldKey to scoped key $key', - ); - await prefs.setBool(key, enabled); - await prefs.remove(oldKey); - } - } - return prefs.getBool(key) ?? false; - } - - Future saveSmazEnabled(String contactKeyHex, bool enabled) async { - if (publicKeyHex.isEmpty) { - appLogger.warn( - 'Public key hex is not set. Cannot save contact settings.', - ); - return; - } - final prefs = PrefsManager.instance; - final key = '$keyFor$contactKeyHex'; - await prefs.setBool(key, enabled); - } - Future loadCyr2LatEnabled(String contactKeyHex) async { if (publicKeyHex.isEmpty) { appLogger.warn( diff --git a/lib/widgets/contact_settings_dialog.dart b/lib/widgets/contact_settings_dialog.dart index d22777e..31c3265 100644 --- a/lib/widgets/contact_settings_dialog.dart +++ b/lib/widgets/contact_settings_dialog.dart @@ -6,7 +6,7 @@ import '../l10n/l10n.dart'; import '../models/contact.dart'; import '../services/app_settings_service.dart'; -/// The per-contact settings dialog (Smaz/Cyr2Lat compression + telemetry +/// The per-contact settings dialog (Cyr2Lat compression + telemetry /// grants). Shared so it can be opened from the chat ellipsis AND the contacts /// long-press menu without duplicating the body (#351). void showContactSettingsDialog(BuildContext context, Contact contact) { @@ -15,9 +15,7 @@ void showContactSettingsDialog(BuildContext context, Contact contact) { context, listen: false, ); - connector.ensureContactSmazSettingLoaded(contact.publicKeyHex); connector.ensureContactCyr2LatSettingLoaded(contact.publicKeyHex); - bool smazEnabled = connector.isContactSmazEnabled(contact.publicKeyHex); bool cyr2latEnabled = connector.isContactCyr2LatEnabled(contact.publicKeyHex); String? selectedCyr2LatProfileId = connector.getContactCyr2LatProfileId( contact.publicKeyHex, @@ -42,26 +40,6 @@ void showContactSettingsDialog(BuildContext context, Contact contact) { ), const Divider(height: 8), ], - SwitchListTile( - contentPadding: EdgeInsets.zero, - title: Text(context.l10n.channels_smazCompression), - subtitle: Text(context.l10n.chat_compressOutgoingMessages), - value: smazEnabled, - onChanged: (value) { - connector.setContactSmazEnabled(contact.publicKeyHex, value); - connector.setContactCyr2LatEnabled( - contact.publicKeyHex, - false, - ); - setDialogState(() { - smazEnabled = value; - if (smazEnabled) { - cyr2latEnabled = false; - } - }); - }, - ), - const Divider(height: 8), SwitchListTile( contentPadding: EdgeInsets.zero, title: Text(context.l10n.channels_cyr2latCompression), @@ -72,12 +50,8 @@ void showContactSettingsDialog(BuildContext context, Contact contact) { contact.publicKeyHex, value, ); - connector.setContactSmazEnabled(contact.publicKeyHex, false); setDialogState(() { cyr2latEnabled = value; - if (cyr2latEnabled) { - smazEnabled = false; - } }); }, ), diff --git a/test/connector/gif_url_outbound_guard_test.dart b/test/connector/gif_url_outbound_guard_test.dart index 86c6fef..1238a73 100644 --- a/test/connector/gif_url_outbound_guard_test.dart +++ b/test/connector/gif_url_outbound_guard_test.dart @@ -5,10 +5,11 @@ import 'package:meshcore_open/helpers/smaz.dart'; import 'package:meshcore_open/storage/prefs_manager.dart'; import 'package:shared_preferences/shared_preferences.dart'; -// #282: the GIF payload is now a URL. Outbound text prep skips Smaz/Cyr2Lat for -// "structured payloads" (it keyed on `g:`/`m:`/`V1|`). A transformed GIF URL -// would arrive as opaque `s:`-prefixed base64 on a stock client, which is worse -// than the raw text this change exists to fix. Pin that it survives intact. +// #420: Smaz send-side compression is removed. Outbound text is no longer +// compressed on any channel/contact (the toggle is gone), so +// prepare*OutboundText passes text through verbatim. Decode is deliberately +// RETAINED (Phase 2 = #421) so messages from lineage peers still sending `s:`, +// and any legacy compressed rows, keep rendering. void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -20,25 +21,32 @@ void main() { await PrefsManager.initialize(); }); - test('Smaz leaves the GIF URL intact on a Smaz-enabled channel', () async { - final connector = MeshCoreConnector(); - await connector.setChannelSmazEnabled(0, true); + group('outbound text is never compressed (#420)', () { + test('a GIF URL passes through unchanged', () { + final connector = MeshCoreConnector(); + final payload = GifHelper.encodeGif(gifId); + final prepared = connector.prepareChannelOutboundText(0, payload); + expect(prepared, payload); + expect(prepared.startsWith('s:'), isFalse); + expect(GifHelper.parseGif(prepared), gifId); + }); - final payload = GifHelper.encodeGif(gifId); - final prepared = connector.prepareChannelOutboundText(0, payload); - - expect(prepared, payload); - expect(prepared.startsWith('s:'), isFalse); - expect(GifHelper.parseGif(prepared), gifId); + test('a compressible sentence is sent verbatim, not s:-encoded', () { + final connector = MeshCoreConnector(); + const sentence = 'hey are you there right now over and to the other end'; + final prepared = connector.prepareChannelOutboundText(0, sentence); + expect(prepared, sentence); + expect(prepared.startsWith('s:'), isFalse); + }); }); - test('Smaz declines to compress a GIF URL at all', () { - // Why the outbound `g:`/`m:`/`V1|` structured-payload guard did not need - // widening for #282: encodeIfSmaller only swaps in the `s:`+base64 form - // when it is genuinely smaller, and base64 overhead exceeds any dictionary - // gain on a URL. Pinned so a future dictionary change cannot silently start - // compressing GIF URLs into something a stock client cannot read. - final payload = GifHelper.encodeGif(gifId); - expect(Smaz.encodeIfSmaller(payload), payload); + group('receive decode is retained for lineage peers (Phase 2 = #421)', () { + test('an s:-compressed payload still decodes back to plaintext', () { + const sentence = 'hey are you there right now over and to the other end'; + final compressed = Smaz.encodeIfSmaller(sentence); + // Guard the guard: the sample must actually compress, else vacuous. + expect(compressed.startsWith('s:'), isTrue); + expect(Smaz.tryDecodePrefixed(compressed), sentence); + }); }); }