diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt index d99feccc35..45756ea21f 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt @@ -1441,8 +1441,11 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a private suspend fun chatItemSimpleUpdate(user: User, aChatItem: AChatItem) { val cInfo = aChatItem.chatInfo val cItem = aChatItem.chatItem - if (!active(user) || chatModel.upsertChatItem(cInfo, cItem)) { - ntfManager.notifyMessageReceived(chatModel.currentUser.value!!, cInfo, cItem) + val notify = { ntfManager.notifyMessageReceived(user, cInfo, cItem) } + if (!active(user)) { + notify() + } else if (chatModel.upsertChatItem(cInfo, cItem)) { + notify() } } diff --git a/apps/ios/Shared/Model/NtfManager.swift b/apps/ios/Shared/Model/NtfManager.swift index 97252f1ade..9663a7319a 100644 --- a/apps/ios/Shared/Model/NtfManager.swift +++ b/apps/ios/Shared/Model/NtfManager.swift @@ -86,15 +86,22 @@ class NtfManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject { if UIApplication.shared.applicationState == .active { switch content.categoryIdentifier { case ntfCategoryMessageReceived: + let recent = recentInTheSameChat(content) if model.chatId == nil { - // in the chat list - return recentInTheSameChat(content) ? [] : [.sound, .list] + // in the chat list... + if model.currentUser?.userId == (content.userInfo["userId"] as? Int64) { + // ... of the current user + return recent ? [] : [.sound, .list] + } else { + // ... of different user + return recent ? [.banner] : [.sound, .banner, .list] + } } else if model.chatId == content.targetContentIdentifier { // in the current chat - return recentInTheSameChat(content) ? [] : [.sound, .list] + return recent ? [] : [.sound, .list] } else { // in another chat - return recentInTheSameChat(content) ? [.banner, .list] : [.sound, .banner, .list] + return recent ? [.banner, .list] : [.sound, .banner, .list] } // this notification is deliverd from the notifications server // when the app is in foreground it does not need to be shown diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index 54f41fc719..1783e8aa0d 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -635,10 +635,10 @@ func apiChatUnread(type: ChatType, id: Int64, unreadChat: Bool) async throws { try await sendCommandOkResp(.apiChatUnread(type: type, id: id, unreadChat: unreadChat)) } -func receiveFile(fileId: Int64) async { +func receiveFile(user: User, fileId: Int64) async { let inline = privacyTransferImagesInlineGroupDefault.get() if let chatItem = await apiReceiveFile(fileId: fileId, inline: inline) { - DispatchQueue.main.async { chatItemSimpleUpdate(chatItem) } + DispatchQueue.main.async { chatItemSimpleUpdate(user, chatItem) } } } @@ -1025,6 +1025,8 @@ func processReceivedMsg(_ res: ChatResponse) async { m.updateContact(contact) m.dismissConnReqView(contact.activeConn.id) m.removeChat(contact.activeConn.id) + } + if contact.directOrUsed { NtfManager.shared.notifyContactConnected(user, contact) } m.setContactNetworkStatus(contact, .connected) @@ -1080,16 +1082,13 @@ func processReceivedMsg(_ res: ChatResponse) async { } } case let .newChatItem(user, aChatItem): - if !active(user) { - if case .rcvNew = aChatItem.chatItem.meta.itemStatus, aChatItem.chatInfo.ntfsEnabled { - m.increaseUnreadCounter(user: user) - } - return - } - let cInfo = aChatItem.chatInfo let cItem = aChatItem.chatItem - m.addChatItem(cInfo, cItem) + if active(user) { + m.addChatItem(cInfo, cItem) + } else if cItem.isRcvNew && cInfo.ntfsEnabled { + m.increaseUnreadCounter(user: user) + } if let file = cItem.file, let mc = cItem.content.msgContent, file.fileSize <= MAX_IMAGE_SIZE_AUTO_RCV { @@ -1097,7 +1096,7 @@ func processReceivedMsg(_ res: ChatResponse) async { if (mc.isImage && acceptImages) || (mc.isVoice && ((file.fileSize > MAX_VOICE_MESSAGE_SIZE_INLINE_SEND && acceptImages) || cInfo.chatType == .group)) { Task { - await receiveFile(fileId: file.fileId) // TODO check inlineFileMode != IFMSent + await receiveFile(user: user, fileId: file.fileId) // TODO check inlineFileMode != IFMSent } } } @@ -1105,28 +1104,21 @@ func processReceivedMsg(_ res: ChatResponse) async { NtfManager.shared.notifyMessageReceived(user, cInfo, cItem) } case let .chatItemStatusUpdated(user, aChatItem): - if !active(user) { return } - let cInfo = aChatItem.chatInfo let cItem = aChatItem.chatItem - var res = false - if !cItem.isDeletedContent { - res = m.upsertChatItem(cInfo, cItem) - } - if res { + if !cItem.isDeletedContent && (!active(user) || m.upsertChatItem(cInfo, cItem)) { NtfManager.shared.notifyMessageReceived(user, cInfo, cItem) - } else if let endTask = m.messageDelivery[cItem.id] { + } + if let endTask = m.messageDelivery[cItem.id] { switch cItem.meta.itemStatus { case .sndSent: endTask() case .sndErrorAuth: endTask() case .sndError: endTask() - default: break + default: () } } case let .chatItemUpdated(user, aChatItem): - if active(user) { - chatItemSimpleUpdate(aChatItem) - } + chatItemSimpleUpdate(user, aChatItem) case let .chatItemDeleted(user, deletedChatItem, toChatItem, _): if !active(user) { if toChatItem == nil && deletedChatItem.chatItem.isRcvNew && deletedChatItem.chatInfo.ntfsEnabled { @@ -1190,21 +1182,13 @@ func processReceivedMsg(_ res: ChatResponse) async { m.updateGroup(toGroup) } case let .rcvFileStart(user, aChatItem): - if active(user) { - chatItemSimpleUpdate(aChatItem) - } + chatItemSimpleUpdate(user, aChatItem) case let .rcvFileComplete(user, aChatItem): - if active(user) { - chatItemSimpleUpdate(aChatItem) - } + chatItemSimpleUpdate(user, aChatItem) case let .sndFileStart(user, aChatItem, _): - if active(user) { - chatItemSimpleUpdate(aChatItem) - } + chatItemSimpleUpdate(user, aChatItem) case let .sndFileComplete(user, aChatItem, _): - if !active(user) { return } - - chatItemSimpleUpdate(aChatItem) + chatItemSimpleUpdate(user, aChatItem) let cItem = aChatItem.chatItem let mc = cItem.content.msgContent if aChatItem.chatInfo.chatType == .direct, @@ -1269,10 +1253,6 @@ func processReceivedMsg(_ res: ChatResponse) async { logger.debug("unsupported event: \(res.responseType)") } - func active(_ user: User) -> Bool { - user.id == m.currentUser?.id - } - func withCall(_ contact: Contact, _ perform: (Call) -> Void) { if let call = m.activeCall, call.contact.apiId == contact.apiId { perform(call) @@ -1283,12 +1263,19 @@ func processReceivedMsg(_ res: ChatResponse) async { } } -func chatItemSimpleUpdate(_ aChatItem: AChatItem) { +func active(_ user: User) -> Bool { + user.id == ChatModel.shared.currentUser?.id +} + +func chatItemSimpleUpdate(_ user: User, _ aChatItem: AChatItem) { let m = ChatModel.shared let cInfo = aChatItem.chatInfo let cItem = aChatItem.chatItem - if m.upsertChatItem(cInfo, cItem) { - NtfManager.shared.notifyMessageReceived(m.currentUser!, cInfo, cItem) + let notify = { NtfManager.shared.notifyMessageReceived(user, cInfo, cItem) } + if !active(user) { + notify() + } else if m.upsertChatItem(cInfo, cItem) { + notify() } } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift index 0faae0c929..1ecc0e68c8 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift @@ -63,7 +63,9 @@ struct CIFileView: View { if fileSizeValid() { Task { logger.debug("CIFileView fileAction - in .rcvInvitation, in Task") - await receiveFile(fileId: file.fileId) + if let user = ChatModel.shared.currentUser { + await receiveFile(user: user, fileId: file.fileId) + } } } else { let prettyMaxFileSize = ByteCountFormatter().string(fromByteCount: MAX_FILE_SIZE) diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift index a8d0fd65c0..a32dd95286 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift @@ -35,7 +35,9 @@ struct CIImageView: View { switch file.fileStatus { case .rcvInvitation: Task { - await receiveFile(fileId: file.fileId) + if let user = ChatModel.shared.currentUser { + await receiveFile(user: user, fileId: file.fileId) + } // TODO image accepted alert? } case .rcvAccepted: