add: messages in Book Club will disappear in 1 minute

Show different message when joining group with disappearing messages
This commit is contained in:
Michael Kirk 2018-06-14 10:08:38 -04:00
parent 0cf751d34f
commit 95b1dced18
9 changed files with 144 additions and 79 deletions

View File

@ -3423,11 +3423,27 @@ typedef OWSContact * (^OWSContactBlock)(YapDatabaseReadWriteTransaction *transac
enabled:YES
durationSeconds:(uint32_t)[durationSeconds intValue]];
[result addObject:[[OWSDisappearingConfigurationUpdateInfoMessage alloc]
initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:@"Alice"]];
initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:@"Alice"
createdInExistingGroupName:nil]];
}
{
NSNumber *durationSeconds = [OWSDisappearingMessagesConfiguration validDurationsSeconds][0];
OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration =
[[OWSDisappearingMessagesConfiguration alloc] initWithThreadId:thread.uniqueId
enabled:YES
durationSeconds:(uint32_t)[durationSeconds intValue]];
[result addObject:[[OWSDisappearingConfigurationUpdateInfoMessage alloc]
initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:nil
createdInExistingGroupName:@"Book Club"]];
}
{
NSNumber *durationSeconds = [[OWSDisappearingMessagesConfiguration validDurationsSeconds] lastObject];
OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration =
@ -3435,10 +3451,11 @@ typedef OWSContact * (^OWSContactBlock)(YapDatabaseReadWriteTransaction *transac
enabled:YES
durationSeconds:(uint32_t)[durationSeconds intValue]];
[result addObject:[[OWSDisappearingConfigurationUpdateInfoMessage alloc]
initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:@"Alice"]];
initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:@"Alice"
createdInExistingGroupName:nil]];
}
{
OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration =
@ -3446,10 +3463,11 @@ typedef OWSContact * (^OWSContactBlock)(YapDatabaseReadWriteTransaction *transac
enabled:NO
durationSeconds:0];
[result addObject:[[OWSDisappearingConfigurationUpdateInfoMessage alloc]
initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:@"Alice"]];
initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:@"Alice"
createdInExistingGroupName:nil]];
}
[result addObject:[TSInfoMessage userNotRegisteredMessageInThread:thread recipientId:@"+19174054215"]];

View File

