Fix content list in message bubble

This commit is contained in:
Benoit Martins 2024-11-19 15:59:49 +01:00
parent 311e245861
commit c6c0793b59
3 changed files with 157 additions and 79 deletions

View file

@ -641,6 +641,16 @@ struct ChatBubbleView: View {
}
.frame(width: 100, height: 100)
.background(Color.grayMain2c200)
.onTapGesture {
if eventLogMessage.message.attachments.first!.type == .fileTransfer && !eventLogMessage.message.isFileTransferInProgress {
CoreContext.shared.doOnCoreQueue { _ in
conversationViewModel.downloadContent(
chatMessage: eventLogMessage.eventModel.eventLog.chatMessage!,
content: eventLogMessage.eventModel.eventLog.chatMessage!.contents.first!
)
}
}
}
VStack {
Text(eventLogMessage.message.attachments.first!.name)
@ -658,7 +668,6 @@ struct ChatBubbleView: View {
.padding(.horizontal, 10)
.frame(maxWidth: .infinity, alignment: .leading)
}
.frame(width: geometryProxy.size.width - 110, height: 100)
.background(.white)
.clipShape(RoundedRectangle(cornerRadius: 10))
.onTapGesture {
@ -666,74 +675,126 @@ struct ChatBubbleView: View {
}
}
} else if eventLogMessage.message.attachments.count > 1 {
let isGroup = conversationViewModel.displayedConversation != nil && conversationViewModel.displayedConversation!.isGroup
LazyVGrid(columns: [
GridItem(.adaptive(minimum: 120), spacing: 1)
], spacing: 3) {
ForEach(eventLogMessage.message.attachments, id: \.id) { attachment in
ZStack {
Rectangle()
.fill(Color(.white))
.frame(width: 120, height: 120)
if #available(iOS 16.0, *) {
AsyncImage(url: attachment.thumbnail) { image in
ZStack {
image
.resizable()
.interpolation(.medium)
.aspectRatio(contentMode: .fill)
if attachment.type == .video {
Image("play-fill")
.renderingMode(.template)
.resizable()
.foregroundStyle(.white)
.frame(width: 40, height: 40, alignment: .leading)
let sizeCard = ((geometryProxy.size.width - 150)/2)-2
let columns = [
GridItem(.adaptive(minimum: sizeCard), spacing: 1)]
LazyVStack {
LazyVGrid(columns: columns) {
ForEach(eventLogMessage.message.attachments, id: \.id) { attachment in
if attachment.type == .image || attachment.type == .gif
|| attachment.type == .video {
ZStack {
Rectangle()
.fill(Color(.white))
.frame(width: sizeCard, height: sizeCard)
if #available(iOS 16.0, *) {
AsyncImage(url: attachment.thumbnail) { image in
ZStack {
image
.resizable()
.interpolation(.medium)
.aspectRatio(contentMode: .fill)
if attachment.type == .video {
Image("play-fill")
.renderingMode(.template)
.resizable()
.foregroundStyle(.white)
.frame(width: 40, height: 40, alignment: .leading)
}
}
} placeholder: {
ProgressView()
}
.layoutPriority(-1)
.onTapGesture {
selectedURLAttachment = attachment.full
}
} else {
AsyncImage(url: attachment.thumbnail) { image in
ZStack {
image
.resizable()
.interpolation(.medium)
.aspectRatio(contentMode: .fill)
if attachment.type == .video {
Image("play-fill")
.renderingMode(.template)
.resizable()
.foregroundStyle(.white)
.frame(width: 40, height: 40, alignment: .leading)
}
}
} placeholder: {
ProgressView()
}
.id(UUID())
.layoutPriority(-1)
.onTapGesture {
selectedURLAttachment = attachment.full
}
}
} placeholder: {
ProgressView()
}
.layoutPriority(-1)
.onTapGesture {
selectedURLAttachment = attachment.full
}
} else {
AsyncImage(url: attachment.thumbnail) { image in
ZStack {
image
.resizable()
.interpolation(.medium)
.aspectRatio(contentMode: .fill)
if attachment.type == .video {
Image("play-fill")
.renderingMode(.template)
.resizable()
.foregroundStyle(.white)
.frame(width: 40, height: 40, alignment: .leading)
}
}
} placeholder: {
ProgressView()
}
.id(UUID())
.layoutPriority(-1)
.onTapGesture {
selectedURLAttachment = attachment.full
}
.clipShape(RoundedRectangle(cornerRadius: 4))
.contentShape(Rectangle())
}
}
}
ForEach(eventLogMessage.message.attachments, id: \.id) { attachment in
if !(attachment.type == .image || attachment.type == .gif
|| attachment.type == .video) {
HStack {
VStack {
Image(getImageOfType(type: attachment.type))
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.grayMain2c700)
.frame(width: 60, height: 60, alignment: .leading)
}
.frame(width: 100, height: 100)
.background(Color.grayMain2c200)
.onTapGesture {
if attachment.type == .fileTransfer && !eventLogMessage.message.isFileTransferInProgress {
if let content = eventLogMessage.eventModel.eventLog.chatMessage!.contents.first(where: {$0.filePath == attachment.full.absoluteString}) {
CoreContext.shared.doOnCoreQueue { _ in
conversationViewModel.downloadContent(
chatMessage: eventLogMessage.eventModel.eventLog.chatMessage!,
content: content
)
}
}
}
}
VStack {
Text(attachment.name)
.foregroundStyle(Color.grayMain2c700)
.default_text_style_600(styleSize: 14)
.truncationMode(.middle)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(1)
Text(attachment.size.formatBytes())
.default_text_style_300(styleSize: 14)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(1)
}
.padding(.horizontal, 10)
.frame(maxWidth: .infinity, alignment: .leading)
}
.background(.white)
.clipShape(RoundedRectangle(cornerRadius: 10))
.onTapGesture {
selectedURLAttachment = attachment.full
}
}
.clipShape(RoundedRectangle(cornerRadius: 4))
.contentShape(Rectangle())
}
}
.frame( width: geometryProxy.size.width > 0
&& CGFloat(122 * eventLogMessage.message.attachments.count) > geometryProxy.size.width - 110 - (isGroup ? 40 : 0)
? 122 * floor(CGFloat(geometryProxy.size.width - 110 - (isGroup ? 40 : 0)) / 122)
: CGFloat(122 * eventLogMessage.message.attachments.count)
)
.frame(width: geometryProxy.size.width - 150)
}
}

View file

@ -88,6 +88,8 @@ public struct Message: Identifiable, Hashable {
public var isIcalendar: Bool
public var messageConferenceInfo: MessageConferenceInfo?
public var isFileTransferInProgress: Bool
public init(
id: String,
appData: String = "",
@ -109,7 +111,8 @@ public struct Message: Identifiable, Hashable {
ephemeralExpireTime: Int = 0,
ephemeralLifetime: Int = 0,
isIcalendar: Bool = false,
messageConferenceInfo: MessageConferenceInfo? = nil
messageConferenceInfo: MessageConferenceInfo? = nil,
isFileTransferInProgress: Bool = false
) {
self.id = id
self.appData = appData
@ -132,6 +135,7 @@ public struct Message: Identifiable, Hashable {
self.ephemeralLifetime = ephemeralLifetime
self.isIcalendar = isIcalendar
self.messageConferenceInfo = messageConferenceInfo
self.isFileTransferInProgress = isFileTransferInProgress
}
public static func makeMessage(

View file

@ -590,7 +590,8 @@ class ConversationViewModel: ObservableObject {
ephemeralExpireTime: eventLog.chatMessage?.ephemeralExpireTime ?? 0,
ephemeralLifetime: eventLog.chatMessage?.ephemeralLifetime ?? 0,
isIcalendar: eventLog.chatMessage?.contents.first?.isIcalendar ?? false,
messageConferenceInfo: eventLog.chatMessage != nil && eventLog.chatMessage!.contents.first != nil && eventLog.chatMessage!.contents.first!.isIcalendar == true ? self.parseConferenceInvite(content: eventLog.chatMessage!.contents.first!) : nil
messageConferenceInfo: eventLog.chatMessage != nil && eventLog.chatMessage!.contents.first != nil && eventLog.chatMessage!.contents.first!.isIcalendar == true ? self.parseConferenceInvite(content: eventLog.chatMessage!.contents.first!) : nil,
isFileTransferInProgress: eventLog.chatMessage!.isFileTransferInProgress
)
)
)
@ -823,7 +824,8 @@ class ConversationViewModel: ObservableObject {
ephemeralExpireTime: eventLog.chatMessage?.ephemeralExpireTime ?? 0,
ephemeralLifetime: eventLog.chatMessage?.ephemeralLifetime ?? 0,
isIcalendar: eventLog.chatMessage?.contents.first?.isIcalendar ?? false,
messageConferenceInfo: eventLog.chatMessage != nil && eventLog.chatMessage!.contents.first != nil && eventLog.chatMessage!.contents.first!.isIcalendar == true ? self.parseConferenceInvite(content: eventLog.chatMessage!.contents.first!) : nil
messageConferenceInfo: eventLog.chatMessage != nil && eventLog.chatMessage!.contents.first != nil && eventLog.chatMessage!.contents.first!.isIcalendar == true ? self.parseConferenceInvite(content: eventLog.chatMessage!.contents.first!) : nil,
isFileTransferInProgress: eventLog.chatMessage!.isFileTransferInProgress
)
), at: 0
)
@ -1069,7 +1071,8 @@ class ConversationViewModel: ObservableObject {
ephemeralExpireTime: eventLog.chatMessage?.ephemeralExpireTime ?? 0,
ephemeralLifetime: eventLog.chatMessage?.ephemeralLifetime ?? 0,
isIcalendar: eventLog.chatMessage?.contents.first?.isIcalendar ?? false,
messageConferenceInfo: eventLog.chatMessage != nil && eventLog.chatMessage!.contents.first != nil && eventLog.chatMessage!.contents.first!.isIcalendar == true ? self.parseConferenceInvite(content: eventLog.chatMessage!.contents.first!) : nil
messageConferenceInfo: eventLog.chatMessage != nil && eventLog.chatMessage!.contents.first != nil && eventLog.chatMessage!.contents.first!.isIcalendar == true ? self.parseConferenceInvite(content: eventLog.chatMessage!.contents.first!) : nil,
isFileTransferInProgress: eventLog.chatMessage!.isFileTransferInProgress
)
)
@ -1363,7 +1366,8 @@ class ConversationViewModel: ObservableObject {
ephemeralExpireTime: eventLog.chatMessage?.ephemeralExpireTime ?? 0,
ephemeralLifetime: eventLog.chatMessage?.ephemeralLifetime ?? 0,
isIcalendar: eventLog.chatMessage?.contents.first?.isIcalendar ?? false,
messageConferenceInfo: eventLog.chatMessage != nil && eventLog.chatMessage!.contents.first != nil && eventLog.chatMessage!.contents.first!.isIcalendar == true ? self.parseConferenceInvite(content: eventLog.chatMessage!.contents.first!) : nil
messageConferenceInfo: eventLog.chatMessage != nil && eventLog.chatMessage!.contents.first != nil && eventLog.chatMessage!.contents.first!.isIcalendar == true ? self.parseConferenceInvite(content: eventLog.chatMessage!.contents.first!) : nil,
isFileTransferInProgress: eventLog.chatMessage!.isFileTransferInProgress
)
), at: 0
)
@ -1608,18 +1612,27 @@ class ConversationViewModel: ObservableObject {
func downloadContent(chatMessage: ChatMessage, content: Content) {
// Log.debug("[ConversationViewModel] Starting downloading content for file \(model.fileName)")
if !chatMessage.isFileTransferInProgress && (content.filePath == nil || content.filePath!.isEmpty) {
if let contentName = content.name {
// let isImage = FileUtil.isExtensionImage(path: contentName)
let file = FileUtil.sharedContainerUrl().appendingPathComponent("Library/Images").absoluteString + (contentName.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? "")
// let file = FileUtil.getFileStoragePath(fileName: contentName ?? "", isImage: isImage)
content.filePath = String(file.dropFirst(7))
Log.info(
"[ConversationViewModel] File \(contentName) will be downloaded at \(content.filePath ?? "NIL")"
)
self.displayedConversation?.downloadContent(chatMessage: chatMessage, content: content)
} else {
Log.error("[ConversationViewModel] Content name is null, can't download it!")
if self.displayedConversation != nil {
if !chatMessage.isFileTransferInProgress && (content.filePath == nil || content.filePath!.isEmpty) {
if let contentName = content.name {
// let isImage = FileUtil.isExtensionImage(path: contentName)
var file = FileUtil.sharedContainerUrl().appendingPathComponent("Library/Images").absoluteString + (contentName.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? "")
// let file = FileUtil.getFileStoragePath(fileName: contentName ?? "", isImage: isImage)
var counter = 1
while FileManager.default.fileExists(atPath: file) {
file = FileUtil.sharedContainerUrl().appendingPathComponent("Library/Images").absoluteString + "\(counter)_" + (contentName.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? "")
counter += 1
}
content.filePath = String(file.dropFirst(7))
Log.info(
"[ConversationViewModel] File \(contentName) will be downloaded at \(content.filePath ?? "NIL")"
)
self.displayedConversation!.downloadContent(chatMessage: chatMessage, content: content)
} else {
Log.error("[ConversationViewModel] Content name is null, can't download it!")
}
}
}
}