From e6ba82c8ff91164330dc962d93cc916517a4c29b Mon Sep 17 00:00:00 2001 From: Arturs Krumins Date: Tue, 6 Aug 2024 01:36:33 +0300 Subject: [PATCH] ios: improve performance, when receiving many messages in a single chat (#4586) * use UnreadCollector for new messages * less confusing * collect removed items to reduce unread counts --------- Co-authored-by: Evgeny Poberezkin --- apps/ios/Shared/Model/ChatModel.swift | 29 +++++++++++++------------- apps/ios/Shared/Model/NtfManager.swift | 8 ++----- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index d973ada34e..2e79c7b8ed 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -333,8 +333,7 @@ final class ChatModel: ObservableObject { [cItem] } if case .rcvNew = cItem.meta.itemStatus { - chats[i].chatStats.unreadCount = chats[i].chatStats.unreadCount + 1 - increaseUnreadCounter(user: currentUser!) + unreadCollector.changeUnreadCounter(cInfo.id, by: 1) } popChatCollector.addChat(cInfo.id) } else { @@ -414,8 +413,8 @@ final class ChatModel: ObservableObject { } func removeChatItem(_ cInfo: ChatInfo, _ cItem: ChatItem) { - if cItem.isRcvNew, let chatIndex = getChatIndex(cInfo.id) { - decreaseUnreadCounter(chatIndex) + if cItem.isRcvNew { + unreadCollector.changeUnreadCounter(cInfo.id, by: -1) } // update previews if let chat = getChat(cInfo.id) { @@ -570,7 +569,7 @@ final class ChatModel: ObservableObject { // update current chat markChatItemRead_(itemIndex) // update preview - unreadCollector.decreaseUnreadCounter(cInfo.id) + unreadCollector.changeUnreadCounter(cInfo.id, by: -1) } } } @@ -590,17 +589,18 @@ final class ChatModel: ObservableObject { let m = ChatModel.shared for (chatId, count) in self.unreadCounts { if let i = m.getChatIndex(chatId) { - m.decreaseUnreadCounter(i, by: count) + m.changeUnreadCounter(i, by: count) } } self.unreadCounts = [:] } .store(in: &bag) } - - // Only call from main thread - func decreaseUnreadCounter(_ chatId: ChatId) { - unreadCounts[chatId] = (unreadCounts[chatId] ?? 0) + 1 + + func changeUnreadCounter(_ chatId: ChatId, by count: Int) { + DispatchQueue.main.async { + self.unreadCounts[chatId] = (self.unreadCounts[chatId] ?? 0) + count + } subject.send() } } @@ -646,25 +646,24 @@ final class ChatModel: ObservableObject { } } - func decreaseUnreadCounter(_ chatIndex: Int, by count: Int = 1) { - chats[chatIndex].chatStats.unreadCount = chats[chatIndex].chatStats.unreadCount - count - decreaseUnreadCounter(user: currentUser!, by: count) + func changeUnreadCounter(_ chatIndex: Int, by count: Int) { + chats[chatIndex].chatStats.unreadCount = chats[chatIndex].chatStats.unreadCount + count + changeUnreadCounter(user: currentUser!, by: count) } func increaseUnreadCounter(user: any UserLike) { changeUnreadCounter(user: user, by: 1) - NtfManager.shared.incNtfBadgeCount() } func decreaseUnreadCounter(user: any UserLike, by: Int = 1) { changeUnreadCounter(user: user, by: -by) - NtfManager.shared.decNtfBadgeCount(by: by) } private func changeUnreadCounter(user: any UserLike, by: Int) { if let i = users.firstIndex(where: { $0.user.userId == user.userId }) { users[i].unreadCount += by } + NtfManager.shared.changeNtfBadgeCount(by: by) } func totalUnreadCountForAllUsers() -> Int { diff --git a/apps/ios/Shared/Model/NtfManager.swift b/apps/ios/Shared/Model/NtfManager.swift index f1fdcc018e..bb938cd231 100644 --- a/apps/ios/Shared/Model/NtfManager.swift +++ b/apps/ios/Shared/Model/NtfManager.swift @@ -238,12 +238,8 @@ class NtfManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject { ntfBadgeCountGroupDefault.set(count) } - func decNtfBadgeCount(by count: Int = 1) { - setNtfBadgeCount(max(0, UIApplication.shared.applicationIconBadgeNumber - count)) - } - - func incNtfBadgeCount(by count: Int = 1) { - setNtfBadgeCount(UIApplication.shared.applicationIconBadgeNumber + count) + func changeNtfBadgeCount(by count: Int = 1) { + setNtfBadgeCount(max(0, UIApplication.shared.applicationIconBadgeNumber + count)) } private func addNotification(_ content: UNMutableNotificationContent) {