From 08015f570febb9181b3334d18d757743720a82df Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 2 Mar 2021 14:25:21 +1100 Subject: [PATCH] Create DataExtractionNotificationInfoMessage --- Session.xcodeproj/project.pbxproj | 12 +++++++ .../Message Cells/InfoMessageCell.swift | 2 +- .../Messages/Signal/TSInfoMessage.h | 11 ++---- .../Messages/Signal/TSInfoMessage.m | 32 ----------------- ...ataExtractionNotificationInfoMessage.swift | 35 +++++++++++++++++++ .../MessageReceiver+Handling.swift | 19 +++++++--- .../Sending & Receiving/MessageReceiver.swift | 1 + .../MessageSender+ClosedGroups.swift | 10 +++--- 8 files changed, 70 insertions(+), 52 deletions(-) create mode 100644 SessionMessagingKit/Sending & Receiving/Data Extraction/DataExtractionNotificationInfoMessage.swift diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 607df2cf0..e4e0ba9fd 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -288,6 +288,7 @@ B8F5F56525EC8453003BF8D4 /* Notification+Contacts.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8F5F56425EC8453003BF8D4 /* Notification+Contacts.swift */; }; B8F5F58325EC94A6003BF8D4 /* Collection+Subscripting.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8F5F58225EC94A6003BF8D4 /* Collection+Subscripting.swift */; }; B8F5F60325EDE16F003BF8D4 /* DataExtractionNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8F5F60225EDE16F003BF8D4 /* DataExtractionNotification.swift */; }; + B8F5F61B25EDE4BF003BF8D4 /* DataExtractionNotificationInfoMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8F5F61A25EDE4BF003BF8D4 /* DataExtractionNotificationInfoMessage.swift */; }; B8FF8DAE25C0D00F004D1F22 /* SessionMessagingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A6F025539DE700C340D1 /* SessionMessagingKit.framework */; }; B8FF8DAF25C0D00F004D1F22 /* SessionUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A679255388CC00C340D1 /* SessionUtilitiesKit.framework */; }; B8FF8E6225C10DA5004D1F22 /* GeoLite2-Country-Blocks-IPv4 in Resources */ = {isa = PBXBuildFile; fileRef = B8FF8E6125C10DA5004D1F22 /* GeoLite2-Country-Blocks-IPv4 */; }; @@ -1285,6 +1286,7 @@ B8F5F56425EC8453003BF8D4 /* Notification+Contacts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+Contacts.swift"; sourceTree = ""; }; B8F5F58225EC94A6003BF8D4 /* Collection+Subscripting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Subscripting.swift"; sourceTree = ""; }; B8F5F60225EDE16F003BF8D4 /* DataExtractionNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataExtractionNotification.swift; sourceTree = ""; }; + B8F5F61A25EDE4BF003BF8D4 /* DataExtractionNotificationInfoMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataExtractionNotificationInfoMessage.swift; sourceTree = ""; }; B8FF8E6125C10DA5004D1F22 /* GeoLite2-Country-Blocks-IPv4 */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; name = "GeoLite2-Country-Blocks-IPv4"; path = "Countries/GeoLite2-Country-Blocks-IPv4"; sourceTree = ""; }; B8FF8E7325C10FC3004D1F22 /* GeoLite2-Country-Locations-English */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; name = "GeoLite2-Country-Locations-English"; path = "Countries/GeoLite2-Country-Locations-English"; sourceTree = ""; }; B8FF8EA525C11FEF004D1F22 /* IPv4.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPv4.swift; sourceTree = ""; }; @@ -2385,6 +2387,14 @@ path = Shared; sourceTree = ""; }; + B8F5F61925EDE4B0003BF8D4 /* Data Extraction */ = { + isa = PBXGroup; + children = ( + B8F5F61A25EDE4BF003BF8D4 /* DataExtractionNotificationInfoMessage.swift */, + ); + path = "Data Extraction"; + sourceTree = ""; + }; B8FF8E6025C10D8B004D1F22 /* Countries */ = { isa = PBXGroup; children = ( @@ -2438,6 +2448,7 @@ children = ( C3D9E3B52567685D0040E4F3 /* Attachments */, C32C5B9E256DC720003C73A2 /* Blocking */, + B8F5F61925EDE4B0003BF8D4 /* Data Extraction */, C32C5B01256DC054003C73A2 /* Expiration */, C32C5D22256DD496003C73A2 /* Link Previews */, C32C5D2D256DD4C4003C73A2 /* Mentions */, @@ -4751,6 +4762,7 @@ C3D9E52725677DF20040E4F3 /* OWSThumbnailService.swift in Sources */, C32C5E75256DE020003C73A2 /* YapDatabaseTransaction+OWS.m in Sources */, C3BBE0802554CDD70050F1E3 /* Storage.swift in Sources */, + B8F5F61B25EDE4BF003BF8D4 /* DataExtractionNotificationInfoMessage.swift in Sources */, C379DCF4256735770002D4EB /* VisibleMessage+Attachment.swift in Sources */, B8856D34256F1192001CE70E /* Environment.m in Sources */, B8B320B7258C30D70020074B /* HTMLMetadata.swift in Sources */, diff --git a/Session/Conversations/Message Cells/InfoMessageCell.swift b/Session/Conversations/Message Cells/InfoMessageCell.swift index c7873cbc1..1391dc952 100644 --- a/Session/Conversations/Message Cells/InfoMessageCell.swift +++ b/Session/Conversations/Message Cells/InfoMessageCell.swift @@ -47,7 +47,7 @@ final class InfoMessageCell : MessageCell { guard let message = viewItem?.interaction as? TSInfoMessage else { return } let icon: UIImage? switch message.messageType { - case .typeDisappearingMessagesUpdate: + case .disappearingMessagesUpdate: var configuration: OWSDisappearingMessagesConfiguration? Storage.read { transaction in configuration = message.thread(with: transaction).disappearingMessagesConfiguration(with: transaction) diff --git a/SessionMessagingKit/Messages/Signal/TSInfoMessage.h b/SessionMessagingKit/Messages/Signal/TSInfoMessage.h index 9213edcb1..4080bbf0e 100644 --- a/SessionMessagingKit/Messages/Signal/TSInfoMessage.h +++ b/SessionMessagingKit/Messages/Signal/TSInfoMessage.h @@ -10,20 +10,13 @@ NS_ASSUME_NONNULL_BEGIN @interface TSInfoMessage : TSMessage typedef NS_ENUM(NSInteger, TSInfoMessageType) { - TSInfoMessageTypeSessionDidEnd, - TSInfoMessageUserNotRegistered, - // TSInfoMessageTypeUnsupportedMessage appears to be obsolete. - TSInfoMessageTypeUnsupportedMessage, TSInfoMessageTypeGroupUpdate, TSInfoMessageTypeGroupQuit, TSInfoMessageTypeDisappearingMessagesUpdate, - TSInfoMessageAddToContactsOffer, - TSInfoMessageAddUserToProfileWhitelistOffer, - TSInfoMessageAddGroupToProfileWhitelistOffer + TSInfoMessageTypeScreenshotNotification, + TSInfoMessageTypeMediaSavedNotification }; -+ (instancetype)userNotRegisteredMessageInThread:(TSThread *)thread recipientId:(NSString *)recipientId; - @property (atomic, readonly) TSInfoMessageType messageType; @property (atomic, readonly, nullable) NSString *customMessage; @property (atomic, readonly, nullable) NSString *unregisteredRecipientId; diff --git a/SessionMessagingKit/Messages/Signal/TSInfoMessage.m b/SessionMessagingKit/Messages/Signal/TSInfoMessage.m index 6d4d2116c..f2a0e3aab 100644 --- a/SessionMessagingKit/Messages/Signal/TSInfoMessage.m +++ b/SessionMessagingKit/Messages/Signal/TSInfoMessage.m @@ -95,15 +95,6 @@ NSUInteger TSInfoMessageSchemaVersion = 1; return self; } -+ (instancetype)userNotRegisteredMessageInThread:(TSThread *)thread recipientId:(NSString *)recipientId -{ - // MJK TODO - remove senderTimestamp - return [[self alloc] initWithTimestamp:[NSDate millisecondTimestamp] - inThread:thread - messageType:TSInfoMessageUserNotRegistered - unregisteredRecipientId:recipientId]; -} - - (OWSInteractionType)interactionType { return OWSInteractionType_Info; @@ -112,33 +103,10 @@ NSUInteger TSInfoMessageSchemaVersion = 1; - (NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction { switch (_messageType) { - case TSInfoMessageTypeSessionDidEnd: - return NSLocalizedString(@"SECURE_SESSION_RESET", nil); - case TSInfoMessageTypeUnsupportedMessage: - return NSLocalizedString(@"UNSUPPORTED_ATTACHMENT", nil); - case TSInfoMessageUserNotRegistered: - if (self.unregisteredRecipientId.length > 0) { - NSString *recipientName = @""; - return [NSString stringWithFormat:NSLocalizedString(@"ERROR_UNREGISTERED_USER_FORMAT", - @"Format string for 'unregistered user' error. Embeds {{the " - @"unregistered user's name or signal id}}."), - recipientName]; - } else { - return NSLocalizedString(@"CONTACT_DETAIL_COMM_TYPE_INSECURE", nil); - } case TSInfoMessageTypeGroupQuit: return NSLocalizedString(@"GROUP_YOU_LEFT", nil); case TSInfoMessageTypeGroupUpdate: return _customMessage != nil ? _customMessage : NSLocalizedString(@"GROUP_UPDATED", nil); - case TSInfoMessageAddToContactsOffer: - return NSLocalizedString(@"ADD_TO_CONTACTS_OFFER", - @"Message shown in conversation view that offers to add an unknown user to your phone's contacts."); - case TSInfoMessageAddUserToProfileWhitelistOffer: - return NSLocalizedString(@"ADD_USER_TO_PROFILE_WHITELIST_OFFER", - @"Message shown in conversation view that offers to share your profile with a user."); - case TSInfoMessageAddGroupToProfileWhitelistOffer: - return NSLocalizedString(@"ADD_GROUP_TO_PROFILE_WHITELIST_OFFER", - @"Message shown in conversation view that offers to share your profile with a group."); default: break; } diff --git a/SessionMessagingKit/Sending & Receiving/Data Extraction/DataExtractionNotificationInfoMessage.swift b/SessionMessagingKit/Sending & Receiving/Data Extraction/DataExtractionNotificationInfoMessage.swift new file mode 100644 index 000000000..6546fb55a --- /dev/null +++ b/SessionMessagingKit/Sending & Receiving/Data Extraction/DataExtractionNotificationInfoMessage.swift @@ -0,0 +1,35 @@ + +@objc(SNDataExtractionNotificationInfoMessage) +final class DataExtractionNotificationInfoMessage : TSInfoMessage { + private let kind: DataExtractionNotification.Kind + + init(kind: DataExtractionNotification.Kind, timestamp: UInt64, thread: TSThread) { + self.kind = kind + let infoMessageType: TSInfoMessageType + switch kind { + case .screenshot: infoMessageType = .screenshotNotification + case .mediaSaved: infoMessageType = .mediaSavedNotification + } + super.init(timestamp: timestamp, in: thread, messageType: infoMessageType) + } + + required init(coder: NSCoder) { + preconditionFailure("Not implemented.") + } + + required init(dictionary dictionaryValue: [String:Any]!) throws { + preconditionFailure("Not implemented.") + } + + override func previewText(with transaction: YapDatabaseReadTransaction) -> String { + guard let thread = thread as? TSContactThread else { return "" } // Should never occur + let sessionID = thread.contactIdentifier() + let displayName = Storage.shared.getContact(with: sessionID)?.displayName(for: .regular) ?? sessionID + switch kind { + case .screenshot: return "\(displayName) took a screenshot." + case .mediaSaved: + // TODO: Use the timestamp and tell the user * which * media was saved + return "Media saved by \(displayName)." + } + } +} diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift index eb7e55741..09d370e82 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift @@ -11,6 +11,7 @@ extension MessageReceiver { case let message as ReadReceipt: handleReadReceipt(message, using: transaction) case let message as TypingIndicator: handleTypingIndicator(message, using: transaction) case let message as ClosedGroupControlMessage: handleClosedGroupControlMessage(message, using: transaction) + case let message as DataExtractionNotification: handleDataExtractionNotification(message, using: transaction) case let message as ExpirationTimerUpdate: handleExpirationTimerUpdate(message, using: transaction) case let message as ConfigurationMessage: handleConfigurationMessage(message, using: transaction) case let message as VisibleMessage: try handleVisibleMessage(message, associatedWithProto: proto, openGroupID: openGroupID, isBackgroundPoll: isBackgroundPoll, using: transaction) @@ -104,6 +105,14 @@ extension MessageReceiver { + // MARK: - Data Extraction Notification + + private static func handleDataExtractionNotification(_ message: DataExtractionNotification, using transaction: Any) { + + } + + + // MARK: - Expiration Timers private static func handleExpirationTimerUpdate(_ message: ExpirationTimerUpdate, using transaction: Any) { @@ -343,7 +352,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: .typeGroupUpdate) + let infoMessage = TSInfoMessage(timestamp: messageSentTimestamp, in: thread, messageType: .groupUpdate) infoMessage.save(with: transaction) } // Add the group to the user's set of public keys to poll for @@ -413,7 +422,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: .typeGroupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: message.sentTimestamp!, in: thread, messageType: .groupUpdate, customMessage: updateInfo) infoMessage.save(with: transaction) } } @@ -436,7 +445,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: .typeGroupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: message.sentTimestamp!, in: thread, messageType: .groupUpdate, customMessage: updateInfo) infoMessage.save(with: transaction) } } @@ -477,7 +486,7 @@ extension MessageReceiver { thread.setGroupModel(newGroupModel, with: transaction) // Notify the user if needed guard members != Set(group.groupMemberIds) else { return } - let infoMessageType: TSInfoMessageType = wasCurrentUserRemoved ? .typeGroupQuit : .typeGroupUpdate + let infoMessageType: TSInfoMessageType = wasCurrentUserRemoved ? .groupQuit : .groupUpdate let updateInfo = group.getInfoStringAboutUpdate(to: newGroupModel) let infoMessage = TSInfoMessage(timestamp: message.sentTimestamp!, in: thread, messageType: infoMessageType, customMessage: updateInfo) infoMessage.save(with: transaction) @@ -517,7 +526,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: .typeGroupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: message.sentTimestamp!, in: thread, messageType: .groupUpdate, customMessage: updateInfo) infoMessage.save(with: transaction) } } diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift index 653f710aa..20daff6db 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift @@ -126,6 +126,7 @@ public enum MessageReceiver { if let readReceipt = ReadReceipt.fromProto(proto) { return readReceipt } if let typingIndicator = TypingIndicator.fromProto(proto) { return typingIndicator } if let closedGroupControlMessage = ClosedGroupControlMessage.fromProto(proto) { return closedGroupControlMessage } + if let dataExtractionNotification = DataExtractionNotification.fromProto(proto) { return dataExtractionNotification } if let expirationTimerUpdate = ExpirationTimerUpdate.fromProto(proto) { return expirationTimerUpdate } if let configurationMessage = ConfigurationMessage.fromProto(proto) { return configurationMessage } if let visibleMessage = VisibleMessage.fromProto(proto) { return visibleMessage } diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift b/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift index 7c963af33..976476f38 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift @@ -39,7 +39,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: .typeGroupUpdate) + let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdate) infoMessage.save(with: transaction) // Return return when(fulfilled: promises).map2 { thread } @@ -125,7 +125,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: .typeGroupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdate, customMessage: updateInfo) infoMessage.save(with: transaction) } @@ -166,7 +166,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: .typeGroupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdate, customMessage: updateInfo) infoMessage.save(with: transaction) } @@ -204,7 +204,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: .typeGroupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdate, customMessage: updateInfo) infoMessage.save(with: transaction) } @@ -237,7 +237,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: .typeGroupUpdate, customMessage: updateInfo) + let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .groupUpdate, customMessage: updateInfo) infoMessage.save(with: transaction) }