From 7bd4d26532c456a614582aa3ce15083a2cdfce38 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 15 Feb 2017 17:09:55 -0500 Subject: [PATCH 1/2] =?UTF-8?q?Add=20=E2=80=9Creceived=20at=E2=80=9D=20tim?= =?UTF-8?q?estamp=20to=20all=20TSMessages=20so=20that=20they=20may=20be=20?= =?UTF-8?q?sorted=20properly.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit // FREEBIE --- src/Contacts/TSThread.m | 8 +++++--- src/Messages/Interactions/TSIncomingMessage.h | 6 ++++++ src/Messages/Interactions/TSIncomingMessage.m | 15 ++++++++++++++- src/Messages/Interactions/TSMessage.h | 13 +++++++++++-- src/Messages/Interactions/TSMessage.m | 10 ++++++++++ src/Messages/Interactions/TSOutgoingMessage.h | 5 +++-- src/Messages/Interactions/TSOutgoingMessage.m | 7 +++++-- src/Storage/TSDatabaseView.m | 10 +++++----- 8 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/Contacts/TSThread.m b/src/Contacts/TSThread.m index aac051814..20fe7917b 100644 --- a/src/Contacts/TSThread.m +++ b/src/Contacts/TSThread.m @@ -248,9 +248,11 @@ NS_ASSUME_NONNULL_BEGIN - (void)updateWithLastMessage:(TSInteraction *)lastMessage transaction:(YapDatabaseReadWriteTransaction *)transaction { NSDate *lastMessageDate = lastMessage.date; - if ([lastMessage isKindOfClass:[TSIncomingMessage class]]) { - TSIncomingMessage *message = (TSIncomingMessage *)lastMessage; - lastMessageDate = message.receivedAt; + if ([lastMessage isKindOfClass:[TSMessage class]]) { + TSMessage *message = (TSMessage *)lastMessage; + if ([message bestReceivedAtDate]) { + lastMessageDate = [message bestReceivedAtDate]; + } } if (!_lastMessageDate || [lastMessageDate timeIntervalSinceDate:self.lastMessageDate] > 0) { diff --git a/src/Messages/Interactions/TSIncomingMessage.h b/src/Messages/Interactions/TSIncomingMessage.h index 2da3622e3..5ffc7de84 100644 --- a/src/Messages/Interactions/TSIncomingMessage.h +++ b/src/Messages/Interactions/TSIncomingMessage.h @@ -121,6 +121,12 @@ extern NSString *const TSIncomingMessageWasReadOnThisDeviceNotification; @property (nonatomic, readonly) NSString *authorId; @property (nonatomic, readonly, getter=wasRead) BOOL read; +// _DO NOT_ access this property directly. You almost certainly +// want to use bestReceivedAtDate instead. +// +// This property has been superceded by TSMessage.receivedAtData. +// This property only exists for backwards compatability with messages +// received before TSMessage.receivedAtData was added. @property (nonatomic, readonly) NSDate *receivedAt; /* diff --git a/src/Messages/Interactions/TSIncomingMessage.m b/src/Messages/Interactions/TSIncomingMessage.m index 5cec33496..803eb950b 100644 --- a/src/Messages/Interactions/TSIncomingMessage.m +++ b/src/Messages/Interactions/TSIncomingMessage.m @@ -61,7 +61,8 @@ NSString *const TSIncomingMessageWasReadOnThisDeviceNotification = @"TSIncomingM _authorId = authorId; _read = NO; - _receivedAt = [NSDate date]; + + OWSAssert(self.receivedAtDate); return self; } @@ -134,6 +135,18 @@ NSString *const TSIncomingMessageWasReadOnThisDeviceNotification = @"TSIncomingM [self touchThreadWithTransaction:transaction]; } +- (nullable NSDate *)bestReceivedAtDate +{ + NSDate *result = [super bestReceivedAtDate]; + if (!result) { + // For backward compatibility with messages received before + // TSMessage.receivedAtData was added, honor TSIncomingMessage.receivedAt + // if TSMessage.receivedAtData is not set. + result = self.receivedAt; + } + return result; +} + #pragma mark - Logging + (NSString *)tag diff --git a/src/Messages/Interactions/TSMessage.h b/src/Messages/Interactions/TSMessage.h index 47179e77c..6dbe22990 100644 --- a/src/Messages/Interactions/TSMessage.h +++ b/src/Messages/Interactions/TSMessage.h @@ -1,5 +1,6 @@ -// Created by Frederic Jacobs on 12/11/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// #import "TSInteraction.h" @@ -29,6 +30,9 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) { @property (nonatomic, readonly) uint64_t expiresAt; @property (nonatomic, readonly) BOOL isExpiringMessage; @property (nonatomic, readonly) BOOL shouldStartExpireTimer; +// _DO NOT_ access this property directly. You almost certainly +// want to use bestReceivedAtDate instead. +@property (nonatomic, readonly) NSDate *receivedAtDate; - (instancetype)initWithTimestamp:(uint64_t)timestamp; @@ -60,6 +64,11 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) { - (BOOL)hasAttachments; +// This message should return TSMessage.receivedAtDate for most messages. +// For messages received before TSMessage.receivedAtDate was added, this +// will try to return TSIncomingMessage.receivedAt. +- (nullable NSDate *)bestReceivedAtDate; + @end NS_ASSUME_NONNULL_END diff --git a/src/Messages/Interactions/TSMessage.m b/src/Messages/Interactions/TSMessage.m index 4b893c7b6..56248e852 100644 --- a/src/Messages/Interactions/TSMessage.m +++ b/src/Messages/Interactions/TSMessage.m @@ -102,6 +102,7 @@ static const NSUInteger OWSMessageSchemaVersion = 3; _expiresInSeconds = expiresInSeconds; _expireStartedAt = expireStartedAt; [self updateExpiresAt]; + _receivedAtDate = [NSDate date]; return self; } @@ -132,6 +133,10 @@ static const NSUInteger OWSMessageSchemaVersion = 3; } _schemaVersion = OWSMessageSchemaVersion; + + // We _DO NOT_ set _receivedAt_ in this constructor. We don't want to + // set the receivedAt time for old messages in the data store. + return self; } @@ -215,6 +220,11 @@ static const NSUInteger OWSMessageSchemaVersion = 3; return self.expiresInSeconds > 0; } +- (nullable NSDate *)bestReceivedAtDate +{ + return self.receivedAtDate; +} + @end NS_ASSUME_NONNULL_END diff --git a/src/Messages/Interactions/TSOutgoingMessage.h b/src/Messages/Interactions/TSOutgoingMessage.h index ff6064da5..9751088fd 100644 --- a/src/Messages/Interactions/TSOutgoingMessage.h +++ b/src/Messages/Interactions/TSOutgoingMessage.h @@ -1,5 +1,6 @@ -// Created by Frederic Jacobs on 15/11/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// #import "TSMessage.h" diff --git a/src/Messages/Interactions/TSOutgoingMessage.m b/src/Messages/Interactions/TSOutgoingMessage.m index e0e4c3bca..de6ff2cc8 100644 --- a/src/Messages/Interactions/TSOutgoingMessage.m +++ b/src/Messages/Interactions/TSOutgoingMessage.m @@ -1,5 +1,6 @@ -// Created by Frederic Jacobs on 15/11/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// #import "TSOutgoingMessage.h" #import "NSDate+millisecondTimeStamp.h" @@ -86,6 +87,8 @@ NS_ASSUME_NONNULL_BEGIN self.groupMetaMessage = TSGroupMessageNone; } + OWSAssert(self.receivedAtDate); + return self; } diff --git a/src/Storage/TSDatabaseView.m b/src/Storage/TSDatabaseView.m index 055431b4d..ecbeb57ef 100644 --- a/src/Storage/TSDatabaseView.m +++ b/src/Storage/TSDatabaseView.m @@ -9,6 +9,7 @@ #import "OWSDevice.h" #import "OWSReadTracking.h" #import "TSIncomingMessage.h" +#import "TSOutgoingMessage.h" #import "TSStorageManager.h" #import "TSThread.h" @@ -265,11 +266,10 @@ NSString *TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevicesData + (NSDate *)localTimeReceiveDateForInteraction:(TSInteraction *)interaction { NSDate *interactionDate = interaction.date; - if ([interaction isKindOfClass:[TSIncomingMessage class]]) { - TSIncomingMessage *message = (TSIncomingMessage *)interaction; - - if (message.receivedAt) { - interactionDate = message.receivedAt; + if ([interaction isKindOfClass:[TSMessage class]]) { + TSMessage *message = (TSMessage *)interaction; + if ([message bestReceivedAtDate]) { + interactionDate = [message bestReceivedAtDate]; } } From 686fe679bdccd1a1b22657250398c5433567f9e7 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 16 Feb 2017 15:39:56 -0500 Subject: [PATCH 2/2] Respond to CR. // FREEBIE --- src/Contacts/TSThread.m | 9 +------ src/Messages/Interactions/TSIncomingMessage.h | 7 ----- src/Messages/Interactions/TSIncomingMessage.m | 12 --------- src/Messages/Interactions/TSInteraction.h | 1 + src/Messages/Interactions/TSInteraction.m | 5 ++++ src/Messages/Interactions/TSMessage.h | 7 +---- src/Messages/Interactions/TSMessage.m | 26 +++++++++++++++---- src/Storage/TSDatabaseView.m | 11 +------- 8 files changed, 30 insertions(+), 48 deletions(-) diff --git a/src/Contacts/TSThread.m b/src/Contacts/TSThread.m index 20fe7917b..cd2b5ac71 100644 --- a/src/Contacts/TSThread.m +++ b/src/Contacts/TSThread.m @@ -246,14 +246,7 @@ NS_ASSUME_NONNULL_BEGIN } - (void)updateWithLastMessage:(TSInteraction *)lastMessage transaction:(YapDatabaseReadWriteTransaction *)transaction { - NSDate *lastMessageDate = lastMessage.date; - - if ([lastMessage isKindOfClass:[TSMessage class]]) { - TSMessage *message = (TSMessage *)lastMessage; - if ([message bestReceivedAtDate]) { - lastMessageDate = [message bestReceivedAtDate]; - } - } + NSDate *lastMessageDate = [lastMessage receiptDateForSorting]; if (!_lastMessageDate || [lastMessageDate timeIntervalSinceDate:self.lastMessageDate] > 0) { _lastMessageDate = lastMessageDate; diff --git a/src/Messages/Interactions/TSIncomingMessage.h b/src/Messages/Interactions/TSIncomingMessage.h index 5ffc7de84..f7804ea2b 100644 --- a/src/Messages/Interactions/TSIncomingMessage.h +++ b/src/Messages/Interactions/TSIncomingMessage.h @@ -121,13 +121,6 @@ extern NSString *const TSIncomingMessageWasReadOnThisDeviceNotification; @property (nonatomic, readonly) NSString *authorId; @property (nonatomic, readonly, getter=wasRead) BOOL read; -// _DO NOT_ access this property directly. You almost certainly -// want to use bestReceivedAtDate instead. -// -// This property has been superceded by TSMessage.receivedAtData. -// This property only exists for backwards compatability with messages -// received before TSMessage.receivedAtData was added. -@property (nonatomic, readonly) NSDate *receivedAt; /* * Marks a message as having been read on this device (as opposed to responding to a remote read receipt). diff --git a/src/Messages/Interactions/TSIncomingMessage.m b/src/Messages/Interactions/TSIncomingMessage.m index 803eb950b..e10acedc8 100644 --- a/src/Messages/Interactions/TSIncomingMessage.m +++ b/src/Messages/Interactions/TSIncomingMessage.m @@ -135,18 +135,6 @@ NSString *const TSIncomingMessageWasReadOnThisDeviceNotification = @"TSIncomingM [self touchThreadWithTransaction:transaction]; } -- (nullable NSDate *)bestReceivedAtDate -{ - NSDate *result = [super bestReceivedAtDate]; - if (!result) { - // For backward compatibility with messages received before - // TSMessage.receivedAtData was added, honor TSIncomingMessage.receivedAt - // if TSMessage.receivedAtData is not set. - result = self.receivedAt; - } - return result; -} - #pragma mark - Logging + (NSString *)tag diff --git a/src/Messages/Interactions/TSInteraction.h b/src/Messages/Interactions/TSInteraction.h index 8ec6fa1e7..6f7c4eeee 100644 --- a/src/Messages/Interactions/TSInteraction.h +++ b/src/Messages/Interactions/TSInteraction.h @@ -31,5 +31,6 @@ + (instancetype)interactionForTimestamp:(uint64_t)timestamp withTransaction:(YapDatabaseReadWriteTransaction *)transaction; +- (nullable NSDate *)receiptDateForSorting; @end diff --git a/src/Messages/Interactions/TSInteraction.m b/src/Messages/Interactions/TSInteraction.m index bab5b4c68..7d09ae755 100644 --- a/src/Messages/Interactions/TSInteraction.m +++ b/src/Messages/Interactions/TSInteraction.m @@ -86,6 +86,11 @@ return [myNumber unsignedLongLongValue]; } +- (nullable NSDate *)receiptDateForSorting +{ + return self.date; +} + - (NSString *)description { return @"Interaction description"; } diff --git a/src/Messages/Interactions/TSMessage.h b/src/Messages/Interactions/TSMessage.h index 6dbe22990..65716cda9 100644 --- a/src/Messages/Interactions/TSMessage.h +++ b/src/Messages/Interactions/TSMessage.h @@ -31,7 +31,7 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) { @property (nonatomic, readonly) BOOL isExpiringMessage; @property (nonatomic, readonly) BOOL shouldStartExpireTimer; // _DO NOT_ access this property directly. You almost certainly -// want to use bestReceivedAtDate instead. +// want to use receiptDateForSorting instead. @property (nonatomic, readonly) NSDate *receivedAtDate; - (instancetype)initWithTimestamp:(uint64_t)timestamp; @@ -64,11 +64,6 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) { - (BOOL)hasAttachments; -// This message should return TSMessage.receivedAtDate for most messages. -// For messages received before TSMessage.receivedAtDate was added, this -// will try to return TSIncomingMessage.receivedAt. -- (nullable NSDate *)bestReceivedAtDate; - @end NS_ASSUME_NONNULL_END diff --git a/src/Messages/Interactions/TSMessage.m b/src/Messages/Interactions/TSMessage.m index 56248e852..92e4a784f 100644 --- a/src/Messages/Interactions/TSMessage.m +++ b/src/Messages/Interactions/TSMessage.m @@ -132,10 +132,13 @@ static const NSUInteger OWSMessageSchemaVersion = 3; _attachmentIds = [NSMutableArray new]; } - _schemaVersion = OWSMessageSchemaVersion; + if (!_receivedAtDate) { + // TSIncomingMessage.receivedAt has been superceded by TSMessage.receivedAtDate. + NSDate *receivedAt = [coder decodeObjectForKey:@"receivedAt"]; + _receivedAtDate = receivedAt; + } - // We _DO NOT_ set _receivedAt_ in this constructor. We don't want to - // set the receivedAt time for old messages in the data store. + _schemaVersion = OWSMessageSchemaVersion; return self; } @@ -220,9 +223,22 @@ static const NSUInteger OWSMessageSchemaVersion = 3; return self.expiresInSeconds > 0; } -- (nullable NSDate *)bestReceivedAtDate +- (nullable NSDate *)receiptDateForSorting +{ + // Prefer receivedAtDate if set, otherwise fallback to date. + return self.receivedAtDate ?: self.date; +} + +#pragma mark - Logging + ++ (NSString *)tag +{ + return [NSString stringWithFormat:@"[%@]", self.class]; +} + +- (NSString *)tag { - return self.receivedAtDate; + return self.class.tag; } @end diff --git a/src/Storage/TSDatabaseView.m b/src/Storage/TSDatabaseView.m index ecbeb57ef..09112389d 100644 --- a/src/Storage/TSDatabaseView.m +++ b/src/Storage/TSDatabaseView.m @@ -264,16 +264,7 @@ NSString *TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevicesData } + (NSDate *)localTimeReceiveDateForInteraction:(TSInteraction *)interaction { - NSDate *interactionDate = interaction.date; - - if ([interaction isKindOfClass:[TSMessage class]]) { - TSMessage *message = (TSMessage *)interaction; - if ([message bestReceivedAtDate]) { - interactionDate = [message bestReceivedAtDate]; - } - } - - return interactionDate; + return [interaction receiptDateForSorting]; } #pragma mark - Logging