diff --git a/Linphone/Assets.xcassets/clock-countdown.imageset/clock-countdown.svg b/Linphone/Assets.xcassets/clock-countdown.imageset/clock-countdown.svg
index 548aeabcd..c59988986 100644
--- a/Linphone/Assets.xcassets/clock-countdown.imageset/clock-countdown.svg
+++ b/Linphone/Assets.xcassets/clock-countdown.imageset/clock-countdown.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Linphone/Assets.xcassets/door.imageset/Contents.json b/Linphone/Assets.xcassets/door.imageset/Contents.json
new file mode 100644
index 000000000..d54a1df16
--- /dev/null
+++ b/Linphone/Assets.xcassets/door.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "door.svg",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Linphone/Assets.xcassets/door.imageset/door.svg b/Linphone/Assets.xcassets/door.imageset/door.svg
new file mode 100644
index 000000000..8952e8d49
--- /dev/null
+++ b/Linphone/Assets.xcassets/door.imageset/door.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Linphone/Assets.xcassets/pencil-simple.imageset/pencil-simple.svg b/Linphone/Assets.xcassets/pencil-simple.imageset/pencil-simple.svg
index 35cfc71c7..ceb292bbf 100644
--- a/Linphone/Assets.xcassets/pencil-simple.imageset/pencil-simple.svg
+++ b/Linphone/Assets.xcassets/pencil-simple.imageset/pencil-simple.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Linphone/Assets.xcassets/user-circle-gear.imageset/user-circle-gear.svg b/Linphone/Assets.xcassets/user-circle-gear.imageset/user-circle-gear.svg
index c406aac63..5b383bc57 100644
--- a/Linphone/Assets.xcassets/user-circle-gear.imageset/user-circle-gear.svg
+++ b/Linphone/Assets.xcassets/user-circle-gear.imageset/user-circle-gear.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Linphone/Assets.xcassets/user-circle.imageset/user-circle.svg b/Linphone/Assets.xcassets/user-circle.imageset/user-circle.svg
index 761ce7d97..797854dd3 100644
--- a/Linphone/Assets.xcassets/user-circle.imageset/user-circle.svg
+++ b/Linphone/Assets.xcassets/user-circle.imageset/user-circle.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Linphone/Assets.xcassets/warning-circle.imageset/warning-circle.svg b/Linphone/Assets.xcassets/warning-circle.imageset/warning-circle.svg
index a04e6ff79..1b69e522a 100644
--- a/Linphone/Assets.xcassets/warning-circle.imageset/warning-circle.svg
+++ b/Linphone/Assets.xcassets/warning-circle.imageset/warning-circle.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Linphone/Localizable.xcstrings b/Linphone/Localizable.xcstrings
index 6fdd2ee8b..797be6b75 100644
--- a/Linphone/Localizable.xcstrings
+++ b/Linphone/Localizable.xcstrings
@@ -947,6 +947,210 @@
}
}
},
+ "conversation_event_admin_set" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "%@ is admin"
+ }
+ },
+ "fr" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "%@ est maintenant administrateur"
+ }
+ }
+ }
+ },
+ "conversation_event_admin_unset" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "%@ is no longer admin"
+ }
+ },
+ "fr" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "%@ n'est plus administrateur"
+ }
+ }
+ }
+ },
+ "conversation_event_conference_created" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "You have joined the group"
+ }
+ },
+ "fr" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Vous avez rejoint le groupe"
+ }
+ }
+ }
+ },
+ "conversation_event_conference_destroyed" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "You have left the group"
+ }
+ },
+ "fr" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Vous avez quitté le groupe"
+ }
+ }
+ }
+ },
+ "conversation_event_device_added" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "New device for %@"
+ }
+ },
+ "fr" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Nouvel appareil pour %@"
+ }
+ }
+ }
+ },
+ "conversation_event_device_removed" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Device for %@ removed"
+ }
+ },
+ "fr" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Appareil supprimé pour %@"
+ }
+ }
+ }
+ },
+ "conversation_event_ephemeral_messages_disabled" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Ephemeral messages have been disabled"
+ }
+ },
+ "fr" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Les messages éphémères ont été désactivés"
+ }
+ }
+ }
+ },
+ "conversation_event_ephemeral_messages_enabled" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Ephemeral messages have been enabled"
+ }
+ },
+ "fr" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Les messages éphémères ont été activés"
+ }
+ }
+ }
+ },
+ "conversation_event_ephemeral_messages_lifetime_changed" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Ephemeral lifetime is now %@"
+ }
+ },
+ "fr" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "La durée des messages éphémères est de %@"
+ }
+ }
+ }
+ },
+ "conversation_event_participant_added" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "%@ has joined"
+ }
+ },
+ "fr" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "%@ a rejoint le groupe"
+ }
+ }
+ }
+ },
+ "conversation_event_participant_removed" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "%@ has left"
+ }
+ },
+ "fr" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "%@ a quitté le groupe"
+ }
+ }
+ }
+ },
+ "conversation_event_subject_changed" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "New subject: %@"
+ }
+ },
+ "fr" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Le groupe a été renommé : %@"
+ }
+ }
+ }
+ },
"conversation_failed_to_create_toast" : {
"extractionState" : "manual",
"localizations" : {
diff --git a/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift b/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift
index fd37145de..4ad63f305 100644
--- a/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift
+++ b/Linphone/UI/Main/Conversations/Fragments/ChatBubbleView.swift
@@ -36,244 +36,272 @@ struct ChatBubbleView: View {
var body: some View {
HStack {
- VStack {
- if !eventLogMessage.message.text.isEmpty || !eventLogMessage.message.attachments.isEmpty {
- HStack(alignment: .top, content: {
- if eventLogMessage.message.isOutgoing {
- Spacer()
- }
- if conversationViewModel.displayedConversation != nil && conversationViewModel.displayedConversation!.isGroup
- && !eventLogMessage.message.isOutgoing && eventLogMessage.message.isFirstMessage {
- VStack {
- Avatar(
- contactAvatarModel: conversationViewModel.participantConversationModel.first(where: {$0.address == eventLogMessage.message.address}) ??
- ContactAvatarModel(friend: nil, name: "??", address: "", withPresence: false),
- avatarSize: 35
- )
- .padding(.top, 30)
+ if eventLogMessage.eventModel.eventLogType == .ConferenceChatMessage {
+ VStack {
+ if !eventLogMessage.message.text.isEmpty || !eventLogMessage.message.attachments.isEmpty {
+ HStack(alignment: .top, content: {
+ if eventLogMessage.message.isOutgoing {
+ Spacer()
}
- } else if conversationViewModel.displayedConversation != nil
- && conversationViewModel.displayedConversation!.isGroup && !eventLogMessage.message.isOutgoing {
- VStack {
- }
- .padding(.leading, 43)
- }
-
- VStack(alignment: .leading, spacing: 0) {
- if conversationViewModel.displayedConversation != nil && conversationViewModel.displayedConversation!.isGroup
+ if conversationViewModel.displayedConversation != nil && conversationViewModel.displayedConversation!.isGroup
&& !eventLogMessage.message.isOutgoing && eventLogMessage.message.isFirstMessage {
- Text(conversationViewModel.participantConversationModel.first(where: {$0.address == eventLogMessage.message.address})?.name ?? "")
- .default_text_style(styleSize: 12)
- .padding(.top, 10)
- .padding(.bottom, 2)
- }
-
- if eventLogMessage.message.isForward {
- HStack {
- if eventLogMessage.message.isOutgoing {
- Spacer()
- }
-
- VStack(alignment: eventLogMessage.message.isOutgoing ? .trailing : .leading, spacing: 0) {
- HStack {
- Image("forward")
- .resizable()
- .frame(width: 15, height: 15, alignment: .leading)
-
- Text("message_forwarded_label")
- .default_text_style(styleSize: 12)
- }
- .padding(.bottom, 2)
- }
-
- if !eventLogMessage.message.isOutgoing {
- Spacer()
- }
+ VStack {
+ Avatar(
+ contactAvatarModel: conversationViewModel.participantConversationModel.first(where: {$0.address == eventLogMessage.message.address}) ??
+ ContactAvatarModel(friend: nil, name: "??", address: "", withPresence: false),
+ avatarSize: 35
+ )
+ .padding(.top, 30)
}
- .frame(maxWidth: .infinity)
+ } else if conversationViewModel.displayedConversation != nil
+ && conversationViewModel.displayedConversation!.isGroup && !eventLogMessage.message.isOutgoing {
+ VStack {
+ }
+ .padding(.leading, 43)
}
- if eventLogMessage.message.replyMessage != nil {
- HStack {
- if eventLogMessage.message.isOutgoing {
- Spacer()
- }
-
- VStack(alignment: eventLogMessage.message.isOutgoing ? .trailing : .leading, spacing: 0) {
- HStack {
- Image("reply")
- .resizable()
- .frame(width: 15, height: 15, alignment: .leading)
-
- Text(conversationViewModel.participantConversationModel.first(
- where: {$0.address == eventLogMessage.message.replyMessage!.address})?.name ?? "")
- .default_text_style(styleSize: 12)
- }
+ VStack(alignment: .leading, spacing: 0) {
+ if conversationViewModel.displayedConversation != nil && conversationViewModel.displayedConversation!.isGroup
+ && !eventLogMessage.message.isOutgoing && eventLogMessage.message.isFirstMessage {
+ Text(conversationViewModel.participantConversationModel.first(where: {$0.address == eventLogMessage.message.address})?.name ?? "")
+ .default_text_style(styleSize: 12)
+ .padding(.top, 10)
.padding(.bottom, 2)
+ }
+
+ if eventLogMessage.message.isForward {
+ HStack {
+ if eventLogMessage.message.isOutgoing {
+ Spacer()
+ }
- VStack(alignment: eventLogMessage.message.isOutgoing ? .trailing : .leading) {
- if !eventLogMessage.message.replyMessage!.text.isEmpty {
- Text(eventLogMessage.message.replyMessage!.text)
- .foregroundStyle(Color.grayMain2c700)
- .default_text_style(styleSize: 16)
- .lineLimit(/*@START_MENU_TOKEN@*/2/*@END_MENU_TOKEN@*/)
- } else if !eventLogMessage.message.replyMessage!.attachmentsNames.isEmpty {
- Text(eventLogMessage.message.replyMessage!.attachmentsNames)
- .foregroundStyle(Color.grayMain2c700)
- .default_text_style(styleSize: 16)
- .lineLimit(/*@START_MENU_TOKEN@*/2/*@END_MENU_TOKEN@*/)
- }
- }
- .padding(.all, 15)
- .padding(.bottom, 15)
- .background(Color.gray200)
- .clipShape(RoundedRectangle(cornerRadius: 1))
- .roundedCorner(
- 16,
- corners: eventLogMessage.message.isOutgoing ? [.topLeft, .topRight, .bottomLeft] : [.topLeft, .topRight, .bottomRight]
- )
- }
- .onTapGesture {
- conversationViewModel.scrollToMessage(message: eventLogMessage.message)
- }
-
- if !eventLogMessage.message.isOutgoing {
- Spacer()
- }
- }
- .frame(maxWidth: .infinity)
- .padding(.bottom, -20)
- }
-
- ZStack {
- HStack {
- if eventLogMessage.message.isOutgoing {
- Spacer()
- }
-
- VStack(alignment: eventLogMessage.message.isOutgoing ? .trailing : .leading) {
- VStack(alignment: eventLogMessage.message.isOutgoing ? .trailing : .leading) {
- if !eventLogMessage.message.attachments.isEmpty {
- messageAttachments()
- }
-
- if !eventLogMessage.message.text.isEmpty {
- Text(eventLogMessage.message.text)
- .foregroundStyle(Color.grayMain2c700)
- .default_text_style(styleSize: 16)
- }
-
- HStack(alignment: .center) {
- Text(conversationViewModel.getMessageTime(startDate: eventLogMessage.message.dateReceived))
- .foregroundStyle(Color.grayMain2c500)
- .default_text_style_300(styleSize: 14)
- .padding(.top, 1)
+ VStack(alignment: eventLogMessage.message.isOutgoing ? .trailing : .leading, spacing: 0) {
+ HStack {
+ Image("forward")
+ .resizable()
+ .frame(width: 15, height: 15, alignment: .leading)
- if (conversationViewModel.displayedConversation != nil && conversationViewModel.displayedConversation!.isGroup)
- || eventLogMessage.message.isOutgoing {
- if eventLogMessage.message.status == .sending {
- ProgressView()
- .controlSize(.mini)
- .progressViewStyle(CircularProgressViewStyle(tint: .orangeMain500))
- .frame(width: 10, height: 10)
- .padding(.top, 1)
- } else if eventLogMessage.message.status != nil {
- Image(conversationViewModel.getImageIMDN(status: eventLogMessage.message.status!))
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.orangeMain500)
- .frame(width: 15, height: 15)
- .padding(.top, 1)
- }
+ Text("message_forwarded_label")
+ .default_text_style(styleSize: 12)
+ }
+ .padding(.bottom, 2)
+ }
+
+ if !eventLogMessage.message.isOutgoing {
+ Spacer()
+ }
+ }
+ .frame(maxWidth: .infinity)
+ }
+
+ if eventLogMessage.message.replyMessage != nil {
+ HStack {
+ if eventLogMessage.message.isOutgoing {
+ Spacer()
+ }
+
+ VStack(alignment: eventLogMessage.message.isOutgoing ? .trailing : .leading, spacing: 0) {
+ HStack {
+ Image("reply")
+ .resizable()
+ .frame(width: 15, height: 15, alignment: .leading)
+
+ Text(conversationViewModel.participantConversationModel.first(
+ where: {$0.address == eventLogMessage.message.replyMessage!.address})?.name ?? "")
+ .default_text_style(styleSize: 12)
+ }
+ .padding(.bottom, 2)
+
+ VStack(alignment: eventLogMessage.message.isOutgoing ? .trailing : .leading) {
+ if !eventLogMessage.message.replyMessage!.text.isEmpty {
+ Text(eventLogMessage.message.replyMessage!.text)
+ .foregroundStyle(Color.grayMain2c700)
+ .default_text_style(styleSize: 16)
+ .lineLimit(/*@START_MENU_TOKEN@*/2/*@END_MENU_TOKEN@*/)
+ } else if !eventLogMessage.message.replyMessage!.attachmentsNames.isEmpty {
+ Text(eventLogMessage.message.replyMessage!.attachmentsNames)
+ .foregroundStyle(Color.grayMain2c700)
+ .default_text_style(styleSize: 16)
+ .lineLimit(/*@START_MENU_TOKEN@*/2/*@END_MENU_TOKEN@*/)
}
}
- .onTapGesture {
- conversationViewModel.selectedMessageToDisplayDetails = eventLogMessage
- conversationViewModel.prepareBottomSheetForDeliveryStatus()
- }
- .disabled(conversationViewModel.selectedMessage != nil)
- .padding(.top, -4)
+ .padding(.all, 15)
+ .padding(.bottom, 15)
+ .background(Color.gray200)
+ .clipShape(RoundedRectangle(cornerRadius: 1))
+ .roundedCorner(
+ 16,
+ corners: eventLogMessage.message.isOutgoing ? [.topLeft, .topRight, .bottomLeft] : [.topLeft, .topRight, .bottomRight]
+ )
+ }
+ .onTapGesture {
+ conversationViewModel.scrollToMessage(message: eventLogMessage.message)
}
- .padding(.all, 15)
- .background(eventLogMessage.message.isOutgoing ? Color.orangeMain100 : Color.grayMain2c100)
- .clipShape(RoundedRectangle(cornerRadius: 3))
- .roundedCorner(
- 16,
- corners: eventLogMessage.message.isOutgoing && eventLogMessage.message.isFirstMessage ? [.topLeft, .topRight, .bottomLeft] :
- (!eventLogMessage.message.isOutgoing && eventLogMessage.message.isFirstMessage ? [.topRight, .bottomRight, .bottomLeft] : [.allCorners]))
- if !eventLogMessage.message.reactions.isEmpty {
- HStack {
- ForEach(0...
+ */
+
+import SwiftUI
+import linphonesw
+
+class EventModel: ObservableObject {
+ @Published var text: String
+ @Published var icon: Image?
+
+ var eventLog: EventLog
+ var eventLogType: EventLog.Kind
+
+ init(eventLog: EventLog) {
+ self.eventLog = eventLog
+ self.eventLogType = eventLog.type
+ self.text = ""
+ self.icon = nil
+ setupEventData()
+ }
+
+ private func setupEventData() {
+ let address = eventLog.participantAddress ?? eventLog.peerAddress
+ if address != nil {
+ ContactsManager.shared.getFriendWithAddressInCoreQueue(address: address) { friendResult in
+ var name = ""
+ if let addressFriend = friendResult {
+ name = addressFriend.name!
+ } else {
+ name = address!.displayName != nil ? address!.displayName! : address!.username!
+ }
+
+ let textValue: String
+ let iconValue: Image?
+
+ switch self.eventLog.type {
+ case .ConferenceCreated:
+ textValue = NSLocalizedString("conversation_event_conference_created", comment: "")
+ case .ConferenceTerminated:
+ textValue = NSLocalizedString("conversation_event_conference_destroyed", comment: "")
+ case .ConferenceParticipantAdded:
+ textValue = String(format: NSLocalizedString("conversation_event_participant_added", comment: ""), address != nil ? name : ">")
+ case .ConferenceParticipantRemoved:
+ textValue = String(format: NSLocalizedString("conversation_event_participant_removed", comment: ""), address != nil ? name : ">")
+ case .ConferenceSubjectChanged:
+ textValue = String(format: NSLocalizedString("conversation_event_subject_changed", comment: ""), self.eventLog.subject ?? "")
+ case .ConferenceParticipantSetAdmin:
+ textValue = String(format: NSLocalizedString("conversation_event_admin_set", comment: ""), address != nil ? name : ">")
+ case .ConferenceParticipantUnsetAdmin:
+ textValue = String(format: NSLocalizedString("conversation_event_admin_unset", comment: ""), address != nil ? name : ">")
+ case .ConferenceParticipantDeviceAdded:
+ textValue = String(format: NSLocalizedString("conversation_event_device_added", comment: ""), address != nil ? name : ">")
+ case .ConferenceParticipantDeviceRemoved:
+ textValue = String(format: NSLocalizedString("conversation_event_device_removed", comment: ""), address != nil ? name : ">")
+ case .ConferenceEphemeralMessageEnabled:
+ textValue = NSLocalizedString("conversation_event_ephemeral_messages_enabled", comment: "")
+ case .ConferenceEphemeralMessageDisabled:
+ textValue = NSLocalizedString("conversation_event_ephemeral_messages_disabled", comment: "")
+ case .ConferenceEphemeralMessageLifetimeChanged:
+ textValue = String(format: NSLocalizedString("conversation_event_ephemeral_messages_lifetime_changed", comment: ""),
+ self.formatEphemeralExpiration(duration: Int64(self.eventLog.ephemeralMessageLifetime)).lowercased())
+ default:
+ textValue = String(self.eventLog.type.rawValue)
+ }
+
+ // Icon assignment
+ switch self.eventLog.type {
+ case .ConferenceEphemeralMessageEnabled, .ConferenceEphemeralMessageDisabled, .ConferenceEphemeralMessageLifetimeChanged:
+ iconValue = Image("clock-countdown")
+ case .ConferenceTerminated:
+ iconValue = Image("warning-circle")
+ case .ConferenceSubjectChanged:
+ iconValue = Image("pencil-simple")
+ case .ConferenceParticipantAdded, .ConferenceParticipantRemoved, .ConferenceParticipantDeviceAdded, .ConferenceParticipantDeviceRemoved:
+ iconValue = Image("door")
+ default:
+ iconValue = Image("user-circle")
+ }
+
+ DispatchQueue.main.async {
+ self.text = textValue
+ self.icon = iconValue
+ }
+ }
+ }
+ }
+
+ private func formatEphemeralExpiration(duration: Int64) -> String {
+ switch duration {
+ case 0:
+ return NSLocalizedString("conversation_ephemeral_messages_duration_disabled", comment: "")
+ case 60:
+ return NSLocalizedString("conversation_ephemeral_messages_duration_one_minute", comment: "")
+ case 3600:
+ return NSLocalizedString("conversation_ephemeral_messages_duration_one_hour", comment: "")
+ case 86400:
+ return NSLocalizedString("conversation_ephemeral_messages_duration_one_day", comment: "")
+ case 259200:
+ return NSLocalizedString("conversation_ephemeral_messages_duration_three_days", comment: "")
+ case 604800:
+ return NSLocalizedString("conversation_ephemeral_messages_duration_one_week", comment: "")
+ default:
+ return "\(duration) s"
+ }
+ }
+}
diff --git a/Linphone/UI/Main/Conversations/ViewModel/ConversationForwardMessageViewModel.swift b/Linphone/UI/Main/Conversations/ViewModel/ConversationForwardMessageViewModel.swift
index 6217bc9c1..eaabb4f48 100644
--- a/Linphone/UI/Main/Conversations/ViewModel/ConversationForwardMessageViewModel.swift
+++ b/Linphone/UI/Main/Conversations/ViewModel/ConversationForwardMessageViewModel.swift
@@ -280,7 +280,7 @@ class ConversationForwardMessageViewModel: ObservableObject {
func forwardMessage() {
CoreContext.shared.doOnCoreQueue { _ in
if self.displayedConversation != nil && self.selectedMessage != nil {
- if let messageToForward = self.selectedMessage!.eventLog.chatMessage {
+ if let messageToForward = self.selectedMessage!.eventModel.eventLog.chatMessage {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
do {
let forwardedMessage = try self.displayedConversation!.chatRoom.createForwardMessage(message: messageToForward)
diff --git a/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift b/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift
index f4ea9e59a..c06f29420 100644
--- a/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift
+++ b/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift
@@ -125,7 +125,7 @@ class ConversationViewModel: ObservableObject {
}
if !self.conversationMessagesSection.isEmpty && !self.conversationMessagesSection[0].rows.isEmpty {
- if let indexMessage = self.conversationMessagesSection[0].rows.firstIndex(where: {$0.eventLog.chatMessage?.messageId == message.messageId}) {
+ if let indexMessage = self.conversationMessagesSection[0].rows.firstIndex(where: {$0.eventModel.eventLog.chatMessage?.messageId == message.messageId}) {
if indexMessage < self.conversationMessagesSection[0].rows.count && self.conversationMessagesSection[0].rows[indexMessage].message.status != statusTmp {
DispatchQueue.main.async {
self.objectWillChange.send()
@@ -153,7 +153,7 @@ class ConversationViewModel: ObservableObject {
statusTmp = .sending
}
- let indexMessage = self.conversationMessagesSection[0].rows.firstIndex(where: {$0.eventLog.chatMessage?.messageId == message.messageId})
+ let indexMessage = self.conversationMessagesSection[0].rows.firstIndex(where: {$0.eventModel.eventLog.chatMessage?.messageId == message.messageId})
DispatchQueue.main.async {
if indexMessage != nil {
@@ -162,7 +162,7 @@ class ConversationViewModel: ObservableObject {
}
}
}, onNewMessageReaction: { (message: ChatMessage, _: ChatMessageReaction) in
- let indexMessage = self.conversationMessagesSection[0].rows.firstIndex(where: {$0.eventLog.chatMessage?.messageId == message.messageId})
+ let indexMessage = self.conversationMessagesSection[0].rows.firstIndex(where: {$0.eventModel.eventLog.chatMessage?.messageId == message.messageId})
var reactionsTmp: [String] = []
message.reactions.forEach({ chatMessageReaction in
reactionsTmp.append(chatMessageReaction.body)
@@ -175,7 +175,7 @@ class ConversationViewModel: ObservableObject {
}
}
}, onReactionRemoved: { (message: ChatMessage, _: Address) in
- let indexMessage = self.conversationMessagesSection[0].rows.firstIndex(where: {$0.eventLog.chatMessage?.messageId == message.messageId})
+ let indexMessage = self.conversationMessagesSection[0].rows.firstIndex(where: {$0.eventModel.eventLog.chatMessage?.messageId == message.messageId})
var reactionsTmp: [String] = []
message.reactions.forEach({ chatMessageReaction in
reactionsTmp.append(chatMessageReaction.body)
@@ -453,7 +453,7 @@ class ConversationViewModel: ObservableObject {
if eventLog.chatMessage != nil {
conversationMessage.append(
EventLogMessage(
- eventLog: eventLog,
+ eventModel: EventModel(eventLog: eventLog),
message: Message(
id: !eventLog.chatMessage!.messageId.isEmpty ? eventLog.chatMessage!.messageId : UUID().uuidString,
status: statusTmp,
@@ -474,9 +474,9 @@ class ConversationViewModel: ObservableObject {
self.addChatMessageDelegate(message: eventLog.chatMessage!)
} else {
- conversationMessage.insert(
+ conversationMessage.append(
EventLogMessage(
- eventLog: eventLog,
+ eventModel: EventModel(eventLog: eventLog),
message: Message(
id: UUID().uuidString,
status: nil,
@@ -489,7 +489,7 @@ class ConversationViewModel: ObservableObject {
ownReaction: "",
reactions: []
)
- ), at: 0
+ )
)
}
}
@@ -672,7 +672,7 @@ class ConversationViewModel: ObservableObject {
if eventLog.chatMessage != nil {
conversationMessagesTmp.insert(
EventLogMessage(
- eventLog: eventLog,
+ eventModel: EventModel(eventLog: eventLog),
message: Message(
id: !eventLog.chatMessage!.messageId.isEmpty ? eventLog.chatMessage!.messageId : UUID().uuidString,
status: statusTmp,
@@ -695,7 +695,7 @@ class ConversationViewModel: ObservableObject {
} else {
conversationMessagesTmp.insert(
EventLogMessage(
- eventLog: eventLog,
+ eventModel: EventModel(eventLog: eventLog),
message: Message(
id: UUID().uuidString,
status: nil,
@@ -902,7 +902,7 @@ class ConversationViewModel: ObservableObject {
if eventLog.chatMessage != nil {
let message = EventLogMessage(
- eventLog: eventLog,
+ eventModel: EventModel(eventLog: eventLog),
message: Message(
id: !eventLog.chatMessage!.messageId.isEmpty ? eventLog.chatMessage!.messageId : UUID().uuidString,
appData: eventLog.chatMessage!.appdata ?? "",
@@ -943,7 +943,7 @@ class ConversationViewModel: ObservableObject {
}
} else {
let message = EventLogMessage(
- eventLog: eventLog,
+ eventModel: EventModel(eventLog: eventLog),
message: Message(
id: UUID().uuidString,
status: nil,
@@ -987,7 +987,7 @@ class ConversationViewModel: ObservableObject {
func scrollToMessage(message: Message) {
coreContext.doOnCoreQueue { _ in
if message.replyMessage != nil {
- if let indexMessage = self.conversationMessagesSection[0].rows.firstIndex(where: {$0.eventLog.chatMessage?.messageId == message.replyMessage!.id}) {
+ if let indexMessage = self.conversationMessagesSection[0].rows.firstIndex(where: {$0.eventModel.eventLog.chatMessage?.messageId == message.replyMessage!.id}) {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "onScrollToIndex"), object: nil, userInfo: ["index": indexMessage, "animated": true])
} else {
if self.conversationMessagesSection[0].rows.last != nil {
@@ -1177,7 +1177,7 @@ class ConversationViewModel: ObservableObject {
if eventLog.chatMessage != nil {
conversationMessagesTmp.insert(
EventLogMessage(
- eventLog: eventLog,
+ eventModel: EventModel(eventLog: eventLog),
message: Message(
id: !eventLog.chatMessage!.messageId.isEmpty ? eventLog.chatMessage!.messageId : UUID().uuidString,
status: statusTmp,
@@ -1200,7 +1200,7 @@ class ConversationViewModel: ObservableObject {
} else {
conversationMessagesTmp.insert(
EventLogMessage(
- eventLog: eventLog,
+ eventModel: EventModel(eventLog: eventLog),
message: Message(
id: UUID().uuidString,
status: nil,
@@ -1243,7 +1243,7 @@ class ConversationViewModel: ObservableObject {
do {
var message: ChatMessage?
if self.messageToReply != nil {
- let chatMessageToReply = self.messageToReply!.eventLog.chatMessage
+ let chatMessageToReply = self.messageToReply!.eventModel.eventLog.chatMessage
if chatMessageToReply != nil {
message = try self.displayedConversation!.chatRoom.createReplyMessage(message: chatMessageToReply!)
}
@@ -1482,7 +1482,7 @@ class ConversationViewModel: ObservableObject {
coreContext.doOnCoreQueue { _ in
if self.selectedMessageToDisplayDetails != nil {
Log.info("[ConversationViewModel] Remove reaction to message with ID \(self.selectedMessageToDisplayDetails!.message.id)")
- let messageToSendReaction = self.selectedMessageToDisplayDetails!.eventLog.chatMessage
+ let messageToSendReaction = self.selectedMessageToDisplayDetails!.eventModel.eventLog.chatMessage
if messageToSendReaction != nil {
do {
let reaction = try messageToSendReaction!.createReaction(utf8Reaction: "")
@@ -1509,7 +1509,7 @@ class ConversationViewModel: ObservableObject {
coreContext.doOnCoreQueue { _ in
if self.selectedMessage != nil {
Log.info("[ConversationViewModel] Sending reaction \(emoji) to message with ID \(self.selectedMessage!.message.id)")
- let messageToSendReaction = self.selectedMessage!.eventLog.chatMessage
+ let messageToSendReaction = self.selectedMessage!.eventModel.eventLog.chatMessage
if messageToSendReaction != nil {
do {
let reaction = try messageToSendReaction!.createReaction(utf8Reaction: messageToSendReaction?.ownReaction?.body == emoji ? "" : emoji)
@@ -1533,9 +1533,9 @@ class ConversationViewModel: ObservableObject {
func resend() {
coreContext.doOnCoreQueue { _ in
- if self.selectedMessage != nil && self.selectedMessage!.eventLog.chatMessage != nil {
- Log.info("[ConversationViewModel] Re-sending message with ID \(self.selectedMessage!.eventLog.chatMessage!)")
- self.selectedMessage!.eventLog.chatMessage!.send()
+ if self.selectedMessage != nil && self.selectedMessage!.eventModel.eventLog.chatMessage != nil {
+ Log.info("[ConversationViewModel] Re-sending message with ID \(self.selectedMessage!.eventModel.eventLog.chatMessage!)")
+ self.selectedMessage!.eventModel.eventLog.chatMessage!.send()
}
}
}
@@ -1543,9 +1543,9 @@ class ConversationViewModel: ObservableObject {
func prepareBottomSheetForDeliveryStatus() {
self.sheetCategories.removeAll()
coreContext.doOnCoreQueue { _ in
- if self.selectedMessageToDisplayDetails != nil && self.selectedMessageToDisplayDetails!.eventLog.chatMessage != nil {
+ if self.selectedMessageToDisplayDetails != nil && self.selectedMessageToDisplayDetails!.eventModel.eventLog.chatMessage != nil {
- let participantsImdnDisplayed = self.selectedMessageToDisplayDetails!.eventLog.chatMessage!.getParticipantsByImdnState(state: .Displayed)
+ let participantsImdnDisplayed = self.selectedMessageToDisplayDetails!.eventModel.eventLog.chatMessage!.getParticipantsByImdnState(state: .Displayed)
var participantListDisplayed: [InnerSheetCategory] = []
participantsImdnDisplayed.forEach({ participantImdn in
if participantImdn.participant != nil && participantImdn.participant!.address != nil {
@@ -1556,7 +1556,7 @@ class ConversationViewModel: ObservableObject {
}
})
- let participantsImdnDeliveredToUser = self.selectedMessageToDisplayDetails!.eventLog.chatMessage!.getParticipantsByImdnState(state: .DeliveredToUser)
+ let participantsImdnDeliveredToUser = self.selectedMessageToDisplayDetails!.eventModel.eventLog.chatMessage!.getParticipantsByImdnState(state: .DeliveredToUser)
var participantListDeliveredToUser: [InnerSheetCategory] = []
participantsImdnDeliveredToUser.forEach({ participantImdn in
if participantImdn.participant != nil && participantImdn.participant!.address != nil {
@@ -1567,7 +1567,7 @@ class ConversationViewModel: ObservableObject {
}
})
- let participantsImdnDelivered = self.selectedMessageToDisplayDetails!.eventLog.chatMessage!.getParticipantsByImdnState(state: .Delivered)
+ let participantsImdnDelivered = self.selectedMessageToDisplayDetails!.eventModel.eventLog.chatMessage!.getParticipantsByImdnState(state: .Delivered)
var participantListDelivered: [InnerSheetCategory] = []
participantsImdnDelivered.forEach({ participantImdn in
if participantImdn.participant != nil && participantImdn.participant!.address != nil {
@@ -1578,7 +1578,7 @@ class ConversationViewModel: ObservableObject {
}
})
- let participantsImdnNotDelivered = self.selectedMessageToDisplayDetails!.eventLog.chatMessage!.getParticipantsByImdnState(state: .NotDelivered)
+ let participantsImdnNotDelivered = self.selectedMessageToDisplayDetails!.eventModel.eventLog.chatMessage!.getParticipantsByImdnState(state: .NotDelivered)
var participantListNotDelivered: [InnerSheetCategory] = []
participantsImdnNotDelivered.forEach({ participantImdn in
if participantImdn.participant != nil && participantImdn.participant!.address != nil {
@@ -1604,7 +1604,7 @@ class ConversationViewModel: ObservableObject {
func prepareBottomSheetForReactions() {
self.sheetCategories.removeAll()
coreContext.doOnCoreQueue { core in
- if self.selectedMessageToDisplayDetails != nil && self.selectedMessageToDisplayDetails!.eventLog.chatMessage != nil {
+ if self.selectedMessageToDisplayDetails != nil && self.selectedMessageToDisplayDetails!.eventModel.eventLog.chatMessage != nil {
let dispatchGroup = DispatchGroup()
var sheetCategoriesTmp: [SheetCategory] = []
@@ -1612,7 +1612,7 @@ class ConversationViewModel: ObservableObject {
var participantList: [[InnerSheetCategory]] = [[]]
var reactionList: [String] = []
- self.selectedMessageToDisplayDetails!.eventLog.chatMessage!.reactions.forEach { chatMessageReaction in
+ self.selectedMessageToDisplayDetails!.eventModel.eventLog.chatMessage!.reactions.forEach { chatMessageReaction in
if chatMessageReaction.fromAddress != nil {
dispatchGroup.enter()
ContactAvatarModel.getAvatarModelFromAddress(address: chatMessageReaction.fromAddress!) { avatarResult in
@@ -1701,6 +1701,14 @@ class ConversationViewModel: ObservableObject {
}
}
}
+
+ func compose() {
+ coreContext.doOnCoreQueue { _ in
+ if self.displayedConversation != nil {
+ self.displayedConversation!.chatRoom.compose()
+ }
+ }
+ }
}
// swiftlint:enable line_length
// swiftlint:enable type_body_length