@ -821,9 +821,11 @@ NS_ASSUME_NONNULL_BEGIN
[self.disappearingMessagesConfiguration save];
OWSDisappearingConfigurationUpdateInfoMessage *infoMessage =
[[OWSDisappearingConfigurationUpdateInfoMessage alloc]
initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:self.thread
configuration:self.disappearingMessagesConfiguration];
initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:self.thread
configuration:self.disappearingMessagesConfiguration
createdByRemoteName:nil
createdInExistingGroupName:nil];
[infoMessage save];
[OWSNotifyRemoteOfUpdatedDisappearingConfigurationJob

View File

@ -659,6 +659,9 @@
/* table cell label in conversation settings */
"DISAPPEARING_MESSAGES" = "Disappearing Messages";
/* Info Message when added to {{group name}} which has enabled message expiration after {{time amount}}, see the *_TIME_AMOUNT strings for context. */
"DISAPPEARING_MESSAGES_CONFIGURATION_GROUP_EXISTING_FORMAT" = "%@ has disappearing messages enabled for %@.";
/* subheading in conversation settings */
"DISAPPEARING_MESSAGES_DESCRIPTION" = "When enabled, messages sent and received in this conversation will disappear after they have been seen.";

View File

@ -134,6 +134,8 @@ NS_ASSUME_NONNULL_BEGIN
[[OWSDisappearingMessagesJob sharedJob] becomeConsistentWithConfigurationForMessage:outgoingMessage
contactsManager:self.contactsManager
transaction:transaction];
// early return to avoid saving an empty incoming message.
OWSAssert(transcript.body.length == 0);
OWSAssert(outgoingMessage.attachmentIds.count == 0);

View File

@ -1,29 +1,24 @@
// Created by Michael Kirk on 9/25/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "TSInfoMessage.h"
NS_ASSUME_NONNULL_BEGIN
@class TSThread;
@class OWSDisappearingMessagesConfiguration;
@class TSThread;
@interface OWSDisappearingConfigurationUpdateInfoMessage : TSInfoMessage
/**
* When remote user updates configuration
* @param remoteName is nil when created by the local user
*/
- (instancetype)initWithTimestamp:(uint64_t)timestamp
thread:(TSThread *)thread
configuration:(OWSDisappearingMessagesConfiguration *)configuration
createdByRemoteName:(NSString *)name;
/**
* When local user updates configuration
*/
- (instancetype)initWithTimestamp:(uint64_t)timestamp
thread:(TSThread *)thread
configuration:(OWSDisappearingMessagesConfiguration *)configuration;
createdByRemoteName:(nullable NSString *)remoteName
createdInExistingGroupName:(nullable NSString *)createdInExistingGroupName;
@end

View File

@ -10,7 +10,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSDisappearingConfigurationUpdateInfoMessage ()
@property (nullable, nonatomic, readonly) NSString *createdByRemoteName;
@property (nonatomic, readonly, nullable) NSString *createdByRemoteName;
@property (nonatomic, readonly, nullable) NSString *createdInExistingGroupName;
@property (nonatomic, readonly) BOOL configurationIsEnabled;
@property (nonatomic, readonly) uint32_t configurationDurationSeconds;
@ -21,22 +22,8 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithTimestamp:(uint64_t)timestamp
thread:(TSThread *)thread
configuration:(OWSDisappearingMessagesConfiguration *)configuration
createdByRemoteName:(NSString *)name
{
self = [self initWithTimestamp:timestamp thread:thread configuration:configuration];
if (!self) {
return self;
}
_createdByRemoteName = name;
return self;
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
thread:(TSThread *)thread
configuration:(OWSDisappearingMessagesConfiguration *)configuration
createdByRemoteName:(nullable NSString *)remoteName
createdInExistingGroupName:(nullable NSString *)createdInExistingGroupName
{
self = [super initWithTimestamp:timestamp inThread:thread messageType:TSInfoMessageTypeDisappearingMessagesUpdate];
if (!self) {
@ -45,6 +32,8 @@ NS_ASSUME_NONNULL_BEGIN
_configurationIsEnabled = configuration.isEnabled;
_configurationDurationSeconds = configuration.durationSeconds;
_createdByRemoteName = remoteName;
_createdInExistingGroupName = createdInExistingGroupName;
return self;
}
@ -73,7 +62,16 @@ NS_ASSUME_NONNULL_BEGIN
@"Info Message when {{other user}} disables or doesn't support disappearing messages");
return [NSString stringWithFormat:infoFormat, self.createdByRemoteName];
}
} else { // Changed by local request
} else if (self.createdInExistingGroupName) {
OWSAssert(self.configurationIsEnabled && self.configurationDurationSeconds > 0);
NSString *infoFormat = NSLocalizedString(@"DISAPPEARING_MESSAGES_CONFIGURATION_GROUP_EXISTING_FORMAT",
@"Info Message when added to {{group name}} which has enabled message expiration after {{time amount}}, "
@"see the *_TIME_AMOUNT strings for context.");
NSString *durationString = [NSString formatDurationSeconds:self.configurationDurationSeconds useShortFormat:NO];
return [NSString stringWithFormat:infoFormat, self.createdByRemoteName, durationString];
} else {
// Changed by local request
if (self.configurationIsEnabled && self.configurationDurationSeconds > 0) {
NSString *infoFormat = NSLocalizedString(@"YOU_UPDATED_DISAPPEARING_MESSAGES_CONFIGURATION",
@"Info message embedding a {{time amount}}, see the *_TIME_AMOUNT strings for context.");

View File

@ -36,6 +36,29 @@ NS_ASSUME_NONNULL_BEGIN
contactsManager:(id<ContactsManagerProtocol>)contactsManager
transaction:(YapDatabaseReadWriteTransaction *)transaction;
/**
* Synchronize our disappearing messages settings with that of the given message. Useful so we can
* become eventually consistent with remote senders.
*
* @param duration
* Can be 0, indicating a non-expiring message, or greater, indicating an expiring message. We match the expiration
* timer of the message, including disabling expiring messages if the message is not an expiring message.
*
* @param timestampForSorting
* timestampForSorting of the message before which we want to appear.
*
* @param remoteContactName
* nil for outgoing messages, otherwise the name of the sender
* @param existingGroupName
* set when being added to a group which already has DM enabled, otherwise nil
*/
- (void)becomeConsistentWithDisappearingDuration:(uint32_t)duration
thread:(TSThread *)thread
appearBeforeTimestamp:(uint64_t)timestampForSorting
createdByRemoteContactName:(nullable NSString *)remoteContactName
createdInExistingGroupName:(nullable NSString *)existingGroupName
transaction:(YapDatabaseReadWriteTransaction *)transaction;
// Clean up any messages that expired since last launch immediately
// and continue cleaning in the background.
- (void)startIfNecessary;

View File

@ -197,57 +197,65 @@ void AssertIsOnDisappearingMessagesQueue()
contactsManager:(id<ContactsManagerProtocol>)contactsManager
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(message);
OWSAssert(contactsManager);
TSThread *thread = [message threadWithTransaction:transaction];
NSString *remoteContactName = nil;
if ([message isKindOfClass:[TSIncomingMessage class]]) {
TSIncomingMessage *incomingMessage = (TSIncomingMessage *)message;
remoteContactName = [contactsManager displayNameForPhoneIdentifier:incomingMessage.messageAuthorId];
}
[self becomeConsistentWithDisappearingDuration:message.expiresInSeconds
thread:thread
appearBeforeTimestamp:message.timestampForSorting
createdByRemoteContactName:remoteContactName
createdInExistingGroupName:nil
transaction:transaction];
}
- (void)becomeConsistentWithDisappearingDuration:(uint32_t)duration
thread:(TSThread *)thread
appearBeforeTimestamp:(uint64_t)timestampForSorting
createdByRemoteContactName:(nullable NSString *)remoteContactName
createdInExistingGroupName:(nullable NSString *)existingGroupName
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(thread);
OWSAssert(timestampForSorting > 0);
OWSAssert(transaction);
__block OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
// 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
OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration =
[OWSDisappearingMessagesConfiguration fetchOrBuildDefaultWithThreadId:message.uniqueThreadId
transaction:transaction];
[thread disappearingMessagesConfigurationWithTransaction:transaction];
if (message.expiresInSeconds == 0) {
if (duration == 0) {
disappearingMessagesConfiguration.enabled = NO;
} else {
disappearingMessagesConfiguration.enabled = YES;
disappearingMessagesConfiguration.durationSeconds = message.expiresInSeconds;
disappearingMessagesConfiguration.durationSeconds = duration;
}
if (!disappearingMessagesConfiguration.dictionaryValueDidChange) {
return;
}
DDLogInfo(@"%@ becoming consistent with disappearing message configuration: %@",
self.logTag,
disappearingMessagesConfiguration.dictionaryValue);
[disappearingMessagesConfiguration saveWithTransaction:transaction];
TSThread *_Nullable thread = [message threadWithTransaction:transaction];
if (!thread) {
// If there's not yet a message thread, we don't create one.
OWSFail(@"%@ in %s thread was unexpectedly nil", self.logTag, __PRETTY_FUNCTION__);
return;
}
if ([message isKindOfClass:[TSIncomingMessage class]]) {
TSIncomingMessage *incomingMessage = (TSIncomingMessage *)message;
NSString *contactName = [contactsManager displayNameForPhoneIdentifier:incomingMessage.messageAuthorId];
// We want the info message to appear _before_ the message.
[[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:message.timestampForSorting - 1
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:contactName]
saveWithTransaction:transaction];
} else {
// We want the info message to appear _before_ the message.
[[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:message.timestampForSorting - 1
thread:thread
configuration:disappearingMessagesConfiguration]
saveWithTransaction:transaction];
}
// We want the info message to appear _before_ the message.
OWSDisappearingConfigurationUpdateInfoMessage *infoMessage =
[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:timestampForSorting - 1
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:remoteContactName
createdInExistingGroupName:existingGroupName];
[infoMessage saveWithTransaction:transaction];
backgroundTask = nil;
}

View File

@ -775,7 +775,8 @@ NS_ASSUME_NONNULL_BEGIN
[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:name];
createdByRemoteName:name
createdInExistingGroupName:nil];
[message saveWithTransaction:transaction];
}
@ -950,6 +951,8 @@ NS_ASSUME_NONNULL_BEGIN
TSGroupThread *newGroupThread =
[TSGroupThread getOrCreateThreadWithGroupId:groupId transaction:transaction];
uint64_t now = [NSDate ows_millisecondTimeStamp];
TSGroupModel *newGroupModel = [[TSGroupModel alloc] initWithTitle:dataMessage.group.name
memberIds:newMemberIds.allObjects
image:oldGroupThread.groupModel.groupImage
@ -959,10 +962,23 @@ NS_ASSUME_NONNULL_BEGIN
newGroupThread.groupModel = newGroupModel;
[newGroupThread saveWithTransaction:transaction];
[[[TSInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
[[[TSInfoMessage alloc] initWithTimestamp:now
inThread:newGroupThread
messageType:TSInfoMessageTypeGroupUpdate
customMessage:updateGroupInfo] saveWithTransaction:transaction];
if (dataMessage.hasExpireTimer && dataMessage.expireTimer > 0) {
// We could use the sender name here, but maybe it makes more sense to attribute it to the group.
NSString *configUpdateName = dataMessage.group.name;
[[OWSDisappearingMessagesJob sharedJob]
becomeConsistentWithDisappearingDuration:dataMessage.expireTimer
thread:newGroupThread
appearBeforeTimestamp:now
createdByRemoteContactName:nil
createdInExistingGroupName:configUpdateName
transaction:transaction];
}
return nil;
}
case OWSSignalServiceProtosGroupContextTypeQuit: {