This commit is contained in:
fmodf 2024-07-10 15:00:54 +02:00
parent 08f3b548a6
commit eb06abaebf
7 changed files with 123 additions and 86 deletions

View file

@ -7,7 +7,7 @@ enum ConversationAction: Codable {
case setReplyText(String) case setReplyText(String)
case showAttachmentPicker(Bool) case showAttachmentPicker(Bool)
case sendAttachment(Attachment) case sendAttachment([ShareItem])
case sendAttachmentDone case sendAttachmentDone
case sendAttachmentError(reason: String) case sendAttachmentError(reason: String)
} }

View file

@ -1,9 +1,6 @@
/* // This file declare global state object for whole app
In 99,99% of time YOU DON'T NEEDED TO CHANGE ANYTHING in this file! // and reducers/actions/middleware types. Core of app.
This file declare global state object for whole app
and reducers/actions/middleware types. Core of app.
*/
import Combine import Combine
import Foundation import Foundation

View file

@ -0,0 +1,10 @@
import Foundation
import SwiftUI
struct ShareItem: Stateable {
let id: String
let type: AttachmentType
let data: Data
let thumbnail: Data
let string: String
}

View file

@ -40,10 +40,13 @@ struct AttachmentContactsPickerView: View {
.clipped() .clipped()
.onTapGesture { .onTapGesture {
if let selectedContact = selectedContact { if let selectedContact = selectedContact {
let attachment = Attachment(id: UUID().uuidString, items: [ store.dispatch(.conversationAction(.sendAttachment([.init(
AttachmentItem(type: .contact, data: Data(), string: selectedContact.contactBareJid) id: UUID().uuidString,
]) type: .contact,
store.dispatch(.conversationAction(.sendAttachment(attachment))) data: Data(),
thumbnail: Data(),
string: selectedContact.contactBareJid
)])))
store.dispatch(.conversationAction(.showAttachmentPicker(false))) store.dispatch(.conversationAction(.showAttachmentPicker(false)))
} }
} }

View file

@ -2,12 +2,34 @@ import SwiftUI
import UIKit import UIKit
struct AttachmentFilesPickerView: View { struct AttachmentFilesPickerView: View {
@EnvironmentObject var store: AppStore
var body: some View { var body: some View {
DocumentPicker() DocumentPicker(
completion: { arr in
let sharedFiles = arr.map {
ShareItem(
id: UUID().uuidString,
type: .file,
data: $0,
thumbnail: Data(),
string: ""
)
}
store.dispatch(.conversationAction(.sendAttachment(sharedFiles)))
store.dispatch(.conversationAction(.showAttachmentPicker(false)))
},
cancel: {
store.dispatch(.conversationAction(.showAttachmentPicker(false)))
}
)
} }
} }
struct DocumentPicker: UIViewControllerRepresentable { struct DocumentPicker: UIViewControllerRepresentable {
let completion: ([Data]) -> Void
let cancel: () -> Void
func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentPicker>) -> UIDocumentPickerViewController { func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentPicker>) -> UIDocumentPickerViewController {
let picker: UIDocumentPickerViewController let picker: UIDocumentPickerViewController
picker = UIDocumentPickerViewController(forOpeningContentTypes: [.item], asCopy: true) picker = UIDocumentPickerViewController(forOpeningContentTypes: [.item], asCopy: true)
@ -35,7 +57,7 @@ struct DocumentPicker: UIViewControllerRepresentable {
} }
func documentPickerWasCancelled(_: UIDocumentPickerViewController) { func documentPickerWasCancelled(_: UIDocumentPickerViewController) {
// Handle cancellation parent.cancel()
} }
} }
} }

View file

@ -62,14 +62,13 @@ struct AttachmentLocationPickerView: View {
} }
.clipped() .clipped()
.onTapGesture { .onTapGesture {
let attachment = Attachment(id: UUID().uuidString, items: [ store.dispatch(.conversationAction(.sendAttachment([.init(
AttachmentItem( id: UUID().uuidString,
type: .location, type: .location,
data: Data(), data: Data(),
string: "\(region.center.latitude),\(region.center.longitude)" thumbnail: Data(),
) string: "\(region.center.latitude),\(region.center.longitude)"
]) )])))
store.dispatch(.conversationAction(.sendAttachment(attachment)))
store.dispatch(.conversationAction(.showAttachmentPicker(false))) store.dispatch(.conversationAction(.showAttachmentPicker(false)))
} }
} }

View file

