wip
This commit is contained in:
parent
6818182f66
commit
3aca0a69c1
9
ConversationsClassic/Helpers/Date+Extensions.swift
Normal file
9
ConversationsClassic/Helpers/Date+Extensions.swift
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension TimeInterval {
|
||||||
|
var minAndSec: String {
|
||||||
|
let minutes = Int(self) / 60
|
||||||
|
let seconds = Int(self) % 60
|
||||||
|
return String(format: "%02d:%02d", minutes, seconds)
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,9 +5,9 @@ struct AttachmentFilesPickerView: View {
|
||||||
@State private var isPickerPresented = false
|
@State private var isPickerPresented = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Button(action: {
|
Button {
|
||||||
isPickerPresented = true
|
isPickerPresented = true
|
||||||
}) {
|
} label: {
|
||||||
Text("Select Files")
|
Text("Select Files")
|
||||||
}
|
}
|
||||||
.sheet(isPresented: $isPickerPresented) {
|
.sheet(isPresented: $isPickerPresented) {
|
||||||
|
|
|
@ -138,26 +138,49 @@ struct AttachmentMediaPickerView: View {
|
||||||
private func fetchImages() {
|
private func fetchImages() {
|
||||||
let fetchOptions = PHFetchOptions()
|
let fetchOptions = PHFetchOptions()
|
||||||
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
|
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
|
||||||
let assets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
|
let assets = PHAsset.fetchAssets(with: fetchOptions)
|
||||||
|
|
||||||
let manager = PHImageManager.default()
|
let manager = PHImageManager.default()
|
||||||
let option = PHImageRequestOptions()
|
let option = PHImageRequestOptions()
|
||||||
option.isSynchronous = true
|
option.isSynchronous = true
|
||||||
|
|
||||||
assets.enumerateObjects { asset, _, _ in
|
assets.enumerateObjects { asset, _, _ in
|
||||||
manager.requestImage(
|
if asset.mediaType == .image {
|
||||||
for: asset,
|
manager.requestImage(
|
||||||
targetSize: PHImageManagerMaximumSize,
|
for: asset,
|
||||||
contentMode: .aspectFill,
|
targetSize: PHImageManagerMaximumSize,
|
||||||
options: option
|
contentMode: .aspectFill,
|
||||||
) { image, _ in
|
options: option
|
||||||
image?.scaleAndCropImage(toExampleSize: CGSize(width: gridSize, height: gridSize), completion: { image in
|
) { image, _ in
|
||||||
if let image {
|
image?.scaleAndCropImage(toExampleSize: CGSize(width: gridSize, height: gridSize), completion: { image in
|
||||||
DispatchQueue.main.async {
|
if let image {
|
||||||
self.photos.append(PhotoView(image: image, gridSize: gridSize))
|
DispatchQueue.main.async {
|
||||||
|
self.photos.append(PhotoView(image: image, gridSize: gridSize))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if asset.mediaType == .video {
|
||||||
|
manager.requestAVAsset(forVideo: asset, options: nil) { avAsset, _, _ in
|
||||||
|
if let avAsset {
|
||||||
|
let imageGenerator = AVAssetImageGenerator(asset: avAsset)
|
||||||
|
imageGenerator.appliesPreferredTrackTransform = true
|
||||||
|
let time = CMTimeMake(value: 1, timescale: 2)
|
||||||
|
do {
|
||||||
|
let imageRef = try imageGenerator.copyCGImage(at: time, actualTime: nil)
|
||||||
|
let thumbnail = UIImage(cgImage: imageRef)
|
||||||
|
thumbnail.scaleAndCropImage(toExampleSize: CGSize(width: gridSize, height: gridSize), completion: { image in
|
||||||
|
if let image {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.photos.append(PhotoView(image: image, gridSize: gridSize, duration: asset.duration.minAndSec))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
print("Failed to create thumbnail image")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,22 +198,39 @@ struct AttachmentMediaPickerView: View {
|
||||||
private struct PhotoView: Identifiable, View {
|
private struct PhotoView: Identifiable, View {
|
||||||
let id = UUID()
|
let id = UUID()
|
||||||
let gridSize: CGFloat
|
let gridSize: CGFloat
|
||||||
|
let duration: String?
|
||||||
|
|
||||||
@State private var image: UIImage
|
@State private var image: UIImage
|
||||||
@State private var ready = false
|
@State private var ready = false
|
||||||
|
|
||||||
init(image: UIImage, gridSize: CGFloat) {
|
init(image: UIImage, gridSize: CGFloat, duration: String? = nil) {
|
||||||
self.image = image
|
self.image = image
|
||||||
self.gridSize = gridSize
|
self.gridSize = gridSize
|
||||||
|
self.duration = duration
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if ready {
|
if ready {
|
||||||
Image(uiImage: image)
|
ZStack {
|
||||||
.resizable()
|
Image(uiImage: image)
|
||||||
.aspectRatio(contentMode: .fill)
|
.resizable()
|
||||||
.frame(width: gridSize, height: gridSize)
|
.aspectRatio(contentMode: .fill)
|
||||||
.clipped()
|
.frame(width: gridSize, height: gridSize)
|
||||||
|
.clipped()
|
||||||
|
if let duration {
|
||||||
|
VStack {
|
||||||
|
Spacer()
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
Text(duration)
|
||||||
|
.foregroundColor(.Material.Text.white)
|
||||||
|
.font(.sub1)
|
||||||
|
.shadow(color: .black, radius: 2)
|
||||||
|
.padding(4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ZStack {
|
ZStack {
|
||||||
Rectangle()
|
Rectangle()
|
||||||
|
|
Loading…
Reference in a new issue