mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 02:58:07 +00:00
Add video preview in message bubble
This commit is contained in:
parent
84ad957568
commit
0682489645
4 changed files with 107 additions and 22 deletions
21
Linphone/Assets.xcassets/play-fill.imageset/Contents.json
vendored
Normal file
21
Linphone/Assets.xcassets/play-fill.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "play-fill.svg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Linphone/Assets.xcassets/play-fill.imageset/play-fill.svg
vendored
Normal file
1
Linphone/Assets.xcassets/play-fill.imageset/play-fill.svg
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M240,128a15.74,15.74,0,0,1-7.6,13.51L88.32,229.65a16,16,0,0,1-16.2.3A15.86,15.86,0,0,1,64,216.13V39.87a15.86,15.86,0,0,1,8.12-13.82,16,16,0,0,1,16.2.3L232.4,114.49A15.74,15.74,0,0,1,240,128Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 314 B |
|
|
@ -160,7 +160,7 @@ struct ChatBubbleView: View {
|
|||
@ViewBuilder
|
||||
func messageAttachments() -> some View {
|
||||
if message.attachments.count == 1 {
|
||||
if message.attachments.first!.type == .image || message.attachments.first!.type == .gif {
|
||||
if message.attachments.first!.type == .image || message.attachments.first!.type == .gif || message.attachments.first!.type == .video {
|
||||
let result = imageDimensions(url: message.attachments.first!.full.absoluteString)
|
||||
ZStack {
|
||||
Rectangle()
|
||||
|
|
@ -185,12 +185,22 @@ struct ChatBubbleView: View {
|
|||
)
|
||||
}
|
||||
|
||||
if message.attachments.first!.type == .image {
|
||||
if message.attachments.first!.type == .image || message.attachments.first!.type == .video {
|
||||
AsyncImage(url: message.attachments.first!.full) { image in
|
||||
image
|
||||
.resizable()
|
||||
.interpolation(.medium)
|
||||
.aspectRatio(contentMode: .fill)
|
||||
ZStack {
|
||||
image
|
||||
.resizable()
|
||||
.interpolation(.medium)
|
||||
.aspectRatio(contentMode: .fill)
|
||||
|
||||
if message.attachments.first!.type == .video {
|
||||
Image("play-fill")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(.white)
|
||||
.frame(width: 40, height: 40, alignment: .leading)
|
||||
}
|
||||
}
|
||||
} placeholder: {
|
||||
ProgressView()
|
||||
}
|
||||
|
|
@ -212,26 +222,34 @@ struct ChatBubbleView: View {
|
|||
GridItem(.adaptive(minimum: 120), spacing: 1)
|
||||
], spacing: 3) {
|
||||
ForEach(message.attachments) { attachment in
|
||||
if attachment.type == .image || attachment.type == .gif {
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(Color(.white))
|
||||
.frame(width: 120, height: 120)
|
||||
|
||||
AsyncImage(url: attachment.full) { image in
|
||||
ZStack {
|
||||
Rectangle()
|
||||
.fill(Color(.white))
|
||||
.frame(width: 120, height: 120)
|
||||
|
||||
AsyncImage(url: attachment.full) { image in
|
||||
ZStack {
|
||||
image
|
||||
.resizable()
|
||||
.interpolation(.medium)
|
||||
.aspectRatio(contentMode: .fill)
|
||||
} placeholder: {
|
||||
ProgressView()
|
||||
|
||||
if attachment.type == .video {
|
||||
Image("play-fill")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(.white)
|
||||
.frame(width: 40, height: 40, alignment: .leading)
|
||||
}
|
||||
}
|
||||
.id(UUID())
|
||||
.layoutPriority(-1)
|
||||
} placeholder: {
|
||||
ProgressView()
|
||||
}
|
||||
.clipShape(RoundedRectangle(cornerRadius: 4))
|
||||
.clipped()
|
||||
.id(UUID())
|
||||
.layoutPriority(-1)
|
||||
}
|
||||
.clipShape(RoundedRectangle(cornerRadius: 4))
|
||||
.clipped()
|
||||
}
|
||||
}
|
||||
.frame(
|
||||
|
|
|
|||
|
|
@ -127,9 +127,28 @@ class ConversationViewModel: ObservableObject {
|
|||
if content.filePath == nil || content.filePath!.isEmpty {
|
||||
self.downloadContent(chatMessage: eventLog.chatMessage!, content: content)
|
||||
} else {
|
||||
if URL(string: self.getNewFilePath(name: content.name ?? "")) != nil {
|
||||
let attachment = Attachment(id: UUID().uuidString, url: URL(string: self.getNewFilePath(name: content.name ?? ""))!, type: (content.name?.lowercased().hasSuffix("gif"))! ? .gif : .image)
|
||||
attachmentList.append(attachment)
|
||||
if content.type != "video" {
|
||||
let path = URL(string: self.getNewFilePath(name: content.name ?? ""))
|
||||
if path != nil {
|
||||
let attachment =
|
||||
Attachment(
|
||||
id: UUID().uuidString,
|
||||
url: path!,
|
||||
type: (content.name?.lowercased().hasSuffix("gif"))! ? .gif : .image
|
||||
)
|
||||
attachmentList.append(attachment)
|
||||
}
|
||||
} else if content.type == "video" {
|
||||
let path = URL(string: self.generateThumbnail(name: content.name ?? ""))
|
||||
if path != nil {
|
||||
let attachment =
|
||||
Attachment(
|
||||
id: UUID().uuidString,
|
||||
url: path!,
|
||||
type: .video
|
||||
)
|
||||
attachmentList.append(attachment)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -483,6 +502,32 @@ class ConversationViewModel: ObservableObject {
|
|||
return "file://" + Factory.Instance.getDownloadDir(context: nil) + (name.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? "")
|
||||
}
|
||||
|
||||
func generateThumbnail(name: String) -> String {
|
||||
do {
|
||||
let path = URL(string: "file://" + Factory.Instance.getDownloadDir(context: nil) + (name.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? ""))
|
||||
let asset = AVURLAsset(url: path!, options: nil)
|
||||
let imgGenerator = AVAssetImageGenerator(asset: asset)
|
||||
imgGenerator.appliesPreferredTrackTransform = true
|
||||
let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1), actualTime: nil)
|
||||
let thumbnail = UIImage(cgImage: cgImage)
|
||||
|
||||
guard let data = thumbnail.jpegData(compressionQuality: 1) ?? thumbnail.pngData() else {
|
||||
return ""
|
||||
}
|
||||
|
||||
let urlName = URL(string: "file://" + Factory.Instance.getDownloadDir(context: nil) + "preview_" + (name.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? "") + ".png")
|
||||
|
||||
if urlName != nil {
|
||||
let decodedData: () = try data.write(to: urlName!)
|
||||
}
|
||||
|
||||
return urlName!.absoluteString
|
||||
} catch let error {
|
||||
print("*** Error generating thumbnail: \(error.localizedDescription)")
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func getMessageTime(startDate: time_t) -> String {
|
||||
let timeInterval = TimeInterval(startDate)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue