Use explicit transactions.

- Start expiration within scope of existing transaction when we're
  already in a transaction

// FREEBIE
pull/1/head
Michael Kirk 7 years ago
parent b7625689cb
commit dfb2a034af

@ -3278,7 +3278,7 @@ NS_ASSUME_NONNULL_BEGIN
attachmentIds:@[] attachmentIds:@[]
expiresInSeconds:0 expiresInSeconds:0
quotedMessage:nil]; quotedMessage:nil];
[message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO]; [message markAsReadWithTransaction:transaction sendReadReceipt:NO];
break; break;
} }
case 1: { case 1: {
@ -3316,7 +3316,7 @@ NS_ASSUME_NONNULL_BEGIN
] ]
expiresInSeconds:0 expiresInSeconds:0
quotedMessage:nil]; quotedMessage:nil];
[message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO]; [message markAsReadWithTransaction:transaction sendReadReceipt:NO];
break; break;
} }
case 3: { case 3: {
@ -3767,7 +3767,7 @@ NS_ASSUME_NONNULL_BEGIN
attachmentIds:[NSMutableArray new] attachmentIds:[NSMutableArray new]
expiresInSeconds:0 expiresInSeconds:0
quotedMessage:nil]; quotedMessage:nil];
[message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO]; [message markAsReadWithTransaction:transaction sendReadReceipt:NO];
} }
{ {
TSOutgoingMessage *message = TSOutgoingMessage *message =
@ -4105,7 +4105,7 @@ NS_ASSUME_NONNULL_BEGIN
attachmentIds:attachmentIds attachmentIds:attachmentIds
expiresInSeconds:0 expiresInSeconds:0
quotedMessage:quotedMessage]; quotedMessage:quotedMessage];
[message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO]; [message markAsReadWithTransaction:transaction sendReadReceipt:NO];
return message; return message;
} }

@ -8,6 +8,8 @@ NS_ASSUME_NONNULL_BEGIN
#define OWSDisappearingMessagesConfigurationDefaultExpirationDuration kDayInterval #define OWSDisappearingMessagesConfigurationDefaultExpirationDuration kDayInterval
@class YapDatabaseReadTransaction;
@interface OWSDisappearingMessagesConfiguration : TSYapDatabaseObject @interface OWSDisappearingMessagesConfiguration : TSYapDatabaseObject
- (instancetype)initDefaultWithThreadId:(NSString *)threadId; - (instancetype)initDefaultWithThreadId:(NSString *)threadId;
@ -21,7 +23,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) BOOL dictionaryValueDidChange; @property (nonatomic, readonly) BOOL dictionaryValueDidChange;
@property (readonly, getter=isNewRecord) BOOL newRecord; @property (readonly, getter=isNewRecord) BOOL newRecord;
+ (instancetype)fetchOrCreateDefaultWithThreadId:(NSString *)threadId; + (instancetype)fetchOrCreateDefaultWithThreadId:(NSString *)threadId
transaction:(YapDatabaseReadTransaction *)transaction;
+ (NSArray<NSNumber *> *)validDurationsSeconds; + (NSArray<NSNumber *> *)validDurationsSeconds;

