From e9797da23821743d433498ef16aa8b84a783a5d2 Mon Sep 17 00:00:00 2001 From: Levitating Pineapple Date: Thu, 1 Aug 2024 18:41:07 +0300 Subject: [PATCH] ios: add throttling for incoming messages --- apps/ios/Shared/Model/SimpleXAPI.swift | 2 +- .../Views/Helpers/NewItemThrottler.swift | 41 +++++++++++++++++++ apps/ios/SimpleX.xcodeproj/project.pbxproj | 4 ++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 apps/ios/Shared/Views/Helpers/NewItemThrottler.swift diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index 6d2897338f..a9bdfab236 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -1711,7 +1711,7 @@ func processReceivedMsg(_ res: ChatResponse) async { let cItem = aChatItem.chatItem await MainActor.run { if active(user) { - m.addChatItem(cInfo, cItem) + NewItemThrottler.shared.receive(cItem, for: cInfo) } else if cItem.isRcvNew && cInfo.ntfsEnabled { m.increaseUnreadCounter(user: user) } diff --git a/apps/ios/Shared/Views/Helpers/NewItemThrottler.swift b/apps/ios/Shared/Views/Helpers/NewItemThrottler.swift new file mode 100644 index 0000000000..5699bda7b4 --- /dev/null +++ b/apps/ios/Shared/Views/Helpers/NewItemThrottler.swift @@ -0,0 +1,41 @@ +// +// Collector.swift +// SimpleX (iOS) +// +// Created by User on 01/08/2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import Foundation +import Combine +import SimpleXChat + +class NewItemThrottler { + static let shared = NewItemThrottler() + + private let subject = PassthroughSubject() + private var bag = Set() + private var accumulated = [(ChatInfo, ChatItem)]() + + private init() { + subject + .throttle(for: 1, scheduler: DispatchQueue.main, latest: true) + .sink { + self.accumulated.forEach { cInfo, cItem in + ChatModel.shared.addChatItem(cInfo, cItem) + } + self.accumulated = [] + } + .store(in: &bag) + } + + func receive(_ cItem: ChatItem, for cInfo: ChatInfo) { + // Messages sent to the current chat are updated directly + if ChatModel.shared.chatId == cInfo.id { + ChatModel.shared.addChatItem(cInfo, cItem) + } else { + DispatchQueue.main.async { self.accumulated.append((cInfo, cItem)) } + subject.send() + } + } +} diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 20c242c51f..0e3ab98a3a 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -200,6 +200,7 @@ CE38A29A2C3FCA54005ED185 /* ImageUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBD2859295711D700EC2CF4 /* ImageUtils.swift */; }; CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = CE38A29B2C3FCD72005ED185 /* SwiftyGif */; }; CE984D4B2C36C5D500E3AEFF /* ChatItemClipShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */; }; + CEC171222C5BCD86006D5472 /* NewItemThrottler.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC171212C5BCD86006D5472 /* NewItemThrottler.swift */; }; CEDE70222C48FD9500233B1F /* SEChatState.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDE70212C48FD9500233B1F /* SEChatState.swift */; }; CEE723AA2C3BD3D70009AE93 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE723A92C3BD3D70009AE93 /* ShareViewController.swift */; }; CEE723B12C3BD3D70009AE93 /* SimpleX SE.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = CEE723A72C3BD3D70009AE93 /* SimpleX SE.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -535,6 +536,7 @@ CE2AD9CD2C452A4D00E844E3 /* ChatUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatUtils.swift; sourceTree = ""; }; CE3097FA2C4C0C9F00180898 /* ErrorAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorAlert.swift; sourceTree = ""; }; CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemClipShape.swift; sourceTree = ""; }; + CEC171212C5BCD86006D5472 /* NewItemThrottler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewItemThrottler.swift; sourceTree = ""; }; CEDE70212C48FD9500233B1F /* SEChatState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SEChatState.swift; sourceTree = ""; }; CEE723A72C3BD3D70009AE93 /* SimpleX SE.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "SimpleX SE.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; CEE723A92C3BD3D70009AE93 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; @@ -786,6 +788,7 @@ 8C74C3ED2C1B942300039E77 /* ChatWallpaper.swift */, 8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */, CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */, + CEC171212C5BCD86006D5472 /* NewItemThrottler.swift */, ); path = Helpers; sourceTree = ""; @@ -1490,6 +1493,7 @@ 18415C6C56DBCEC2CBBD2F11 /* WebRTCClient.swift in Sources */, 184152CEF68D2336FC2EBCB0 /* CallViewRenderers.swift in Sources */, 5CB634AD29E46CF70066AD6B /* LocalAuthView.swift in Sources */, + CEC171222C5BCD86006D5472 /* NewItemThrottler.swift in Sources */, 18415FEFE153C5920BFB7828 /* GroupWelcomeView.swift in Sources */, 18415F9A2D551F9757DA4654 /* CIVideoView.swift in Sources */, 184158C131FDB829D8A117EA /* VideoPlayerView.swift in Sources */,