import Combine import Foundation import UIKit final class FileMiddleware { static let shared = FileMiddleware() func middleware(state _: AppState, action: AppAction) -> AnyPublisher { switch action { case .conversationAction(.messagesUpdated(let messages)): return Future { promise in for message in messages where message.remotePath != nil && message.localPath == nil { DispatchQueue.main.async { // swiftlint:disable:next force_unwrapping store.dispatch(.fileAction(.downloadAttachmentFile(id: message.id, remotePath: message.remotePath!))) } } promise(.success(.empty)) }.eraseToAnyPublisher() case .fileAction(.downloadAttachmentFile(let id, let remotePath)): return Future { promise in let localUrl = FileProcessing.fileFolder.appendingPathComponent(id).appendingPathExtension(remotePath.pathExtension) DownloadManager.shared.enqueueDownload(from: remotePath, to: localUrl) { error in DispatchQueue.main.async { if let error { store.dispatch(.fileAction(.downloadingAttachmentFileFailed(id: id, reason: error.localizedDescription))) } else { store.dispatch(.fileAction(.attachmentFileDownloaded(id: id, localUrl: localUrl))) } } } promise(.success(.empty)) }.eraseToAnyPublisher() case .fileAction(.attachmentFileDownloaded(let id, let localUrl)): return Just(.fileAction(.createAttachmentThumbnail(id: id, localUrl: localUrl))) .eraseToAnyPublisher() case .fileAction(.createAttachmentThumbnail(let id, let localUrl)): return Future { promise in if let thumbnailUrl = FileProcessing.shared.createThumbnail(id: id, localUrl: localUrl) { promise(.success(.fileAction(.attachmentThumbnailCreated(id: id, thumbnailUrl: thumbnailUrl)))) } else { promise(.success(.empty)) } } .eraseToAnyPublisher() default: return Empty().eraseToAnyPublisher() } } }