mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 11:08:06 +00:00
Fix content list in message bubble
This commit is contained in:
parent
311e245861
commit
c6c0793b59
3 changed files with 157 additions and 79 deletions
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue