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

97 lines
3.9 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()
private var downloader = DownloadManager()
2024-07-11 13:59:24 +00:00
func middleware(state _: AppState, action: AppAction) -> AnyPublisher<AppAction, Never> {
switch action {
2024-07-12 11:43:14 +00:00
case .conversationAction(.attachmentsUpdated(let attachments)):
DispatchQueue.global(qos: .background).async {
for attachment in attachments where attachment.localPath == nil {
if let remotePath = attachment.remotePath {
let localUrl = self.fileFolder.appendingPathComponent(attachment.id)
self.downloader.download(from: remotePath, to: localUrl) { error in
if error == nil {
DispatchQueue.main.async {
store.dispatch(.fileAction(.attachmentFileDownloaded(id: attachment.id, localUrl: localUrl)))
}
}
}
}
}
}
return Empty().eraseToAnyPublisher()
case .fileAction(.attachmentFileDownloaded(let id, let localUrl)):
DispatchQueue.global(qos: .background).async {
guard let attachment = store.state.conversationsState.currentAttachments.first(where: { $0.id == id }) else { return }
switch attachment.type {
case .image:
if let data = try? Data(contentsOf: localUrl), let image = UIImage(data: data) {
image.scaleAndCropImage(toExampleSize: CGSizeMake(Const.attachmentPreviewSize, Const.attachmentPreviewSize)) { img in
if let img = img, let data = img.jpegData(compressionQuality: 1.0) {
let thumbnailUrl = self.fileFolder.appendingPathComponent("\(id)_thumbnail.jpg")
do {
try data.write(to: thumbnailUrl)
DispatchQueue.main.async {
store.dispatch(.fileAction(.attachmentThumbnailCreated(id: id, thumbnailUrl: thumbnailUrl)))
}
} catch {
print("Error writing thumbnail: \(error)")
}
}
}
}
case .movie:
// self.downloadAndMakeThumbnail(for: attachment)
break
default:
break
2024-07-11 13:59:24 +00:00
}
}
return Empty().eraseToAnyPublisher()
default:
return Empty().eraseToAnyPublisher()
}
}
}
2024-07-12 11:43:14 +00:00
private extension FileMiddleware {
var fileFolder: URL {
// swiftlint:disable:next force_unwrapping
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
return documentsURL.appendingPathComponent(Const.fileFolder)
}
}
private final class DownloadManager {
private let urlSession: URLSession
init() {
let configuration = URLSessionConfiguration.default
urlSession = URLSession(configuration: configuration)
}
func download(from url: URL, to localUrl: URL, completion: @escaping (Error?) -> Void) {
let task = urlSession.downloadTask(with: url) { tempLocalUrl, _, error in
if let tempLocalUrl = tempLocalUrl, error == nil {
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: localUrl)
completion(nil)
} catch let writeError {
completion(writeError)
}
} else {
completion(error)
}
}
task.resume()
}
}