diff --git a/Linphone/UI/Call/CallView.swift b/Linphone/UI/Call/CallView.swift index 47614097b..5d89945f1 100644 --- a/Linphone/UI/Call/CallView.swift +++ b/Linphone/UI/Call/CallView.swift @@ -377,7 +377,7 @@ struct CallView: View { && $0.friend!.name == addressFriend!.name && $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly() }) - : ContactAvatarModel(friend: nil, name: "", withPresence: false) + : ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false) if addressFriend != nil && addressFriend!.photo != nil && !addressFriend!.photo!.isEmpty { if contactAvatarModel != nil { @@ -732,7 +732,7 @@ struct CallView: View { && $0.friend!.name == addressFriend!.name && $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly() }) - : ContactAvatarModel(friend: nil, name: "", withPresence: false) + : ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false) if addressFriend != nil && addressFriend!.photo != nil && !addressFriend!.photo!.isEmpty { if contactAvatarModel != nil { diff --git a/Linphone/UI/Call/Fragments/CallsListFragment.swift b/Linphone/UI/Call/Fragments/CallsListFragment.swift index 83abbd81e..d80560e0c 100644 --- a/Linphone/UI/Call/Fragments/CallsListFragment.swift +++ b/Linphone/UI/Call/Fragments/CallsListFragment.swift @@ -226,7 +226,7 @@ struct CallsListFragment: View { && $0.friend!.name == addressFriend!.name && $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly() }) - : ContactAvatarModel(friend: nil, name: "", withPresence: false) + : ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false) if addressFriend != nil && addressFriend!.photo != nil && !addressFriend!.photo!.isEmpty { if contactAvatarModel != nil { diff --git a/Linphone/UI/Call/ViewModel/MeetingWaitingRoomViewModel.swift b/Linphone/UI/Call/ViewModel/MeetingWaitingRoomViewModel.swift index 080d9897e..681096d73 100644 --- a/Linphone/UI/Call/ViewModel/MeetingWaitingRoomViewModel.swift +++ b/Linphone/UI/Call/ViewModel/MeetingWaitingRoomViewModel.swift @@ -68,6 +68,8 @@ class MeetingWaitingRoomViewModel: ObservableObject { ? ContactsManager.shared.getFriendWithAddress(address: core.defaultAccount!.contactAddress!) : nil + let addressTmp = friend?.address?.asStringUriOnly() ?? "" + if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { userNameTmp = friend!.address!.displayName! } else { @@ -82,8 +84,8 @@ class MeetingWaitingRoomViewModel: ObservableObject { ? ContactsManager.shared.avatarListModel.first(where: { $0.friend!.name == friend!.name && $0.friend!.address!.asStringUriOnly() == core.defaultAccount!.contactAddress!.asStringUriOnly() - }) ?? ContactAvatarModel(friend: nil, name: userNameTmp, withPresence: false) - : ContactAvatarModel(friend: nil, name: userNameTmp, withPresence: false) + }) ?? ContactAvatarModel(friend: nil, name: userNameTmp, address: addressTmp, withPresence: false) + : ContactAvatarModel(friend: nil, name: userNameTmp, address: addressTmp, withPresence: false) if core.videoEnabled && !core.videoPreviewEnabled { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { diff --git a/Linphone/UI/Main/Contacts/Fragments/ContactInnerFragment.swift b/Linphone/UI/Main/Contacts/Fragments/ContactInnerFragment.swift index 47748c66f..87457c6c2 100644 --- a/Linphone/UI/Main/Contacts/Fragments/ContactInnerFragment.swift +++ b/Linphone/UI/Main/Contacts/Fragments/ContactInnerFragment.swift @@ -286,7 +286,7 @@ struct ContactInnerFragment: View { #Preview { ContactInnerFragment( - contactAvatarModel: ContactAvatarModel(friend: nil, name: "", withPresence: true), + contactAvatarModel: ContactAvatarModel(friend: nil, name: "", address: "", withPresence: true), contactViewModel: ContactViewModel(), editContactViewModel: EditContactViewModel(), isShowDeletePopup: .constant(false), diff --git a/Linphone/UI/Main/Contacts/Fragments/EditContactFragment.swift b/Linphone/UI/Main/Contacts/Fragments/EditContactFragment.swift index fdb38f566..3af2c475b 100644 --- a/Linphone/UI/Main/Contacts/Fragments/EditContactFragment.swift +++ b/Linphone/UI/Main/Contacts/Fragments/EditContactFragment.swift @@ -155,7 +155,12 @@ struct EditContactFragment: View { && !editContactViewModel.selectedEditFriend!.photo!.isEmpty && selectedImage == nil && !removedImage { Avatar(contactAvatarModel: - ContactAvatarModel(friend: editContactViewModel.selectedEditFriend!, name: editContactViewModel.selectedEditFriend?.name ?? "", withPresence: false), avatarSize: 100 + ContactAvatarModel( + friend: editContactViewModel.selectedEditFriend!, + name: editContactViewModel.selectedEditFriend?.name ?? "", + address: editContactViewModel.selectedEditFriend?.address?.asStringUriOnly() ?? "", + withPresence: false + ), avatarSize: 100 ) } else if selectedImage == nil { diff --git a/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift b/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift index 9f7ba90c0..e7b1d297b 100644 --- a/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift +++ b/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift @@ -27,6 +27,8 @@ class ContactAvatarModel: ObservableObject { let name: String + let address: String + let withPresence: Bool? @Published var lastPresenceInfo: String @@ -35,9 +37,10 @@ class ContactAvatarModel: ObservableObject { private var friendSuscription: AnyCancellable? - init(friend: Friend?, name: String, withPresence: Bool?) { + init(friend: Friend?, name: String, address: String, withPresence: Bool?) { self.friend = friend self.name = name + self.address = address self.withPresence = withPresence if friend != nil && withPresence == true { @@ -122,12 +125,12 @@ class ContactAvatarModel: ObservableObject { }) if avatarModel == nil { - avatarModel = ContactAvatarModel(friend: nil, name: addressFriend.name!, withPresence: false) + avatarModel = ContactAvatarModel(friend: nil, name: addressFriend.name!, address: address.asStringUriOnly(), withPresence: false) } return avatarModel! } else { let name = address.displayName != nil ? address.displayName! : address.username! - return ContactAvatarModel(friend: nil, name: name, withPresence: false) + return ContactAvatarModel(friend: nil, name: name, address: address.asStringUriOnly(), withPresence: false) } } } diff --git a/Linphone/UI/Main/ContentView.swift b/Linphone/UI/Main/ContentView.swift index 1bac741d9..259851373 100644 --- a/Linphone/UI/Main/ContentView.swift +++ b/Linphone/UI/Main/ContentView.swift @@ -728,7 +728,7 @@ struct ContentView: View { && $0.friend!.name == addressFriend!.name && $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly() }) - : ContactAvatarModel(friend: nil, name: "", withPresence: false) + : ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false) if contactAvatarModel != nil { HistoryContactFragment( diff --git a/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift b/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift index 9622af92b..b8697a70b 100644 --- a/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift +++ b/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift @@ -30,32 +30,106 @@ struct ChatBubbleView: View { var body: some View { VStack { - HStack { - if message.isOutgoing { - Spacer() - } - - VStack(alignment: message.isOutgoing ? .trailing : .leading) { - if !message.attachments.isEmpty { - messageAttachments() + if !message.text.isEmpty || !message.attachments.isEmpty { + HStack { + if message.isOutgoing { + Spacer() } - if !message.text.isEmpty { - Text(message.text) - .foregroundStyle(Color.grayMain2c700) - .default_text_style(styleSize: 16) + if conversationViewModel.displayedConversation != nil && conversationViewModel.displayedConversation!.isGroup && !message.isOutgoing && message.isFirstMessage { + VStack { + Avatar( + contactAvatarModel: conversationViewModel.participantConversationModel.first(where: {$0.address == message.address}) ?? + ContactAvatarModel(friend: nil, name: "??", address: "", withPresence: false), + avatarSize: 35 + ) + .padding(.top, 30) + + Spacer() + } + } else if conversationViewModel.displayedConversation != nil && conversationViewModel.displayedConversation!.isGroup && !message.isOutgoing { + VStack { + Avatar( + contactAvatarModel: ContactAvatarModel(friend: nil, name: "??", address: "", withPresence: false), + avatarSize: 35 + ) + + Spacer() + } + .hidden() + } + + VStack(alignment: .leading, spacing: 0) { + if conversationViewModel.displayedConversation != nil && conversationViewModel.displayedConversation!.isGroup && !message.isOutgoing && message.isFirstMessage { + Text(conversationViewModel.participantConversationModel.first(where: {$0.address == message.address})?.name ?? "") + .default_text_style(styleSize: 12) + .padding(.top, 10) + .padding(.bottom, 2) + } + ZStack { + if conversationViewModel.displayedConversation != nil && conversationViewModel.displayedConversation!.isGroup && message.isFirstMessage { + VStack { + if message.isOutgoing { + Spacer() + } + + HStack { + if message.isOutgoing { + Spacer() + } + + VStack { + } + .frame(width: 15, height: 15) + .background(message.isOutgoing ? Color.orangeMain100 : Color.grayMain2c100) + .clipShape(RoundedRectangle(cornerRadius: 2)) + + if !message.isOutgoing { + Spacer() + } + } + + if !message.isOutgoing { + Spacer() + } + } + } + + HStack { + if message.isOutgoing { + Spacer() + } + + VStack(alignment: message.isOutgoing ? .trailing : .leading) { + if !message.attachments.isEmpty { + messageAttachments() + } + + if !message.text.isEmpty { + Text(message.text) + .foregroundStyle(Color.grayMain2c700) + .default_text_style(styleSize: 16) + } + } + .padding(.all, 15) + .background(message.isOutgoing ? Color.orangeMain100 : Color.grayMain2c100) + .clipShape(RoundedRectangle(cornerRadius: 16)) + + if !message.isOutgoing { + Spacer() + } + } + } + .frame(maxWidth: .infinity) + } + + if !message.isOutgoing { + Spacer() } } - .padding(.all, 15) - .background(message.isOutgoing ? Color.orangeMain100 : Color.grayMain2c100) - .clipShape(RoundedRectangle(cornerRadius: 16)) - - if !message.isOutgoing { - Spacer() - } + .padding(.leading, message.isOutgoing ? 40 : 0) + .padding(.trailing, !message.isOutgoing ? 40 : 0) } - .padding(.leading, message.isOutgoing ? 40 : 0) - .padding(.trailing, !message.isOutgoing ? 40 : 0) } } diff --git a/Linphone/UI/Main/Conversations/Model/ConversationModel.swift b/Linphone/UI/Main/Conversations/Model/ConversationModel.swift index 0311c4e8e..24544bb50 100644 --- a/Linphone/UI/Main/Conversations/Model/ConversationModel.swift +++ b/Linphone/UI/Main/Conversations/Model/ConversationModel.swift @@ -90,7 +90,7 @@ class ConversationModel: ObservableObject { self.unreadMessagesCount = 0 - self.avatarModel = ContactAvatarModel(friend: nil, name: "", withPresence: false) + self.avatarModel = ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false) //self.isBeingDeleted = MutableLiveData() @@ -199,13 +199,25 @@ class ConversationModel: ObservableObject { } } + let addressTmp = addressFriend?.address?.asStringUriOnly() ?? "" + let avatarModelTmp = addressFriend != nil && !self.isGroup ? ContactsManager.shared.avatarListModel.first(where: { $0.friend!.name == addressFriend!.name && $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly() }) - ?? ContactAvatarModel(friend: nil, name: self.subject, withPresence: false) - : ContactAvatarModel(friend: nil, name: self.subject, withPresence: false) + ?? ContactAvatarModel( + friend: nil, + name: self.subject, + address: addressTmp, + withPresence: false + ) + : ContactAvatarModel( + friend: nil, + name: self.subject, + address: addressTmp, + withPresence: false + ) DispatchQueue.main.async { self.avatarModel = avatarModelTmp diff --git a/Linphone/UI/Main/Conversations/Model/Message.swift b/Linphone/UI/Main/Conversations/Model/Message.swift index ecc65b40f..7ed606a4b 100644 --- a/Linphone/UI/Main/Conversations/Model/Message.swift +++ b/Linphone/UI/Main/Conversations/Model/Message.swift @@ -61,6 +61,8 @@ public struct Message: Identifiable, Hashable { public var createdAt: Date public var isOutgoing: Bool + public var address: String + public var isFirstMessage: Bool public var text: String public var attachments: [Attachment] public var recording: Recording? @@ -71,6 +73,8 @@ public struct Message: Identifiable, Hashable { status: Status? = nil, createdAt: Date = Date(), isOutgoing: Bool, + address: String, + isFirstMessage: Bool = false, text: String = "", attachments: [Attachment] = [], recording: Recording? = nil, @@ -80,6 +84,8 @@ public struct Message: Identifiable, Hashable { self.status = status self.createdAt = createdAt self.isOutgoing = isOutgoing + self.isFirstMessage = isFirstMessage + self.address = address self.text = text self.attachments = attachments self.recording = recording @@ -111,6 +117,8 @@ public struct Message: Identifiable, Hashable { status: status, createdAt: draft.createdAt, isOutgoing: draft.isOutgoing, + address: draft.address, + isFirstMessage: draft.isFirstMessage, text: draft.text, attachments: attachments, recording: draft.recording, @@ -127,7 +135,7 @@ extension Message { extension Message: Equatable { public static func == (lhs: Message, rhs: Message) -> Bool { - lhs.id == rhs.id && lhs.status == rhs.status + lhs.id == rhs.id && lhs.status == rhs.status && lhs.isFirstMessage == rhs.isFirstMessage } } @@ -150,18 +158,24 @@ public struct ReplyMessage: Codable, Identifiable, Hashable { public var id: String + public var address: String + public var isFirstMessage: Bool public var text: String public var isOutgoing: Bool public var attachments: [Attachment] public var recording: Recording? public init(id: String, + address: String, + isFirstMessage: Bool = false, text: String = "", isOutgoing: Bool, attachments: [Attachment] = [], recording: Recording? = nil) { self.id = id + self.address = address + self.isFirstMessage = isFirstMessage self.text = text self.isOutgoing = isOutgoing self.attachments = attachments @@ -169,20 +183,22 @@ public struct ReplyMessage: Codable, Identifiable, Hashable { } func toMessage() -> Message { - Message(id: id, isOutgoing: isOutgoing, text: text, attachments: attachments, recording: recording) + Message(id: id, isOutgoing: isOutgoing, address: address, isFirstMessage: isFirstMessage, text: text, attachments: attachments, recording: recording) } } public extension Message { func toReplyMessage() -> ReplyMessage { - ReplyMessage(id: id, text: text, isOutgoing: isOutgoing, attachments: attachments, recording: recording) + ReplyMessage(id: id, address: address, isFirstMessage: isFirstMessage, text: text, isOutgoing: isOutgoing, attachments: attachments, recording: recording) } } public struct DraftMessage { public var id: String? public let isOutgoing: Bool + public let address: String + public let isFirstMessage: Bool public let text: String public let medias: [Media] public let recording: Recording? @@ -191,6 +207,8 @@ public struct DraftMessage { public init(id: String? = nil, isOutgoing: Bool, + address: String, + isFirstMessage: Bool, text: String, medias: [Media], recording: Recording?, @@ -198,6 +216,8 @@ public struct DraftMessage { createdAt: Date) { self.id = id self.isOutgoing = isOutgoing + self.address = address + self.isFirstMessage = isFirstMessage self.text = text self.medias = medias self.recording = recording diff --git a/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift b/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift index 20fd96d87..a717bd6fb 100644 --- a/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift +++ b/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift @@ -38,6 +38,7 @@ class ConversationViewModel: ObservableObject { @Published var conversationMessagesIds: [String] = [] @Published var conversationMessagesSection: [MessagesSection] = [] + @Published var participantConversationModel: [ContactAvatarModel] = [] init() {} @@ -91,9 +92,25 @@ class ConversationViewModel: ObservableObject { } } + func getParticipantConversationModel() { + coreContext.doOnCoreQueue { _ in + if self.displayedConversation != nil { + self.displayedConversation!.chatRoom.participants.forEach { participant in + if participant.address != nil { + let avatarModelTmp = ContactAvatarModel.getAvatarModelFromAddress(address: participant.address!) + DispatchQueue.main.async { + self.participantConversationModel.append(avatarModelTmp) + } + } + } + } + } + } + func getMessages() { self.getHistorySize() self.getUnreadMessagesCount() + self.getParticipantConversationModel() coreContext.doOnCoreQueue { _ in if self.displayedConversation != nil { let historyEvents = self.displayedConversation!.chatRoom.getHistoryRangeEvents(begin: 0, end: 30) @@ -121,11 +138,30 @@ class ConversationViewModel: ObservableObject { } } - conversationMessage.append(Message( - id: UUID().uuidString, - isOutgoing: eventLog.chatMessage?.isOutgoing ?? false, - text: contentText, - attachments: attachmentList)) + let addressPrecCleaned = index > 0 ? historyEvents[index - 1].chatMessage?.fromAddress?.clone() : eventLog.chatMessage?.fromAddress?.clone() + addressPrecCleaned?.clean() + + let addressNextCleaned = index <= historyEvents.count - 2 ? historyEvents[index + 1].chatMessage?.fromAddress?.clone() : eventLog.chatMessage?.fromAddress?.clone() + addressNextCleaned?.clean() + + let addressCleaned = eventLog.chatMessage?.fromAddress?.clone() + addressCleaned?.clean() + + let isFirstMessageIncomingTmp = index > 0 ? addressPrecCleaned?.asStringUriOnly() != addressCleaned?.asStringUriOnly() : true + let isFirstMessageOutgoingTmp = index <= historyEvents.count - 2 ? addressNextCleaned?.asStringUriOnly() != addressCleaned?.asStringUriOnly() : true + + let isFirstMessageTmp = (eventLog.chatMessage?.isOutgoing ?? false) ? isFirstMessageOutgoingTmp : isFirstMessageIncomingTmp + + conversationMessage.append( + Message( + id: UUID().uuidString, + isOutgoing: eventLog.chatMessage?.isOutgoing ?? false, + address: addressCleaned?.asStringUriOnly() ?? "", + isFirstMessage: isFirstMessageTmp, + text: contentText, + attachments: attachmentList + ) + ) } DispatchQueue.main.async { @@ -143,7 +179,7 @@ class ConversationViewModel: ObservableObject { let historyEvents = self.displayedConversation!.chatRoom.getHistoryRangeEvents(begin: self.conversationMessagesSection[0].rows.count, end: self.conversationMessagesSection[0].rows.count + 30) var conversationMessagesTmp: [Message] = [] - historyEvents.reversed().forEach { eventLog in + historyEvents.enumerated().reversed().forEach { index, eventLog in let attachmentList: [Attachment] = [] var contentText = "" @@ -155,10 +191,26 @@ class ConversationViewModel: ObservableObject { } } + let addressPrecCleaned = index > 0 ? historyEvents[index - 1].chatMessage?.fromAddress?.clone() : eventLog.chatMessage?.fromAddress?.clone() + addressPrecCleaned?.clean() + + let addressNextCleaned = index <= historyEvents.count - 2 ? historyEvents[index + 1].chatMessage?.fromAddress?.clone() : eventLog.chatMessage?.fromAddress?.clone() + addressNextCleaned?.clean() + + let addressCleaned = eventLog.chatMessage?.fromAddress?.clone() + addressCleaned?.clean() + + let isFirstMessageIncomingTmp = index > 0 ? addressPrecCleaned?.asStringUriOnly() != addressCleaned?.asStringUriOnly() : true + let isFirstMessageOutgoingTmp = index <= historyEvents.count - 2 ? addressNextCleaned?.asStringUriOnly() != addressCleaned?.asStringUriOnly() : true + + let isFirstMessageTmp = (eventLog.chatMessage?.isOutgoing ?? false) ? isFirstMessageOutgoingTmp : isFirstMessageIncomingTmp + conversationMessagesTmp.insert( Message( id: UUID().uuidString, isOutgoing: eventLog.chatMessage?.isOutgoing ?? false, + address: addressCleaned?.asStringUriOnly() ?? "", + isFirstMessage: isFirstMessageTmp, text: contentText, attachments: attachmentList ), at: 0 @@ -167,6 +219,9 @@ class ConversationViewModel: ObservableObject { if !conversationMessagesTmp.isEmpty { DispatchQueue.main.async { + if self.conversationMessagesSection[0].rows.last?.address == conversationMessagesTmp.last?.address { + self.conversationMessagesSection[0].rows[self.conversationMessagesSection[0].rows.count - 1].isFirstMessage = false + } self.conversationMessagesSection[0].rows.append(contentsOf: conversationMessagesTmp.reversed()) } } @@ -175,7 +230,6 @@ class ConversationViewModel: ObservableObject { } func getNewMessages(eventLogs: [EventLog]) { - var conversationMessage: [Message] = [] eventLogs.enumerated().forEach { index, eventLog in var attachmentList: [Attachment] = [] var contentText = "" @@ -197,14 +251,50 @@ class ConversationViewModel: ObservableObject { } } + let addressPrecCleaned = index > 0 ? eventLogs[index - 1].chatMessage?.fromAddress?.clone() : eventLog.chatMessage?.fromAddress?.clone() + addressPrecCleaned?.clean() + + let addressNextCleaned = index <= eventLogs.count - 2 ? eventLogs[index + 1].chatMessage?.fromAddress?.clone() : eventLog.chatMessage?.fromAddress?.clone() + addressNextCleaned?.clean() + + let addressCleaned = eventLog.chatMessage?.fromAddress?.clone() + addressCleaned?.clean() + + let isFirstMessageIncomingTmp = index > 0 + ? addressPrecCleaned?.asStringUriOnly() != addressCleaned?.asStringUriOnly() + : ( + self.conversationMessagesSection.isEmpty || self.conversationMessagesSection[0].rows.isEmpty + ? true + : self.conversationMessagesSection[0].rows[0].address != addressCleaned?.asStringUriOnly() + ) + + let isFirstMessageOutgoingTmp = index <= eventLogs.count - 2 + ? addressNextCleaned?.asStringUriOnly() == addressCleaned?.asStringUriOnly() + : ( + self.conversationMessagesSection.isEmpty || self.conversationMessagesSection[0].rows.isEmpty + ? true + : !self.conversationMessagesSection[0].rows[0].isOutgoing || self.conversationMessagesSection[0].rows[0].address == addressCleaned?.asStringUriOnly() + ) + + let isFirstMessageTmp = (eventLog.chatMessage?.isOutgoing ?? false) ? isFirstMessageOutgoingTmp : isFirstMessageIncomingTmp + let message = Message( id: UUID().uuidString, isOutgoing: eventLog.chatMessage?.isOutgoing ?? false, + address: addressCleaned?.asStringUriOnly() ?? "", + isFirstMessage: isFirstMessageTmp, text: contentText, attachments: attachmentList ) DispatchQueue.main.async { + if !self.conversationMessagesSection.isEmpty + && !self.conversationMessagesSection[0].rows.isEmpty + && self.conversationMessagesSection[0].rows[0].isOutgoing + && (self.conversationMessagesSection[0].rows[0].address == message.address) { + self.conversationMessagesSection[0].rows[0].isFirstMessage = false + } + if self.conversationMessagesSection.isEmpty { self.conversationMessagesSection.append(MessagesSection(date: Date(), rows: [message])) } else { diff --git a/Linphone/UI/Main/History/Fragments/HistoryContactFragment.swift b/Linphone/UI/Main/History/Fragments/HistoryContactFragment.swift index 1121b86e0..f41b44a91 100644 --- a/Linphone/UI/Main/History/Fragments/HistoryContactFragment.swift +++ b/Linphone/UI/Main/History/Fragments/HistoryContactFragment.swift @@ -628,7 +628,7 @@ struct HistoryContactFragment: View { #Preview { HistoryContactFragment( - contactAvatarModel: ContactAvatarModel(friend: nil, name: "", withPresence: false), + contactAvatarModel: ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false), historyViewModel: HistoryViewModel(), historyListViewModel: HistoryListViewModel(), contactViewModel: ContactViewModel(), diff --git a/Linphone/UI/Main/History/Fragments/HistoryListFragment.swift b/Linphone/UI/Main/History/Fragments/HistoryListFragment.swift index f101a6802..57b1fa6b1 100644 --- a/Linphone/UI/Main/History/Fragments/HistoryListFragment.swift +++ b/Linphone/UI/Main/History/Fragments/HistoryListFragment.swift @@ -49,7 +49,7 @@ struct HistoryListFragment: View { && $0.friend!.name == addressFriend!.name && $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly() }) - : ContactAvatarModel(friend: nil, name: "", withPresence: false) + : ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false) if addressFriend != nil && addressFriend!.photo != nil && !addressFriend!.photo!.isEmpty { if contactAvatarModel != nil { diff --git a/Linphone/Utils/MagicSearchSingleton.swift b/Linphone/Utils/MagicSearchSingleton.swift index 8b7352d08..cf23e5905 100644 --- a/Linphone/Utils/MagicSearchSingleton.swift +++ b/Linphone/Utils/MagicSearchSingleton.swift @@ -86,7 +86,14 @@ final class MagicSearchSingleton: ObservableObject { self.contactsManager.lastSearch.forEach { searchResult in if searchResult.friend != nil { - self.contactsManager.avatarListModel.append(ContactAvatarModel(friend: searchResult.friend!, name: searchResult.friend?.name ?? "", withPresence: true)) + self.contactsManager.avatarListModel.append( + ContactAvatarModel( + friend: searchResult.friend!, + name: searchResult.friend?.name ?? "", + address: searchResult.friend?.address?.clone()?.asStringUriOnly() ?? "", + withPresence: true + ) + ) } }