mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
Fix duplicate self messages
This commit is contained in:
@@ -292,6 +292,16 @@ class AppProvider with ChangeNotifier {
|
||||
String? _resolveContactNameForNotification(Uint8List? publicKey) {
|
||||
if (publicKey == null || publicKey.isEmpty) return null;
|
||||
|
||||
final ownPublicKey = connectionProvider.deviceInfo.publicKey;
|
||||
final ownName =
|
||||
connectionProvider.deviceInfo.deviceName ??
|
||||
connectionProvider.deviceInfo.selfName;
|
||||
if (_matchesPublicKeyPrefix(publicKey, ownPublicKey) &&
|
||||
ownName != null &&
|
||||
ownName.trim().isNotEmpty) {
|
||||
return ownName;
|
||||
}
|
||||
|
||||
Contact? contact;
|
||||
if (publicKey.length >= 32) {
|
||||
contact = contactsProvider.findContactByKey(publicKey);
|
||||
@@ -304,6 +314,60 @@ class AppProvider with ChangeNotifier {
|
||||
return contact?.advName;
|
||||
}
|
||||
|
||||
static bool shouldIgnoreSelfReplay({
|
||||
required Message message,
|
||||
required Uint8List? ownPublicKey,
|
||||
required String? ownName,
|
||||
}) {
|
||||
if ((!message.isContactMessage && !message.isChannelMessage) ||
|
||||
message.pathLen > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_matchesPublicKeyPrefix(message.senderPublicKeyPrefix, ownPublicKey)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final trimmedSenderName = message.senderName?.trim();
|
||||
final trimmedOwnName = ownName?.trim();
|
||||
if (trimmedSenderName == null ||
|
||||
trimmedSenderName.isEmpty ||
|
||||
trimmedOwnName == null ||
|
||||
trimmedOwnName.isEmpty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return trimmedSenderName == trimmedOwnName;
|
||||
}
|
||||
|
||||
static bool _matchesPublicKeyPrefix(
|
||||
Uint8List? candidateKey,
|
||||
Uint8List? ownPublicKey,
|
||||
) {
|
||||
if (candidateKey == null ||
|
||||
candidateKey.isEmpty ||
|
||||
ownPublicKey == null ||
|
||||
ownPublicKey.isEmpty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final compareLength = candidateKey.length >= 6 && ownPublicKey.length >= 6
|
||||
? 6
|
||||
: (candidateKey.length < ownPublicKey.length
|
||||
? candidateKey.length
|
||||
: ownPublicKey.length);
|
||||
if (compareLength <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var index = 0; index < compareLength; index++) {
|
||||
if (candidateKey[index] != ownPublicKey[index]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Load map enabled setting from shared preferences
|
||||
Future<void> _loadMapEnabled() async {
|
||||
try {
|
||||
@@ -850,6 +914,17 @@ class AppProvider with ChangeNotifier {
|
||||
|
||||
// When a message is received
|
||||
connectionProvider.onMessageReceived = (message) {
|
||||
if (AppProvider.shouldIgnoreSelfReplay(
|
||||
message: message,
|
||||
ownPublicKey: connectionProvider.deviceInfo.publicKey,
|
||||
ownName:
|
||||
connectionProvider.deviceInfo.deviceName ??
|
||||
connectionProvider.deviceInfo.selfName,
|
||||
)) {
|
||||
debugPrint('⏭️ [AppProvider] Ignoring self replay: ${message.id}');
|
||||
return;
|
||||
}
|
||||
|
||||
// Enrich message with sender name from contacts first
|
||||
Message enrichedMessage = message;
|
||||
Contact? senderContact;
|
||||
|
||||
@@ -505,6 +505,7 @@ class MessagesProvider with ChangeNotifier {
|
||||
);
|
||||
}
|
||||
}
|
||||
enhancedMessage = _resolveSenderNameIfNeeded(enhancedMessage);
|
||||
|
||||
// For channel messages with sender name, try to link with contact
|
||||
Message finalMessage = enhancedMessage;
|
||||
@@ -634,17 +635,36 @@ class MessagesProvider with ChangeNotifier {
|
||||
if (existing.channelIdx != message.channelIdx) {
|
||||
return false;
|
||||
}
|
||||
final existingSender = existing.senderKeyShort ?? existing.senderName;
|
||||
final incomingSender = message.senderKeyShort ?? message.senderName;
|
||||
if (existingSender == incomingSender) {
|
||||
final existingSenderKey = existing.senderKeyShort;
|
||||
final incomingSenderKey = message.senderKeyShort;
|
||||
if (existingSenderKey != null &&
|
||||
incomingSenderKey != null &&
|
||||
existingSenderKey == incomingSenderKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// When we send to a channel we add a local "sent" bubble immediately,
|
||||
// then firmware may later sync back the same message as a received
|
||||
// channel item with only the public sender handle. Only fold that replay
|
||||
// into the original bubble after LOG_RX_DATA has already confirmed it as
|
||||
// our own transmitted packet.
|
||||
final existingSenderName = _normalizeSenderName(existing.senderName);
|
||||
final incomingSenderName = _normalizeSenderName(message.senderName);
|
||||
if (existingSenderName != null &&
|
||||
incomingSenderName != null &&
|
||||
existingSenderName == incomingSenderName) {
|
||||
if (!existing.isSentMessage && !message.isSentMessage) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// When we send to a channel we add a local "sent" bubble immediately,
|
||||
// then firmware may later sync back the same message as a received
|
||||
// channel item under our public handle. Only fold that replay into the
|
||||
// original bubble after LOG_RX_DATA has already confirmed it as our
|
||||
// transmitted packet.
|
||||
if (existing.isSentMessage &&
|
||||
existing.echoCount > 0 &&
|
||||
!message.isSentMessage &&
|
||||
(existing.senderTimestamp - message.senderTimestamp).abs() <= 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (existing.isSentMessage &&
|
||||
existing.echoCount > 0 &&
|
||||
!message.isSentMessage &&
|
||||
@@ -694,6 +714,29 @@ class MessagesProvider with ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
String? _normalizeSenderName(String? value) {
|
||||
final trimmed = value?.trim();
|
||||
if (trimmed == null || trimmed.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
return trimmed.toLowerCase();
|
||||
}
|
||||
|
||||
Message _resolveSenderNameIfNeeded(Message message) {
|
||||
if (message.senderName != null || message.senderPublicKeyPrefix == null) {
|
||||
return message;
|
||||
}
|
||||
|
||||
final resolvedSenderName = resolveContactNameCallback?.call(
|
||||
message.senderPublicKeyPrefix,
|
||||
);
|
||||
if (resolvedSenderName == null || resolvedSenderName.trim().isEmpty) {
|
||||
return message;
|
||||
}
|
||||
|
||||
return message.copyWith(senderName: resolvedSenderName.trim());
|
||||
}
|
||||
|
||||
/// Trigger urgent notification for SAR marker
|
||||
Future<void> _triggerSarNotification(
|
||||
Message message,
|
||||
@@ -1251,6 +1294,7 @@ class MessagesProvider with ChangeNotifier {
|
||||
);
|
||||
}
|
||||
}
|
||||
enhancedMessage = _resolveSenderNameIfNeeded(enhancedMessage);
|
||||
|
||||
// Check for duplicates (shouldn't happen for sent messages, but be safe)
|
||||
if (_findDuplicateMessageIndex(enhancedMessage) != -1) {
|
||||
|
||||
Reference in New Issue
Block a user