@ -51,8 +51,10 @@ NS_ASSUME_NONNULL_BEGIN
} }
+ (instancetype)fetchOrCreateDefaultWithThreadId:(NSString *)threadId + (instancetype)fetchOrCreateDefaultWithThreadId:(NSString *)threadId
transaction:(YapDatabaseReadTransaction *)transaction
{ {
OWSDisappearingMessagesConfiguration *savedConfiguration = [self fetchObjectWithUniqueID:threadId]; OWSDisappearingMessagesConfiguration *savedConfiguration =
[self fetchObjectWithUniqueID:threadId transaction:transaction];
if (savedConfiguration) { if (savedConfiguration) {
return savedConfiguration; return savedConfiguration;
} else { } else {

@ -230,7 +230,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
for (id<OWSReadTracking> message in [self unseenMessagesWithTransaction:transaction]) { for (id<OWSReadTracking> message in [self unseenMessagesWithTransaction:transaction]) {
[message markAsReadWithTransaction:transaction sendReadReceipt:YES updateExpiration:YES]; [message markAsReadWithTransaction:transaction sendReadReceipt:YES];
} }
// Just to be defensive, we'll also check for unread messages. // Just to be defensive, we'll also check for unread messages.

@ -134,9 +134,13 @@ NS_ASSUME_NONNULL_BEGIN
} }
if (transcript.isExpirationTimerUpdate) { if (transcript.isExpirationTimerUpdate) {
[OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:outgoingMessage [[OWSDisappearingMessagesJob sharedJob] becomeConsistentWithConfigurationForMessage:outgoingMessage
contactsManager:self.contactsManager]; contactsManager:self.contactsManager
transaction:transaction];
// early return to avoid saving an empty incoming message. // early return to avoid saving an empty incoming message.
OWSAssert(transcript.body.length == 0);
OWSAssert(outgoingMessage.attachmentIds.count == 0);
return; return;
} }
@ -147,10 +151,12 @@ NS_ASSUME_NONNULL_BEGIN
[outgoingMessage saveWithTransaction:transaction]; [outgoingMessage saveWithTransaction:transaction];
[outgoingMessage updateWithWasSentFromLinkedDeviceWithTransaction:transaction]; [outgoingMessage updateWithWasSentFromLinkedDeviceWithTransaction:transaction];
[OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:outgoingMessage [[OWSDisappearingMessagesJob sharedJob] becomeConsistentWithConfigurationForMessage:outgoingMessage
contactsManager:self.contactsManager]; contactsManager:self.contactsManager
[OWSDisappearingMessagesJob setExpirationForMessage:outgoingMessage transaction:transaction];
expirationStartedAt:transcript.expirationStartedAt]; [[OWSDisappearingMessagesJob sharedJob] setExpirationForMessage:outgoingMessage
expirationStartedAt:transcript.expirationStartedAt
transaction:transaction];
[self.readReceiptManager applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:outgoingMessage [self.readReceiptManager applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:outgoingMessage
transaction:transaction]; transaction:transaction];

@ -186,7 +186,6 @@ NSUInteger TSErrorMessageSchemaVersion = 1;
- (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
sendReadReceipt:(BOOL)sendReadReceipt sendReadReceipt:(BOOL)sendReadReceipt
updateExpiration:(BOOL)updateExpiration
{ {
OWSAssert(transaction); OWSAssert(transaction);
@ -200,7 +199,7 @@ NSUInteger TSErrorMessageSchemaVersion = 1;
[self saveWithTransaction:transaction]; [self saveWithTransaction:transaction];
[self touchThreadWithTransaction:transaction]; [self touchThreadWithTransaction:transaction];
// Ignore sendReadReceipt and updateExpiration; they don't apply to error messages. // Ignore sendReadReceipt - it doesn't apply to error messages.
} }
@end @end

@ -136,7 +136,6 @@ NS_ASSUME_NONNULL_BEGIN
- (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
sendReadReceipt:(BOOL)sendReadReceipt sendReadReceipt:(BOOL)sendReadReceipt
updateExpiration:(BOOL)updateExpiration
{ {
OWSAssert(transaction); OWSAssert(transaction);
@ -150,9 +149,9 @@ NS_ASSUME_NONNULL_BEGIN
[self saveWithTransaction:transaction]; [self saveWithTransaction:transaction];
[self touchThreadWithTransaction:transaction]; [self touchThreadWithTransaction:transaction];
if (updateExpiration) { [[OWSDisappearingMessagesJob sharedJob] startExpirationForMessage:self
[OWSDisappearingMessagesJob setExpirationForMessage:self]; transaction:transaction];
}
if (sendReadReceipt) { if (sendReadReceipt) {
[OWSReadReceiptManager.sharedManager messageWasReadLocally:self]; [OWSReadReceiptManager.sharedManager messageWasReadLocally:self];

@ -131,7 +131,6 @@ NSUInteger TSInfoMessageSchemaVersion = 1;
- (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
sendReadReceipt:(BOOL)sendReadReceipt sendReadReceipt:(BOOL)sendReadReceipt
updateExpiration:(BOOL)updateExpiration
{ {
OWSAssert(transaction); OWSAssert(transaction);
@ -145,7 +144,7 @@ NSUInteger TSInfoMessageSchemaVersion = 1;
[self saveWithTransaction:transaction]; [self saveWithTransaction:transaction];
[self touchThreadWithTransaction:transaction]; [self touchThreadWithTransaction:transaction];
// Ignore sendReadReceipt and updateExpiration; they don't apply to info messages. // Ignore sendReadReceipt, it doesn't apply to info messages.
} }
@end @end

@ -7,6 +7,7 @@ NS_ASSUME_NONNULL_BEGIN
@class OWSPrimaryStorage; @class OWSPrimaryStorage;
@class TSMessage; @class TSMessage;
@class TSThread; @class TSThread;
@class YapDatabaseReadWriteTransaction;
@protocol ContactsManagerProtocol; @protocol ContactsManagerProtocol;
@ -16,9 +17,13 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE;
+ (void)setExpirationsForThread:(TSThread *)thread; //+ (void)setExpirationsForThread:(TSThread *)thread;
+ (void)setExpirationForMessage:(TSMessage *)message; - (void)startExpirationForMessage:(TSMessage *)message
+ (void)setExpirationForMessage:(TSMessage *)message expirationStartedAt:(uint64_t)expirationStartedAt; transaction:(YapDatabaseReadWriteTransaction *_Nonnull)transaction;
- (void)setExpirationForMessage:(TSMessage *)message
expirationStartedAt:(uint64_t)expirationStartedAt
transaction:(YapDatabaseReadWriteTransaction *_Nonnull)transaction;
/** /**
* Synchronize our disappearing messages settings with that of the given message. Useful so we can * Synchronize our disappearing messages settings with that of the given message. Useful so we can
@ -31,8 +36,9 @@ NS_ASSUME_NONNULL_BEGIN
* @param contactsManager * @param contactsManager
* Provides the contact name responsible for any configuration changes in an info message. * Provides the contact name responsible for any configuration changes in an info message.
*/ */
+ (void)becomeConsistentWithConfigurationForMessage:(TSMessage *)message - (void)becomeConsistentWithConfigurationForMessage:(TSMessage *)message
contactsManager:(id<ContactsManagerProtocol>)contactsManager; contactsManager:(id<ContactsManagerProtocol>)contactsManager
transaction:(YapDatabaseReadWriteTransaction *)transaction;
// Clean up any messages that expired since last launch immediately // Clean up any messages that expired since last launch immediately
// and continue cleaning in the background. // and continue cleaning in the background.

@ -166,42 +166,23 @@ void AssertIsOnDisappearingMessagesQueue()
return deletedCount; return deletedCount;
} }
+ (void)setExpirationForMessage:(TSMessage *)message - (void)startExpirationForMessage:(TSMessage *)message
{ transaction:(YapDatabaseReadWriteTransaction *_Nonnull)transaction
dispatch_async(self.serialQueue, ^{
[[self sharedJob] setExpirationForMessage:message];
});
}
- (void)setExpirationForMessage:(TSMessage *)message
{ {
if (!message.isExpiringMessage) { if (!message.isExpiringMessage) {
return; return;
} }
OWSDisappearingMessagesConfiguration *disappearingConfig = OWSDisappearingMessagesConfiguration *disappearingConfig =
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:message.uniqueThreadId]; [OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:message.uniqueThreadId transaction:transaction];
if (!disappearingConfig.isEnabled) { if (!disappearingConfig.isEnabled) {
return; return;
} }
[self setExpirationForMessage:message expirationStartedAt:[NSDate ows_millisecondTimeStamp]]; [self setExpirationForMessage:message
} expirationStartedAt:[NSDate ows_millisecondTimeStamp]
transaction:transaction];
+ (void)setExpirationForMessage:(TSMessage *)message expirationStartedAt:(uint64_t)expirationStartedAt
{
dispatch_async(self.serialQueue, ^{
[[self sharedJob] setExpirationForMessage:message expirationStartedAt:expirationStartedAt];
});
}
// This method should only be called on the serialQueue.
- (void)setExpirationForMessage:(TSMessage *)message expirationStartedAt:(uint64_t)expirationStartedAt
{
[self.databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[self setExpirationForMessage:message expirationStartedAt:expirationStartedAt transaction:transaction];
}];
} }
- (void)setExpirationForMessage:(TSMessage *)message - (void)setExpirationForMessage:(TSMessage *)message
@ -222,29 +203,23 @@ void AssertIsOnDisappearingMessagesQueue()
[message updateWithExpireStartedAt:expirationStartedAt transaction:transaction]; [message updateWithExpireStartedAt:expirationStartedAt transaction:transaction];
} }
// Necessary that the async expiration run happens *after* the message is saved with expiration configuration. [transaction addCompletionQueue:nil
completionBlock:^{
// Necessary that the async expiration run happens *after* the message is saved with it's new
// expiration configuration.
[self scheduleRunByDate:[NSDate ows_dateWithMillisecondsSince1970:message.expiresAt]]; [self scheduleRunByDate:[NSDate ows_dateWithMillisecondsSince1970:message.expiresAt]];
}];
} }
+ (void)setExpirationsForThread:(TSThread *)thread - (void)setExpirationsForThread:(TSThread *)thread transaction:(YapDatabaseReadWriteTransaction *)transaction
{
dispatch_async(self.serialQueue, ^{
[[self sharedJob] setExpirationsForThread:thread];
});
}
// This method should only be called on the serialQueue.
- (void)setExpirationsForThread:(TSThread *)thread
{ {
OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
uint64_t now = [NSDate ows_millisecondTimeStamp]; uint64_t now = [NSDate ows_millisecondTimeStamp];
[self.databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[self.disappearingMessagesFinder [self.disappearingMessagesFinder
enumerateUnstartedExpiringMessagesInThread:thread enumerateUnstartedExpiringMessagesInThread:thread
block:^(TSMessage *_Nonnull message) { block:^(TSMessage *_Nonnull message) {
DDLogWarn( DDLogWarn(@"%@ Starting expiring message which should have already "
@"%@ Starting expiring message which should have already "
@"been started.", @"been started.",
self.logTag); self.logTag);
// specify "now" in case D.M. have since been disabled, but we have // specify "now" in case D.M. have since been disabled, but we have
@ -254,30 +229,24 @@ void AssertIsOnDisappearingMessagesQueue()
transaction:transaction]; transaction:transaction];
} }
transaction:transaction]; transaction:transaction];
}];
backgroundTask = nil; backgroundTask = nil;
} }
+ (void)becomeConsistentWithConfigurationForMessage:(TSMessage *)message
contactsManager:(id<ContactsManagerProtocol>)contactsManager
{
[[self sharedJob] becomeConsistentWithConfigurationForMessage:message contactsManager:contactsManager];
}
- (void)becomeConsistentWithConfigurationForMessage:(TSMessage *)message - (void)becomeConsistentWithConfigurationForMessage:(TSMessage *)message
contactsManager:(id<ContactsManagerProtocol>)contactsManager contactsManager:(id<ContactsManagerProtocol>)contactsManager
transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssert(message); OWSAssert(message);
OWSAssert(contactsManager); OWSAssert(contactsManager);
__block OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; __block OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
dispatch_async(OWSDisappearingMessagesJob.serialQueue, ^{
// Become eventually consistent in the case that the remote changed their settings at the same time. // Become eventually consistent in the case that the remote changed their settings at the same time.
// Also in case remote doesn't support expiring messages // Also in case remote doesn't support expiring messages
OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration = OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration =
[OWSDisappearingMessagesConfiguration fetchOrCreateDefaultWithThreadId:message.uniqueThreadId]; [OWSDisappearingMessagesConfiguration fetchOrCreateDefaultWithThreadId:message.uniqueThreadId
transaction:transaction];
BOOL changed = NO; BOOL changed = NO;
if (message.expiresInSeconds == 0) { if (message.expiresInSeconds == 0) {
@ -287,7 +256,7 @@ void AssertIsOnDisappearingMessagesQueue()
@"consistent.", @"consistent.",
self.logTag); self.logTag);
disappearingMessagesConfiguration.enabled = NO; disappearingMessagesConfiguration.enabled = NO;
[disappearingMessagesConfiguration save]; [disappearingMessagesConfiguration saveWithTransaction:transaction];
} }
} else if (message.expiresInSeconds != disappearingMessagesConfiguration.durationSeconds) { } else if (message.expiresInSeconds != disappearingMessagesConfiguration.durationSeconds) {
changed = YES; changed = YES;
@ -296,7 +265,7 @@ void AssertIsOnDisappearingMessagesQueue()
self.logTag); self.logTag);
disappearingMessagesConfiguration.enabled = YES; disappearingMessagesConfiguration.enabled = YES;
disappearingMessagesConfiguration.durationSeconds = message.expiresInSeconds; disappearingMessagesConfiguration.durationSeconds = message.expiresInSeconds;
[disappearingMessagesConfiguration save]; [disappearingMessagesConfiguration saveWithTransaction:transaction];
} }
if (!changed) { if (!changed) {
@ -311,17 +280,16 @@ void AssertIsOnDisappearingMessagesQueue()
[[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:message.timestamp - 1 [[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:message.timestamp - 1
thread:message.thread thread:message.thread
configuration:disappearingMessagesConfiguration configuration:disappearingMessagesConfiguration
createdByRemoteName:contactName] save]; createdByRemoteName:contactName] saveWithTransaction:transaction];
} else { } else {
// We want the info message to appear _before_ the message. // We want the info message to appear _before_ the message.
[[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:message.timestamp - 1 [[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:message.timestamp - 1
thread:message.thread thread:message.thread
configuration:disappearingMessagesConfiguration] configuration:disappearingMessagesConfiguration]
save]; saveWithTransaction:transaction];
} }
backgroundTask = nil; backgroundTask = nil;
});
} }
- (void)startIfNecessary - (void)startIfNecessary

