Added Cyr2Lat compression by replacing 2-byte cyrillic chars by 1-byte latin

This commit is contained in:
HDDen
2026-04-22 03:59:43 +03:00
parent 6b6a881c7a
commit 609d0c8dbc
47 changed files with 1350 additions and 12 deletions
+63 -4
View File
@@ -16,6 +16,7 @@ import '../models/message.dart';
import '../models/path_selection.dart';
import '../models/translation_support.dart';
import '../helpers/reaction_helper.dart';
import '../helpers/cyr2lat.dart';
import '../helpers/smaz.dart';
import '../services/app_debug_log_service.dart';
import '../services/ble_debug_log_service.dart';
@@ -283,9 +284,11 @@ class MeshCoreConnector extends ChangeNotifier {
final UnreadStore _unreadStore = UnreadStore();
List<Channel> _cachedChannels = [];
final Map<int, bool> _channelSmazEnabled = {};
final Map<int, bool> _channelCyr2LatEnabled = {};
bool _lastSentWasCliCommand =
false; // Track if last sent message was a CLI command
final Map<String, bool> _contactSmazEnabled = {};
final Map<String, bool> _contactCyr2LatEnabled = {};
final Set<String> _knownContactKeys = {};
final Map<String, int> _contactUnreadCount = {};
final Map<String, RepeaterBatterySnapshot> _repeaterBatterySnapshots = {};
@@ -607,6 +610,18 @@ class MeshCoreConnector extends ChangeNotifier {
_ensureContactSmazSettingLoaded(contactKeyHex);
}
bool isChannelCyr2LatEnabled(int channelIndex) {
return _channelCyr2LatEnabled[channelIndex] ?? false;
}
bool isContactCyr2LatEnabled(String contactKeyHex) {
return _contactCyr2LatEnabled[contactKeyHex] ?? false;
}
void ensureContactCyr2LatSettingLoaded(String contactKeyHex) {
_ensureContactCyr2LatSettingLoaded(contactKeyHex);
}
Future<void> loadUnreadState() async {
_contactUnreadCount
..clear()
@@ -682,6 +697,10 @@ class MeshCoreConnector extends ChangeNotifier {
Future<void> 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();
}
@@ -692,6 +711,25 @@ class MeshCoreConnector extends ChangeNotifier {
notifyListeners();
}
Future<void> 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();
}
Future<void> setContactCyr2LatEnabled(
String contactKeyHex,
bool enabled,
) async {
_contactCyr2LatEnabled[contactKeyHex] = enabled;
await _contactSettingsStore.saveCyr2LatEnabled(contactKeyHex, enabled);
notifyListeners();
}
Future<void> _loadChannelOrder() async {
_channelOrder = await _channelOrderStore.loadChannelOrder();
_applyChannelOrder();
@@ -828,6 +866,7 @@ class MeshCoreConnector extends ChangeNotifier {
..addAll(cached);
for (final contact in cached) {
_ensureContactSmazSettingLoaded(contact.publicKeyHex);
_ensureContactCyr2LatSettingLoaded(contact.publicKeyHex);
}
}
@@ -840,9 +879,12 @@ class MeshCoreConnector extends ChangeNotifier {
Future<void> 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);
}
}
@@ -4432,6 +4474,15 @@ class MeshCoreConnector extends ChangeNotifier {
});
}
void _ensureContactCyr2LatSettingLoaded(String contactKeyHex) {
if (_contactCyr2LatEnabled.containsKey(contactKeyHex)) return;
_contactSettingsStore.loadCyr2LatEnabled(contactKeyHex).then((enabled) {
if (_contactCyr2LatEnabled[contactKeyHex] == enabled) return;
_contactCyr2LatEnabled[contactKeyHex] = enabled;
notifyListeners();
});
}
/// Prepares contact outbound text by applying SMAZ encoding if enabled.
/// This should be used to transform text before computing ACK hashes.
String prepareContactOutboundText(Contact contact, String text) {
@@ -4440,8 +4491,12 @@ class MeshCoreConnector extends ChangeNotifier {
trimmed.startsWith('g:') ||
trimmed.startsWith('m:') ||
trimmed.startsWith('V1|');
if (!isStructuredPayload && isContactSmazEnabled(contact.publicKeyHex)) {
return Smaz.encodeIfSmaller(text);
if (!isStructuredPayload) {
if (isContactSmazEnabled(contact.publicKeyHex)) {
return Smaz.encodeIfSmaller(text);
} else if (isContactCyr2LatEnabled(contact.publicKeyHex)) {
return Cyr2Lat.encode(text);
}
}
return text;
}
@@ -4450,8 +4505,12 @@ class MeshCoreConnector extends ChangeNotifier {
final trimmed = text.trim();
final isStructuredPayload =
trimmed.startsWith('g:') || trimmed.startsWith('m:');
if (!isStructuredPayload && isChannelSmazEnabled(channelIndex)) {
return Smaz.encodeIfSmaller(text);
if (!isStructuredPayload) {
if (isChannelSmazEnabled(channelIndex)) {
return Smaz.encodeIfSmaller(text);
} else if (isChannelCyr2LatEnabled(channelIndex)) {
return Cyr2Lat.encode(text);
}
}
return text;
}