wip
This commit is contained in:
parent
ce85b7dff9
commit
f60c14cc74
|
@ -1,110 +0,0 @@
|
||||||
// import AVFoundation
|
|
||||||
// import Photos
|
|
||||||
// import SwiftUI
|
|
||||||
// import UIKit
|
|
||||||
//
|
|
||||||
// class MediaManager: NSObject, ObservableObject {
|
|
||||||
// // @Published var photos: [UIImage] = []
|
|
||||||
// @Published var cameraFeed: UIImage?
|
|
||||||
//
|
|
||||||
// // @Published var galleryAccessLevel: PHAuthorizationStatus = .notDetermined
|
|
||||||
// @Published var cameraAccessLevel: AVAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: .video)
|
|
||||||
//
|
|
||||||
// override init() {
|
|
||||||
// super.init()
|
|
||||||
// NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
|
|
||||||
//
|
|
||||||
// // DispatchQueue.main.async { [weak self] in
|
|
||||||
// // // self?.fetchPhotos()
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // private func fetchPhotos() {
|
|
||||||
// // galleryAccessLevel = PHPhotoLibrary.authorizationStatus()
|
|
||||||
// //
|
|
||||||
// // let fetchOptions = PHFetchOptions()
|
|
||||||
// // fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
|
|
||||||
// // let assets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
|
|
||||||
// //
|
|
||||||
// // let manager = PHImageManager.default()
|
|
||||||
// // let option = PHImageRequestOptions()
|
|
||||||
// // option.isSynchronous = true
|
|
||||||
// //
|
|
||||||
// // assets.enumerateObjects { asset, _, _ in
|
|
||||||
// // manager.requestImage(for: asset, targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: option) { image, _ in
|
|
||||||
// // if let image = image {
|
|
||||||
// // DispatchQueue.main.async {
|
|
||||||
// // self.photos.append(image)
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
//
|
|
||||||
// private func setupCameraFeed() {
|
|
||||||
// cameraAccessLevel = AVCaptureDevice.authorizationStatus(for: .video)
|
|
||||||
//
|
|
||||||
// let captureSession = AVCaptureSession()
|
|
||||||
// captureSession.sessionPreset = .medium
|
|
||||||
//
|
|
||||||
// guard let backCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) else {
|
|
||||||
// print("Unable to access the back camera!")
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// do {
|
|
||||||
// let input = try AVCaptureDeviceInput(device: backCamera)
|
|
||||||
// if captureSession.canAddInput(input) {
|
|
||||||
// captureSession.addInput(input)
|
|
||||||
// }
|
|
||||||
// } catch {
|
|
||||||
// print("Error Unable to initialize back camera: \(error.localizedDescription)")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let videoOutput = AVCaptureVideoDataOutput()
|
|
||||||
// videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
|
|
||||||
// if captureSession.canAddOutput(videoOutput) {
|
|
||||||
// captureSession.addOutput(videoOutput)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// captureSession.startRunning()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// extension MediaManager: AVCaptureVideoDataOutputSampleBufferDelegate {
|
|
||||||
// func captureOutput(_: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from _: AVCaptureConnection) {
|
|
||||||
// print("Capturing output started")
|
|
||||||
// guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
|
|
||||||
// let context = CIContext()
|
|
||||||
// guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// DispatchQueue.main.async {
|
|
||||||
// self.cameraFeed = UIImage(cgImage: cgImage)
|
|
||||||
// print("Updated camera feed")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// extension MediaManager {
|
|
||||||
// func openAppSettings() {
|
|
||||||
// if
|
|
||||||
// let appSettingsUrl = URL(string: UIApplication.openSettingsURLString),
|
|
||||||
// UIApplication.shared.canOpenURL(appSettingsUrl)
|
|
||||||
// {
|
|
||||||
// UIApplication.shared.open(appSettingsUrl, completionHandler: nil)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @objc private func appDidBecomeActive() {
|
|
||||||
// // Update access levels
|
|
||||||
// // galleryAccessLevel = PHPhotoLibrary.authorizationStatus()
|
|
||||||
// cameraAccessLevel = AVCaptureDevice.authorizationStatus(for: .video)
|
|
||||||
// setupCameraFeed()
|
|
||||||
// }
|
|
||||||
// }
|
|
|
@ -4,9 +4,9 @@ import SwiftUI
|
||||||
|
|
||||||
struct AttachmentMediaPickerView: View {
|
struct AttachmentMediaPickerView: View {
|
||||||
@State private var isCameraAccessGranted = AVCaptureDevice.authorizationStatus(for: .video) == .authorized
|
@State private var isCameraAccessGranted = AVCaptureDevice.authorizationStatus(for: .video) == .authorized
|
||||||
|
|
||||||
@State private var isGalleryAccessGranted = PHPhotoLibrary.authorizationStatus() == .authorized
|
@State private var isGalleryAccessGranted = PHPhotoLibrary.authorizationStatus() == .authorized
|
||||||
@State private var images = [UIImage]()
|
|
||||||
|
@State private var photos = [PhotoView]()
|
||||||
|
|
||||||
let gridSize = UIScreen.main.bounds.width / 3
|
let gridSize = UIScreen.main.bounds.width / 3
|
||||||
|
|
||||||
|
@ -55,12 +55,8 @@ struct AttachmentMediaPickerView: View {
|
||||||
|
|
||||||
// For pictures
|
// For pictures
|
||||||
if isGalleryAccessGranted {
|
if isGalleryAccessGranted {
|
||||||
ForEach(images.indices, id: \.self) { index in
|
ForEach(photos) { photo in
|
||||||
Image(uiImage: images[index])
|
photo
|
||||||
.resizable()
|
|
||||||
.aspectRatio(1, contentMode: .fit)
|
|
||||||
.frame(maxWidth: .infinity)
|
|
||||||
.clipped()
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Button {
|
Button {
|
||||||
|
@ -86,8 +82,10 @@ struct AttachmentMediaPickerView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
checkCameraAccess()
|
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 0.2) {
|
||||||
checkGalleryAccess()
|
checkCameraAccess()
|
||||||
|
checkGalleryAccess()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,13 +151,13 @@ struct AttachmentMediaPickerView: View {
|
||||||
contentMode: .aspectFill,
|
contentMode: .aspectFill,
|
||||||
options: option
|
options: option
|
||||||
) { image, _ in
|
) { image, _ in
|
||||||
if let image = image {
|
image?.scaleAndCropImage(toExampleSize: CGSize(width: gridSize, height: gridSize), completion: { image in
|
||||||
DispatchQueue.main.async {
|
if let image {
|
||||||
if let img = scaleAndCropImage(image, toSize: CGSize(width: gridSize, height: gridSize)) {
|
DispatchQueue.main.async {
|
||||||
self.images.append(img)
|
self.photos.append(PhotoView(image: image, gridSize: gridSize))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,17 +170,45 @@ struct AttachmentMediaPickerView: View {
|
||||||
UIApplication.shared.open(appSettingsUrl, completionHandler: nil)
|
UIApplication.shared.open(appSettingsUrl, completionHandler: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func scaleAndCropImage(_ image: UIImage, toSize size: CGSize) -> UIImage? {
|
private struct PhotoView: Identifiable, View {
|
||||||
let imageView = UIImageView(frame: CGRect(origin: .zero, size: size))
|
let id = UUID()
|
||||||
imageView.contentMode = .scaleAspectFill
|
let gridSize: CGFloat
|
||||||
imageView.image = image
|
|
||||||
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
|
@State private var image: UIImage
|
||||||
guard let context = UIGraphicsGetCurrentContext() else { return nil }
|
@State private var ready = false
|
||||||
imageView.layer.render(in: context)
|
|
||||||
let result = UIGraphicsGetImageFromCurrentImageContext()
|
init(image: UIImage, gridSize: CGFloat) {
|
||||||
UIGraphicsEndImageContext()
|
self.image = image
|
||||||
return result
|
self.gridSize = gridSize
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
if ready {
|
||||||
|
Image(uiImage: image)
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fill)
|
||||||
|
.frame(width: gridSize, height: gridSize)
|
||||||
|
.clipped()
|
||||||
|
} else {
|
||||||
|
ZStack {
|
||||||
|
Rectangle()
|
||||||
|
.fill(Color.Main.backgroundLight)
|
||||||
|
.overlay {
|
||||||
|
ProgressView()
|
||||||
|
}
|
||||||
|
.frame(width: gridSize, height: gridSize)
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
image.scaleAndCropImage(toExampleSize: CGSize(width: gridSize, height: gridSize), completion: { image in
|
||||||
|
if let image {
|
||||||
|
self.image = image
|
||||||
|
ready = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,147 +241,6 @@ struct CameraView: UIViewRepresentable {
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUIView(_ uiView: CameraUIView, context _: Context) {
|
func updateUIView(_ uiView: CameraUIView, context _: Context) {
|
||||||
// Update the previewLayer frame when the view updates
|
|
||||||
uiView.previewLayer?.frame = uiView.bounds
|
uiView.previewLayer?.frame = uiView.bounds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct AttachmentMediaPickerView: View {
|
|
||||||
// @StateObject private var mediaManager = MediaManager()
|
|
||||||
//
|
|
||||||
// var body: some View {
|
|
||||||
// ScrollView {
|
|
||||||
// LazyVGrid(columns: Array(repeating: .init(.flexible()), count: 3)) {
|
|
||||||
// ForEach(elements) { element in
|
|
||||||
// element
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// .padding(.horizontal, 8)
|
|
||||||
// }
|
|
||||||
// .padding(.vertical, 8)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private var elements: [GridElement] {
|
|
||||||
// print("Creating elements")
|
|
||||||
// var result: [GridElement] = []
|
|
||||||
//
|
|
||||||
// // camera
|
|
||||||
// if let feed = mediaManager.cameraFeed, mediaManager.cameraAccessLevel == .authorized {
|
|
||||||
// result.append(GridElement(id: UUID(), type: .cameraFeed, content: feed) {
|
|
||||||
// print("Go to capture???")
|
|
||||||
// })
|
|
||||||
// print("Added camera feed")
|
|
||||||
// } else if mediaManager.cameraAccessLevel == .restricted {
|
|
||||||
// result.append(GridElement(id: UUID(), type: .cameraRestricted, content: nil) {
|
|
||||||
// print("Show alert")
|
|
||||||
// })
|
|
||||||
// print("Added camera restricted")
|
|
||||||
// } else {
|
|
||||||
// result.append(GridElement(id: UUID(), type: .cameraAskButton, content: nil) {
|
|
||||||
// mediaManager.openAppSettings()
|
|
||||||
// })
|
|
||||||
// print("Added camera ask button")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // photos
|
|
||||||
// // if mediaManager.galleryAccessLevel == .restricted {
|
|
||||||
// // result.append(GridElement(id: UUID(), type: .photoRestricted, content: nil))
|
|
||||||
// // } else {
|
|
||||||
// // for photo in mediaManager.photos {
|
|
||||||
// // result.append(GridElement(id: UUID(), type: .photo, content: photo))
|
|
||||||
// // }
|
|
||||||
// // if mediaManager.galleryAccessLevel != .authorized {
|
|
||||||
// // result.append(GridElement(id: UUID(), type: .photoAskButton, content: nil))
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
//
|
|
||||||
// return result
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private enum GridElementType {
|
|
||||||
// case cameraFeed
|
|
||||||
// case cameraAskButton
|
|
||||||
// case cameraRestricted
|
|
||||||
// case photo
|
|
||||||
// case photoAskButton
|
|
||||||
// case photoRestricted
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private struct GridElement: View, Identifiable {
|
|
||||||
// let id: UUID
|
|
||||||
// let type: GridElementType
|
|
||||||
// let content: UIImage?
|
|
||||||
// let action: () -> Void
|
|
||||||
//
|
|
||||||
// var body: some View {
|
|
||||||
// switch type {
|
|
||||||
// case .cameraFeed:
|
|
||||||
// image
|
|
||||||
// .resizable()
|
|
||||||
// .aspectRatio(contentMode: .fill)
|
|
||||||
// .frame(width: 100, height: 100)
|
|
||||||
// .clipped()
|
|
||||||
//
|
|
||||||
// case .cameraAskButton:
|
|
||||||
// Button {
|
|
||||||
// action()
|
|
||||||
// } label: {
|
|
||||||
// RoundedRectangle(cornerRadius: 5)
|
|
||||||
// .stroke(Color.Main.backgroundDark, lineWidth: 2)
|
|
||||||
// .overlay {
|
|
||||||
// Image(systemName: "camera")
|
|
||||||
// .foregroundColor(.Material.tortoiseLight300)
|
|
||||||
// .font(.system(size: 40))
|
|
||||||
// }
|
|
||||||
// .frame(height: 100)
|
|
||||||
// // .resizable()
|
|
||||||
// // .aspectRatio(contentMode: .fill)
|
|
||||||
// // .frame(width: 100, height: 100)
|
|
||||||
// // .clipped()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// case .photo:
|
|
||||||
// image
|
|
||||||
// .resizable()
|
|
||||||
// .aspectRatio(contentMode: .fill)
|
|
||||||
// .frame(width: 100, height: 100)
|
|
||||||
// .clipped()
|
|
||||||
//
|
|
||||||
// case .photoAskButton:
|
|
||||||
// Button {
|
|
||||||
// action()
|
|
||||||
// } label: {
|
|
||||||
// Image(systemName: "photo.badge.plus")
|
|
||||||
// .resizable()
|
|
||||||
// .aspectRatio(contentMode: .fill)
|
|
||||||
// .frame(width: 100, height: 100)
|
|
||||||
// .clipped()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// case .photoRestricted, .cameraRestricted:
|
|
||||||
// Button {
|
|
||||||
// action()
|
|
||||||
// } label: {
|
|
||||||
// Image(systemName: "cross")
|
|
||||||
// .resizable()
|
|
||||||
// .aspectRatio(contentMode: .fill)
|
|
||||||
// .frame(width: 100, height: 100)
|
|
||||||
// .clipped()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private var image: Image {
|
|
||||||
// guard let content = content else {
|
|
||||||
// return Image(systemName: "questionmark.square.dashed")
|
|
||||||
// }
|
|
||||||
// return Image(uiImage: content)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// struct AttachmentMediaPickerView_Previews: PreviewProvider {
|
|
||||||
// static var previews: some View {
|
|
||||||
// AttachmentMediaPickerView()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
44
ConversationsClassic/View/UIToolkit/UIImage+Crop.swift
Normal file
44
ConversationsClassic/View/UIToolkit/UIImage+Crop.swift
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension UIImage {
|
||||||
|
func scaleAndCropImage(toExampleSize _: CGSize, completion: @escaping (UIImage?) -> Void) {
|
||||||
|
DispatchQueue.global(qos: .background).async {
|
||||||
|
guard let cgImage = self.cgImage else {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
completion(nil)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let contextImage: UIImage = .init(cgImage: cgImage)
|
||||||
|
var contextSize: CGSize = contextImage.size
|
||||||
|
|
||||||
|
var posX: CGFloat = 0.0
|
||||||
|
var posY: CGFloat = 0.0
|
||||||
|
let cgwidth: CGFloat = self.size.width
|
||||||
|
let cgheight: CGFloat = self.size.height
|
||||||
|
|
||||||
|
// Check and handle if the image is wider than the requested size
|
||||||
|
if contextSize.width > contextSize.height {
|
||||||
|
posX = ((contextSize.width - contextSize.height) / 2)
|
||||||
|
contextSize.width = contextSize.height
|
||||||
|
} else if contextSize.width < contextSize.height {
|
||||||
|
// Check and handle if the image is taller than the requested size
|
||||||
|
posY = ((contextSize.height - contextSize.width) / 2)
|
||||||
|
contextSize.height = contextSize.width
|
||||||
|
}
|
||||||
|
|
||||||
|
let rect: CGRect = .init(x: posX, y: posY, width: cgwidth, height: cgheight)
|
||||||
|
guard let contextCg = contextImage.cgImage, let imgRef = contextCg.cropping(to: rect) else {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
completion(nil)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let image: UIImage = .init(cgImage: imgRef, scale: self.scale, orientation: self.imageOrientation)
|
||||||
|
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
completion(image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue