From 846a93849895a1713609a69fb93d55c5dc86c596 Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Tue, 20 Aug 2024 10:03:02 +0200 Subject: [PATCH] Add reply bubble message --- .../Fragments/ChatBubbleView.swift | 36 +++++- .../UI/Main/Conversations/Model/Message.swift | 3 + .../ViewModel/ConversationViewModel.swift | 108 ++++++++++++++++++ 3 files changed, 146 insertions(+), 1 deletion(-) diff --git a/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift b/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift index 75070b266..d88f2f016 100644 --- a/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift +++ b/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift @@ -63,8 +63,42 @@ struct ChatBubbleView: View { .padding(.top, 10) .padding(.bottom, 2) } + + if message.replyMessage != nil { + HStack { + if message.isOutgoing { + Spacer() + } + + VStack(alignment: message.isOutgoing ? .trailing : .leading) { + VStack(alignment: message.isOutgoing ? .trailing : .leading) { + if !message.replyMessage!.text.isEmpty { + Text(message.replyMessage!.text) + .foregroundStyle(Color.grayMain2c700) + .default_text_style(styleSize: 16) + .lineLimit(/*@START_MENU_TOKEN@*/2/*@END_MENU_TOKEN@*/) + } else if !message.replyMessage!.attachmentsNames.isEmpty { + Text(message.replyMessage!.attachmentsNames) + .foregroundStyle(Color.grayMain2c700) + .default_text_style(styleSize: 16) + .lineLimit(/*@START_MENU_TOKEN@*/2/*@END_MENU_TOKEN@*/) + } + } + .padding(.all, 15) + .padding(.bottom, 20) + .background(Color.gray200) + .clipShape(RoundedRectangle(cornerRadius: 16)) + } + + if !message.isOutgoing { + Spacer() + } + } + .frame(maxWidth: .infinity) + .padding(.bottom, -20) + } + ZStack { - HStack { if message.isOutgoing { Spacer() diff --git a/Linphone/UI/Main/Conversations/Model/Message.swift b/Linphone/UI/Main/Conversations/Model/Message.swift index 495848fde..067621a79 100644 --- a/Linphone/UI/Main/Conversations/Model/Message.swift +++ b/Linphone/UI/Main/Conversations/Model/Message.swift @@ -183,6 +183,7 @@ public struct ReplyMessage: Codable, Identifiable, Hashable { public var text: String public var isOutgoing: Bool public var dateReceived: time_t + public var attachmentsNames: String public var attachments: [Attachment] public var recording: Recording? @@ -192,6 +193,7 @@ public struct ReplyMessage: Codable, Identifiable, Hashable { text: String = "", isOutgoing: Bool, dateReceived: time_t, + attachmentsNames: String = "", attachments: [Attachment] = [], recording: Recording? = nil) { @@ -201,6 +203,7 @@ public struct ReplyMessage: Codable, Identifiable, Hashable { self.text = text self.isOutgoing = isOutgoing self.dateReceived = dateReceived + self.attachmentsNames = attachmentsNames self.attachments = attachments self.recording = recording } diff --git a/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift b/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift index 6d2ff4472..2bc81ec94 100644 --- a/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift +++ b/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift @@ -307,6 +307,37 @@ class ConversationViewModel: ObservableObject { attachmentNameList = String(attachmentNameList.dropFirst(2)) } + var replyMessageTmp: ReplyMessage? + if eventLog.chatMessage?.replyMessage != nil { + let addressReplyCleaned = eventLog.chatMessage?.replyMessage?.fromAddress?.clone() + addressCleaned?.clean() + + let contentReplyText = eventLog.chatMessage?.replyMessage?.utf8Text ?? "" + + var attachmentNameReplyList: String = "" + + eventLog.chatMessage?.replyMessage?.contents.forEach { content in + if !content.isText { + attachmentNameReplyList += ", \(content.name!)" + } + } + + if !attachmentNameReplyList.isEmpty { + attachmentNameReplyList = String(attachmentNameReplyList.dropFirst(2)) + } + + replyMessageTmp = ReplyMessage( + id: eventLog.chatMessage?.replyMessage!.messageId ?? UUID().uuidString, + address: addressReplyCleaned?.asStringUriOnly() ?? "", + isFirstMessage: false, + text: contentReplyText, + isOutgoing: false, + dateReceived: 0, + attachmentsNames: attachmentNameReplyList, + attachments: [] + ) + } + if eventLog.chatMessage != nil { conversationMessage.append( Message( @@ -319,6 +350,7 @@ class ConversationViewModel: ObservableObject { text: contentText, attachmentsNames: attachmentNameList, attachments: attachmentList, + replyMessage: replyMessageTmp, ownReaction: eventLog.chatMessage?.ownReaction?.body ?? "", reactions: reactionsTmp ) @@ -458,6 +490,37 @@ class ConversationViewModel: ObservableObject { attachmentNameList = String(attachmentNameList.dropFirst(2)) } + var replyMessageTmp: ReplyMessage? + if eventLog.chatMessage?.replyMessage != nil { + let addressReplyCleaned = eventLog.chatMessage?.replyMessage?.fromAddress?.clone() + addressCleaned?.clean() + + let contentReplyText = eventLog.chatMessage?.replyMessage?.utf8Text ?? "" + + var attachmentNameReplyList: String = "" + + eventLog.chatMessage?.replyMessage?.contents.forEach { content in + if !content.isText { + attachmentNameReplyList += ", \(content.name!)" + } + } + + if !attachmentNameReplyList.isEmpty { + attachmentNameReplyList = String(attachmentNameReplyList.dropFirst(2)) + } + + replyMessageTmp = ReplyMessage( + id: eventLog.chatMessage?.replyMessage!.messageId ?? UUID().uuidString, + address: addressReplyCleaned?.asStringUriOnly() ?? "", + isFirstMessage: false, + text: contentReplyText, + isOutgoing: false, + dateReceived: 0, + attachmentsNames: attachmentNameReplyList, + attachments: [] + ) + } + if eventLog.chatMessage != nil { conversationMessagesTmp.insert( Message( @@ -470,6 +533,7 @@ class ConversationViewModel: ObservableObject { text: contentText, attachmentsNames: attachmentNameList, attachments: attachmentList, + replyMessage: replyMessageTmp, ownReaction: eventLog.chatMessage?.ownReaction?.body ?? "", reactions: reactionsTmp ), at: 0 @@ -622,6 +686,37 @@ class ConversationViewModel: ObservableObject { attachmentNameList = String(attachmentNameList.dropFirst(2)) } + var replyMessageTmp: ReplyMessage? + if eventLog.chatMessage?.replyMessage != nil { + let addressReplyCleaned = eventLog.chatMessage?.replyMessage?.fromAddress?.clone() + addressCleaned?.clean() + + let contentReplyText = eventLog.chatMessage?.replyMessage?.utf8Text ?? "" + + var attachmentNameReplyList: String = "" + + eventLog.chatMessage?.replyMessage?.contents.forEach { content in + if !content.isText { + attachmentNameReplyList += ", \(content.name!)" + } + } + + if !attachmentNameReplyList.isEmpty { + attachmentNameReplyList = String(attachmentNameReplyList.dropFirst(2)) + } + + replyMessageTmp = ReplyMessage( + id: eventLog.chatMessage?.replyMessage!.messageId ?? UUID().uuidString, + address: addressReplyCleaned?.asStringUriOnly() ?? "", + isFirstMessage: false, + text: contentReplyText, + isOutgoing: false, + dateReceived: 0, + attachmentsNames: attachmentNameReplyList, + attachments: [] + ) + } + if eventLog.chatMessage != nil { let message = Message( id: eventLog.chatMessage?.messageId ?? UUID().uuidString, @@ -633,6 +728,7 @@ class ConversationViewModel: ObservableObject { text: contentText, attachmentsNames: attachmentNameList, attachments: attachmentList, + replyMessage: replyMessageTmp, ownReaction: eventLog.chatMessage?.ownReaction?.body ?? "", reactions: reactionsTmp ) @@ -707,6 +803,18 @@ class ConversationViewModel: ObservableObject { let message = try? self.displayedConversation!.chatRoom.createEmptyMessage() //} + /* + var message: Message? + if messageToReply != nil { + let chatMessageToReply = try? self.displayedConversation!.chatRoom.findMessage(messageId: messageToReply!.id) + if chatMessageToReply != nil { + message = try? self.displayedConversation!.chatRoom.createReplyMessage(message: chatMessageToReply!) + } + } else { + message = try? self.displayedConversation!.chatRoom.createEmptyMessage() + } + */ + let toSend = self.messageText.trimmingCharacters(in: .whitespacesAndNewlines) if !toSend.isEmpty { if message != nil {