@ -1092,7 +1092,7 @@ NS_ASSUME_NONNULL_BEGIN
BOOL shouldMarkMessageAsRead = [envelope.source isEqualToString:localNumber]; BOOL shouldMarkMessageAsRead = [envelope.source isEqualToString:localNumber];
if (shouldMarkMessageAsRead) { if (shouldMarkMessageAsRead) {
// Don't send a read receipt for messages sent by ourselves. // Don't send a read receipt for messages sent by ourselves.
[incomingMessage markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:YES]; [incomingMessage markAsReadWithTransaction:transaction sendReadReceipt:NO];
} }
TSQuotedMessage *_Nullable quotedMessage = incomingMessage.quotedMessage; TSQuotedMessage *_Nullable quotedMessage = incomingMessage.quotedMessage;
@ -1130,8 +1130,9 @@ NS_ASSUME_NONNULL_BEGIN
[OWSReadReceiptManager.sharedManager applyEarlyReadReceiptsForIncomingMessage:incomingMessage [OWSReadReceiptManager.sharedManager applyEarlyReadReceiptsForIncomingMessage:incomingMessage
transaction:transaction]; transaction:transaction];
[OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:incomingMessage [[OWSDisappearingMessagesJob sharedJob] becomeConsistentWithConfigurationForMessage:incomingMessage
contactsManager:self.contactsManager]; contactsManager:self.contactsManager
transaction:transaction];
// Update thread preview in inbox // Update thread preview in inbox
[thread touchWithTransaction:transaction]; [thread touchWithTransaction:transaction];