@ -95,14 +95,19 @@ struct AttachmentMediaPickerView: View {
} }
} }
.fullScreenCover(isPresented: $showCameraPicker) { .fullScreenCover(isPresented: $showCameraPicker) {
CameraPicker(sourceType: .camera) { data, type in // TODO: fix it
store.dispatch(.conversationAction(.sendAttachment(.init( // CameraPicker(sourceType: .camera) { data, type in
id: UUID().uuidString, // store.dispatch(.conversationAction(.sendAttachment([.init(
items: [.init(type: type, data: data, string: "")] // id: UUID().uuidString,
)))) // type: type,
showCameraPicker = false // data: data,
} // thumbnail: Data(),
.edgesIgnoringSafeArea(.all) // string: ""
// )])))
// showCameraPicker = false
// store.dispatch(.conversationAction(.showAttachmentPicker(false)))
// }
// .edgesIgnoringSafeArea(.all)
} }
// Send panel // Send panel
@ -233,52 +238,52 @@ struct AttachmentMediaPickerView: View {
} }
} }
private func sendGalleryMedia(ids: [String]) { private func sendGalleryMedia(ids _: [String]) {
var media: [AttachmentItem] = [] // var media: [AttachmentItem] = []
let dispatchGroup = DispatchGroup() // let dispatchGroup = DispatchGroup()
//
let asset = PHAsset.fetchAssets(withLocalIdentifiers: ids, options: nil) // let asset = PHAsset.fetchAssets(withLocalIdentifiers: ids, options: nil)
asset.enumerateObjects { asset, _, _ in // asset.enumerateObjects { asset, _, _ in
dispatchGroup.enter() // dispatchGroup.enter()
if asset.mediaType == .image { // if asset.mediaType == .image {
let manager = PHImageManager.default() // let manager = PHImageManager.default()
let option = PHImageRequestOptions() // let option = PHImageRequestOptions()
option.isSynchronous = true // option.isSynchronous = true
//
manager.requestImage( // manager.requestImage(
for: asset, // for: asset,
targetSize: PHImageManagerMaximumSize, // targetSize: PHImageManagerMaximumSize,
contentMode: .aspectFill, // contentMode: .aspectFill,
options: option // options: option
) { image, _ in // ) { image, _ in
if let image { // if let image {
let data = image.jpegData(compressionQuality: 1.0) ?? Data() // let data = image.jpegData(compressionQuality: 1.0) ?? Data()
media.append(.init(type: .image, data: data, string: "")) // media.append(.init(type: .image, data: data, string: ""))
} // }
dispatchGroup.leave() // dispatchGroup.leave()
} // }
} else if asset.mediaType == .video { // } else if asset.mediaType == .video {
let manager = PHImageManager.default() // let manager = PHImageManager.default()
let option = PHVideoRequestOptions() // let option = PHVideoRequestOptions()
option.version = .current // option.version = .current
option.deliveryMode = .highQualityFormat // option.deliveryMode = .highQualityFormat
//
manager.requestAVAsset(forVideo: asset, options: option) { avAsset, _, _ in // manager.requestAVAsset(forVideo: asset, options: option) { avAsset, _, _ in
if let avAsset { // if let avAsset {
let url = (avAsset as? AVURLAsset)?.url // let url = (avAsset as? AVURLAsset)?.url
let data = try? Data(contentsOf: url ?? URL(fileURLWithPath: "")) // let data = try? Data(contentsOf: url ?? URL(fileURLWithPath: ""))
media.append(.init(type: .movie, data: data ?? Data(), string: "")) // media.append(.init(type: .movie, data: data ?? Data(), string: ""))
} // }
dispatchGroup.leave() // dispatchGroup.leave()
} // }
} // }
} // }
dispatchGroup.notify(queue: .main) { // dispatchGroup.notify(queue: .main) {
store.dispatch(.conversationAction(.sendAttachment(.init( // store.dispatch(.conversationAction(.sendAttachment(.init(
id: UUID().uuidString, // id: UUID().uuidString,
items: media // items: media
)))) // ))))
} // }
} }
} }
@ -406,7 +411,7 @@ struct CameraView: UIViewRepresentable {
struct CameraPicker: UIViewControllerRepresentable { struct CameraPicker: UIViewControllerRepresentable {
var sourceType: UIImagePickerController.SourceType var sourceType: UIImagePickerController.SourceType
var completionHandler: (Data, AttachmentType) -> Void var completionHandler: (Data, Data, AttachmentType) -> Void
func makeUIViewController(context: Context) -> UIImagePickerController { func makeUIViewController(context: Context) -> UIImagePickerController {
let picker = UIImagePickerController() let picker = UIImagePickerController()
@ -436,17 +441,18 @@ struct CameraPicker: UIViewControllerRepresentable {
// swiftlint:disable:next force_cast // swiftlint:disable:next force_cast
let mediaType = info[.mediaType] as! String let mediaType = info[.mediaType] as! String
if mediaType == UTType.image.identifier { // TODO: fix it
if let image = info[.originalImage] as? UIImage { // if mediaType == UTType.image.identifier {
let data = image.jpegData(compressionQuality: 1.0) ?? Data() // if let image = info[.originalImage] as? UIImage {
parent.completionHandler(data, .image) // let data = image.jpegData(compressionQuality: 1.0) ?? Data()
} // parent.completionHandler(data, .image)
} else if mediaType == UTType.movie.identifier { // }
if let url = info[.mediaURL] as? URL { // } else if mediaType == UTType.movie.identifier {
let data = try? Data(contentsOf: url) // if let url = info[.mediaURL] as? URL {
parent.completionHandler(data ?? Data(), .movie) // let data = try? Data(contentsOf: url)
} // parent.completionHandler(data ?? Data(), .movie)
} // }
// }
} }
} }
} }