From 955e3abdad1d9447fb8b370597d99358ea95acfb Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Wed, 5 May 2021 10:38:09 +1000 Subject: [PATCH] Clean up group update handling --- .../Messages/Signal/TSInfoMessage.h | 5 +- .../Messages/Signal/TSInfoMessage.m | 4 +- .../MessageReceiver+Handling.swift | 18 ++-- .../MessageSender+ClosedGroups.swift | 10 +- SessionMessagingKit/Threads/TSGroupModel.h | 3 +- SessionMessagingKit/Threads/TSGroupModel.m | 99 +++++++------------ 6 files changed, 56 insertions(+), 83 deletions(-) diff --git a/SessionMessagingKit/Messages/Signal/TSInfoMessage.h b/SessionMessagingKit/Messages/Signal/TSInfoMessage.h index 4080bbf0e..745ffd0d6 100644 --- a/SessionMessagingKit/Messages/Signal/TSInfoMessage.h +++ b/SessionMessagingKit/Messages/Signal/TSInfoMessage.h @@ -10,8 +10,9 @@ NS_ASSUME_NONNULL_BEGIN @interface TSInfoMessage : TSMessage typedef NS_ENUM(NSInteger, TSInfoMessageType) { - TSInfoMessageTypeGroupUpdate, - TSInfoMessageTypeGroupQuit, + TSInfoMessageTypeGroupCreated, + TSInfoMessageTypeGroupUpdated, + TSInfoMessageTypeGroupCurrentUserLeft, TSInfoMessageTypeDisappearingMessagesUpdate, TSInfoMessageTypeScreenshotNotification, TSInfoMessageTypeMediaSavedNotification diff --git a/SessionMessagingKit/Messages/Signal/TSInfoMessage.m b/SessionMessagingKit/Messages/Signal/TSInfoMessage.m index f2a0e3aab..fbe3ec656 100644 --- a/SessionMessagingKit/Messages/Signal/TSInfoMessage.m +++ b/SessionMessagingKit/Messages/Signal/TSInfoMessage.m @@ -103,9 +103,9 @@ NSUInteger TSInfoMessageSchemaVersion = 1; - (NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction { switch (_messageType) { - case TSInfoMessageTypeGroupQuit: + case TSInfoMessageTypeGroupCurrentUserLeft: return NSLocalizedString(@"GROUP_YOU_LEFT", nil); - case TSInfoMessageTypeGroupUpdate: + case TSInfoMessageTypeGroupUpdated: return _customMessage != nil ? _customMessage : NSLocalizedString(@"GROUP_UPDATED", nil); default: break; diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift index 6d5b53998..934d16a61 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift @@ -398,7 +398,7 @@ extension MessageReceiver { thread = TSGroupThread.getOrCreateThread(with: group, transaction: transaction) thread.save(with: transaction) // Notify the user - let infoMessage = TSInfoMessage(timestamp: messageSentTimestamp, in: thread, messageType: .groupUpdate) + let infoMessage = TSInfoMessage(timestamp: messageSentTimestamp, in: thread, messageType: .groupCreated) infoMessage.save(with: transaction) } // Add the group to the user's set of public keys to poll for @@ -470,7 +470,7 @@ extension MessageReceiver { // Notify the user if needed guard name != group.groupName else { return } let updateInfo = group.getInfoStringAboutUpdate(to: newGroupModel) - let infoMessage = TSInfoMessage(timestamp: message.sentTimestamp!, in: thread, messageType: .groupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: message.sentTimestamp!, in: thread, messageType: .groupUpdated, customMessage: updateInfo) infoMessage.save(with: transaction) } } @@ -504,7 +504,7 @@ extension MessageReceiver { // Notify the user if needed guard members != Set(group.groupMemberIds) else { return } let updateInfo = group.getInfoStringAboutUpdate(to: newGroupModel) - let infoMessage = TSInfoMessage(timestamp: message.sentTimestamp!, in: thread, messageType: .groupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: message.sentTimestamp!, in: thread, messageType: .groupUpdated, customMessage: updateInfo) infoMessage.save(with: transaction) } } @@ -548,7 +548,7 @@ extension MessageReceiver { thread.setGroupModel(newGroupModel, with: transaction) // Notify the user if needed guard members != Set(group.groupMemberIds) else { return } - let infoMessageType: TSInfoMessageType = wasCurrentUserRemoved ? .groupQuit : .groupUpdate + let infoMessageType: TSInfoMessageType = wasCurrentUserRemoved ? .groupCurrentUserLeft : .groupUpdated let updateInfo = group.getInfoStringAboutUpdate(to: newGroupModel) let infoMessage = TSInfoMessage(timestamp: message.sentTimestamp!, in: thread, messageType: infoMessageType, customMessage: updateInfo) infoMessage.save(with: transaction) @@ -581,8 +581,14 @@ extension MessageReceiver { thread.setGroupModel(newGroupModel, with: transaction) // Notify the user if needed guard members != Set(group.groupMemberIds) else { return } - let updateInfo = group.getInfoStringAboutUpdate(to: newGroupModel) - let infoMessage = TSInfoMessage(timestamp: message.sentTimestamp!, in: thread, messageType: .groupUpdate, customMessage: updateInfo) + let contact = Storage.shared.getContact(with: message.sender!) + let updateInfo: String + if let displayName = contact?.displayName(for: Contact.Context.regular) { + updateInfo = String(format: NSLocalizedString("GROUP_MEMBER_LEFT", comment: ""), displayName) + } else { + updateInfo = NSLocalizedString("GROUP_UPDATED", comment: "") + } + let infoMessage = TSInfoMessage(timestamp: message.sentTimestamp!, in: thread, messageType: .groupUpdated, customMessage: updateInfo) infoMessage.save(with: transaction) } } diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift b/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift index 8e54cb894..2fac0e5ea 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift @@ -41,7 +41,7 @@ extension MessageSender { // Notify the PN server promises.append(PushNotificationAPI.performOperation(.subscribe, for: groupPublicKey, publicKey: userPublicKey)) // Notify the user - let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdate) + let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupCreated) infoMessage.save(with: transaction) // Return return when(fulfilled: promises).map2 { thread } @@ -137,7 +137,7 @@ extension MessageSender { thread.setGroupModel(newGroupModel, with: transaction) // Notify the user let updateInfo = group.getInfoStringAboutUpdate(to: newGroupModel) - let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdated, customMessage: updateInfo) infoMessage.save(with: transaction) // Return return Promise.value(()) @@ -182,7 +182,7 @@ extension MessageSender { thread.setGroupModel(newGroupModel, with: transaction) // Notify the user let updateInfo = group.getInfoStringAboutUpdate(to: newGroupModel) - let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdated, customMessage: updateInfo) infoMessage.save(with: transaction) // Return return Promise.value(()) @@ -233,7 +233,7 @@ extension MessageSender { // Notify the user if needed (not if only zombie members were removed) if !membersToRemove.subtracting(oldZombies).isEmpty { let updateInfo = group.getInfoStringAboutUpdate(to: newGroupModel) - let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdated, customMessage: updateInfo) infoMessage.save(with: transaction) } // Return @@ -280,7 +280,7 @@ extension MessageSender { thread.setGroupModel(newGroupModel, with: transaction) // Notify the user let updateInfo = group.getInfoStringAboutUpdate(to: newGroupModel) - let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupCurrentUserLeft, customMessage: updateInfo) infoMessage.save(with: transaction) // Return return promise diff --git a/SessionMessagingKit/Threads/TSGroupModel.h b/SessionMessagingKit/Threads/TSGroupModel.h index 6467d216d..f05879470 100644 --- a/SessionMessagingKit/Threads/TSGroupModel.h +++ b/SessionMessagingKit/Threads/TSGroupModel.h @@ -21,7 +21,6 @@ extern const int32_t kGroupIdLength; @property (nullable, readonly, nonatomic) NSString *groupName; @property (readonly, nonatomic) NSData *groupId; @property (nonatomic) GroupType groupType; -@property (nonatomic) NSMutableSet *removedMembers; #if TARGET_OS_IOS @property (nullable, nonatomic, strong) UIImage *groupImage; @@ -36,7 +35,7 @@ extern const int32_t kGroupIdLength; - (BOOL)isEqual:(id)other; - (BOOL)isEqualToGroupModel:(TSGroupModel *)model; - (NSString *)getInfoStringAboutUpdateTo:(TSGroupModel *)model; -- (void)updateGroupId: (NSData *)newGroupId; + #endif @end diff --git a/SessionMessagingKit/Threads/TSGroupModel.m b/SessionMessagingKit/Threads/TSGroupModel.m index 430b35d55..2ad8f00bf 100644 --- a/SessionMessagingKit/Threads/TSGroupModel.m +++ b/SessionMessagingKit/Threads/TSGroupModel.m @@ -20,6 +20,11 @@ const int32_t kGroupIdLength = 16; @implementation TSGroupModel +- (nullable NSString *)groupName +{ + return _groupName.filterStringForDisplay; +} + #if TARGET_OS_IOS - (instancetype)initWithTitle:(nullable NSString *)title memberIds:(NSArray *)memberIds @@ -30,7 +35,7 @@ const int32_t kGroupIdLength = 16; { _groupName = title; _groupMemberIds = [memberIds copy]; - _groupImage = image; // image is stored in DB + _groupImage = image; _groupType = groupType; _groupId = groupId; _groupAdminIds = [adminIds copy]; @@ -54,10 +59,6 @@ const int32_t kGroupIdLength = 16; if (_groupAdminIds == nil) { _groupAdminIds = [NSArray new]; } - - if (_removedMembers == nil) { - _removedMembers = [NSMutableSet new]; - } return self; } @@ -97,75 +98,56 @@ const int32_t kGroupIdLength = 16; } - (NSString *)getInfoStringAboutUpdateTo:(TSGroupModel *)newModel { + // This is only invoked for group * changes *, i.e. not when a group is created. + NSString *userPublicKey = [SNGeneralUtilities getUserPublicKey]; NSString *updatedGroupInfoString = @""; if (self == newModel) { return NSLocalizedString(@"GROUP_UPDATED", @""); } + // Name change if (![_groupName isEqual:newModel.groupName]) { - if (newModel.groupName.length == 0) { - updatedGroupInfoString = [updatedGroupInfoString stringByAppendingString:@"Closed group created"]; - } else { - updatedGroupInfoString = [updatedGroupInfoString stringByAppendingString:[NSString stringWithFormat:NSLocalizedString(@"GROUP_TITLE_CHANGED", @""), newModel.groupName]]; - } - } - if (_groupImage != nil && newModel.groupImage != nil && - !([UIImagePNGRepresentation(_groupImage) isEqualToData:UIImagePNGRepresentation(newModel.groupImage)])) { - updatedGroupInfoString = - [updatedGroupInfoString stringByAppendingString:NSLocalizedString(@"GROUP_AVATAR_CHANGED", @"")]; + updatedGroupInfoString = [updatedGroupInfoString stringByAppendingString:[NSString stringWithFormat:NSLocalizedString(@"GROUP_TITLE_CHANGED", @""), newModel.groupName]]; } + // Added & removed members NSSet *oldMembers = [NSSet setWithArray:_groupMemberIds]; NSSet *newMembers = [NSSet setWithArray:newModel.groupMemberIds]; - NSMutableSet *membersWhoJoined = [NSMutableSet setWithSet:newMembers]; - [membersWhoJoined minusSet:oldMembers]; + NSMutableSet *addedMembers = newMembers.mutableCopy; + [addedMembers minusSet:oldMembers]; - NSMutableSet *membersWhoLeft = [NSMutableSet setWithSet:oldMembers]; - [membersWhoLeft minusSet:newMembers]; - [membersWhoLeft minusSet:newModel.removedMembers]; + NSMutableSet *removedMembers = oldMembers.mutableCopy; + [removedMembers minusSet:newMembers]; + NSMutableSet *removedMembersMinusSelf = removedMembers.mutableCopy; + [removedMembersMinusSelf minusSet:[NSSet setWithObject:userPublicKey]]; - if ([membersWhoLeft count] > 0) { - NSArray *oldMembersNames = [[membersWhoLeft allObjects] map:^NSString*(NSString* publicKey) { - return [[LKStorage.shared getContactWithSessionID:publicKey] displayNameFor:SNContactContextRegular] ?: publicKey; + if (removedMembersMinusSelf.count > 0) { + NSArray *removedMemberNames = [removedMembers.allObjects map:^NSString *(NSString *publicKey) { + SNContact *contact = [LKStorage.shared getContactWithSessionID:publicKey]; + return [contact displayNameFor:SNContactContextRegular] ?: publicKey; }]; + NSString *format = removedMembers.count > 1 ? NSLocalizedString(@"GROUP_MEMBERS_REMOVED", @"") : NSLocalizedString(@"GROUP_MEMBER_REMOVED", @""); updatedGroupInfoString = [updatedGroupInfoString stringByAppendingString:[NSString - stringWithFormat:NSLocalizedString(@"GROUP_MEMBER_LEFT", @""), - [oldMembersNames componentsJoinedByString:@", "]]]; + stringWithFormat: format, + [removedMemberNames componentsJoinedByString:@", "]]]; } - if (membersWhoJoined.count > 0) { - NSArray *newMembersNames = [[membersWhoJoined allObjects] map:^NSString*(NSString* publicKey) { - return [[LKStorage.shared getContactWithSessionID:publicKey] displayNameFor:SNContactContextRegular] ?: publicKey; + if (addedMembers.count > 0) { + NSArray *addedMemberNames = [[addedMembers allObjects] map:^NSString*(NSString* publicKey) { + SNContact *contact = [LKStorage.shared getContactWithSessionID:publicKey]; + return [contact displayNameFor:SNContactContextRegular] ?: publicKey; }]; updatedGroupInfoString = [updatedGroupInfoString stringByAppendingString:[NSString stringWithFormat:NSLocalizedString(@"GROUP_MEMBER_JOINED", @""), - [newMembersNames componentsJoinedByString:@", "]]]; + [addedMemberNames componentsJoinedByString:@", "]]]; } - - if (newModel.removedMembers.count > 0) { - if ([newModel.removedMembers containsObject:[SNGeneralUtilities getUserPublicKey]]) { - updatedGroupInfoString = [updatedGroupInfoString - stringByAppendingString:NSLocalizedString(@"YOU_WERE_REMOVED", @"")]; - } else { - NSArray *removedMemberNames = [newModel.removedMembers.allObjects map:^NSString*(NSString* publicKey) { - return [[LKStorage.shared getContactWithSessionID:publicKey] displayNameFor:SNContactContextRegular] ?: publicKey; - }]; - if ([removedMemberNames count] > 1) { - updatedGroupInfoString = [updatedGroupInfoString - stringByAppendingString:[NSString - stringWithFormat:NSLocalizedString(@"GROUP_MEMBERS_REMOVED", @""), - [removedMemberNames componentsJoinedByString:@", "]]]; - } - else { - updatedGroupInfoString = [updatedGroupInfoString - stringByAppendingString:[NSString - stringWithFormat:NSLocalizedString(@"GROUP_MEMBER_REMOVED", @""), - removedMemberNames[0]]]; - } - } + + if ([removedMembers containsObject:userPublicKey]) { + updatedGroupInfoString = [updatedGroupInfoString stringByAppendingString:NSLocalizedString(@"YOU_WERE_REMOVED", @"")]; } + // Return if ([updatedGroupInfoString length] == 0) { updatedGroupInfoString = NSLocalizedString(@"GROUP_UPDATED", @""); } @@ -174,21 +156,6 @@ const int32_t kGroupIdLength = 16; #endif -- (nullable NSString *)groupName -{ - return _groupName.filterStringForDisplay; -} - -- (void)setRemovedMembers:(NSMutableSet *)removedMembers -{ - _removedMembers = removedMembers; -} - -- (void)updateGroupId: (NSData *)newGroupId -{ - _groupId = newGroupId; -} - @end NS_ASSUME_NONNULL_END