@ -84,14 +84,6 @@ NS_SWIFT_NAME(MessageSender)
success:(void (^)(void))successHandler success:(void (^)(void))successHandler
failure:(void (^)(NSError *error))failureHandler; failure:(void (^)(NSError *error))failureHandler;
/**
* Set local configuration to match that of the of `outgoingMessage`'s sender
*
* We do this because messages and async message latency make it possible for thread participants disappearing messags
* configuration to get out of sync.
*/
- (void)becomeConsistentWithDisappearingConfigurationForMessage:(TSOutgoingMessage *)outgoingMessage;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -1052,13 +1052,10 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[self sendSyncTranscriptForMessage:message]; [self sendSyncTranscriptForMessage:message];
} }
[OWSDisappearingMessagesJob setExpirationForMessage:message]; [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
} [[OWSDisappearingMessagesJob sharedJob] startExpirationForMessage:message
transaction:transaction];
- (void)becomeConsistentWithDisappearingConfigurationForMessage:(TSOutgoingMessage *)outgoingMessage }];
{
[OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:outgoingMessage
contactsManager:self.contactsManager];
} }
- (void)handleSendToMyself:(TSOutgoingMessage *)outgoingMessage - (void)handleSendToMyself:(TSOutgoingMessage *)outgoingMessage

