From a951c84e48af21849ae44f97dcf8724fcd2e73c7 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 28 Jul 2021 16:13:43 +1000 Subject: [PATCH 01/26] prepare for push notification filter --- .../NotificationServiceExtension.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/SessionNotificationServiceExtension/NotificationServiceExtension.swift b/SessionNotificationServiceExtension/NotificationServiceExtension.swift index 38e2f6966..35cd7f1ac 100644 --- a/SessionNotificationServiceExtension/NotificationServiceExtension.swift +++ b/SessionNotificationServiceExtension/NotificationServiceExtension.swift @@ -14,6 +14,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension override public func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler self.notificationContent = request.content.mutableCopy() as? UNMutableNotificationContent + let userPublicKey = SNGeneralUtilities.getUserPublicKey() // Abort if the main app is running var isMainAppAndActive = false @@ -36,6 +37,10 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension do { let (message, proto) = try MessageReceiver.parse(envelopeAsData, openGroupMessageServerID: nil, using: transaction) let senderPublicKey = message.sender! + if (senderPublicKey == userPublicKey) { + // Ignore PNs of messages sent from current user. + return self.completeSilenty() + } var senderDisplayName = Storage.shared.getContact(with: senderPublicKey)?.displayName(for: .regular) ?? senderPublicKey let snippet: String var userInfo: [String:Any] = [ NotificationServiceExtension.isFromRemoteKey : true ] @@ -56,6 +61,10 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension if let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction), let group = thread as? TSGroupThread, group.groupModel.groupType == .closedGroup { // Should always be true because we don't get PNs for open groups senderDisplayName = String(format: NotificationStrings.incomingGroupMessageTitleFormat, senderDisplayName, group.groupModel.groupName ?? MessageStrings.newGroupDefaultTitle) + if let messageBody = tsIncomingMessage.previewText(with: transaction).filterForDisplay, !messageBody.contains("@\(userPublicKey)") && group.isOnlyNotifyMentions { + // Ignore PNs if the group is set to only notify mentions + return self.completeSilenty() + } } case let closedGroupControlMessage as ClosedGroupControlMessage: // TODO: We could consider actually handling the update here. Not sure if there's enough time though, seeing as though From ad351d8009ebb9b11a34f5ca0338ce83ccc619a7 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Thu, 29 Jul 2021 10:46:00 +1000 Subject: [PATCH 02/26] clean --- .../NotifyMentions.imageset/Contents.json | 15 ++------------- .../ic_notification_mentions-1.png | Bin 2527 -> 0 bytes .../ic_notification_mentions-2.png | Bin 2527 -> 0 bytes .../ic_notification_mentions.png | Bin 2527 -> 0 bytes .../ic_notifications_mentions.pdf | Bin 0 -> 1599 bytes .../NotificationServiceExtension.swift | 2 +- 6 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions-1.png delete mode 100644 Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions-2.png delete mode 100644 Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions.png create mode 100644 Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notifications_mentions.pdf diff --git a/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/Contents.json b/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/Contents.json index 60527f39d..87de6e895 100644 --- a/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/Contents.json +++ b/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/Contents.json @@ -1,19 +1,8 @@ { "images" : [ { - "filename" : "ic_notification_mentions.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "ic_notification_mentions-1.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "ic_notification_mentions-2.png", - "idiom" : "universal", - "scale" : "3x" + "filename" : "ic_notifications_mentions.pdf", + "idiom" : "universal" } ], "info" : { diff --git a/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions-1.png b/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions-1.png deleted file mode 100644 index fe39a8b3566e28a7e49d515e69bfe566a6311dc5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2527 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 UDKNa?u8^eU3M?WbDP4>G2YGc2X#fBK literal 0 HcmV?d00001 diff --git a/SessionNotificationServiceExtension/NotificationServiceExtension.swift b/SessionNotificationServiceExtension/NotificationServiceExtension.swift index 35cd7f1ac..2cb60549b 100644 --- a/SessionNotificationServiceExtension/NotificationServiceExtension.swift +++ b/SessionNotificationServiceExtension/NotificationServiceExtension.swift @@ -61,7 +61,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension if let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction), let group = thread as? TSGroupThread, group.groupModel.groupType == .closedGroup { // Should always be true because we don't get PNs for open groups senderDisplayName = String(format: NotificationStrings.incomingGroupMessageTitleFormat, senderDisplayName, group.groupModel.groupName ?? MessageStrings.newGroupDefaultTitle) - if let messageBody = tsIncomingMessage.previewText(with: transaction).filterForDisplay, !messageBody.contains("@\(userPublicKey)") && group.isOnlyNotifyMentions { + if let messageBody = tsIncomingMessage.previewText(with: transaction).filterForDisplay, !messageBody.contains("@\(userPublicKey)") && group.isOnlyNotifyingForMentions { // Ignore PNs if the group is set to only notify mentions return self.completeSilenty() } From 556e13cc729c5c38ea0bd3447fa17e67a053e856 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Fri, 30 Jul 2021 10:44:48 +1000 Subject: [PATCH 03/26] Fix crash --- SignalUtilitiesKit/Messaging/OWSMessageUtils.m | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/SignalUtilitiesKit/Messaging/OWSMessageUtils.m b/SignalUtilitiesKit/Messaging/OWSMessageUtils.m index 09ab38cb6..9f7d6ea41 100644 --- a/SignalUtilitiesKit/Messaging/OWSMessageUtils.m +++ b/SignalUtilitiesKit/Messaging/OWSMessageUtils.m @@ -72,11 +72,13 @@ NS_ASSUME_NONNULL_BEGIN [LKStorage readWithBlock:^(YapDatabaseReadTransaction *transaction) { YapDatabaseViewTransaction *unreadMessages = [transaction ext:TSUnreadDatabaseViewExtensionName]; NSArray *allGroups = [unreadMessages allGroups]; + // FIXME: Confusingly, `allGroups` includes contact threads as well for (NSString *groupID in allGroups) { - TSGroupThread *thread = [TSGroupThread fetchObjectWithUniqueID:groupID transaction:transaction]; - if (thread.isMuted) continue; + TSThread *thread = [TSThread fetchObjectWithUniqueID:groupID transaction:transaction]; + if (thread.isMuted) { continue; } + BOOL isGroupThread = thread.isGroupThread; [unreadMessages enumerateKeysAndObjectsInGroup:groupID - usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) { + usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) { if (![object conformsToProtocol:@protocol(OWSReadTracking)]) { return; } @@ -85,9 +87,11 @@ NS_ASSUME_NONNULL_BEGIN NSLog(@"Found an already read message in the * unread * messages list."); return; } - TSIncomingMessage * incomingMessage = (TSIncomingMessage *)object; - if (incomingMessage != nil && thread.isOnlyNotifyingForMentions && !incomingMessage.isUserMentioned) { - return; + if ([object isKindOfClass:TSIncomingMessage.class] && isGroupThread) { + TSIncomingMessage *incomingMessage = (TSIncomingMessage *)object; + if (((TSGroupThread *)thread).isOnlyNotifyingForMentions && !incomingMessage.isUserMentioned) { + return; + } } count += 1; }]; From 1543dc7b1fabbd37aaecbf414b9d246358874a3b Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Fri, 30 Jul 2021 10:46:15 +1000 Subject: [PATCH 04/26] Update build number --- Session.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 782dde5b6..ade942d22 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -5063,7 +5063,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 281; + CURRENT_PROJECT_VERSION = 282; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5132,7 +5132,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 281; + CURRENT_PROJECT_VERSION = 282; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -5193,7 +5193,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 281; + CURRENT_PROJECT_VERSION = 282; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5263,7 +5263,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 281; + CURRENT_PROJECT_VERSION = 282; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6148,7 +6148,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 281; + CURRENT_PROJECT_VERSION = 282; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -6216,7 +6216,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 281; + CURRENT_PROJECT_VERSION = 282; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", From 593ab499520399c1047e078b10759737f1c0b8b5 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 09:12:01 +1000 Subject: [PATCH 05/26] Increase voice message recording limit to 3 minutes --- Session/Conversations/ConversationVC+Interaction.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index 89ae4dc4e..01d8b320a 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -689,7 +689,7 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc return cancelVoiceMessageRecording() } // Limit voice messages to a minute - audioTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: false, block: { [weak self] _ in + audioTimer = Timer.scheduledTimer(withTimeInterval: 180, repeats: false, block: { [weak self] _ in self?.snInputView.hideVoiceMessageUI() self?.endVoiceMessageRecording() }) From 68515310140ca1ca00a59188819c0c8807057a4f Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 09:12:56 +1000 Subject: [PATCH 06/26] Update build number --- Session.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index ade942d22..c6cda64de 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -5063,7 +5063,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 282; + CURRENT_PROJECT_VERSION = 283; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5132,7 +5132,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 282; + CURRENT_PROJECT_VERSION = 283; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -5193,7 +5193,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 282; + CURRENT_PROJECT_VERSION = 283; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5263,7 +5263,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 282; + CURRENT_PROJECT_VERSION = 283; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6148,7 +6148,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 282; + CURRENT_PROJECT_VERSION = 283; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -6216,7 +6216,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 282; + CURRENT_PROJECT_VERSION = 283; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", From dff9f287b84173f95abccdf95cedb0f6fc30a883 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 09:37:48 +1000 Subject: [PATCH 07/26] Resolve FIXME --- Session/Shared/ConversationCell.swift | 3 +-- SignalUtilitiesKit/Profile Pictures/ProfilePictureView.swift | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Session/Shared/ConversationCell.swift b/Session/Shared/ConversationCell.swift index 46074851b..3b1d8ca6a 100644 --- a/Session/Shared/ConversationCell.swift +++ b/Session/Shared/ConversationCell.swift @@ -157,8 +157,7 @@ final class ConversationCell : UITableViewCell { // MARK: Updating private func update() { AssertIsOnMainThread() - guard let thread = threadViewModel?.threadRecord, let threadID = thread.uniqueId else { return } - MentionsManager.populateUserPublicKeyCacheIfNeeded(for: threadID) // FIXME: This is a terrible place to do this + guard let thread = threadViewModel?.threadRecord else { return } let isBlocked: Bool if let thread = thread as? TSContactThread { isBlocked = SSKEnvironment.shared.blockingManager.isRecipientIdBlocked(thread.contactSessionID()) diff --git a/SignalUtilitiesKit/Profile Pictures/ProfilePictureView.swift b/SignalUtilitiesKit/Profile Pictures/ProfilePictureView.swift index c1485ad68..b91303954 100644 --- a/SignalUtilitiesKit/Profile Pictures/ProfilePictureView.swift +++ b/SignalUtilitiesKit/Profile Pictures/ProfilePictureView.swift @@ -69,7 +69,7 @@ public final class ProfilePictureView : UIView { publicKey = "" useFallbackPicture = true } else { // A closed group - var users = MentionsManager.userPublicKeyCache[thread.uniqueId!] ?? [] + var users = Set(thread.groupModel.groupMemberIds) users.remove(getUserHexEncodedPublicKey()) var randomUsers = users.sorted() // Sort to provide a level of stability if users.count == 1 { From 9b525f77b61585cb7b879fa4f11284aebb51fa36 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 09:38:06 +1000 Subject: [PATCH 08/26] Update build number --- Session.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index c6cda64de..fee9f747f 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -5063,7 +5063,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 283; + CURRENT_PROJECT_VERSION = 284; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5132,7 +5132,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 283; + CURRENT_PROJECT_VERSION = 284; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -5193,7 +5193,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 283; + CURRENT_PROJECT_VERSION = 284; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5263,7 +5263,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 283; + CURRENT_PROJECT_VERSION = 284; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6148,7 +6148,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 283; + CURRENT_PROJECT_VERSION = 284; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -6216,7 +6216,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 283; + CURRENT_PROJECT_VERSION = 284; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", From e8d8377a049a8a8867bf44727762f299d58fc58d Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 09:58:50 +1000 Subject: [PATCH 09/26] Fix threading bug --- .../Sending & Receiving/MessageReceiver+Handling.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift index ffebdd830..b6e2550a8 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift @@ -288,7 +288,11 @@ extension MessageReceiver { // Notify the user if needed guard (isMainAppAndActive || isBackgroundPoll), let tsIncomingMessage = TSMessage.fetch(uniqueId: tsMessageID, transaction: transaction) as? TSIncomingMessage, let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction) else { return tsMessageID } - SSKEnvironment.shared.notificationsManager!.notifyUser(for: tsIncomingMessage, in: thread, transaction: transaction) + DispatchQueue.main.async { + Storage.read { transaction in + SSKEnvironment.shared.notificationsManager!.notifyUser(for: tsIncomingMessage, in: thread, transaction: transaction) + } + } return tsMessageID } From c5c75a306e27c6b4be8d0f5f6323b7baafc07a9c Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 10:41:24 +1000 Subject: [PATCH 10/26] Hopefully fix scrolling issue --- Session/Conversations/ConversationVC.swift | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 439394502..19a5fd4ed 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -55,6 +55,11 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat return messagesTableView.contentSize.height - tableViewUnobscuredHeight } + var isCloseToBottom: Bool { + let margin = (self.lastPageTop - self.messagesTableView.contentOffset.y) + return margin <= ConversationVC.scrollToBottomMargin + } + lazy var mnemonic: String = { let identityManager = OWSIdentityManager.shared() let databaseConnection = identityManager.value(forKey: "dbConnection") as! YapDatabaseConnection @@ -314,6 +319,13 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat baselineKeyboardHeight = newHeight self.messagesTableView.keyboardHeight = newHeight } + let margin = (self.lastPageTop - self.messagesTableView.contentOffset.y) + // HACK: If the keyboard is coming up and we're very close to the bottom, scroll to the + // bottom. This "fixes" an issue where the conversation would randomly scroll up sometimes + // when bringing up the keyboard. + if newHeight > 200 && margin <= 2 { + scrollToBottom(isAnimated: false) + } scrollButtonConstraint?.constant = -(newHeight + 16) let newContentOffsetY = max(self.messagesTableView.contentOffset.y + min(lastPageTop, 0) + newHeight - self.messagesTableView.keyboardHeight, 0.0) self.messagesTableView.contentOffset.y = newContentOffsetY @@ -353,13 +365,11 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat if update.viewItem?.interaction is TSOutgoingMessage { shouldScrollToBottom = true } else { - let margin = (self.lastPageTop - self.messagesTableView.contentOffset.y) - shouldScrollToBottom = margin <= ConversationVC.scrollToBottomMargin + shouldScrollToBottom = self.isCloseToBottom } case .update: self.messagesTableView.reloadRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .fade) - let margin = (self.lastPageTop - self.messagesTableView.contentOffset.y) - shouldScrollToBottom = margin <= ConversationVC.scrollToBottomMargin + shouldScrollToBottom = self.isCloseToBottom default: preconditionFailure() } } From 12a995bc917c39fcc856e47cc1c2466b9677af86 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 3 Aug 2021 13:47:11 +1000 Subject: [PATCH 11/26] enable only notify mention for closed groups --- .../Settings/OWSConversationSettingsViewController.m | 2 +- .../Meta/SessionNotificationServiceExtension.entitlements | 2 ++ .../NotificationServiceExtension.swift | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Session/Conversations/Settings/OWSConversationSettingsViewController.m b/Session/Conversations/Settings/OWSConversationSettingsViewController.m index 3d303ca9d..33a3823fa 100644 --- a/Session/Conversations/Settings/OWSConversationSettingsViewController.m +++ b/Session/Conversations/Settings/OWSConversationSettingsViewController.m @@ -515,7 +515,7 @@ CGFloat kIconViewLength = 24; [weakSelf.navigationController pushViewController:vc animated:YES]; }]]; - if (self.isOpenGroup) { + if (self.isGroupThread) { // Notification Settings [section addItem:[OWSTableItem itemWithCustomCellBlock:^{ UITableViewCell *cell = [OWSTableItem newCell]; diff --git a/SessionNotificationServiceExtension/Meta/SessionNotificationServiceExtension.entitlements b/SessionNotificationServiceExtension/Meta/SessionNotificationServiceExtension.entitlements index 758088249..71a223d61 100644 --- a/SessionNotificationServiceExtension/Meta/SessionNotificationServiceExtension.entitlements +++ b/SessionNotificationServiceExtension/Meta/SessionNotificationServiceExtension.entitlements @@ -2,6 +2,8 @@ + com.apple.developer.usernotifications.filtering + aps-environment development com.apple.security.application-groups diff --git a/SessionNotificationServiceExtension/NotificationServiceExtension.swift b/SessionNotificationServiceExtension/NotificationServiceExtension.swift index 2cb60549b..fd51ffd0b 100644 --- a/SessionNotificationServiceExtension/NotificationServiceExtension.swift +++ b/SessionNotificationServiceExtension/NotificationServiceExtension.swift @@ -61,7 +61,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension if let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction), let group = thread as? TSGroupThread, group.groupModel.groupType == .closedGroup { // Should always be true because we don't get PNs for open groups senderDisplayName = String(format: NotificationStrings.incomingGroupMessageTitleFormat, senderDisplayName, group.groupModel.groupName ?? MessageStrings.newGroupDefaultTitle) - if let messageBody = tsIncomingMessage.previewText(with: transaction).filterForDisplay, !messageBody.contains("@\(userPublicKey)") && group.isOnlyNotifyingForMentions { + if group.isOnlyNotifyingForMentions && !tsIncomingMessage.isUserMentioned { // Ignore PNs if the group is set to only notify mentions return self.completeSilenty() } From 7c82ede432223ab603c1b766a8ca2281fa98e664 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 3 Aug 2021 14:25:10 +1000 Subject: [PATCH 12/26] fix a minor mention issue that it won't show the name if there is no white space after a mention --- Session/Utilities/MentionUtilities.swift | 2 +- .../NotificationServiceExtension.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Session/Utilities/MentionUtilities.swift b/Session/Utilities/MentionUtilities.swift index 5c888b09d..0faeb712a 100644 --- a/Session/Utilities/MentionUtilities.swift +++ b/Session/Utilities/MentionUtilities.swift @@ -14,7 +14,7 @@ public final class MentionUtilities : NSObject { MentionsManager.populateUserPublicKeyCacheIfNeeded(for: threadID, in: transaction) } var string = string - let regex = try! NSRegularExpression(pattern: "@[0-9a-fA-F]*", options: []) + let regex = try! NSRegularExpression(pattern: "@[0-9a-fA-F]{66}", options: []) let knownPublicKeys = MentionsManager.userPublicKeyCache[threadID] ?? [] // Should always be populated at this point var mentions: [(range: NSRange, publicKey: String)] = [] var outerMatch = regex.firstMatch(in: string, options: .withoutAnchoringBounds, range: NSRange(location: 0, length: string.utf16.count)) diff --git a/SessionNotificationServiceExtension/NotificationServiceExtension.swift b/SessionNotificationServiceExtension/NotificationServiceExtension.swift index fd51ffd0b..9565a7be4 100644 --- a/SessionNotificationServiceExtension/NotificationServiceExtension.swift +++ b/SessionNotificationServiceExtension/NotificationServiceExtension.swift @@ -201,7 +201,7 @@ private extension String { func replacingMentions(for threadID: String, using transaction: YapDatabaseReadWriteTransaction) -> String { MentionsManager.populateUserPublicKeyCacheIfNeeded(for: threadID, in: transaction) var result = self - let regex = try! NSRegularExpression(pattern: "@[0-9a-fA-F]*", options: []) + let regex = try! NSRegularExpression(pattern: "@[0-9a-fA-F]{66}", options: []) let knownPublicKeys = MentionsManager.userPublicKeyCache[threadID] ?? [] var mentions: [(range: NSRange, publicKey: String)] = [] var m0 = regex.firstMatch(in: result, options: .withoutAnchoringBounds, range: NSRange(location: 0, length: result.utf16.count)) From 36f592be4b9eea1ddcb82114663f21f296d40bcb Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 3 Aug 2021 14:26:59 +1000 Subject: [PATCH 13/26] clean --- Session/Utilities/MentionUtilities.swift | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Session/Utilities/MentionUtilities.swift b/Session/Utilities/MentionUtilities.swift index 0faeb712a..f0f5be6c8 100644 --- a/Session/Utilities/MentionUtilities.swift +++ b/Session/Utilities/MentionUtilities.swift @@ -44,9 +44,4 @@ public final class MentionUtilities : NSObject { } return result } - - public static func isUserMentioned(in string: String) -> Bool { - let userPublicKey = getUserHexEncodedPublicKey() - return string.contains("@\(userPublicKey)") - } } From e6949a5ae823212d9e12e6d8809d28151dfd411d Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 14:28:46 +1000 Subject: [PATCH 14/26] Fix glitch and add FIXME --- Session/Conversations/ConversationVC.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 19a5fd4ed..6d8b152ed 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -368,7 +368,8 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat shouldScrollToBottom = self.isCloseToBottom } case .update: - self.messagesTableView.reloadRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .fade) + // FIXME: This is called many times when a message is inserted, leading to bad performance + self.messagesTableView.reloadRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .none) shouldScrollToBottom = self.isCloseToBottom default: preconditionFailure() } From 7f0b87a2b22eb863f1396ca60e127a05bb0db844 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 15:36:54 +1000 Subject: [PATCH 15/26] Avoid unnecessary conversation screen updates --- Session.xcodeproj/project.pbxproj | 4 +++ Session/Conversations/ConversationVC.swift | 4 +-- Session/Conversations/ConversationViewModel.m | 14 +++++++--- .../OWSConversationSettingsViewController.m | 2 +- .../DownloadAttachmentModal.swift | 2 +- .../Database/Storage+Messaging.swift | 4 +-- .../Jobs/AttachmentUploadJob.swift | 8 +++--- .../Sending & Receiving/MessageSender.swift | 1 + SessionMessagingKit/Threads/TSGroupThread.h | 2 +- SessionMessagingKit/Threads/TSGroupThread.m | 2 +- .../Utilities/MessageInvalidator.swift | 27 +++++++++++++++++++ 11 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 SessionMessagingKit/Utilities/MessageInvalidator.swift diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index fee9f747f..c8d531f1e 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -169,6 +169,7 @@ B8269D2925C7A4B400488AB4 /* InputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8269D2825C7A4B400488AB4 /* InputView.swift */; }; B8269D3325C7A8C600488AB4 /* InputViewButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8269D3225C7A8C600488AB4 /* InputViewButton.swift */; }; B8269D3D25C7B34D00488AB4 /* InputTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8269D3C25C7B34D00488AB4 /* InputTextView.swift */; }; + B82A0C3826B9098200C1BCE3 /* MessageInvalidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82A0C3726B9098200C1BCE3 /* MessageInvalidator.swift */; }; B82B40882399EB0E00A248E7 /* LandingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82B40872399EB0E00A248E7 /* LandingVC.swift */; }; B82B408A2399EC0600A248E7 /* FakeChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82B40892399EC0600A248E7 /* FakeChatView.swift */; }; B82B408C239A068800A248E7 /* RegisterVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82B408B239A068800A248E7 /* RegisterVC.swift */; }; @@ -1149,6 +1150,7 @@ B8269D2825C7A4B400488AB4 /* InputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputView.swift; sourceTree = ""; }; B8269D3225C7A8C600488AB4 /* InputViewButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputViewButton.swift; sourceTree = ""; }; B8269D3C25C7B34D00488AB4 /* InputTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputTextView.swift; sourceTree = ""; }; + B82A0C3726B9098200C1BCE3 /* MessageInvalidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageInvalidator.swift; sourceTree = ""; }; B82B40872399EB0E00A248E7 /* LandingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandingVC.swift; sourceTree = ""; }; B82B40892399EC0600A248E7 /* FakeChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeChatView.swift; sourceTree = ""; }; B82B408B239A068800A248E7 /* RegisterVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterVC.swift; sourceTree = ""; }; @@ -3115,6 +3117,7 @@ C33FDBC1255A581700E217F9 /* General.swift */, B8AE760925ABFB00001A84D2 /* GeneralUtilities.h */, B8AE760A25ABFB5A001A84D2 /* GeneralUtilities.m */, + B82A0C3726B9098200C1BCE3 /* MessageInvalidator.swift */, C3A71D0A2558989C0043A11F /* MessageWrapper.swift */, C3A71D4E25589FF30043A11F /* NSData+messagePadding.h */, C3A71D4825589FF20043A11F /* NSData+messagePadding.m */, @@ -4746,6 +4749,7 @@ C32C5C01256DC9A0003C73A2 /* OWSIdentityManager.m in Sources */, C32C59C4256DB41F003C73A2 /* TSContactThread.m in Sources */, C32C5AB0256DBE8F003C73A2 /* TSOutgoingMessage.m in Sources */, + B82A0C3826B9098200C1BCE3 /* MessageInvalidator.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 6d8b152ed..67039536c 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -368,9 +368,9 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat shouldScrollToBottom = self.isCloseToBottom } case .update: - // FIXME: This is called many times when a message is inserted, leading to bad performance + shouldScrollToBottom = self.isCloseToBottom // Check this * before * reloading the row + print("[Test] UPDATE") self.messagesTableView.reloadRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .none) - shouldScrollToBottom = self.isCloseToBottom default: preconditionFailure() } } diff --git a/Session/Conversations/ConversationViewModel.m b/Session/Conversations/ConversationViewModel.m index 55e1baa18..588711011 100644 --- a/Session/Conversations/ConversationViewModel.m +++ b/Session/Conversations/ConversationViewModel.m @@ -822,9 +822,13 @@ NS_ASSUME_NONNULL_BEGIN OWSFailDebug(@"Can't find holdover view item."); return [self.delegate conversationViewModelDidUpdate:ConversationUpdate.reloadUpdate]; } - if (!viewItem.hasCachedLayoutState) { - [updatedItemSet addObject:itemId]; - [updatedNeighborItemSet addObject:itemId]; + + if ([viewItem.interaction isKindOfClass:TSMessage.class]) { + TSMessage *message = (TSMessage *)viewItem.interaction; + if ([MessageInvalidator isInvalidated:message]) { + [updatedItemSet addObject:itemId]; + [updatedNeighborItemSet addObject:itemId]; + } } } @@ -864,6 +868,10 @@ NS_ASSUME_NONNULL_BEGIN oldViewItemCount:oldItemIdList.count updatedNeighborItemSet:updatedNeighborItemSet]; + for (NSString *itemID in updatedItemSet) { + [MessageInvalidator markAsUpdated:itemID]; + } + return [self.delegate conversationViewModelDidUpdate:[ConversationUpdate diffUpdateWithUpdateItems:updateItems shouldAnimateUpdates:shouldAnimateUpdates]]; diff --git a/Session/Conversations/Settings/OWSConversationSettingsViewController.m b/Session/Conversations/Settings/OWSConversationSettingsViewController.m index 3d303ca9d..82b8166b5 100644 --- a/Session/Conversations/Settings/OWSConversationSettingsViewController.m +++ b/Session/Conversations/Settings/OWSConversationSettingsViewController.m @@ -1002,7 +1002,7 @@ CGFloat kIconViewLength = 24; UISwitch *uiSwitch = (UISwitch *)sender; BOOL isEnabled = uiSwitch.isOn; [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [(TSGroupThread *)self.thread setisOnlyNotifyingForMentions:isEnabled withTransaction:transaction]; + [(TSGroupThread *)self.thread setIsOnlyNotifyingForMentions:isEnabled withTransaction:transaction]; }]; } diff --git a/Session/Conversations/Views & Modals/DownloadAttachmentModal.swift b/Session/Conversations/Views & Modals/DownloadAttachmentModal.swift index 402c32032..1c8c88842 100644 --- a/Session/Conversations/Views & Modals/DownloadAttachmentModal.swift +++ b/Session/Conversations/Views & Modals/DownloadAttachmentModal.swift @@ -70,7 +70,7 @@ final class DownloadAttachmentModal : Modal { contact.isTrusted = true Storage.write(with: { transaction in Storage.shared.setContact(contact, using: transaction) - message.touch(with: transaction) + MessageInvalidator.invalidate(message, with: transaction) }, completion: { Storage.shared.resumeAttachmentDownloadJobsIfNeeded(for: message.uniqueThreadId) }) diff --git a/SessionMessagingKit/Database/Storage+Messaging.swift b/SessionMessagingKit/Database/Storage+Messaging.swift index 21e8d40e5..0a6a84f99 100644 --- a/SessionMessagingKit/Database/Storage+Messaging.swift +++ b/SessionMessagingKit/Database/Storage+Messaging.swift @@ -67,7 +67,7 @@ extension Storage { pointer.state = state pointer.save(with: transaction) guard let tsMessage = TSMessage.fetch(uniqueId: tsMessageID, transaction: transaction) else { return } - tsMessage.touch(with: transaction) + MessageInvalidator.invalidate(tsMessage, with: transaction) } /// Also touches the associated message. @@ -75,7 +75,7 @@ extension Storage { let transaction = transaction as! YapDatabaseReadWriteTransaction stream.save(with: transaction) guard let tsMessage = TSMessage.fetch(uniqueId: tsMessageID, transaction: transaction) else { return } - tsMessage.touch(with: transaction) + MessageInvalidator.invalidate(tsMessage, with: transaction) } private static let receivedMessageTimestampsCollection = "ReceivedMessageTimestampsCollection" diff --git a/SessionMessagingKit/Jobs/AttachmentUploadJob.swift b/SessionMessagingKit/Jobs/AttachmentUploadJob.swift index e3f9a1df6..401824b69 100644 --- a/SessionMessagingKit/Jobs/AttachmentUploadJob.swift +++ b/SessionMessagingKit/Jobs/AttachmentUploadJob.swift @@ -118,12 +118,14 @@ public final class AttachmentUploadJob : NSObject, Job, NSCoding { // NSObject/N delegate?.handleJobSucceeded(self) SNMessagingKitConfiguration.shared.storage.resumeMessageSendJobIfNeeded(messageSendJobID) Storage.shared.write(with: { transaction in - var interaction: TSInteraction? + var message: TSMessage? let transaction = transaction as! YapDatabaseReadWriteTransaction TSDatabaseSecondaryIndexes.enumerateMessages(withTimestamp: self.message.sentTimestamp!, with: { _, key, _ in - interaction = TSInteraction.fetch(uniqueId: key, transaction: transaction) + message = TSMessage.fetch(uniqueId: key, transaction: transaction) }, using: transaction) - interaction?.touch(with: transaction) // To refresh the associated message cell and hide the loader + if let message = message { + MessageInvalidator.invalidate(message, with: transaction) + } }, completion: { }) } diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender.swift b/SessionMessagingKit/Sending & Receiving/MessageSender.swift index 456ba6e23..8b4cfdff0 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender.swift @@ -340,6 +340,7 @@ public final class MessageSender : NSObject { recipients.forEach { recipient in tsMessage.update(withSentRecipient: recipient, wasSentByUD: true, transaction: transaction) } + MessageInvalidator.invalidate(tsMessage, with: transaction) // Start the disappearing messages timer if needed OWSDisappearingMessagesJob.shared().startAnyExpiration(for: tsMessage, expirationStartedAt: NSDate.millisecondTimestamp(), transaction: transaction) } diff --git a/SessionMessagingKit/Threads/TSGroupThread.h b/SessionMessagingKit/Threads/TSGroupThread.h index 0599d0461..09f551854 100644 --- a/SessionMessagingKit/Threads/TSGroupThread.h +++ b/SessionMessagingKit/Threads/TSGroupThread.h @@ -45,7 +45,7 @@ extern NSString *const TSGroupThread_NotificationKey_UniqueId; transaction:(YapDatabaseReadWriteTransaction *)transaction; - (void)setGroupModel:(TSGroupModel *)newGroupModel withTransaction:(YapDatabaseReadWriteTransaction *)transaction; -- (void)setisOnlyNotifyingForMentions:(BOOL)isOnlyNotifyingForMentions withTransaction:(YapDatabaseReadWriteTransaction *)transaction; +- (void)setIsOnlyNotifyingForMentions:(BOOL)isOnlyNotifyingForMentions withTransaction:(YapDatabaseReadWriteTransaction *)transaction; - (void)leaveGroupWithSneakyTransaction; - (void)leaveGroupWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; diff --git a/SessionMessagingKit/Threads/TSGroupThread.m b/SessionMessagingKit/Threads/TSGroupThread.m index f05d42732..382f6ed5e 100644 --- a/SessionMessagingKit/Threads/TSGroupThread.m +++ b/SessionMessagingKit/Threads/TSGroupThread.m @@ -208,7 +208,7 @@ NSString *const TSGroupThread_NotificationKey_UniqueId = @"TSGroupThread_Notific }]; } -- (void)setisOnlyNotifyingForMentions:(BOOL)isOnlyNotifyingForMentions withTransaction:(YapDatabaseReadWriteTransaction *)transaction +- (void)setIsOnlyNotifyingForMentions:(BOOL)isOnlyNotifyingForMentions withTransaction:(YapDatabaseReadWriteTransaction *)transaction { self.isOnlyNotifyingForMentions = isOnlyNotifyingForMentions; diff --git a/SessionMessagingKit/Utilities/MessageInvalidator.swift b/SessionMessagingKit/Utilities/MessageInvalidator.swift new file mode 100644 index 000000000..83619e091 --- /dev/null +++ b/SessionMessagingKit/Utilities/MessageInvalidator.swift @@ -0,0 +1,27 @@ + +/// A message is invalidated when it needs to be re-rendered in the UI. Examples of when this happens include: +/// +/// • When the sent or read status of a message is updated. +/// • When an attachment is uploaded or downloaded. +@objc public final class MessageInvalidator : NSObject { + private static var invalidatedMessages: Set = [] + + @objc public static let shared = MessageInvalidator() + + private override init() { } + + @objc public static func invalidate(_ message: TSMessage, with transaction: YapDatabaseReadWriteTransaction) { + guard let id = message.uniqueId else { return } + invalidatedMessages.insert(id) + message.touch(with: transaction) + } + + @objc public static func isInvalidated(_ message: TSMessage) -> Bool { + guard let id = message.uniqueId else { return false } + return invalidatedMessages.contains(id) + } + + @objc public static func markAsUpdated(_ id: String) { + invalidatedMessages.remove(id) + } +} From ec41a9e08e7ac0575f816aa60e62c9b4e720d56a Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 15:39:00 +1000 Subject: [PATCH 16/26] Remove hack --- Session/Conversations/ConversationVC.swift | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 67039536c..496f1807d 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -320,12 +320,6 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat self.messagesTableView.keyboardHeight = newHeight } let margin = (self.lastPageTop - self.messagesTableView.contentOffset.y) - // HACK: If the keyboard is coming up and we're very close to the bottom, scroll to the - // bottom. This "fixes" an issue where the conversation would randomly scroll up sometimes - // when bringing up the keyboard. - if newHeight > 200 && margin <= 2 { - scrollToBottom(isAnimated: false) - } scrollButtonConstraint?.constant = -(newHeight + 16) let newContentOffsetY = max(self.messagesTableView.contentOffset.y + min(lastPageTop, 0) + newHeight - self.messagesTableView.keyboardHeight, 0.0) self.messagesTableView.contentOffset.y = newContentOffsetY From 7d56e51690cdfeecbc02098843627cdee7455268 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 15:43:53 +1000 Subject: [PATCH 17/26] Simplify conversation screen updating logic --- Session/Conversations/ConversationVC.swift | 36 +++------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 496f1807d..8913200b8 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -347,7 +347,6 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat return messagesTableView.reloadData() } var shouldScrollToBottom = false - let shouldAnimate = conversationUpdate.shouldAnimateUpdates let batchUpdates: () -> Void = { for update in conversationUpdate.updateItems! { switch update.updateItemType { @@ -362,47 +361,20 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat shouldScrollToBottom = self.isCloseToBottom } case .update: - shouldScrollToBottom = self.isCloseToBottom // Check this * before * reloading the row print("[Test] UPDATE") - self.messagesTableView.reloadRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .none) + self.messagesTableView.reloadRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .fade) default: preconditionFailure() } } } - let batchUpdatesCompletion: (Bool) -> Void = { isFinished in + messagesTableView.performBatchUpdates(batchUpdates) { _ in if shouldScrollToBottom { self.scrollToBottom(isAnimated: true) - } else { - // This is a workaround for an issue where after an attachment is sent without the keyboard showing before, - // once the keyboard shows, the table view's content offset can be wrong and the last message won't completely show. - // This is caused by the main run loop calling some table view update method that sets the content offset back to - // the previous value when the keyboard is shown. - self.messagesTableView.reloadData() } self.markAllAsRead() } - if shouldAnimate { - messagesTableView.performBatchUpdates(batchUpdates, completion: batchUpdatesCompletion) - } else { - // HACK: We use `UIView.animateWithDuration:0` rather than `UIView.performWithAnimation` to work around a - // UIKit Crash like: - // - // *** Assertion failure in -[ConversationViewLayout prepareForCollectionViewUpdates:], - // /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.7.47/UICollectionViewLayout.m:760 - // *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'While - // preparing update a visible view at {length = 2, path = 0 - 142} - // wasn't found in the current data model and was not in an update animation. This is an internal - // error.' - // - // I'm unclear if this is a bug in UIKit, or if we're doing something crazy in - // ConversationViewLayout#prepareLayout. To reproduce, rapidily insert and delete items into the - // conversation. - UIView.animate(withDuration: 0) { - self.messagesTableView.performBatchUpdates(batchUpdates, completion: batchUpdatesCompletion) - if shouldScrollToBottom { - self.scrollToBottom(isAnimated: false) - } - } + if shouldScrollToBottom { + self.scrollToBottom(isAnimated: false) } } From c132b16d0169477ca6345f02af760df525a16676 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 15:45:04 +1000 Subject: [PATCH 18/26] Update build number --- Session.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index fee9f747f..eb58542f3 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -5063,7 +5063,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 284; + CURRENT_PROJECT_VERSION = 285; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5132,7 +5132,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 284; + CURRENT_PROJECT_VERSION = 285; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -5193,7 +5193,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 284; + CURRENT_PROJECT_VERSION = 285; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5263,7 +5263,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 284; + CURRENT_PROJECT_VERSION = 285; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6148,7 +6148,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 284; + CURRENT_PROJECT_VERSION = 285; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -6216,7 +6216,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 284; + CURRENT_PROJECT_VERSION = 285; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", From eb29b5d64142f1d29eebe2a185c5b4801bfbd5c0 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 15:46:34 +1000 Subject: [PATCH 19/26] Minor cleanup --- .../NotificationServiceExtension.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SessionNotificationServiceExtension/NotificationServiceExtension.swift b/SessionNotificationServiceExtension/NotificationServiceExtension.swift index 9565a7be4..983fdb7ce 100644 --- a/SessionNotificationServiceExtension/NotificationServiceExtension.swift +++ b/SessionNotificationServiceExtension/NotificationServiceExtension.swift @@ -38,7 +38,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension let (message, proto) = try MessageReceiver.parse(envelopeAsData, openGroupMessageServerID: nil, using: transaction) let senderPublicKey = message.sender! if (senderPublicKey == userPublicKey) { - // Ignore PNs of messages sent from current user. + // Ignore PNs for messages sent by the current user return self.completeSilenty() } var senderDisplayName = Storage.shared.getContact(with: senderPublicKey)?.displayName(for: .regular) ?? senderPublicKey @@ -52,6 +52,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension } let thread = tsIncomingMessage.thread(with: transaction) if thread.isMuted { + // Ignore PNs if the thread is muted return self.completeSilenty() } let threadID = thread.uniqueId! @@ -62,7 +63,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension group.groupModel.groupType == .closedGroup { // Should always be true because we don't get PNs for open groups senderDisplayName = String(format: NotificationStrings.incomingGroupMessageTitleFormat, senderDisplayName, group.groupModel.groupName ?? MessageStrings.newGroupDefaultTitle) if group.isOnlyNotifyingForMentions && !tsIncomingMessage.isUserMentioned { - // Ignore PNs if the group is set to only notify mentions + // Ignore PNs if the group is set to only notify for mentions return self.completeSilenty() } } From 1b0a12d7c0d3a2258495a39eb862b693be762724 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 3 Aug 2021 16:21:30 +1000 Subject: [PATCH 20/26] Don't unnecessarily unsubscribe from closed group PNs We don't need to do this anymore as we now have the ability to ignore PNs in the notification service extension --- .../Settings/OWSConversationSettingsViewController.m | 11 ----------- .../Notifications/PushNotificationAPI.swift | 8 +------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/Session/Conversations/Settings/OWSConversationSettingsViewController.m b/Session/Conversations/Settings/OWSConversationSettingsViewController.m index 7d3135714..b703a58ff 100644 --- a/Session/Conversations/Settings/OWSConversationSettingsViewController.m +++ b/Session/Conversations/Settings/OWSConversationSettingsViewController.m @@ -861,17 +861,6 @@ CGFloat kIconViewLength = 24; [self.thread updateWithMutedUntilDate:nil transaction:transaction]; }]; } - if (self.isClosedGroup) { - NSString *groupPublicKey = [LKGroupUtilities getDecodedGroupID:((TSGroupThread *)self.thread).groupModel.groupId]; - NSString *userPublicKey = [SNGeneralUtilities getUserPublicKey]; - if (uiSwitch.isOn) { - [[LKPushNotificationAPI performOperation:ClosedGroupOperationUnsubscribe - forClosedGroupWithPublicKey:groupPublicKey userPublicKey:userPublicKey] retainUntilComplete]; - } else { - [[LKPushNotificationAPI performOperation:ClosedGroupOperationSubscribe - forClosedGroupWithPublicKey:groupPublicKey userPublicKey:userPublicKey] retainUntilComplete]; - } - } } - (void)blockConversationSwitchDidChange:(id)sender diff --git a/SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift b/SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift index b725e1527..8fccb96ec 100644 --- a/SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift +++ b/SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift @@ -88,13 +88,7 @@ public final class PushNotificationAPI : NSObject { } // Subscribe to all closed groups Storage.shared.getUserClosedGroupPublicKeys().forEach { closedGroupPublicKey in - let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(closedGroupPublicKey) - let threadOrNil = TSGroupThread.fetch(uniqueId: TSGroupThread.threadId(fromGroupId: groupID)) - if threadOrNil?.isMuted == true { - // Do nothing - } else { - performOperation(.subscribe, for: closedGroupPublicKey, publicKey: publicKey) - } + performOperation(.subscribe, for: closedGroupPublicKey, publicKey: publicKey) } return promise } From 1dc463a9edda1fe4d8a778d2e4fd64f662cc417d Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 5 Aug 2021 09:21:20 +1000 Subject: [PATCH 21/26] Update build number --- Session.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index eb58542f3..157faa987 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -5063,7 +5063,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 285; + CURRENT_PROJECT_VERSION = 286; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5132,7 +5132,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 285; + CURRENT_PROJECT_VERSION = 286; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -5193,7 +5193,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 285; + CURRENT_PROJECT_VERSION = 286; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5263,7 +5263,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 285; + CURRENT_PROJECT_VERSION = 286; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6148,7 +6148,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 285; + CURRENT_PROJECT_VERSION = 286; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -6216,7 +6216,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 285; + CURRENT_PROJECT_VERSION = 286; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", From 3db8231bde4eb6102640ef7b4792d5e325fa4123 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 5 Aug 2021 09:51:12 +1000 Subject: [PATCH 22/26] Fix glitch --- Session/Conversations/ConversationVC.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 8913200b8..a48223371 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -362,7 +362,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat } case .update: print("[Test] UPDATE") - self.messagesTableView.reloadRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .fade) + self.messagesTableView.reloadRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .none) default: preconditionFailure() } } From b8c4e6aa93e26a917342dc9a88ffc85369679607 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 5 Aug 2021 10:02:52 +1000 Subject: [PATCH 23/26] Avoid unnecessary conversation screen updates --- Session/Conversations/ConversationVC.swift | 1 + .../Sending & Receiving/MessageSender.swift | 12 ++++++++---- .../Utilities/MessageInvalidator.swift | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index a48223371..35f5e1dde 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -353,6 +353,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat case .delete: self.messagesTableView.deleteRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .fade) case .insert: + print("[Test] INSERT") // Perform inserts before updates self.messagesTableView.insertRows(at: [ IndexPath(row: Int(update.newIndex), section: 0) ], with: .fade) if update.viewItem?.interaction is TSOutgoingMessage { diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender.swift b/SessionMessagingKit/Sending & Receiving/MessageSender.swift index 8b4cfdff0..4994a13a1 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender.swift @@ -337,10 +337,12 @@ public final class MessageSender : NSObject { let thread = TSGroupThread.fetch(uniqueId: threadID, transaction: transaction), thread.isClosedGroup { recipients = thread.groupModel.groupMemberIds } - recipients.forEach { recipient in - tsMessage.update(withSentRecipient: recipient, wasSentByUD: true, transaction: transaction) + if !tsMessage.wasSentToAnyRecipient { + recipients.forEach { recipient in + tsMessage.update(withSentRecipient: recipient, wasSentByUD: true, transaction: transaction) + } + MessageInvalidator.invalidate(tsMessage, with: transaction) } - MessageInvalidator.invalidate(tsMessage, with: transaction) // Start the disappearing messages timer if needed OWSDisappearingMessagesJob.shared().startAnyExpiration(for: tsMessage, expirationStartedAt: NSDate.millisecondTimestamp(), transaction: transaction) } @@ -359,6 +361,8 @@ public final class MessageSender : NSObject { public static func handleFailedMessageSend(_ message: Message, with error: Swift.Error, using transaction: Any) { guard let tsMessage = TSOutgoingMessage.find(withTimestamp: message.sentTimestamp!) else { return } - tsMessage.update(sendingError: error, transaction: transaction as! YapDatabaseReadWriteTransaction) + let transaction = transaction as! YapDatabaseReadWriteTransaction + tsMessage.update(sendingError: error, transaction: transaction) + MessageInvalidator.invalidate(tsMessage, with: transaction) } } diff --git a/SessionMessagingKit/Utilities/MessageInvalidator.swift b/SessionMessagingKit/Utilities/MessageInvalidator.swift index 83619e091..2d87e5c38 100644 --- a/SessionMessagingKit/Utilities/MessageInvalidator.swift +++ b/SessionMessagingKit/Utilities/MessageInvalidator.swift @@ -11,7 +11,7 @@ private override init() { } @objc public static func invalidate(_ message: TSMessage, with transaction: YapDatabaseReadWriteTransaction) { - guard let id = message.uniqueId else { return } + guard let id = message.uniqueId, !isInvalidated(message) else { return } invalidatedMessages.insert(id) message.touch(with: transaction) } From 50d17be43b534d95834ad2402d10284d4d01268e Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 5 Aug 2021 10:11:20 +1000 Subject: [PATCH 24/26] Fix animation glitch --- Session/Conversations/ConversationVC.swift | 20 ++++++++++--------- .../Sending & Receiving/MessageSender.swift | 9 +++------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 35f5e1dde..cec77ffda 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -351,11 +351,11 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat for update in conversationUpdate.updateItems! { switch update.updateItemType { case .delete: - self.messagesTableView.deleteRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .fade) + self.messagesTableView.deleteRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .none) case .insert: print("[Test] INSERT") // Perform inserts before updates - self.messagesTableView.insertRows(at: [ IndexPath(row: Int(update.newIndex), section: 0) ], with: .fade) + self.messagesTableView.insertRows(at: [ IndexPath(row: Int(update.newIndex), section: 0) ], with: .none) if update.viewItem?.interaction is TSOutgoingMessage { shouldScrollToBottom = true } else { @@ -368,14 +368,16 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat } } } - messagesTableView.performBatchUpdates(batchUpdates) { _ in - if shouldScrollToBottom { - self.scrollToBottom(isAnimated: true) + UIView.performWithoutAnimation { + messagesTableView.performBatchUpdates(batchUpdates) { _ in + if shouldScrollToBottom { + self.scrollToBottom(isAnimated: false) + } + self.markAllAsRead() + } + if shouldScrollToBottom { + self.scrollToBottom(isAnimated: false) } - self.markAllAsRead() - } - if shouldScrollToBottom { - self.scrollToBottom(isAnimated: false) } } diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender.swift b/SessionMessagingKit/Sending & Receiving/MessageSender.swift index 4994a13a1..b9ef948c7 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender.swift @@ -330,19 +330,16 @@ public final class MessageSender : NSObject { if let tsMessage = TSOutgoingMessage.find(withTimestamp: message.sentTimestamp!) { // Track the open group server message ID tsMessage.openGroupServerMessageID = message.openGroupServerMessageID ?? 0 - tsMessage.save(with: transaction) // Mark the message as sent var recipients = [ message.recipient! ] if case .closedGroup(_) = destination, let threadID = message.threadID, // threadID should always be set at this point let thread = TSGroupThread.fetch(uniqueId: threadID, transaction: transaction), thread.isClosedGroup { recipients = thread.groupModel.groupMemberIds } - if !tsMessage.wasSentToAnyRecipient { - recipients.forEach { recipient in - tsMessage.update(withSentRecipient: recipient, wasSentByUD: true, transaction: transaction) - } - MessageInvalidator.invalidate(tsMessage, with: transaction) + recipients.forEach { recipient in + tsMessage.update(withSentRecipient: recipient, wasSentByUD: true, transaction: transaction) } + tsMessage.save(with: transaction) // Start the disappearing messages timer if needed OWSDisappearingMessagesJob.shared().startAnyExpiration(for: tsMessage, expirationStartedAt: NSDate.millisecondTimestamp(), transaction: transaction) } From e311d2878f513d407dfb073881e65c78c8b54c8c Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 5 Aug 2021 10:47:15 +1000 Subject: [PATCH 25/26] Fix message status indicator bug --- Session/Conversations/ConversationVC.swift | 22 ++++++++++++++++--- .../Message Cells/VisibleMessageCell.swift | 2 +- .../Sending & Receiving/MessageSender.swift | 1 + .../Threads/Notification+Thread.swift | 2 ++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index cec77ffda..6077d5f68 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -205,6 +205,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat notificationCenter.addObserver(self, selector: #selector(addOrRemoveBlockedBanner), name: NSNotification.Name(rawValue: kNSNotificationName_BlockListDidChange), object: nil) notificationCenter.addObserver(self, selector: #selector(handleGroupUpdatedNotification), name: .groupThreadUpdated, object: nil) notificationCenter.addObserver(self, selector: #selector(sendScreenshotNotificationIfNeeded), name: UIApplication.userDidTakeScreenshotNotification, object: nil) + notificationCenter.addObserver(self, selector: #selector(handleMessageSentStatusChanged), name: .messageSentStatusDidChange, object: nil) // Mentions MentionsManager.populateUserPublicKeyCacheIfNeeded(for: thread.uniqueId!) // Draft @@ -319,7 +320,6 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat baselineKeyboardHeight = newHeight self.messagesTableView.keyboardHeight = newHeight } - let margin = (self.lastPageTop - self.messagesTableView.contentOffset.y) scrollButtonConstraint?.constant = -(newHeight + 16) let newContentOffsetY = max(self.messagesTableView.contentOffset.y + min(lastPageTop, 0) + newHeight - self.messagesTableView.keyboardHeight, 0.0) self.messagesTableView.contentOffset.y = newContentOffsetY @@ -353,7 +353,6 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat case .delete: self.messagesTableView.deleteRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .none) case .insert: - print("[Test] INSERT") // Perform inserts before updates self.messagesTableView.insertRows(at: [ IndexPath(row: Int(update.newIndex), section: 0) ], with: .none) if update.viewItem?.interaction is TSOutgoingMessage { @@ -362,7 +361,6 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat shouldScrollToBottom = self.isCloseToBottom } case .update: - print("[Test] UPDATE") self.messagesTableView.reloadRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .none) default: preconditionFailure() } @@ -411,6 +409,24 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat reloadInputViews() } + @objc private func handleMessageSentStatusChanged() { + DispatchQueue.main.async { + guard let indexPaths = self.messagesTableView.indexPathsForVisibleRows else { return } + var indexPathsToReload: [IndexPath] = [] + for indexPath in indexPaths { + guard let cell = self.messagesTableView.cellForRow(at: indexPath) as? VisibleMessageCell else { continue } + let isLast = (indexPath.item == (self.messagesTableView.numberOfRows(inSection: 0) - 1)) + guard !isLast else { continue } + if !cell.messageStatusImageView.isHidden { + indexPathsToReload.append(indexPath) + } + } + UIView.performWithoutAnimation { + self.messagesTableView.reloadRows(at: indexPathsToReload, with: .none) + } + } + } + // MARK: General @objc func addOrRemoveBlockedBanner() { func detach() { diff --git a/Session/Conversations/Message Cells/VisibleMessageCell.swift b/Session/Conversations/Message Cells/VisibleMessageCell.swift index 7b0725944..30cf15727 100644 --- a/Session/Conversations/Message Cells/VisibleMessageCell.swift +++ b/Session/Conversations/Message Cells/VisibleMessageCell.swift @@ -81,7 +81,7 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate { private lazy var snContentView = UIView() - private lazy var messageStatusImageView: UIImageView = { + internal lazy var messageStatusImageView: UIImageView = { let result = UIImageView() result.contentMode = .scaleAspectFit result.layer.cornerRadius = VisibleMessageCell.messageStatusImageViewSize / 2 diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender.swift b/SessionMessagingKit/Sending & Receiving/MessageSender.swift index b9ef948c7..c001faaf1 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender.swift @@ -340,6 +340,7 @@ public final class MessageSender : NSObject { tsMessage.update(withSentRecipient: recipient, wasSentByUD: true, transaction: transaction) } tsMessage.save(with: transaction) + NotificationCenter.default.post(name: .messageSentStatusDidChange, object: nil, userInfo: nil) // Start the disappearing messages timer if needed OWSDisappearingMessagesJob.shared().startAnyExpiration(for: tsMessage, expirationStartedAt: NSDate.millisecondTimestamp(), transaction: transaction) } diff --git a/SessionMessagingKit/Threads/Notification+Thread.swift b/SessionMessagingKit/Threads/Notification+Thread.swift index 77b74d0ef..4b61f8f1b 100644 --- a/SessionMessagingKit/Threads/Notification+Thread.swift +++ b/SessionMessagingKit/Threads/Notification+Thread.swift @@ -3,10 +3,12 @@ public extension Notification.Name { static let groupThreadUpdated = Notification.Name("groupThreadUpdated") static let muteSettingUpdated = Notification.Name("muteSettingUpdated") + static let messageSentStatusDidChange = Notification.Name("messageSentStatusDidChange") } @objc public extension NSNotification { @objc static let groupThreadUpdated = Notification.Name.groupThreadUpdated.rawValue as NSString @objc static let muteSettingUpdated = Notification.Name.muteSettingUpdated.rawValue as NSString + @objc static let messageSentStatusDidChange = Notification.Name.messageSentStatusDidChange.rawValue as NSString } From 29acca574c765083baaf6a55c85f60cfd5891668 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 5 Aug 2021 10:48:24 +1000 Subject: [PATCH 26/26] Update build number --- Session.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 9c812f91f..e5c66860d 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -5067,7 +5067,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 286; + CURRENT_PROJECT_VERSION = 287; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5136,7 +5136,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 286; + CURRENT_PROJECT_VERSION = 287; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -5197,7 +5197,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 286; + CURRENT_PROJECT_VERSION = 287; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5267,7 +5267,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 286; + CURRENT_PROJECT_VERSION = 287; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6152,7 +6152,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 286; + CURRENT_PROJECT_VERSION = 287; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -6220,7 +6220,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 286; + CURRENT_PROJECT_VERSION = 287; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)",