ios: show notifications for different users (#1874)

* ios: show notifications for different users

* refactore

* terminate background taks on chat item update

* refactor

* refactor2

* refactor3

* refactor 4

* refactor5

* fix chat item update in Android

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
This commit is contained in:
Stanislav Dmitrenko
2023-02-02 16:09:36 +00:00
committed by GitHub
parent c55a7692c5
commit bcca27bfdb
5 changed files with 51 additions and 50 deletions

View File

@@ -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()
}
}

View File

@@ -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

View File

@@ -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()
}
}

View File

@@ -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)

View File

@@ -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: