another.im-ios/ConversationsClassic/AppCore/Middlewares/FileMiddleware.swift
2024-07-14 15:00:14 +02:00

78 lines
3.5 KiB
Swift

import Combine
import Foundation
import UIKit
final class FileMiddleware {
static let shared = FileMiddleware()
private var downloadingMessageIDs = ThreadSafeSet<String>()
func middleware(state _: AppState, action: AppAction) -> AnyPublisher<AppAction, Never> {
switch action {
case .conversationAction(.messagesUpdated(let messages)):
return Future { [weak self] promise in
guard let wSelf = self else {
promise(.success(.empty))
return
}
for message in messages where message.attachmentRemotePath != nil && message.attachmentLocalPath == nil {
if wSelf.downloadingMessageIDs.contains(message.id) {
continue
}
wSelf.downloadingMessageIDs.insert(message.id)
DispatchQueue.main.async {
// swiftlint:disable:next force_unwrapping
store.dispatch(.fileAction(.downloadAttachmentFile(messageId: message.id, attachmentRemotePath: message.attachmentRemotePath!)))
}
}
promise(.success(.empty))
}.eraseToAnyPublisher()
case .fileAction(.downloadAttachmentFile(let id, let attachmentRemotePath)):
return Future { promise in
let localName = "\(id)_\(UUID().uuidString)\(attachmentRemotePath.lastPathComponent)"
let localUrl = FileProcessing.fileFolder.appendingPathComponent(localName)
DownloadManager.shared.enqueueDownload(from: attachmentRemotePath, to: localUrl) { error in
DispatchQueue.main.async {
if let error {
store.dispatch(.fileAction(.downloadingAttachmentFileFailed(messageId: id, reason: error.localizedDescription)))
} else {
store.dispatch(.fileAction(.attachmentFileDownloaded(messageId: id, localName: localName)))
}
}
}
promise(.success(.empty))
}.eraseToAnyPublisher()
case .fileAction(.attachmentFileDownloaded(let id, let localName)):
return Future { [weak self] promise in
self?.downloadingMessageIDs.remove(id)
promise(.success(.fileAction(.createAttachmentThumbnail(messageId: id, localName: localName))))
}
.eraseToAnyPublisher()
case .fileAction(.createAttachmentThumbnail(let id, let localName)):
return Future { [weak self] promise in
if let thumbnailName = FileProcessing.shared.createThumbnail(localName: localName) {
self?.downloadingMessageIDs.remove(id)
promise(.success(.fileAction(.attachmentThumbnailCreated(messageId: id, thumbnailName: thumbnailName))))
} else {
self?.downloadingMessageIDs.remove(id)
promise(.success(.empty))
}
}
.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()
}
}
}