From ad54e0925301a55b74db60725ccbd056e7b09718 Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Tue, 4 Feb 2025 17:47:02 +0100 Subject: [PATCH 1/2] Fix displayed chat room reset --- Linphone/Core/CoreContext.swift | 1 - Linphone/UI/Main/ContentView.swift | 1 - .../Fragments/ChatBubbleView.swift | 6 +- .../Fragments/ConversationFragment.swift | 10 ++- .../Fragments/ConversationsListFragment.swift | 11 +-- .../ViewModel/ConversationViewModel.swift | 78 ++++++++++++++----- 6 files changed, 72 insertions(+), 35 deletions(-) diff --git a/Linphone/Core/CoreContext.swift b/Linphone/Core/CoreContext.swift index 5731daf4c..021cb3bf3 100644 --- a/Linphone/Core/CoreContext.swift +++ b/Linphone/Core/CoreContext.swift @@ -42,7 +42,6 @@ final class CoreContext: ObservableObject { @Published var loggingInProgress: Bool = false @Published var coreIsStarted: Bool = false @Published var accounts: [AccountModel] = [] - @Published var enteredForeground = false @Published var shortcuts: [ShortcutModel] = [] private var mCore: Core! private var mIterateSuscription: AnyCancellable? diff --git a/Linphone/UI/Main/ContentView.swift b/Linphone/UI/Main/ContentView.swift index f89800258..534b6f9b9 100644 --- a/Linphone/UI/Main/ContentView.swift +++ b/Linphone/UI/Main/ContentView.swift @@ -1378,7 +1378,6 @@ struct ContentView: View { orientation = newOrientation } .onChange(of: scenePhase) { newPhase in - CoreContext.shared.enteredForeground = newPhase == .active orientation = UIDevice.current.orientation if newPhase == .active { conversationsListViewModel.computeChatRoomsList(filter: "") diff --git a/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift b/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift index e4fbb984f..717aefad6 100644 --- a/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift +++ b/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift @@ -374,10 +374,8 @@ struct ChatBubbleView: View { } } .onTapGesture { - if !CoreContext.shared.enteredForeground { - conversationViewModel.selectedMessageToDisplayDetails = eventLogMessage - conversationViewModel.prepareBottomSheetForDeliveryStatus() - } + conversationViewModel.selectedMessageToDisplayDetails = eventLogMessage + conversationViewModel.prepareBottomSheetForDeliveryStatus() } .disabled(conversationViewModel.selectedMessage != nil) .padding(.top, -4) diff --git a/Linphone/UI/Main/Conversations/Fragments/ConversationFragment.swift b/Linphone/UI/Main/Conversations/Fragments/ConversationFragment.swift index d63a78dff..792da3ed0 100644 --- a/Linphone/UI/Main/Conversations/Fragments/ConversationFragment.swift +++ b/Linphone/UI/Main/Conversations/Fragments/ConversationFragment.swift @@ -24,6 +24,7 @@ import UniformTypeIdentifiers // swiftlint:disable type_body_length struct ConversationFragment: View { + @Environment(\.scenePhase) var scenePhase @State private var orientation = UIDevice.current.orientation private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom } @@ -162,6 +163,11 @@ struct ConversationFragment: View { .background(Color.gray100.ignoresSafeArea(.keyboard)) } } + .onChange(of: scenePhase) { newPhase in + if newPhase == .active { + conversationViewModel.resetDisplayedChatRoom() + } + } } .navigationViewStyle(.stack) } @@ -662,7 +668,7 @@ struct ConversationFragment: View { .focused($isMessageTextFocused) .padding(.vertical, 5) .onChange(of: conversationViewModel.messageText) { text in - if !text.isEmpty && !CoreContext.shared.enteredForeground { + if !text.isEmpty { conversationViewModel.compose() } } @@ -675,7 +681,7 @@ struct ConversationFragment: View { .default_text_style(styleSize: 15) .focused($isMessageTextFocused) .onChange(of: conversationViewModel.messageText) { text in - if !text.isEmpty && !CoreContext.shared.enteredForeground { + if !text.isEmpty { conversationViewModel.compose() } } diff --git a/Linphone/UI/Main/Conversations/Fragments/ConversationsListFragment.swift b/Linphone/UI/Main/Conversations/Fragments/ConversationsListFragment.swift index ba4c4c72b..d5dad9550 100644 --- a/Linphone/UI/Main/Conversations/Fragments/ConversationsListFragment.swift +++ b/Linphone/UI/Main/Conversations/Fragments/ConversationsListFragment.swift @@ -190,20 +190,13 @@ struct ConversationRow: View { .listRowSeparator(.hidden) .background(.white) .onReceive(pub) { _ in - if CoreContext.shared.enteredForeground && conversationViewModel.displayedConversation != nil - && (navigationManager.peerAddr == nil || navigationManager.peerAddr == conversationViewModel.displayedConversation!.remoteSipUri) { - if conversationViewModel.displayedConversation != nil { - conversationViewModel.resetDisplayedChatRoom(conversationsList: conversationsListViewModel.conversationsList) - } - } - - CoreContext.shared.enteredForeground = false - + /* if navigationManager.peerAddr != nil && conversation.remoteSipUri.contains(navigationManager.peerAddr!) { conversationViewModel.getChatRoomWithStringAddress(conversationsList: conversationsListViewModel.conversationsList, stringAddr: navigationManager.peerAddr!) navigationManager.peerAddr = nil } + */ } .onTapGesture { conversationViewModel.changeDisplayedChatRoom(conversationModel: conversation) diff --git a/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift b/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift index bc8d7f756..cb70e97bb 100644 --- a/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift +++ b/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift @@ -165,6 +165,46 @@ class ConversationViewModel: ObservableObject { } } + func addConversationDelegate(chatRoom: ChatRoom) { + let chatRoomDelegate = ChatRoomDelegateStub( onIsComposingReceived: { (_: ChatRoom, _: Address, _: Bool) in + self.computeComposingLabel() + }, onChatMessagesReceived: { (_: ChatRoom, eventLogs: [EventLog]) in + self.getNewMessages(eventLogs: eventLogs) + }, onChatMessageSending: { (_: ChatRoom, eventLog: EventLog) in + self.getNewMessages(eventLogs: [eventLog]) + }, onParticipantAdded: { (_: ChatRoom, eventLogs: EventLog) in + self.getNewMessages(eventLogs: [eventLogs]) + self.getParticipantConversationModel() + }, onParticipantRemoved: { (_: ChatRoom, eventLogs: EventLog) in + self.getNewMessages(eventLogs: [eventLogs]) + self.getParticipantConversationModel() + }, onParticipantAdminStatusChanged: { (_: ChatRoom, eventLogs: EventLog) in + self.getNewMessages(eventLogs: [eventLogs]) + self.getParticipantConversationModel() + }, onSubjectChanged: { (_: ChatRoom, eventLogs: EventLog) in + self.getNewMessages(eventLogs: [eventLogs]) + }, onConferenceJoined: {(_: ChatRoom, eventLog: EventLog) in + self.getNewMessages(eventLogs: [eventLog]) + if self.displayedConversation != nil { + DispatchQueue.main.async { + self.displayedConversation!.isReadOnly = false + } + } + }, onConferenceLeft: {(_: ChatRoom, eventLog: EventLog) in + self.getNewMessages(eventLogs: [eventLog]) + if self.displayedConversation != nil { + DispatchQueue.main.async { + self.displayedConversation!.isReadOnly = true + } + } + }, onEphemeralEvent: {(_: ChatRoom, eventLogs: EventLog) in + self.getNewMessages(eventLogs: [eventLogs]) + }, onEphemeralMessageDeleted: {(_: ChatRoom, eventLog: EventLog) in + self.removeMessage(eventLog) + }) + self.chatRoomDelegateHolder = ChatRoomDelegateHolder(chatroom: chatRoom, delegate: chatRoomDelegate) + } + func addChatMessageDelegate(message: ChatMessage) { if self.displayedConversation != nil { var statusTmp: Message.Status? = .sending @@ -1744,31 +1784,33 @@ class ConversationViewModel: ObservableObject { self.getMessages() } - func resetDisplayedChatRoom(conversationsList: [ConversationModel]) { + func resetDisplayedChatRoom() { //(conversationsList: [ConversationModel]) { + /* guard !conversationsList.isEmpty else { Log.info("\(ConversationViewModel.TAG) The conversation list is empty.") return } - + */ if !self.conversationMessagesSection.isEmpty && !self.conversationMessagesSection[0].rows.isEmpty { if let displayedConversation = self.displayedConversation { - conversationsList.forEach { conversation in - if conversation.id == displayedConversation.id { - self.displayedConversation = conversation - self.computeComposingLabel() - - if let updatedDisplayedConversation = self.displayedConversation { - CoreContext.shared.doOnCoreQueue { _ in - let historyEventsSizeTmp = updatedDisplayedConversation.chatRoom.historyEventsSize - if self.displayedConversationHistorySize < historyEventsSizeTmp { - let eventLogList = updatedDisplayedConversation.chatRoom.getHistoryRangeEvents(begin: 0, end: historyEventsSizeTmp - self.displayedConversationHistorySize) - - if !eventLogList.isEmpty { - self.getNewMessages(eventLogs: eventLogList) - } - } + //conversationsList.forEach { conversation in + CoreContext.shared.doOnCoreQueue { core in + let nilParams: ConferenceParams? = nil + if let newChatRoom = core.searchChatRoom(params: nilParams, localAddr: nil, remoteAddr: displayedConversation.chatRoom.peerAddress, participants: nil) { + if LinphoneUtils.getChatRoomId(room: newChatRoom) == displayedConversation.id { + self.addConversationDelegate(chatRoom: newChatRoom) + let conversation = ConversationModel(chatRoom: newChatRoom) + DispatchQueue.main.async { + self.displayedConversation = conversation + } + self.computeComposingLabel() + let historyEventsSizeTmp = newChatRoom.historyEventsSize + if self.displayedConversationHistorySize < historyEventsSizeTmp { + let eventLogList = newChatRoom.getHistoryRangeEvents(begin: 0, end: historyEventsSizeTmp - self.displayedConversationHistorySize) - self.addConversationDelegate() + if !eventLogList.isEmpty { + self.getNewMessages(eventLogs: eventLogList) + } } } } From be53335b671e63f00474be066e84dfc2471d3b1c Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Thu, 6 Feb 2025 17:52:34 +0100 Subject: [PATCH 2/2] Bug fixes for the public beta --- Linphone/Contacts/ContactsManager.swift | 41 +++++++------ .../Fragments/ContactInnerFragment.swift | 15 +++-- .../Contacts/Model/ContactAvatarModel.swift | 18 +++--- Linphone/UI/Main/ContentView.swift | 8 ++- .../Fragments/ConversationsListFragment.swift | 11 ---- .../ConversationsListViewModel.swift | 61 +++++++++++++++++-- .../UI/Main/History/Model/HistoryModel.swift | 23 ++++--- 7 files changed, 117 insertions(+), 60 deletions(-) diff --git a/Linphone/Contacts/ContactsManager.swift b/Linphone/Contacts/ContactsManager.swift index a2e7e11c1..56ab39e91 100644 --- a/Linphone/Contacts/ContactsManager.swift +++ b/Linphone/Contacts/ContactsManager.swift @@ -150,14 +150,23 @@ final class ContactsManager: ObservableObject { linphoneFriend.addAddress(address: address!) linphoneFriend.done() + let addressTmp = linphoneFriend.address?.clone()?.asStringUriOnly() ?? "" addedAvatarListModel.append( ContactAvatarModel( friend: linphoneFriend, name: linphoneFriend.name ?? "", - address: linphoneFriend.address?.clone()?.asStringUriOnly() ?? "", + address: addressTmp, withPresence: true ) ) + + DispatchQueue.main.async { + NotificationCenter.default.post( + name: NSNotification.Name("ContactAdded"), + object: nil, + userInfo: ["address": addressTmp] + ) + } } } @@ -342,25 +351,21 @@ final class ContactsManager: ObservableObject { } func getFriendWithAddress(address: Address?) -> Friend? { - if address != nil { - let clonedAddress = address!.clone() - clonedAddress!.clean() - let sipUri = clonedAddress!.asStringUriOnly() - - if self.friendList != nil && !self.friendList!.friends.isEmpty { - var friend: Friend? - friend = self.friendList!.friends.first(where: {$0.addresses.contains(where: {$0.asStringUriOnly() == sipUri})}) - if friend == nil && self.linphoneFriendList != nil && !self.linphoneFriendList!.friends.isEmpty { - friend = self.linphoneFriendList!.friends.first(where: {$0.addresses.contains(where: {$0.asStringUriOnly() == sipUri})}) - } - - return friend - } else { - return nil - } - } else { + print("getFriendWithAddress") + guard let address = address, let clonedAddress = address.clone() else { return nil } + clonedAddress.clean() + let sipUri = clonedAddress.asStringUriOnly() + + var friend: Friend? + if let friendList = self.friendList { + friend = friendList.friends.first(where: { $0.addresses.contains(where: { $0.asStringUriOnly() == sipUri }) }) + } + if friend == nil, let linphoneFriendList = self.linphoneFriendList { + friend = linphoneFriendList.friends.first(where: { $0.addresses.contains(where: { $0.asStringUriOnly() == sipUri }) }) + } + return friend } func getFriendWithAddressInCoreQueue(address: Address?, completion: @escaping (Friend?) -> Void) { diff --git a/Linphone/UI/Main/Contacts/Fragments/ContactInnerFragment.swift b/Linphone/UI/Main/Contacts/Fragments/ContactInnerFragment.swift index 9fb71ae6a..f84184751 100644 --- a/Linphone/UI/Main/Contacts/Fragments/ContactInnerFragment.swift +++ b/Linphone/UI/Main/Contacts/Fragments/ContactInnerFragment.swift @@ -163,17 +163,18 @@ struct ContactInnerFragment: View { Image("phone") .renderingMode(.template) .resizable() - .foregroundStyle(Color.grayMain2c600) + .foregroundStyle(contactAvatarModel.address.isEmpty ? Color.grayMain2c400 : Color.grayMain2c600) .frame(width: 25, height: 25) } .padding(16) - .background(Color.grayMain2c200) + .background(contactAvatarModel.address.isEmpty ? Color.grayMain2c100 : Color.grayMain2c200) .cornerRadius(40) Text("contact_call_action") .default_text_style(styleSize: 14) } }) + .disabled(contactAvatarModel.address.isEmpty) Spacer() @@ -195,17 +196,18 @@ struct ContactInnerFragment: View { Image("chat-teardrop-text") .renderingMode(.template) .resizable() - .foregroundStyle(Color.grayMain2c600) + .foregroundStyle(contactAvatarModel.address.isEmpty ? Color.grayMain2c400 : Color.grayMain2c600) .frame(width: 25, height: 25) } .padding(16) - .background(Color.grayMain2c200) + .background(contactAvatarModel.address.isEmpty ? Color.grayMain2c100 : Color.grayMain2c200) .cornerRadius(40) Text("contact_message_action") .default_text_style(styleSize: 14) } }) + .disabled(contactAvatarModel.address.isEmpty) Spacer() @@ -227,17 +229,18 @@ struct ContactInnerFragment: View { Image("video-camera") .renderingMode(.template) .resizable() - .foregroundStyle(Color.grayMain2c600) + .foregroundStyle(contactAvatarModel.address.isEmpty ? Color.grayMain2c400 : Color.grayMain2c600) .frame(width: 25, height: 25) } .padding(16) - .background(Color.grayMain2c200) + .background(contactAvatarModel.address.isEmpty ? Color.grayMain2c100 : Color.grayMain2c200) .cornerRadius(40) Text("contact_video_call_action") .default_text_style(styleSize: 14) } }) + .disabled(contactAvatarModel.address.isEmpty) Spacer() } diff --git a/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift b/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift index 2c069c1b7..34eea1cc4 100644 --- a/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift +++ b/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift @@ -22,6 +22,7 @@ import linphonesw import Combine class ContactAvatarModel: ObservableObject, Identifiable { + let id = UUID() let friend: Friend? @@ -46,24 +47,23 @@ class ContactAvatarModel: ObservableObject, Identifiable { self.name = name self.address = address var addressesTmp: [String] = [] - if friend != nil { - friend!.addresses.forEach { address in + if let friend = friend { + friend.addresses.forEach { address in addressesTmp.append(address.asStringUriOnly()) } } self.addresses = addressesTmp self.nativeUri = friend?.nativeUri ?? "" self.withPresence = withPresence - if friend != nil && - withPresence == true { + if let friend = friend, withPresence == true { self.lastPresenceInfo = "" - self.presenceStatus = friend!.consolidatedPresence + self.presenceStatus = friend.consolidatedPresence - if friend!.consolidatedPresence == .Online || friend!.consolidatedPresence == .Busy { - if friend!.consolidatedPresence == .Online || friend!.presenceModel!.latestActivityTimestamp != -1 { - self.lastPresenceInfo = (friend!.consolidatedPresence == .Online) ? - "Online" : getCallTime(startDate: friend!.presenceModel!.latestActivityTimestamp) + if friend.consolidatedPresence == .Online || friend.consolidatedPresence == .Busy { + if friend.consolidatedPresence == .Online || friend.presenceModel?.latestActivityTimestamp != -1 { + self.lastPresenceInfo = (friend.consolidatedPresence == .Online) ? + "Online" : getCallTime(startDate: friend.presenceModel!.latestActivityTimestamp) } else { self.lastPresenceInfo = "Away" } diff --git a/Linphone/UI/Main/ContentView.swift b/Linphone/UI/Main/ContentView.swift index 534b6f9b9..f586619a6 100644 --- a/Linphone/UI/Main/ContentView.swift +++ b/Linphone/UI/Main/ContentView.swift @@ -86,6 +86,9 @@ struct ContentView: View { var body: some View { let pub = NotificationCenter.default .publisher(for: NSNotification.Name("ContactLoaded")) + let pub2 = NotificationCenter.default + .publisher(for: NSNotification.Name("ContactAdded")) + .compactMap { $0.userInfo?["address"] as? String } let imageChanged = NotificationCenter.default .publisher(for: NSNotification.Name("ImageChanged")) GeometryReader { geometry in @@ -110,7 +113,7 @@ struct ContentView: View { Spacer() if callViewModel.callsCounter == 1 { - Text(String(localized: "\(callViewModel.isPaused || telecomManager.isPausedByRemote ? "call_state_paused" : "call_state_connected")")) + Text(callViewModel.isPaused || telecomManager.isPausedByRemote ? String(localized: "call_state_paused") : String(localized: "call_state_connected")) .default_text_style_white(styleSize: 16) .padding(.trailing, 10) } @@ -1358,6 +1361,9 @@ struct ContentView: View { conversationsListViewModel.updateChatRoomsList() historyListViewModel.refreshHistoryAvatarModel() } + .onReceive(pub2) { address in + conversationsListViewModel.updateChatRoom(address: address) + } } .overlay { if isMenuOpen { diff --git a/Linphone/UI/Main/Conversations/Fragments/ConversationsListFragment.swift b/Linphone/UI/Main/Conversations/Fragments/ConversationsListFragment.swift index d5dad9550..ecb3c0df7 100644 --- a/Linphone/UI/Main/Conversations/Fragments/ConversationsListFragment.swift +++ b/Linphone/UI/Main/Conversations/Fragments/ConversationsListFragment.swift @@ -85,8 +85,6 @@ struct ConversationRow: View { @Binding var text: String var body: some View { - let pub = NotificationCenter.default - .publisher(for: NSNotification.Name("ChatRoomsComputed")) HStack { Avatar(contactAvatarModel: conversation.avatarModel, avatarSize: 50) @@ -189,15 +187,6 @@ struct ConversationRow: View { .listRowInsets(EdgeInsets(top: 6, leading: 20, bottom: 6, trailing: 20)) .listRowSeparator(.hidden) .background(.white) - .onReceive(pub) { _ in - /* - if navigationManager.peerAddr != nil - && conversation.remoteSipUri.contains(navigationManager.peerAddr!) { - conversationViewModel.getChatRoomWithStringAddress(conversationsList: conversationsListViewModel.conversationsList, stringAddr: navigationManager.peerAddr!) - navigationManager.peerAddr = nil - } - */ - } .onTapGesture { conversationViewModel.changeDisplayedChatRoom(conversationModel: conversation) } diff --git a/Linphone/UI/Main/Conversations/ViewModel/ConversationsListViewModel.swift b/Linphone/UI/Main/Conversations/ViewModel/ConversationsListViewModel.swift index 88566a7bd..102070527 100644 --- a/Linphone/UI/Main/Conversations/ViewModel/ConversationsListViewModel.swift +++ b/Linphone/UI/Main/Conversations/ViewModel/ConversationsListViewModel.swift @@ -61,11 +61,6 @@ class ConversationsListViewModel: ObservableObject { } } - DispatchQueue.main.async { - //self.conversationsList = self.conversationsListTmp - NotificationCenter.default.post(name: NSNotification.Name("ChatRoomsComputed"), object: nil) - } - self.updateUnreadMessagesCount() } } @@ -128,6 +123,62 @@ class ConversationsListViewModel: ObservableObject { } } + func updateChatRoom(address: String) { + CoreContext.shared.doOnCoreQueue { _ in + if let contactAvatarModel = self.contactsManager.avatarListModel.first(where: {$0.addresses.contains(address)}) { + self.conversationsListTmp.forEach { conversationModel in + if conversationModel.participantsAddress.contains(contactAvatarModel.address) { + if conversationModel.isGroup && conversationModel.participantsAddress.count > 1 { + let lastMessage = conversationModel.chatRoom.lastMessageInHistory + if lastMessage != nil && lastMessage!.fromAddress != nil && lastMessage!.fromAddress!.asStringUriOnly().contains(contactAvatarModel.address) { + var fromAddressFriend = lastMessage!.fromAddress != nil + ? self.contactsManager.getFriendWithAddress(address: lastMessage!.fromAddress)?.name ?? nil + : nil + + if !lastMessage!.isOutgoing && lastMessage!.chatRoom != nil && !lastMessage!.chatRoom!.hasCapability(mask: ChatRoom.Capabilities.OneToOne.rawValue) { + if fromAddressFriend == nil { + if lastMessage!.fromAddress!.displayName != nil { + fromAddressFriend = lastMessage!.fromAddress!.displayName! + ": " + } else if lastMessage!.fromAddress!.username != nil { + fromAddressFriend = lastMessage!.fromAddress!.username! + ": " + } else { + fromAddressFriend = String(lastMessage!.fromAddress!.asStringUriOnly().dropFirst(4)) + ": " + } + } else { + fromAddressFriend! += ": " + } + + } else { + fromAddressFriend = nil + } + let lastMessageTextTmp = (fromAddressFriend ?? "") + + (lastMessage!.contents.first(where: {$0.isText == true})?.utf8Text ?? (lastMessage!.contents.first(where: {$0.isFile == true || $0.isFileTransfer == true})?.name ?? "")) + + let index = self.conversationsList.firstIndex(where: { $0.chatRoom === conversationModel.chatRoom }) + + DispatchQueue.main.async { + conversationModel.lastMessageText = lastMessageTextTmp + if index != nil { + self.conversationsList[index!].lastMessageText = lastMessageTextTmp + } + } + } + } else if !conversationModel.isGroup && conversationModel.participantsAddress.first != nil && conversationModel.participantsAddress.first!.contains(contactAvatarModel.address) { + let index = self.conversationsList.firstIndex(where: { $0.chatRoom === conversationModel.chatRoom }) + DispatchQueue.main.async { + conversationModel.avatarModel = contactAvatarModel + conversationModel.subject = contactAvatarModel.name + if index != nil { + self.conversationsList[index!].avatarModel = contactAvatarModel + } + } + } + } + } + } + } + } + func addConversationDelegate() { coreContext.doOnCoreQueue { core in self.coreConversationDelegate = CoreDelegateStub(onMessagesReceived: { (_: Core, chatRoom: ChatRoom, _: [ChatMessage]) in diff --git a/Linphone/UI/Main/History/Model/HistoryModel.swift b/Linphone/UI/Main/History/Model/HistoryModel.swift index 92cd1a3eb..d7fd45c47 100644 --- a/Linphone/UI/Main/History/Model/HistoryModel.swift +++ b/Linphone/UI/Main/History/Model/HistoryModel.swift @@ -112,24 +112,27 @@ class HistoryModel: ObservableObject { func refreshAvatarModel() { coreContext.doOnCoreQueue { _ in - let addressFriendTmp = ContactsManager.shared.getFriendWithAddress( - address: self.callLog.dir == .Outgoing ? self.callLog.toAddress! : self.callLog.fromAddress! - ) - if addressFriendTmp != nil { + guard let address = (self.callLog.dir == .Outgoing ? self.callLog.toAddress : self.callLog.fromAddress) else { + DispatchQueue.main.async { + self.avatarModel = ContactAvatarModel(friend: nil, name: self.addressName, address: self.address, withPresence: false) + } + return + } + + let addressFriendTmp = ContactsManager.shared.getFriendWithAddress(address: address) + if let addressFriendTmp = addressFriendTmp { self.addressFriend = addressFriendTmp let addressNameTmp = self.addressName - let avatarModelTmp = addressFriendTmp != nil - ? ContactsManager.shared.avatarListModel.first(where: { - $0.friend!.name == addressFriendTmp!.name - && $0.friend!.address!.asStringUriOnly() == addressFriendTmp!.address!.asStringUriOnly() + let avatarModelTmp = ContactsManager.shared.avatarListModel.first(where: { + guard let friend = $0.friend else { return false } + return friend.name == addressFriendTmp.name && friend.address?.asStringUriOnly() == addressFriendTmp.address?.asStringUriOnly() }) ?? ContactAvatarModel(friend: nil, name: self.addressName, address: self.address, withPresence: false) - : ContactAvatarModel(friend: nil, name: self.addressName, address: self.address, withPresence: false) DispatchQueue.main.async { self.addressFriend = addressFriendTmp - self.addressName = addressFriendTmp!.name ?? addressNameTmp + self.addressName = addressFriendTmp.name ?? addressNameTmp self.avatarModel = avatarModelTmp } } else {