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 showAttachmentPicker(Bool)
case sendAttachment(Attachment)
case sendAttachment([ShareItem])
case sendAttachmentDone
case sendAttachmentError(reason: String)
}

View file

@ -1,9 +1,6 @@
/*
In 99,99% of time YOU DON'T NEEDED TO CHANGE ANYTHING in this file!
// This file declare global state object for whole app
// 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 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()
.onTapGesture {
if let selectedContact = selectedContact {
let attachment = Attachment(id: UUID().uuidString, items: [
AttachmentItem(type: .contact, data: Data(), string: selectedContact.contactBareJid)
])
store.dispatch(.conversationAction(.sendAttachment(attachment)))
store.dispatch(.conversationAction(.sendAttachment([.init(
id: UUID().uuidString,
type: .contact,
data: Data(),
thumbnail: Data(),
string: selectedContact.contactBareJid
)])))
store.dispatch(.conversationAction(.showAttachmentPicker(false)))
}
}

View file

@ -2,12 +2,34 @@ import SwiftUI
import UIKit
struct AttachmentFilesPickerView: View {
@EnvironmentObject var store: AppStore
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 {
let completion: ([Data]) -> Void
let cancel: () -> Void
func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentPicker>) -> UIDocumentPickerViewController {
let picker: UIDocumentPickerViewController
picker = UIDocumentPickerViewController(forOpeningContentTypes: [.item], asCopy: true)
@ -35,7 +57,7 @@ struct DocumentPicker: UIViewControllerRepresentable {
}
func documentPickerWasCancelled(_: UIDocumentPickerViewController) {
// Handle cancellation
parent.cancel()
}
}
}

View file

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

View file

@ -95,14 +95,19 @@ struct AttachmentMediaPickerView: View {
}
}
.fullScreenCover(isPresented: $showCameraPicker) {
CameraPicker(sourceType: .camera) { data, type in
store.dispatch(.conversationAction(.sendAttachment(.init(
id: UUID().uuidString,
items: [.init(type: type, data: data, string: "")]
))))
showCameraPicker = false
}
.edgesIgnoringSafeArea(.all)
// TODO: fix it
// CameraPicker(sourceType: .camera) { data, type in
// store.dispatch(.conversationAction(.sendAttachment([.init(
// id: UUID().uuidString,
// type: type,
// data: data,
// thumbnail: Data(),
// string: ""
// )])))
// showCameraPicker = false
// store.dispatch(.conversationAction(.showAttachmentPicker(false)))
// }
// .edgesIgnoringSafeArea(.all)
}
// Send panel
@ -233,52 +238,52 @@ struct AttachmentMediaPickerView: View {
}
}
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 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
// ))))
// }
}
}
@ -406,7 +411,7 @@ struct CameraView: UIViewRepresentable {
struct CameraPicker: UIViewControllerRepresentable {
var sourceType: UIImagePickerController.SourceType
var completionHandler: (Data, AttachmentType) -> Void
var completionHandler: (Data, Data, AttachmentType) -> Void
func makeUIViewController(context: Context) -> UIImagePickerController {
let picker = UIImagePickerController()
@ -436,17 +441,18 @@ struct CameraPicker: UIViewControllerRepresentable {
// swiftlint:disable:next force_cast
let mediaType = info[.mediaType] as! String
if mediaType == UTType.image.identifier {
if let image = info[.originalImage] as? UIImage {
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 {
let data = try? Data(contentsOf: url)
parent.completionHandler(data ?? Data(), .movie)
}
}
// TODO: fix it
// if mediaType == UTType.image.identifier {
// if let image = info[.originalImage] as? UIImage {
// 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 {
// let data = try? Data(contentsOf: url)
// parent.completionHandler(data ?? Data(), .movie)
// }
// }
}
}
}