From 7aad5c5971f9305fd4be7905e38b7d9fd10d12c6 Mon Sep 17 00:00:00 2001 From: Frederic Jacobs Date: Sat, 28 Feb 2015 15:27:56 +0100 Subject: [PATCH] Fixing UX issue with unsynchronized clocks. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TextSecure messages don’t get assigned a timestamp by the server. All of it is done end-to-end between both clients. A client could have a misconfigured clock or might want to forge a timestamp. Therefore, we address this issue by introducing a new receivedAt timestamp for incoming messages that will be used to sort the messages. --- .../textsecure/Messages/TSIncomingMessage.h | 3 +- .../textsecure/Messages/TSIncomingMessage.m | 10 +++--- .../src/textsecure/Storage/TSDatabaseView.m | 33 ++++++++++++++++++- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/Signal/src/textsecure/Messages/TSIncomingMessage.h b/Signal/src/textsecure/Messages/TSIncomingMessage.h index c0ab25a5d..9ceaf33af 100644 --- a/Signal/src/textsecure/Messages/TSIncomingMessage.h +++ b/Signal/src/textsecure/Messages/TSIncomingMessage.h @@ -42,9 +42,10 @@ inThread:(TSGroupThread*)thread authorId:(NSString*)authorId messageBody:(NSString*)body - attachments:(NSArray*)attachments; + attachments:(NSArray*)attachments; @property (nonatomic, readonly) NSString *authorId; @property (nonatomic, getter = wasRead) BOOL read; +@property (nonatomic, readonly) NSDate *receivedAt; @end diff --git a/Signal/src/textsecure/Messages/TSIncomingMessage.m b/Signal/src/textsecure/Messages/TSIncomingMessage.m index a80cd8a5f..1d4012dec 100644 --- a/Signal/src/textsecure/Messages/TSIncomingMessage.m +++ b/Signal/src/textsecure/Messages/TSIncomingMessage.m @@ -19,8 +19,9 @@ self = [super initWithTimestamp:timestamp inThread:thread messageBody:body attachments:attachments]; if (self) { - _authorId = authorId; - _read = NO; + _authorId = authorId; + _read = NO; + _receivedAt = [NSDate date]; } return self; @@ -34,8 +35,9 @@ self = [super initWithTimestamp:timestamp inThread:thread messageBody:body attachments:attachments]; if (self) { - _authorId = nil; - _read = NO; + _authorId = nil; + _read = NO; + _receivedAt = [NSDate date]; } return self; diff --git a/Signal/src/textsecure/Storage/TSDatabaseView.m b/Signal/src/textsecure/Storage/TSDatabaseView.m index 08bbff3fc..ca59be3a9 100644 --- a/Signal/src/textsecure/Storage/TSDatabaseView.m +++ b/Signal/src/textsecure/Storage/TSDatabaseView.m @@ -163,11 +163,42 @@ NSString *TSUnreadDatabaseViewExtensionName = @"TSUnreadDatabaseViewExtensionNa TSInteraction *message1 = (TSInteraction*)object1; TSInteraction *message2 = (TSInteraction*)object2; - return [message1.date compare:message2.date]; + NSDate *date1 = [self localTimeReceiveDateForInteraction:message1]; + NSDate *date2 = [self localTimeReceiveDateForInteraction:message2]; + + NSComparisonResult result = [date1 compare:date2]; + + // NSDates are only accurate to the second, we might want finer precision + if (result != NSOrderedSame) { + return result; + } + + if (message1.timestamp > message2.timestamp) { + return NSOrderedDescending; + } else if (message1.timestamp < message2.timestamp){ + return NSOrderedAscending; + } else{ + return NSOrderedSame; + } } return NSOrderedSame; }]; } ++ (NSDate*)localTimeReceiveDateForInteraction:(TSInteraction*)interaction{ + NSDate *interactionDate = interaction.date; + + if ([interaction isKindOfClass:[TSIncomingMessage class]]) { + TSIncomingMessage *message = (TSIncomingMessage*)interaction; + + if (message.receivedAt) { + interactionDate = message.receivedAt; + } + + } + + return interactionDate; +} + @end