damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit 2be83560bcfd6272813df95a16f00c7329b9849b
parent 4c0c8b6678247bc53c0c99f275bf232c832e2a14
Author: kernelkind <kernelkind@gmail.com>
Date:   Mon, 19 Feb 2024 15:53:57 -0500

refactor: rename ImagePicker -> MediaPicker

The responsibility of MediaPicker is to 'pick' all sorts of media, not
just images.

Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mdamus.xcodeproj/project.pbxproj | 8++++----
Ddamus/Views/ImagePicker.swift | 131-------------------------------------------------------------------------------
Adamus/Views/MediaPicker.swift | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdamus/Views/PostView.swift | 2+-
Mdamus/Views/Profile/EditPictureControl.swift | 4++--
5 files changed, 138 insertions(+), 138 deletions(-)

diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj @@ -640,7 +640,7 @@ F71694F22A67314D001F4053 /* SuggestedUserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71694F12A67314D001F4053 /* SuggestedUserView.swift */; }; F71694F42A6732B7001F4053 /* GradientFollowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71694F32A6732B7001F4053 /* GradientFollowButton.swift */; }; F71694F82A6983AF001F4053 /* GrayGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71694F72A6983AF001F4053 /* GrayGradient.swift */; }; - F757933A29D7AECD007DEAC1 /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = F757933929D7AECD007DEAC1 /* ImagePicker.swift */; }; + F757933A29D7AECD007DEAC1 /* MediaPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = F757933929D7AECD007DEAC1 /* MediaPicker.swift */; }; F75BA12D29A1855400E10810 /* BookmarksManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75BA12C29A1855400E10810 /* BookmarksManager.swift */; }; F75BA12F29A18EF500E10810 /* BookmarksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75BA12E29A18EF500E10810 /* BookmarksView.swift */; }; F7908E92298B0F0700AB113A /* RelayDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7908E91298B0F0700AB113A /* RelayDetailView.swift */; }; @@ -1419,7 +1419,7 @@ F71694F12A67314D001F4053 /* SuggestedUserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestedUserView.swift; sourceTree = "<group>"; }; F71694F32A6732B7001F4053 /* GradientFollowButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientFollowButton.swift; sourceTree = "<group>"; }; F71694F72A6983AF001F4053 /* GrayGradient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GrayGradient.swift; sourceTree = "<group>"; }; - F757933929D7AECD007DEAC1 /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = "<group>"; }; + F757933929D7AECD007DEAC1 /* MediaPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPicker.swift; sourceTree = "<group>"; }; F75BA12C29A1855400E10810 /* BookmarksManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksManager.swift; sourceTree = "<group>"; }; F75BA12E29A18EF500E10810 /* BookmarksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksView.swift; sourceTree = "<group>"; }; F7908E91298B0F0700AB113A /* RelayDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayDetailView.swift; sourceTree = "<group>"; }; @@ -1991,7 +1991,7 @@ 4C75EFAC28049CFB0006080F /* PostButton.swift */, 4C75EFA327FA577B0006080F /* PostView.swift */, 9CA876E129A00CE90003B9A3 /* AttachMediaUtility.swift */, - F757933929D7AECD007DEAC1 /* ImagePicker.swift */, + F757933929D7AECD007DEAC1 /* MediaPicker.swift */, 9C83F89229A937B900136C08 /* TextViewWrapper.swift */, 4C3AC7A42836987600E1F516 /* MainTabView.swift */, 4C363A8B28236B92006E126D /* PubkeyView.swift */, @@ -3028,7 +3028,7 @@ 4C190F202A535FC200027FD5 /* CustomizeZapModel.swift in Sources */, D798D22C2B086C7400234419 /* NostrEvent+.swift in Sources */, 4C75EFB728049D990006080F /* RelayPool.swift in Sources */, - F757933A29D7AECD007DEAC1 /* ImagePicker.swift in Sources */, + F757933A29D7AECD007DEAC1 /* MediaPicker.swift in Sources */, 4CF0ABEE29844B5500D66079 /* AnyEncodable.swift in Sources */, B57B4C662B312C3700A232C0 /* NostrAuth.swift in Sources */, 4CB8838D296F710400DC99E7 /* Reposted.swift in Sources */, diff --git a/damus/Views/ImagePicker.swift b/damus/Views/ImagePicker.swift @@ -1,131 +0,0 @@ -// -// ImagePicker.swift -// damus -// -// Created by Swift on 3/31/23. -// - -import UIKit -import SwiftUI -import PhotosUI - -struct ImagePicker: UIViewControllerRepresentable { - - @Environment(\.presentationMode) - @Binding private var presentationMode - - @Binding var image_upload_confirm: Bool - var imagesOnly: Bool = false - let onMediaPicked: (MediaUpload) -> Void - - final class Coordinator: NSObject, PHPickerViewControllerDelegate { - let parent: ImagePicker - - init(_ parent: ImagePicker) { - self.parent = parent - } - - func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { - if results.isEmpty { - self.parent.presentationMode.dismiss() - } - - for result in results { - if result.itemProvider.hasItemConformingToTypeIdentifier(UTType.image.identifier) { - result.itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in - guard let image = image as? UIImage, error == nil else { return } - let fixedImage = image.fixOrientation() - - if let savedURL = self.saveImageToTemporaryFolder(image: fixedImage), - removeGPSDataFromImage(fromImageURL: savedURL) { - self.parent.onMediaPicked(.image(savedURL)) - self.parent.image_upload_confirm = true - } - } - } else if result.itemProvider.hasItemConformingToTypeIdentifier(UTType.movie.identifier) { - result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { (url, error) in - guard let url, error == nil else { return } - - guard let url = self.saveVideoToTemporaryFolder(videoURL: url) else { return } - self.parent.onMediaPicked(.video(url)) - self.parent.image_upload_confirm = true - } - } - } - } - - func saveImageToTemporaryFolder(image: UIImage, imageType: String = "png") -> URL? { - // Convert UIImage to Data - let imageData: Data? - if imageType.lowercased() == "jpeg" { - imageData = image.jpegData(compressionQuality: 1.0) - } else { - imageData = image.pngData() - } - - guard let data = imageData else { - print("Failed to convert UIImage to Data.") - return nil - } - - // Generate a temporary URL with a unique filename - let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) - let uniqueImageName = "\(UUID().uuidString).\(imageType)" - let temporaryImageURL = temporaryDirectoryURL.appendingPathComponent(uniqueImageName) - - // Save the image data to the temporary URL - do { - try data.write(to: temporaryImageURL) - return temporaryImageURL - } catch { - print("Error saving image data to temporary URL: \(error.localizedDescription)") - return nil - } - } - - func saveVideoToTemporaryFolder(videoURL: URL) -> URL? { - let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) - let fileExtension = videoURL.pathExtension - let uniqueFileName = UUID().uuidString + (fileExtension.isEmpty ? "" : ".\(fileExtension)") - let destinationURL = temporaryDirectoryURL.appendingPathComponent(uniqueFileName) - - do { - try FileManager.default.copyItem(at: videoURL, to: destinationURL) - return destinationURL - } catch { - print("Error copying file: \(error.localizedDescription)") - return nil - } - } - } - - func makeCoordinator() -> Coordinator { - Coordinator(self) - } - - func makeUIViewController(context: Context) -> PHPickerViewController { - var configuration = PHPickerConfiguration(photoLibrary: .shared()) - configuration.selectionLimit = 1 - configuration.filter = imagesOnly ? .images : .any(of: [.images, .videos]) - - let picker = PHPickerViewController(configuration: configuration) - picker.delegate = context.coordinator as any PHPickerViewControllerDelegate - return picker - } - - func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) { - } -} - -extension UIImage { - func fixOrientation() -> UIImage { - guard imageOrientation != .up else { return self } - - UIGraphicsBeginImageContextWithOptions(size, false, scale) - draw(in: CGRect(origin: .zero, size: size)) - let normalizedImage = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() - - return normalizedImage ?? self - } -} diff --git a/damus/Views/MediaPicker.swift b/damus/Views/MediaPicker.swift @@ -0,0 +1,131 @@ +// +// ImagePicker.swift +// damus +// +// Created by Swift on 3/31/23. +// + +import UIKit +import SwiftUI +import PhotosUI + +struct MediaPicker: UIViewControllerRepresentable { + + @Environment(\.presentationMode) + @Binding private var presentationMode + + @Binding var image_upload_confirm: Bool + var imagesOnly: Bool = false + let onMediaPicked: (MediaUpload) -> Void + + final class Coordinator: NSObject, PHPickerViewControllerDelegate { + let parent: MediaPicker + + init(_ parent: MediaPicker) { + self.parent = parent + } + + func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { + if results.isEmpty { + self.parent.presentationMode.dismiss() + } + + for result in results { + if result.itemProvider.hasItemConformingToTypeIdentifier(UTType.image.identifier) { + result.itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in + guard let image = image as? UIImage, error == nil else { return } + let fixedImage = image.fixOrientation() + + if let savedURL = self.saveImageToTemporaryFolder(image: fixedImage), + removeGPSDataFromImage(fromImageURL: savedURL) { + self.parent.onMediaPicked(.image(savedURL)) + self.parent.image_upload_confirm = true + } + } + } else if result.itemProvider.hasItemConformingToTypeIdentifier(UTType.movie.identifier) { + result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { (url, error) in + guard let url, error == nil else { return } + + guard let url = self.saveVideoToTemporaryFolder(videoURL: url) else { return } + self.parent.onMediaPicked(.video(url)) + self.parent.image_upload_confirm = true + } + } + } + } + + func saveImageToTemporaryFolder(image: UIImage, imageType: String = "png") -> URL? { + // Convert UIImage to Data + let imageData: Data? + if imageType.lowercased() == "jpeg" { + imageData = image.jpegData(compressionQuality: 1.0) + } else { + imageData = image.pngData() + } + + guard let data = imageData else { + print("Failed to convert UIImage to Data.") + return nil + } + + // Generate a temporary URL with a unique filename + let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) + let uniqueImageName = "\(UUID().uuidString).\(imageType)" + let temporaryImageURL = temporaryDirectoryURL.appendingPathComponent(uniqueImageName) + + // Save the image data to the temporary URL + do { + try data.write(to: temporaryImageURL) + return temporaryImageURL + } catch { + print("Error saving image data to temporary URL: \(error.localizedDescription)") + return nil + } + } + + func saveVideoToTemporaryFolder(videoURL: URL) -> URL? { + let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) + let fileExtension = videoURL.pathExtension + let uniqueFileName = UUID().uuidString + (fileExtension.isEmpty ? "" : ".\(fileExtension)") + let destinationURL = temporaryDirectoryURL.appendingPathComponent(uniqueFileName) + + do { + try FileManager.default.copyItem(at: videoURL, to: destinationURL) + return destinationURL + } catch { + print("Error copying file: \(error.localizedDescription)") + return nil + } + } + } + + func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + func makeUIViewController(context: Context) -> PHPickerViewController { + var configuration = PHPickerConfiguration(photoLibrary: .shared()) + configuration.selectionLimit = 1 + configuration.filter = imagesOnly ? .images : .any(of: [.images, .videos]) + + let picker = PHPickerViewController(configuration: configuration) + picker.delegate = context.coordinator as any PHPickerViewControllerDelegate + return picker + } + + func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) { + } +} + +extension UIImage { + func fixOrientation() -> UIImage { + guard imageOrientation != .up else { return self } + + UIGraphicsBeginImageContextWithOptions(size, false, scale) + draw(in: CGRect(origin: .zero, size: size)) + let normalizedImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return normalizedImage ?? self + } +} diff --git a/damus/Views/PostView.swift b/damus/Views/PostView.swift @@ -420,7 +420,7 @@ struct PostView: View { } .background(DamusColors.adaptableWhite.edgesIgnoringSafeArea(.all)) .sheet(isPresented: $attach_media) { - ImagePicker(image_upload_confirm: $image_upload_confirm) { media in + MediaPicker(image_upload_confirm: $image_upload_confirm) { media in self.mediaToUpload = media } .alert(NSLocalizedString("Are you sure you want to upload this media?", comment: "Alert message asking if the user wants to upload media."), isPresented: $image_upload_confirm) { diff --git a/damus/Views/Profile/EditPictureControl.swift b/damus/Views/Profile/EditPictureControl.swift @@ -61,7 +61,7 @@ struct EditPictureControl: View { } .sheet(isPresented: $show_camera) { - ImagePicker(image_upload_confirm: $image_upload_confirm, imagesOnly: true) { media in + MediaPicker(image_upload_confirm: $image_upload_confirm, imagesOnly: true) { media in self.mediaToUpload = media } .alert(NSLocalizedString("Are you sure you want to upload this image?", comment: "Alert message asking if the user wants to upload an image."), isPresented: $image_upload_confirm) { @@ -75,7 +75,7 @@ struct EditPictureControl: View { } } .sheet(isPresented: $show_library) { - ImagePicker(image_upload_confirm: $image_upload_confirm, imagesOnly: true) { media in + MediaPicker(image_upload_confirm: $image_upload_confirm, imagesOnly: true) { media in if case .image = media { self.mediaToUpload = media } else {