This commit is contained in:
fmodf 2024-07-16 20:05:15 +02:00
parent e448dc6823
commit 0ca8ec93a7
5 changed files with 74 additions and 8 deletions

View file

@ -5,7 +5,7 @@ enum SharingAction: Stateable {
case shareLocation(lat: Double, lon: Double) case shareLocation(lat: Double, lon: Double)
case shareContact(jid: String) case shareContact(jid: String)
case shareDocuments([Data]) case shareDocuments([Data], [String])
case shareMedia(ids: [String]) case shareMedia(ids: [String])
case checkCameraAccess case checkCameraAccess

View file

@ -166,6 +166,23 @@ final class FileProcessing {
return nil return nil
} }
} }
// This function also creates new id for file from document sharing
func copyDocumentsForUploading(data: [Data], extensions: [String]) -> [(String, String)] {
data.enumerated().compactMap { index, data in
let newMessageId = UUID().uuidString
let fileId = UUID().uuidString
let localName = "\(newMessageId)_\(fileId).\(extensions[index])"
let localUrl = FileProcessing.fileFolder.appendingPathComponent(localName)
do {
try data.write(to: localUrl)
return (newMessageId, localName)
} catch {
print("FileProcessing: Error writing document: \(error)")
return nil
}
}
}
} }
private extension FileProcessing { private extension FileProcessing {

View file

@ -97,9 +97,13 @@ final class SharingMiddleware {
return Empty().eraseToAnyPublisher() return Empty().eraseToAnyPublisher()
} }
case .sharingAction(.shareDocuments(let data)): case .sharingAction(.shareDocuments(let data, let extensions)):
print("Sharing documents: \(data.count)") return Future { promise in
return Empty().eraseToAnyPublisher() let ids = FileProcessing.shared.copyDocumentsForUploading(data: data, extensions: extensions)
promise(.success(.fileAction(.itemsCopiedForUploading(newMessageIds: ids.map { $0.0 }, localNames: ids.map { $0.1 })))
)
}
.eraseToAnyPublisher()
case .sharingAction(.shareContact(let jid)): case .sharingAction(.shareContact(let jid)):
if let chat = state.conversationsState.currentChat { if let chat = state.conversationsState.currentChat {

View file

@ -1,5 +1,6 @@
import AVKit import AVKit
import MapKit import MapKit
import QuickLook
import SwiftUI import SwiftUI
struct ConversationMessageContainer: View { struct ConversationMessageContainer: View {
@ -92,6 +93,14 @@ private struct AttachmentView: View {
placeholder placeholder
} }
case .file:
if let file = message.attachmentLocalPath {
DocumentPreview(url: file)
.frame(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize)
} else {
placeholder
}
default: default:
placeholder placeholder
} }
@ -175,3 +184,37 @@ private struct VideoPlayerView: UIViewControllerRepresentable {
// Update the controller if needed. // Update the controller if needed.
} }
} }
struct DocumentPreview: UIViewControllerRepresentable {
var url: URL
func makeUIViewController(context: Context) -> QLPreviewController {
let controller = QLPreviewController()
controller.dataSource = context.coordinator
return controller
}
func updateUIViewController(_: QLPreviewController, context _: Context) {
// Update the controller if needed.
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, QLPreviewControllerDataSource {
var parent: DocumentPreview
init(_ parent: DocumentPreview) {
self.parent = parent
}
func numberOfPreviewItems(in _: QLPreviewController) -> Int {
1
}
func previewController(_: QLPreviewController, previewItemAt _: Int) -> QLPreviewItem {
parent.url as QLPreviewItem
}
}
}

View file

@ -6,9 +6,9 @@ struct SharingFilesPickerView: View {
var body: some View { var body: some View {
DocumentPicker( DocumentPicker(
completion: { dataArray in completion: { dataArray, extensionsArray in
store.dispatch(.sharingAction(.showSharing(false))) store.dispatch(.sharingAction(.showSharing(false)))
store.dispatch(.sharingAction(.shareDocuments(dataArray))) store.dispatch(.sharingAction(.shareDocuments(dataArray, extensionsArray)))
}, },
cancel: { cancel: {
store.dispatch(.sharingAction(.showSharing(false))) store.dispatch(.sharingAction(.showSharing(false)))
@ -18,7 +18,7 @@ struct SharingFilesPickerView: View {
} }
struct DocumentPicker: UIViewControllerRepresentable { struct DocumentPicker: UIViewControllerRepresentable {
let completion: ([Data]) -> Void let completion: ([Data], [String]) -> Void
let cancel: () -> Void let cancel: () -> Void
func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentPicker>) -> UIDocumentPickerViewController { func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentPicker>) -> UIDocumentPickerViewController {
@ -44,15 +44,17 @@ struct DocumentPicker: UIViewControllerRepresentable {
func documentPicker(_: UIDocumentPickerViewController, didPickDocumentsAt: [URL]) { func documentPicker(_: UIDocumentPickerViewController, didPickDocumentsAt: [URL]) {
var dataArray = [Data]() var dataArray = [Data]()
var extensionArray = [String]()
for url in didPickDocumentsAt { for url in didPickDocumentsAt {
do { do {
let data = try Data(contentsOf: url) let data = try Data(contentsOf: url)
dataArray.append(data) dataArray.append(data)
extensionArray.append(url.pathExtension)
} catch { } catch {
print("Unable to load data from \(url): \(error)") print("Unable to load data from \(url): \(error)")
} }
} }
parent.completion(dataArray) parent.completion(dataArray, extensionArray)
} }
func documentPickerWasCancelled(_: UIDocumentPickerViewController) { func documentPickerWasCancelled(_: UIDocumentPickerViewController) {