From bb502ba79a53c0cb545cda176552bff154d72772 Mon Sep 17 00:00:00 2001 From: fmodf Date: Sun, 14 Jul 2024 15:00:14 +0200 Subject: [PATCH] wip --- .../AppCore/Actions/FileActions.swift | 2 + .../AppCore/Middlewares/FileMiddleware.swift | 8 ++ .../Middlewares/SharingMiddleware.swift | 77 +++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/ConversationsClassic/AppCore/Actions/FileActions.swift b/ConversationsClassic/AppCore/Actions/FileActions.swift index 5e44717..84b1682 100644 --- a/ConversationsClassic/AppCore/Actions/FileActions.swift +++ b/ConversationsClassic/AppCore/Actions/FileActions.swift @@ -7,4 +7,6 @@ enum FileAction: Stateable { case createAttachmentThumbnail(messageId: String, localName: String) case attachmentThumbnailCreated(messageId: String, thumbnailName: String) + + case copyFileForUploading(messageId: String, fileData: Data, thumbnailData: Data?) } diff --git a/ConversationsClassic/AppCore/Middlewares/FileMiddleware.swift b/ConversationsClassic/AppCore/Middlewares/FileMiddleware.swift index dcd5eab..39cc82e 100644 --- a/ConversationsClassic/AppCore/Middlewares/FileMiddleware.swift +++ b/ConversationsClassic/AppCore/Middlewares/FileMiddleware.swift @@ -62,6 +62,14 @@ final class FileMiddleware { } .eraseToAnyPublisher() + case .fileAction(.copyFileForUploading(let messageId, let data, let thumbnail)): + print("=====") + print("copyFileForUploading") + print(data.count) + print(thumbnail?.count) + print("=====") + return Empty().eraseToAnyPublisher() + default: return Empty().eraseToAnyPublisher() } diff --git a/ConversationsClassic/AppCore/Middlewares/SharingMiddleware.swift b/ConversationsClassic/AppCore/Middlewares/SharingMiddleware.swift index 312029f..fd11849 100644 --- a/ConversationsClassic/AppCore/Middlewares/SharingMiddleware.swift +++ b/ConversationsClassic/AppCore/Middlewares/SharingMiddleware.swift @@ -7,8 +7,10 @@ import UIKit final class SharingMiddleware { static let shared = SharingMiddleware() + // swiftlint:disable:next function_body_length func middleware(state: AppState, action: AppAction) -> AnyPublisher { switch action { + // MARK: - Camera and Gallery Access case .sharingAction(.checkCameraAccess): return Future { promise in let status = AVCaptureDevice.authorizationStatus(for: .video) @@ -114,6 +116,68 @@ final class SharingMiddleware { } return Empty().eraseToAnyPublisher() + // MARK: - Sharing + case .sharingAction(.shareMedia(let ids)): + return Future { promise in + let assets = PHAsset.fetchAssets(withLocalIdentifiers: ids, options: nil) + assets.enumerateObjects { asset, _, _ in + if asset.mediaType == .image { + PHImageManager.default().requestImage( + for: asset, + targetSize: PHImageManagerMaximumSize, + contentMode: .aspectFill, + options: nil + ) { image, _ in + if let data = image?.jpegData(compressionQuality: 1.0) { + DispatchQueue.main.async { + let newMessageId = UUID().uuidString + store.dispatch(.fileAction(.copyFileForUploading( + messageId: newMessageId, + fileData: data, + thumbnailData: store.state.sharingState.galleryItems.first(where: { $0.id == asset.localIdentifier })?.thumbnail + ))) + } + } + } + } else if asset.mediaType == .video { + let options = PHVideoRequestOptions() + options.version = .original + options.deliveryMode = .highQualityFormat + PHImageManager.default().requestAVAsset(forVideo: asset, options: options) { avAsset, _, _ in + guard let urlAsset = avAsset as? AVURLAsset else { return } + let exporter = AVAssetExportSession(asset: urlAsset, presetName: AVAssetExportPresetHighestQuality) + exporter?.outputFileType = .mp4 + let outputURL = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString + ".mp4") + exporter?.outputURL = outputURL + exporter?.exportAsynchronously { + switch exporter?.status { + case .completed: + if let data = try? Data(contentsOf: outputURL) { + DispatchQueue.main.async { + let newMessageId = UUID().uuidString + store.dispatch(.fileAction(.copyFileForUploading( + messageId: newMessageId, + fileData: data, + thumbnailData: nil + ))) + } + } + + default: + break + } + } + } + } + } + promise(.success(.empty)) + } + .eraseToAnyPublisher() + + case .sharingAction(.cameraCaptured(let media, let type)): + print("Camera captured: \(media.count)") + return Empty().eraseToAnyPublisher() + case .sharingAction(.shareLocation(let lat, let lon)): if let chat = state.conversationsState.currentChat { let msg = "geo:\(lat),\(lon)" @@ -123,6 +187,19 @@ final class SharingMiddleware { return Empty().eraseToAnyPublisher() } + case .sharingAction(.shareDocuments(let data)): + print("Sharing documents: \(data.count)") + return Empty().eraseToAnyPublisher() + + case .sharingAction(.shareContact(let jid)): + if let chat = state.conversationsState.currentChat { + let msg = "contact:\(jid)" + return Just(.conversationAction(.sendMessage(from: chat.account, to: chat.participant, body: msg))) + .eraseToAnyPublisher() + } else { + return Empty().eraseToAnyPublisher() + } + default: return Empty().eraseToAnyPublisher() }