Add IMDN and Date in ChatBubbleView

This commit is contained in:
Benoit Martins 2024-05-17 15:06:20 +02:00
parent 415cf274b1
commit ae19bad388
3 changed files with 125 additions and 3 deletions

View file

@ -110,6 +110,30 @@ struct ChatBubbleView: View {
.foregroundStyle(Color.grayMain2c700)
.default_text_style(styleSize: 16)
}
HStack(alignment: .center) {
Text(conversationViewModel.getMessageTime(startDate: message.dateReceived))
.foregroundStyle(Color.grayMain2c500)
.default_text_style_300(styleSize: 14)
.padding(.top, 1)
if (conversationViewModel.displayedConversation != nil && conversationViewModel.displayedConversation!.isGroup) || message.isOutgoing {
if message.status == .sending {
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: .orangeMain500))
.frame(width: 15, height: 15)
.padding(.top, 1)
} else if message.status != nil {
Image(conversationViewModel.getImageIMDN(status: message.status!))
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.orangeMain500)
.frame(width: 15, height: 15)
.padding(.top, 1)
}
}
}
.padding(.top, -4)
}
.padding(.all, 15)
.background(message.isOutgoing ? Color.orangeMain100 : Color.grayMain2c100)

View file

@ -24,6 +24,7 @@ public struct Message: Identifiable, Hashable {
public enum Status: Equatable, Hashable {
case sending
case sent
case received
case read
case error(DraftMessage)
@ -33,6 +34,8 @@ public struct Message: Identifiable, Hashable {
return hasher.combine("sending")
case .sent:
return hasher.combine("sent")
case .received:
return hasher.combine("received")
case .read:
return hasher.combine("read")
case .error:
@ -46,6 +49,8 @@ public struct Message: Identifiable, Hashable {
return true
case (.sent, .sent):
return true
case (.received, .received):
return true
case (.read, .read):
return true
case ( .error(_), .error(_)):
@ -60,6 +65,7 @@ public struct Message: Identifiable, Hashable {
public var status: Status?
public var createdAt: Date
public var isOutgoing: Bool
public var dateReceived: time_t
public var address: String
public var isFirstMessage: Bool
@ -73,6 +79,7 @@ public struct Message: Identifiable, Hashable {
status: Status? = nil,
createdAt: Date = Date(),
isOutgoing: Bool,
dateReceived: time_t,
address: String,
isFirstMessage: Bool = false,
text: String = "",
@ -84,6 +91,7 @@ public struct Message: Identifiable, Hashable {
self.status = status
self.createdAt = createdAt
self.isOutgoing = isOutgoing
self.dateReceived = dateReceived
self.isFirstMessage = isFirstMessage
self.address = address
self.text = text
@ -117,6 +125,7 @@ public struct Message: Identifiable, Hashable {
status: status,
createdAt: draft.createdAt,
isOutgoing: draft.isOutgoing,
dateReceived: draft.dateReceived,
address: draft.address,
isFirstMessage: draft.isFirstMessage,
text: draft.text,
@ -162,6 +171,7 @@ public struct ReplyMessage: Codable, Identifiable, Hashable {
public var isFirstMessage: Bool
public var text: String
public var isOutgoing: Bool
public var dateReceived: time_t
public var attachments: [Attachment]
public var recording: Recording?
@ -170,6 +180,7 @@ public struct ReplyMessage: Codable, Identifiable, Hashable {
isFirstMessage: Bool = false,
text: String = "",
isOutgoing: Bool,
dateReceived: time_t,
attachments: [Attachment] = [],
recording: Recording? = nil) {
@ -178,25 +189,27 @@ public struct ReplyMessage: Codable, Identifiable, Hashable {
self.isFirstMessage = isFirstMessage
self.text = text
self.isOutgoing = isOutgoing
self.dateReceived = dateReceived
self.attachments = attachments
self.recording = recording
}
func toMessage() -> Message {
Message(id: id, isOutgoing: isOutgoing, address: address, isFirstMessage: isFirstMessage, text: text, attachments: attachments, recording: recording)
Message(id: id, isOutgoing: isOutgoing, dateReceived: dateReceived, address: address, isFirstMessage: isFirstMessage, text: text, attachments: attachments, recording: recording)
}
}
public extension Message {
func toReplyMessage() -> ReplyMessage {
ReplyMessage(id: id, address: address, isFirstMessage: isFirstMessage, text: text, isOutgoing: isOutgoing, attachments: attachments, recording: recording)
ReplyMessage(id: id, address: address, isFirstMessage: isFirstMessage, text: text, isOutgoing: isOutgoing, dateReceived: dateReceived, attachments: attachments, recording: recording)
}
}
public struct DraftMessage {
public var id: String?
public let isOutgoing: Bool
public var dateReceived: time_t
public let address: String
public let isFirstMessage: Bool
public let text: String
@ -207,6 +220,7 @@ public struct DraftMessage {
public init(id: String? = nil,
isOutgoing: Bool,
dateReceived: time_t,
address: String,
isFirstMessage: Bool,
text: String,
@ -216,6 +230,7 @@ public struct DraftMessage {
createdAt: Date) {
self.id = id
self.isOutgoing = isOutgoing
self.dateReceived = dateReceived
self.address = address
self.isFirstMessage = isFirstMessage
self.text = text

View file

@ -31,7 +31,6 @@ class ConversationViewModel: ObservableObject {
@Published var displayedConversationHistorySize: Int = 0
@Published var displayedConversationUnreadMessagesCount: Int = 0
@Published var messageText: String = ""
private var chatRoomSuscriptions = Set<AnyCancellable?>()
@ -151,10 +150,26 @@ class ConversationViewModel: ObservableObject {
let isFirstMessageTmp = (eventLog.chatMessage?.isOutgoing ?? false) ? isFirstMessageOutgoingTmp : isFirstMessageIncomingTmp
var statusTmp: Message.Status? = .sending
switch eventLog.chatMessage?.state {
case .InProgress:
statusTmp = .sending
case .Delivered:
statusTmp = .sent
case .DeliveredToUser:
statusTmp = .received
case .Displayed:
statusTmp = .read
default:
statusTmp = nil
}
conversationMessage.append(
Message(
id: UUID().uuidString,
status: statusTmp,
isOutgoing: eventLog.chatMessage?.isOutgoing ?? false,
dateReceived: eventLog.chatMessage?.time ?? 0,
address: addressCleaned?.asStringUriOnly() ?? "",
isFirstMessage: isFirstMessageTmp,
text: contentText,
@ -204,10 +219,26 @@ class ConversationViewModel: ObservableObject {
let isFirstMessageTmp = (eventLog.chatMessage?.isOutgoing ?? false) ? isFirstMessageOutgoingTmp : isFirstMessageIncomingTmp
var statusTmp: Message.Status? = .sending
switch eventLog.chatMessage?.state {
case .InProgress:
statusTmp = .sending
case .Delivered:
statusTmp = .sent
case .DeliveredToUser:
statusTmp = .received
case .Displayed:
statusTmp = .read
default:
statusTmp = nil
}
conversationMessagesTmp.insert(
Message(
id: UUID().uuidString,
status: statusTmp,
isOutgoing: eventLog.chatMessage?.isOutgoing ?? false,
dateReceived: eventLog.chatMessage?.time ?? 0,
address: addressCleaned?.asStringUriOnly() ?? "",
isFirstMessage: isFirstMessageTmp,
text: contentText,
@ -277,9 +308,25 @@ class ConversationViewModel: ObservableObject {
let isFirstMessageTmp = (eventLog.chatMessage?.isOutgoing ?? false) ? isFirstMessageOutgoingTmp : isFirstMessageIncomingTmp
var statusTmp: Message.Status? = .sending
switch eventLog.chatMessage?.state {
case .InProgress:
statusTmp = .sending
case .Delivered:
statusTmp = .sent
case .DeliveredToUser:
statusTmp = .received
case .Displayed:
statusTmp = .read
default:
statusTmp = nil
}
let message = Message(
id: UUID().uuidString,
status: statusTmp,
isOutgoing: eventLog.chatMessage?.isOutgoing ?? false,
dateReceived: eventLog.chatMessage?.time ?? 0,
address: addressCleaned?.asStringUriOnly() ?? "",
isFirstMessage: isFirstMessageTmp,
text: contentText,
@ -426,6 +473,42 @@ class ConversationViewModel: ObservableObject {
func getNewFilePath(name: String) -> String {
return "file://" + Factory.Instance.getDownloadDir(context: nil) + name
}
func getMessageTime(startDate: time_t) -> String {
let timeInterval = TimeInterval(startDate)
let myNSDate = Date(timeIntervalSince1970: timeInterval)
if Calendar.current.isDateInToday(myNSDate) {
let formatter = DateFormatter()
formatter.dateFormat = Locale.current.identifier == "fr_FR" ? "HH:mm" : "h:mm a"
return formatter.string(from: myNSDate)
} else if Calendar.current.isDate(myNSDate, equalTo: .now, toGranularity: .year) {
let formatter = DateFormatter()
formatter.dateFormat = Locale.current.identifier == "fr_FR" ? "dd/MM HH:mm" : "MM/dd h:mm a"
return formatter.string(from: myNSDate)
} else {
let formatter = DateFormatter()
formatter.dateFormat = Locale.current.identifier == "fr_FR" ? "dd/MM/yy HH:mm" : "MM/dd/yy h:mm a"
return formatter.string(from: myNSDate)
}
}
func getImageIMDN(status: Message.Status) -> String {
switch status {
case .sending:
return ""
case .sent:
return "envelope-simple"
case .received:
return "check"
case .read:
return "checks"
case .error:
return ""
}
}
}
struct LinphoneCustomEventLog: Hashable {
var id = UUID()