mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-06-29 21:50:32 +10:00
feat(localization): update contact settings translations for multiple languages
- Translated contact settings and related strings in Slovenian, Swedish, Ukrainian, Chinese, Dutch, Polish, Portuguese, Russian, and Slovak. - Added new strings for discovered contacts actions such as adding, copying, and deleting contacts. - Enhanced the DiscoveryContact model to include a rawPacket field for better data handling. - Updated the contacts screen to support new actions in the context menu for discovered contacts. - Improved the contact discovery store to handle the serialization of the new rawPacket field.
This commit is contained in:
@@ -283,6 +283,7 @@ class MeshCoreConnector extends ChangeNotifier {
|
||||
int? get batteryMillivolts => _batteryMillivolts;
|
||||
int get maxContacts => _maxContacts;
|
||||
int get maxChannels => _maxChannels;
|
||||
Set<String> get knownContactKeys => Set.unmodifiable(_knownContactKeys);
|
||||
bool get isSyncingQueuedMessages => _isSyncingQueuedMessages;
|
||||
bool get isSyncingChannels => _isSyncingChannels;
|
||||
int get channelSyncProgress =>
|
||||
@@ -1534,6 +1535,50 @@ class MeshCoreConnector extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> removeDiscoveredContact(DiscoveryContact contact) async {
|
||||
if (!isConnected) return;
|
||||
_discoveredContacts.removeWhere(
|
||||
(c) => c.publicKeyHex == contact.publicKeyHex,
|
||||
);
|
||||
unawaited(_persistDiscoveredContacts());
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> importDiscoveredContact(DiscoveryContact contact) async {
|
||||
if (!isConnected) return;
|
||||
await sendFrame(
|
||||
buildSetAutoAddConfigFrame(
|
||||
autoAddChat: true,
|
||||
autoAddRepeater: true,
|
||||
autoAddRoomServer: true,
|
||||
autoAddSensor: true,
|
||||
overwriteOldest: _overwriteOldest,
|
||||
),
|
||||
);
|
||||
await sendFrame(buildImportContactFrame(contact.rawPacket));
|
||||
await sendFrame(
|
||||
buildSetAutoAddConfigFrame(
|
||||
autoAddChat: _autoAddUsers,
|
||||
autoAddRepeater: _autoAddRepeaters,
|
||||
autoAddRoomServer: _autoAddRoomServers,
|
||||
autoAddSensor: _autoAddSensors,
|
||||
overwriteOldest: _overwriteOldest,
|
||||
),
|
||||
);
|
||||
|
||||
_handleContactAdvert(
|
||||
Contact(
|
||||
publicKey: contact.publicKey,
|
||||
name: contact.name,
|
||||
type: contact.type,
|
||||
pathLength: contact.pathLength,
|
||||
path: contact.path,
|
||||
lastSeen: DateTime.now(),
|
||||
),
|
||||
);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> clearContactPath(Contact contact) async {
|
||||
if (!isConnected) return;
|
||||
|
||||
@@ -3705,22 +3750,29 @@ class MeshCoreConnector extends ChangeNotifier {
|
||||
appLogger.warn('Malformed RX frame: $e', tag: 'Connector');
|
||||
return;
|
||||
}
|
||||
|
||||
final rawPacket = frame.sublist(3);
|
||||
switch (payloadType) {
|
||||
case payloadTypeADVERT:
|
||||
_handlePayloadAdvertReceived(payload, pathBytes, routeType, snr);
|
||||
_handlePayloadAdvertReceived(
|
||||
rawPacket,
|
||||
payload,
|
||||
pathBytes,
|
||||
routeType,
|
||||
snr,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
void _handlePayloadAdvertReceived(
|
||||
Uint8List frame,
|
||||
Uint8List rawPacket,
|
||||
Uint8List payload,
|
||||
Uint8List path,
|
||||
int routeType,
|
||||
double snr,
|
||||
) {
|
||||
final advert = BufferReader(frame);
|
||||
final advert = BufferReader(payload);
|
||||
double latitude = 0.0;
|
||||
double longitude = 0.0;
|
||||
String name = '';
|
||||
@@ -3785,7 +3837,7 @@ class MeshCoreConnector extends ChangeNotifier {
|
||||
(_autoAddSensors && type == advTypeSensor)) {
|
||||
_handleContactAdvert(newContact);
|
||||
} else {
|
||||
_handleDiscovery(newContact);
|
||||
_handleDiscovery(newContact, rawPacket);
|
||||
}
|
||||
_updateDirectRepeater(newContact, snr, path);
|
||||
return;
|
||||
@@ -3890,9 +3942,42 @@ class MeshCoreConnector extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
void _handleDiscovery(Contact contact) {
|
||||
void _handleDiscovery(Contact contact, Uint8List rawPacket) {
|
||||
debugPrint('Discovered new contact: ${contact.name}');
|
||||
|
||||
final existingIndex = _discoveredContacts.indexWhere(
|
||||
(c) => c.publicKeyHex == contact.publicKeyHex,
|
||||
);
|
||||
final existingContactsIndex = _contacts.indexWhere(
|
||||
(c) => c.publicKeyHex == contact.publicKeyHex,
|
||||
);
|
||||
|
||||
if (existingContactsIndex >= 0) {
|
||||
if (existingIndex >= 0) {
|
||||
removeDiscoveredContact(_discoveredContacts[existingIndex]);
|
||||
unawaited(_persistDiscoveredContacts());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Update existing contact
|
||||
if (existingIndex >= 0) {
|
||||
_discoveredContacts[existingIndex] = _discoveredContacts[existingIndex]
|
||||
.copyWith(
|
||||
rawPacket: rawPacket,
|
||||
name: contact.name,
|
||||
type: contact.type,
|
||||
pathLength: contact.pathLength,
|
||||
path: contact.path,
|
||||
latitude: contact.latitude,
|
||||
longitude: contact.longitude,
|
||||
lastSeen: contact.lastSeen,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final disContact = DiscoveryContact(
|
||||
rawPacket: rawPacket,
|
||||
publicKey: contact.publicKey,
|
||||
name: contact.name,
|
||||
type: contact.type,
|
||||
|
||||
@@ -114,25 +114,27 @@ class BufferWriter {
|
||||
}
|
||||
|
||||
void writeHex(String hex) {
|
||||
// Validate hex string length is even and not empty
|
||||
if (hex.isEmpty || hex.length % 2 != 0) {
|
||||
throw FormatException('Invalid hex string length: ${hex.length}');
|
||||
}
|
||||
List<int> result = [];
|
||||
for (int i = 0; i < hex.length ~/ 2; i++) {
|
||||
final hexByte = hex.substring(i * 2, i * 2 + 2);
|
||||
final byte = int.tryParse(hexByte, radix: 16);
|
||||
if (byte == null) {
|
||||
throw FormatException(
|
||||
'Invalid hex characters at position $i: $hexByte',
|
||||
);
|
||||
}
|
||||
result.add(byte);
|
||||
}
|
||||
writeBytes(Uint8List.fromList(result));
|
||||
writeBytes(hex2Uint8List(hex));
|
||||
}
|
||||
}
|
||||
|
||||
Uint8List hex2Uint8List(String hex) {
|
||||
// Validate hex string length is even and not empty
|
||||
if (hex.isEmpty || hex.length % 2 != 0) {
|
||||
throw FormatException('Invalid hex string length: ${hex.length}');
|
||||
}
|
||||
List<int> result = [];
|
||||
for (int i = 0; i < hex.length ~/ 2; i++) {
|
||||
final hexByte = hex.substring(i * 2, i * 2 + 2);
|
||||
final byte = int.tryParse(hexByte, radix: 16);
|
||||
if (byte == null) {
|
||||
throw FormatException('Invalid hex characters at position $i: $hexByte');
|
||||
}
|
||||
result.add(byte);
|
||||
}
|
||||
return Uint8List.fromList(result);
|
||||
}
|
||||
|
||||
// Command codes (to device)
|
||||
const int cmdAppStart = 1;
|
||||
const int cmdSendTxtMsg = 2;
|
||||
@@ -827,10 +829,10 @@ Uint8List buildExportContactFrame(Uint8List pubKey) {
|
||||
|
||||
// Build a import contact frame
|
||||
// [cmd][contact_frame x98+]
|
||||
Uint8List buildImportContactFrame(String contactFrame) {
|
||||
Uint8List buildImportContactFrame(Uint8List contactFrame) {
|
||||
final writer = BufferWriter();
|
||||
writer.writeByte(cmdImportContact);
|
||||
writer.writeHex(contactFrame);
|
||||
writer.writeBytes(contactFrame);
|
||||
return writer.toBytes();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user