commit d9f2317728e7152d6fce47ae75f8554bd209cd21
parent 4effaa432424e877f15fe7d50939d1e92ee711e9
Author: William Casarin <jb55@jb55.com>
Date: Mon, 21 Oct 2024 09:44:10 -0700
Merge 'Maintain images preview as per the selection order' from 'github/pr/2595'
Swift Coder (2):
Maintain images preview as per the selection order
document
Diffstat:
1 file changed, 36 insertions(+), 13 deletions(-)
diff --git a/damus/Views/MediaPicker.swift b/damus/Views/MediaPicker.swift
@@ -20,7 +20,12 @@ struct MediaPicker: UIViewControllerRepresentable {
final class Coordinator: NSObject, PHPickerViewControllerDelegate {
- let parent: MediaPicker
+ var parent: MediaPicker
+
+ // properties used for returning medias in the same order as picking
+ let dispatchGroup: DispatchGroup = DispatchGroup()
+ var orderIds: [String] = []
+ var orderMap: [String: PreUploadedMedia] = [:]
init(_ parent: MediaPicker) {
self.parent = parent
@@ -32,6 +37,11 @@ struct MediaPicker: UIViewControllerRepresentable {
}
for result in results {
+
+ let orderId = result.assetIdentifier ?? UUID().uuidString
+ orderIds.append(orderId)
+ dispatchGroup.enter()
+
if result.itemProvider.hasItemConformingToTypeIdentifier(UTType.image.identifier) {
result.itemProvider.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) { (item, error) in
guard let url = item as? URL else { return }
@@ -50,7 +60,7 @@ struct MediaPicker: UIViewControllerRepresentable {
do {
try imageData.write(to: destinationURL)
Task {
- await self.chooseMedia(.processed_image(destinationURL))
+ await self.chooseMedia(.processed_image(destinationURL), orderId: orderId)
}
}
catch {
@@ -64,13 +74,13 @@ struct MediaPicker: UIViewControllerRepresentable {
url: url,
fallback: processImage,
unprocessedEnum: {.unprocessed_image($0)},
- processedEnum: {.processed_image($0)}
- )
+ processedEnum: {.processed_image($0)},
+ orderId: orderId)
} else {
// Media was taken from camera
result.itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in
if let image = image as? UIImage, error == nil {
- self.chooseMedia(.uiimage(image))
+ self.chooseMedia(.uiimage(image), orderId: orderId)
}
}
}
@@ -83,35 +93,48 @@ struct MediaPicker: UIViewControllerRepresentable {
url: url,
fallback: processVideo,
unprocessedEnum: {.unprocessed_video($0)},
- processedEnum: {.processed_video($0)}
+ processedEnum: {.processed_video($0)}, orderId: orderId
)
}
}
}
+
+ dispatchGroup.notify(queue: .main) { [weak self] in
+ guard let self = self else { return }
+ var arrMedia: [PreUploadedMedia] = []
+ for id in self.orderIds {
+ if let media = self.orderMap[id] {
+ arrMedia.append(media)
+ self.parent.onMediaPicked(media)
+ }
+ }
+ }
}
- private func chooseMedia(_ media: PreUploadedMedia) {
- self.parent.onMediaPicked(media)
+
+ private func chooseMedia(_ media: PreUploadedMedia, orderId: String) {
self.parent.image_upload_confirm = true
+ self.orderMap[orderId] = media
+ self.dispatchGroup.leave()
}
- private func attemptAcquireResourceAndChooseMedia(url: URL, fallback: (URL) -> URL?, unprocessedEnum: (URL) -> PreUploadedMedia, processedEnum: (URL) -> PreUploadedMedia) {
+ private func attemptAcquireResourceAndChooseMedia(url: URL, fallback: (URL) -> URL?, unprocessedEnum: (URL) -> PreUploadedMedia, processedEnum: (URL) -> PreUploadedMedia, orderId: String) {
if url.startAccessingSecurityScopedResource() {
// Have permission from system to use url out of scope
print("Acquired permission to security scoped resource")
- self.chooseMedia(unprocessedEnum(url))
+ self.chooseMedia(unprocessedEnum(url), orderId: orderId)
} else {
// Need to copy URL to non-security scoped location
guard let newUrl = fallback(url) else { return }
- self.chooseMedia(processedEnum(newUrl))
+ self.chooseMedia(processedEnum(newUrl), orderId: orderId)
}
}
}
func makeCoordinator() -> Coordinator {
- Coordinator(self)
- }
+ Coordinator(self)
+ }
func makeUIViewController(context: Context) -> PHPickerViewController {
var configuration = PHPickerConfiguration(photoLibrary: .shared())