From fe156108b585d824f9768ebb4cc56894721396b8 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Mon, 1 Nov 2021 15:03:05 -0700 Subject: [PATCH] Rely on Index from NewGroupMessage to sync Timelines --- LIBCWTCH-GO.version | 2 +- lib/cwtch/cwtchNotifier.dart | 51 +++++++++++++++++----------- lib/models/messages/textmessage.dart | 2 +- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/LIBCWTCH-GO.version b/LIBCWTCH-GO.version index 1df52e42..f0e8a400 100644 --- a/LIBCWTCH-GO.version +++ b/LIBCWTCH-GO.version @@ -1 +1 @@ -v1.3.0-3-gfcc9d71-2021-09-30-23-09 \ No newline at end of file +v1.3.1-8-g4529984-2021-11-01-22-03 \ No newline at end of file diff --git a/lib/cwtch/cwtchNotifier.dart b/lib/cwtch/cwtchNotifier.dart index 90071154..7119233a 100644 --- a/lib/cwtch/cwtchNotifier.dart +++ b/lib/cwtch/cwtchNotifier.dart @@ -145,24 +145,34 @@ class CwtchNotifier { break; case "NewMessageFromGroup": if (data["ProfileOnion"] != data["RemotePeer"]) { - //if not currently open - if (appState.selectedProfile != data["ProfileOnion"] || appState.selectedConversation != data["GroupID"]) { - profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["GroupID"])!.unreadMessages++; + var idx = int.parse(data["Index"]); + var currentTotal = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["GroupID"])!.totalMessages; + + // Only bother to do anything if we know about the group and the provided index is greater than our current total... + if (currentTotal != null) { + if (idx >= currentTotal) { + profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["GroupID"])!.totalMessages = idx + 1; + + //if not currently open + if (appState.selectedProfile != data["ProfileOnion"] || appState.selectedConversation != data["GroupID"]) { + profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["GroupID"])!.unreadMessages++; + } + + var timestampSent = DateTime.tryParse(data['TimestampSent'])!; + // TODO: There are 2 timestamps associated with a new group message - time sent and time received. + // Sent refers to the time a profile alleges they sent a message + // Received refers to the time we actually saw the message from the server + // These can obviously be very different for legitimate reasons. + // We also maintain a relative hash-link through PreviousMessageSignature which is the ground truth for + // order. + // In the future we will want to combine these 3 ordering mechanisms into a cohesive view of the timeline + // For now we perform some minimal checks on the sent timestamp to use to provide a useful ordering for honest contacts + // and ensure that malicious contacts in groups can only set this timestamp to a value within the range of `last seen message time` + // and `local now`. + profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(data["GroupID"], timestampSent.toLocal()); + notificationManager.notify("New Message From Group!"); + } } - profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["GroupID"])!.totalMessages++; - var timestampSent = DateTime.tryParse(data['TimestampSent'])!; - // TODO: There are 2 timestamps associated with a new group message - time sent and time received. - // Sent refers to the time a profile alleges they sent a message - // Received refers to the time we actually saw the message from the server - // These can obviously be very different for legitimate reasons. - // We also maintain a relative hash-link through PreviousMessageSignature which is the ground truth for - // order. - // In the future we will want to combine these 3 ordering mechanisms into a cohesive view of the timeline - // For now we perform some minimal checks on the sent timestamp to use to provide a useful ordering for honest contacts - // and ensure that malicious contacts in groups can only set this timestamp to a value within the range of `last seen message time` - // and `local now`. - profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(data["GroupID"], timestampSent.toLocal()); - notificationManager.notify("New Message From Group!"); } else { // from me (already displayed - do not update counter) var idx = data["Signature"]; @@ -180,7 +190,10 @@ class CwtchNotifier { case "MessageCounterResync": var contactHandle = data["RemotePeer"]; if (contactHandle == null || contactHandle == "") contactHandle = data["GroupID"]; - profileCN.getProfile(data["Identity"])?.contactList.getContact(contactHandle)!.totalMessages = int.parse(data["Data"]); + var total = int.parse(data["Data"]); + if (total != profileCN.getProfile(data["Identity"])?.contactList.getContact(contactHandle)!.totalMessages) { + profileCN.getProfile(data["Identity"])?.contactList.getContact(contactHandle)!.totalMessages = total; + } break; case "SendMessageToPeerError": // Ignore @@ -316,7 +329,7 @@ class CwtchNotifier { } break; case "NewRetValMessageFromPeer": - if (data["Path"] == "name") { + if (data["Path"] == "name" && data["Data"].toString().trim().length > 0) { // Update locally on the UI... if (profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"]) != null) { profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.nickname = data["Data"]; diff --git a/lib/models/messages/textmessage.dart b/lib/models/messages/textmessage.dart index b4acd725..4f0d4906 100644 --- a/lib/models/messages/textmessage.dart +++ b/lib/models/messages/textmessage.dart @@ -32,7 +32,7 @@ class TextMessage extends Message { return ChangeNotifierProvider.value( value: this.metadata, builder: (bcontext, child) { - String idx = Provider.of(context).isGroup == true && this.metadata.signature != null ? this.metadata.signature! : this.metadata.messageIndex.toString(); + String idx = this.metadata.messageIndex.toString(); return MessageRow(MessageBubble(this.content), key: Provider.of(bcontext).getMessageKey(idx)); }); }