From ec7b075b35553bf9c4ef17877bc8bc4be7a4a8c8 Mon Sep 17 00:00:00 2001 From: fmodf Date: Wed, 10 Jul 2024 20:13:17 +0200 Subject: [PATCH] wip --- .../Middlewares/SharingMiddleware.swift | 197 ------------------ .../AttachmentMediaPickerView.swift | 112 +++++----- 2 files changed, 58 insertions(+), 251 deletions(-) diff --git a/ConversationsClassic/AppCore/Middlewares/SharingMiddleware.swift b/ConversationsClassic/AppCore/Middlewares/SharingMiddleware.swift index 2ac71fe..b5cf5c1 100644 --- a/ConversationsClassic/AppCore/Middlewares/SharingMiddleware.swift +++ b/ConversationsClassic/AppCore/Middlewares/SharingMiddleware.swift @@ -20,9 +20,6 @@ final class SharingMiddleware { case .notDetermined: AVCaptureDevice.requestAccess(for: .video) { granted in promise(.success(.sharingAction(.setCameraAccess(granted)))) - // DispatchQueue.main.async { - // self.isCameraAccessGranted = granted - // } } case .denied, .restricted: @@ -44,12 +41,6 @@ final class SharingMiddleware { case .notDetermined: PHPhotoLibrary.requestAuthorization { status in promise(.success(.sharingAction(.setGalleryAccess(status == .authorized)))) - // DispatchQueue.main.async { - // self.isGalleryAccessGranted = status == .authorized - // if self.isGalleryAccessGranted { - // self.fetchGallery() - // } - // } } case .denied, .restricted: @@ -164,191 +155,3 @@ final class SharingMiddleware { } } } - -// private func fetchGallery() { -// let fetchOptions = PHFetchOptions() -// fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] -// let assets = PHAsset.fetchAssets(with: fetchOptions) -// -// let manager = PHImageManager.default() -// let option = PHImageRequestOptions() -// option.isSynchronous = true -// -// assets.enumerateObjects { asset, _, _ in -// if asset.mediaType == .image { -// manager.requestImage( -// for: asset, -// targetSize: PHImageManagerMaximumSize, -// contentMode: .aspectFill, -// options: option -// ) { image, _ in -// image?.scaleAndCropImage(toExampleSize: CGSize(width: gridSize, height: gridSize), completion: { image in -// if let image { -// DispatchQueue.main.async { -// self.thumbnails.append(ThumbnailView(id: asset.localIdentifier, image: image, gridSize: gridSize, selected: $selectedMedia)) -// } -// } -// }) -// } -// } 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.thumbnails.append(ThumbnailView(id: asset.localIdentifier, image: image, gridSize: gridSize, selected: $selectedMedia, duration: asset.duration.minAndSec)) -// } -// } -// }) -// } catch { -// print("Failed to create thumbnail image") -// } -// } -// } -// } -// } -// } - -// private func sendGalleryMedia(ids _: [String]) { -// var media: [AttachmentItem] = [] -// let dispatchGroup = DispatchGroup() -// -// let asset = PHAsset.fetchAssets(withLocalIdentifiers: ids, options: nil) -// asset.enumerateObjects { asset, _, _ in -// dispatchGroup.enter() -// if asset.mediaType == .image { -// let manager = PHImageManager.default() -// let option = PHImageRequestOptions() -// option.isSynchronous = true -// -// manager.requestImage( -// for: asset, -// targetSize: PHImageManagerMaximumSize, -// contentMode: .aspectFill, -// options: option -// ) { image, _ in -// if let image { -// let data = image.jpegData(compressionQuality: 1.0) ?? Data() -// media.append(.init(type: .image, data: data, string: "")) -// } -// dispatchGroup.leave() -// } -// } else if asset.mediaType == .video { -// let manager = PHImageManager.default() -// let option = PHVideoRequestOptions() -// option.version = .current -// option.deliveryMode = .highQualityFormat -// -// manager.requestAVAsset(forVideo: asset, options: option) { avAsset, _, _ in -// if let avAsset { -// let url = (avAsset as? AVURLAsset)?.url -// let data = try? Data(contentsOf: url ?? URL(fileURLWithPath: "")) -// media.append(.init(type: .movie, data: data ?? Data(), string: "")) -// } -// dispatchGroup.leave() -// } -// } -// } -// dispatchGroup.notify(queue: .main) { -// store.dispatch(.conversationAction(.sendAttachment(.init( -// id: UUID().uuidString, -// items: media -// )))) -// } -// } -// } -// -// private struct ThumbnailView: Identifiable, View { -// let id: String -// let gridSize: CGFloat -// let duration: String? -// -// @State private var image: UIImage -// @State private var ready = false -// @State private var selected = false -// @Binding var selectedMedia: [SelectedMedia] -// -// init(id: String, image: UIImage, gridSize: CGFloat, selected: Binding<[SelectedMedia]>, duration: String? = nil) { -// self.id = id -// self.image = image -// self.gridSize = gridSize -// _selectedMedia = selected -// self.duration = duration -// } -// -// var body: some View { -// if ready { -// ZStack { -// Image(uiImage: image) -// .resizable() -// .aspectRatio(contentMode: .fill) -// .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) -// } -// } -// } -// if selected { -// VStack { -// HStack { -// Spacer() -// Circle() -// .frame(width: 30, height: 30) -// .shadow(color: .black, radius: 2) -// .foregroundColor(.Material.Shape.white) -// .overlay { -// Image(systemName: "checkmark") -// .foregroundColor(.Material.Elements.active) -// .font(.body3) -// } -// .padding(4) -// } -// Spacer() -// } -// } -// } -// .onTapGesture { -// withAnimation { -// selected.toggle() -// if selected { -// selectedMedia.append(SelectedMedia(id: id)) -// } else { -// selectedMedia.removeAll { $0.id == id } -// } -// } -// } -// } else { -// ZStack { -// Rectangle() -// .fill(Color.Material.Background.light) -// .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 -// } -// }) -// } -// } -// } -// } diff --git a/ConversationsClassic/View/Screens/Attachments/AttachmentMediaPickerView.swift b/ConversationsClassic/View/Screens/Attachments/AttachmentMediaPickerView.swift index 565d813..02b983d 100644 --- a/ConversationsClassic/View/Screens/Attachments/AttachmentMediaPickerView.swift +++ b/ConversationsClassic/View/Screens/Attachments/AttachmentMediaPickerView.swift @@ -3,15 +3,12 @@ import MobileCoreServices import Photos import SwiftUI -struct SelectedMedia { - let id: String -} - struct AttachmentMediaPickerView: View { @EnvironmentObject var store: AppStore - - @State private var selectedMedia = [SelectedMedia]() @State private var showCameraPicker = false + @State private var cameraReady = false + + @State private var selectedItems: [String] = [] var body: some View { let columns = Array(repeating: GridItem(.flexible(), spacing: 0), count: 3) @@ -22,22 +19,33 @@ struct AttachmentMediaPickerView: View { LazyVGrid(columns: columns, spacing: 0) { // For camera if store.state.sharingState.isCameraAccessGranted { - ZStack { - CameraView() - .aspectRatio(1, contentMode: .fit) + if cameraReady { + ZStack { + CameraView() + .aspectRatio(1, contentMode: .fit) + .frame(maxWidth: .infinity) + Image(systemName: "camera") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 40, height: 40) + .foregroundColor(.white) + .padding(8) + .background(Color.black.opacity(0.5)) + .clipShape(Circle()) + .padding(8) + } + .onTapGesture { + showCameraPicker = true + } + } else { + ProgressView() .frame(maxWidth: .infinity) - Image(systemName: "camera") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 40, height: 40) - .foregroundColor(.white) - .padding(8) - .background(Color.black.opacity(0.5)) - .clipShape(Circle()) - .padding(8) - } - .onTapGesture { - showCameraPicker = true + .frame(height: 100) + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { + cameraReady = true + } + } } } else { Button { @@ -64,7 +72,7 @@ struct AttachmentMediaPickerView: View { // For gallery if store.state.sharingState.isGalleryAccessGranted { ForEach(store.state.sharingState.galleryItems) { item in - GridViewItem(item: item) + GridViewItem(item: item, selected: $selectedItems) } } else { Button { @@ -102,7 +110,7 @@ struct AttachmentMediaPickerView: View { Rectangle() .foregroundColor(.Material.Shape.black) .frame(maxWidth: .infinity) - .frame(height: self.selectedMedia.isEmpty ? 0 : 50) + .frame(height: self.selectedItems.isEmpty ? 0 : 50) .overlay { HStack { Text(L10n.Attachment.Send.media) @@ -117,7 +125,7 @@ struct AttachmentMediaPickerView: View { } .clipped() .onTapGesture { - let ids = selectedMedia.map { $0.id } + // let ids = selectedMedia.map { $0.id } // sendGalleryMedia(ids: ids) store.dispatch(.sharingAction(.showSharing(false))) } @@ -125,10 +133,6 @@ struct AttachmentMediaPickerView: View { .onAppear { store.dispatch(.sharingAction(.checkCameraAccess)) store.dispatch(.sharingAction(.checkGalleryAccess)) - // DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 0.2) { - // checkCameraAccess() - // checkGalleryAccess() - // } } .onChange(of: store.state.sharingState.isGalleryAccessGranted) { granted in if granted { @@ -140,6 +144,8 @@ struct AttachmentMediaPickerView: View { private struct GridViewItem: View { let item: SharingGalleryItem + @Binding var selected: [String] + @State var isSelected = false var body: some View { if let data = item.thumbnail { @@ -162,34 +168,32 @@ private struct GridViewItem: View { } } } - // if selected { - // VStack { - // HStack { - // Spacer() - // Circle() - // .frame(width: 30, height: 30) - // .shadow(color: .black, radius: 2) - // .foregroundColor(.Material.Shape.white) - // .overlay { - // Image(systemName: "checkmark") - // .foregroundColor(.Material.Elements.active) - // .font(.body3) - // } - // .padding(4) - // } - // Spacer() - // } - // } + if isSelected { + VStack { + HStack { + Spacer() + Circle() + .frame(width: 30, height: 30) + .shadow(color: .black, radius: 2) + .foregroundColor(.Material.Shape.white) + .overlay { + Image(systemName: "checkmark") + .foregroundColor(.Material.Elements.active) + .font(.body3) + } + .padding(4) + } + Spacer() + } + } } .onTapGesture { - // withAnimation { - // selected.toggle() - // if selected { - // selectedMedia.append(SelectedMedia(id: id)) - // } else { - // selectedMedia.removeAll { $0.id == id } - // } - // } + isSelected.toggle() + if isSelected { + selected.removeAll { $0 == item.id } + } else { + selected.append(item.id) + } } } else { ZStack {