@ -431,11 +431,15 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
if (!readReceipt) { if (!readReceipt) {
return; return;
} }
[message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:YES]; [message markAsReadWithTransaction:transaction sendReadReceipt:NO];
[readReceipt removeWithTransaction:transaction]; [readReceipt removeWithTransaction:transaction];
[[NSNotificationCenter defaultCenter] postNotificationNameAsync:kIncomingMessageMarkedAsReadNotification [transaction addCompletionQueue:nil
completionBlock:^{
[[NSNotificationCenter defaultCenter]
postNotificationNameAsync:kIncomingMessageMarkedAsReadNotification
object:message]; object:message];
}];
} }
- (void)processReadReceiptsFromLinkedDevice:(NSArray<OWSSignalServiceProtosSyncMessageRead *> *)readReceiptProtos - (void)processReadReceiptsFromLinkedDevice:(NSArray<OWSSignalServiceProtosSyncMessageRead *> *)readReceiptProtos
@ -538,13 +542,18 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
} else { } else {
DDLogError(@"Marking %zd messages as read by linked device.", interactions.count); DDLogError(@"Marking %zd messages as read by linked device.", interactions.count);
} }
for (id<OWSReadTracking> possiblyRead in interactions) { for (id<OWSReadTracking> possiblyRead in interactions) {
[possiblyRead markAsReadWithTransaction:transaction sendReadReceipt:wasLocal updateExpiration:YES]; [possiblyRead markAsReadWithTransaction:transaction sendReadReceipt:wasLocal];
if ([possiblyRead isKindOfClass:[TSIncomingMessage class]]) { if ([possiblyRead isKindOfClass:[TSIncomingMessage class]]) {
TSIncomingMessage *incomingMessage = (TSIncomingMessage *)possiblyRead; TSIncomingMessage *incomingMessage = (TSIncomingMessage *)possiblyRead;
[[NSNotificationCenter defaultCenter] postNotificationNameAsync:kIncomingMessageMarkedAsReadNotification [transaction addCompletionQueue:nil
completionBlock:^{
[[NSNotificationCenter defaultCenter]
postNotificationNameAsync:kIncomingMessageMarkedAsReadNotification
object:incomingMessage]; object:incomingMessage];
}];
} }
} }
} }

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
@class YapDatabaseReadWriteTransaction; @class YapDatabaseReadWriteTransaction;
@ -21,10 +21,9 @@
- (BOOL)shouldAffectUnreadCounts; - (BOOL)shouldAffectUnreadCounts;
/** /**
* Used for *responding* to a remote read receipt or in response to user activity. * Used both for *responding* to a remote read receipt and in response to the local user's activity.
*/ */
- (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
sendReadReceipt:(BOOL)sendReadReceipt sendReadReceipt:(BOOL)sendReadReceipt;
updateExpiration:(BOOL)updateExpiration;
@end @end

@ -96,7 +96,6 @@ NSUInteger TSCallCurrentSchemaVersion = 1;
- (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
sendReadReceipt:(BOOL)sendReadReceipt sendReadReceipt:(BOOL)sendReadReceipt
updateExpiration:(BOOL)updateExpiration
{ {
OWSAssert(transaction); OWSAssert(transaction);
@ -110,7 +109,7 @@ NSUInteger TSCallCurrentSchemaVersion = 1;
[self saveWithTransaction:transaction]; [self saveWithTransaction:transaction];
[self touchThreadWithTransaction:transaction]; [self touchThreadWithTransaction:transaction];
// Ignore sendReadReceipt and updateExpiration; they don't apply to calls. // Ignore sendReadReceipt - it doesn't apply to calls.
} }
#pragma mark - Methods #pragma mark - Methods

Loading…
Cancel
Save