conversations-classic-ios/ConversationsClassic/AppCore/Middlewares/FileMiddleware.swift

69 lines
3.1 KiB
Swift
Raw Normal View History

2024-07-11 13:59:24 +00:00
import Combine
2024-07-12 11:43:14 +00:00
import Foundation
import UIKit
2024-07-11 13:59:24 +00:00
final class FileMiddleware {
2024-07-12 11:43:14 +00:00
static let shared = FileMiddleware()
2024-07-13 14:23:03 +00:00
private var downloadingMessageIDs = ThreadSafeSet<String>()
2024-07-11 13:59:24 +00:00
func middleware(state _: AppState, action: AppAction) -> AnyPublisher<AppAction, Never> {
switch action {
2024-07-13 13:38:15 +00:00
case .conversationAction(.messagesUpdated(let messages)):
2024-07-13 14:23:03 +00:00
return Future { [weak self] promise in
guard let wSelf = self else {
promise(.success(.empty))
return
}
2024-07-13 13:42:47 +00:00
for message in messages where message.attachmentRemotePath != nil && message.attachmentLocalPath == nil {
2024-07-13 14:23:03 +00:00
if wSelf.downloadingMessageIDs.contains(message.id) {
continue
}
wSelf.downloadingMessageIDs.insert(message.id)
2024-07-13 01:29:46 +00:00
DispatchQueue.main.async {
// swiftlint:disable:next force_unwrapping
2024-07-13 13:42:47 +00:00
store.dispatch(.fileAction(.downloadAttachmentFile(id: message.id, attachmentRemotePath: message.attachmentRemotePath!)))
2024-07-12 11:43:14 +00:00
}
}
2024-07-13 01:29:46 +00:00
promise(.success(.empty))
}.eraseToAnyPublisher()
2024-07-12 11:43:14 +00:00
2024-07-13 13:42:47 +00:00
case .fileAction(.downloadAttachmentFile(let id, let attachmentRemotePath)):
2024-07-13 01:29:46 +00:00
return Future { promise in
2024-07-13 13:42:47 +00:00
let localUrl = FileProcessing.fileFolder.appendingPathComponent(id).appendingPathExtension(attachmentRemotePath.pathExtension)
DownloadManager.shared.enqueueDownload(from: attachmentRemotePath, to: localUrl) { error in
2024-07-13 01:29:46 +00:00
DispatchQueue.main.async {
if let error {
store.dispatch(.fileAction(.downloadingAttachmentFileFailed(id: id, reason: error.localizedDescription)))
} else {
store.dispatch(.fileAction(.attachmentFileDownloaded(id: id, localUrl: localUrl)))
2024-07-12 11:43:14 +00:00
}
}
2024-07-13 01:29:46 +00:00
}
promise(.success(.empty))
}.eraseToAnyPublisher()
2024-07-12 11:43:14 +00:00
2024-07-13 01:29:46 +00:00
case .fileAction(.attachmentFileDownloaded(let id, let localUrl)):
2024-07-13 14:23:03 +00:00
return Future { [weak self] promise in
self?.downloadingMessageIDs.remove(id)
promise(.success(.fileAction(.createAttachmentThumbnail(id: id, localUrl: localUrl))))
}
.eraseToAnyPublisher()
2024-07-12 11:43:14 +00:00
2024-07-13 01:29:46 +00:00
case .fileAction(.createAttachmentThumbnail(let id, let localUrl)):
2024-07-13 14:23:03 +00:00
return Future { [weak self] promise in
2024-07-14 08:52:15 +00:00
if let thumbnailUrl = FileProcessing.shared.createThumbnail(localUrl: localUrl) {
2024-07-13 14:23:03 +00:00
self?.downloadingMessageIDs.remove(id)
2024-07-13 01:29:46 +00:00
promise(.success(.fileAction(.attachmentThumbnailCreated(id: id, thumbnailUrl: thumbnailUrl))))
} else {
2024-07-13 14:23:03 +00:00
self?.downloadingMessageIDs.remove(id)
2024-07-13 01:29:46 +00:00
promise(.success(.empty))
2024-07-11 13:59:24 +00:00
}
}
2024-07-13 01:29:46 +00:00
.eraseToAnyPublisher()
2024-07-11 13:59:24 +00:00
default:
return Empty().eraseToAnyPublisher()
}
}
}