diff --git a/ConversationsClassic/AppCore/Files/DownloadManager.swift b/ConversationsClassic/AppCore/Files/DownloadManager.swift index a496212..0df85f9 100644 --- a/ConversationsClassic/AppCore/Files/DownloadManager.swift +++ b/ConversationsClassic/AppCore/Files/DownloadManager.swift @@ -27,10 +27,6 @@ final class DownloadManager { if let tempLocalUrl = tempLocalUrl, error == nil { do { - let destinationDirectory = localUrl.deletingLastPathComponent() - if !FileManager.default.fileExists(atPath: destinationDirectory.path) { - try FileManager.default.createDirectory(at: destinationDirectory, withIntermediateDirectories: true, attributes: nil) - } if FileManager.default.fileExists(atPath: localUrl.path) { try FileManager.default.removeItem(at: localUrl) } diff --git a/ConversationsClassic/AppCore/Files/FileProcessing.swift b/ConversationsClassic/AppCore/Files/FileProcessing.swift index a8fc1c2..b1e7bc5 100644 --- a/ConversationsClassic/AppCore/Files/FileProcessing.swift +++ b/ConversationsClassic/AppCore/Files/FileProcessing.swift @@ -7,12 +7,18 @@ final class FileProcessing { static var fileFolder: URL { // swiftlint:disable:next force_unwrapping let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! - return documentsURL.appendingPathComponent(Const.fileFolder) + let subdirectoryURL = documentsURL.appendingPathComponent(Const.fileFolder) + if !FileManager.default.fileExists(atPath: subdirectoryURL.path) { + try? FileManager.default.createDirectory(at: subdirectoryURL, withIntermediateDirectories: true, attributes: nil) + } + return subdirectoryURL } - func createThumbnail(id: String, localUrl: URL) -> URL? { - // make path for thumbnail - let thumbnailUrl = FileProcessing.fileFolder.appendingPathComponent(id).appendingPathExtension("png") + func createThumbnail(localUrl: URL) -> URL? { + let fileExtension = localUrl.pathExtension + let fileNameWithoutExtension = localUrl.deletingPathExtension().lastPathComponent + let thumbnailFileName = fileNameWithoutExtension + "_thumb." + fileExtension + let thumbnailUrl = FileProcessing.fileFolder.appendingPathComponent(thumbnailFileName) // check if thumbnail already exists if FileManager.default.fileExists(atPath: thumbnailUrl.path) { diff --git a/ConversationsClassic/AppCore/Middlewares/DatabaseMiddleware.swift b/ConversationsClassic/AppCore/Middlewares/DatabaseMiddleware.swift index 94e9de3..4c3abac 100644 --- a/ConversationsClassic/AppCore/Middlewares/DatabaseMiddleware.swift +++ b/ConversationsClassic/AppCore/Middlewares/DatabaseMiddleware.swift @@ -263,6 +263,29 @@ final class DatabaseMiddleware { .eraseToAnyPublisher() // MARK: Attachments + case .fileAction(.downloadAttachmentFile(let id, _)): + return Future { promise in + Task(priority: .background) { [weak self] in + guard let database = self?.database else { + promise(.success(.databaseAction(.updateAttachmentFailed(id: id, reason: L10n.Global.Error.genericDbError))) + ) + return + } + do { + _ = try database._db.write { db in + try Message + .filter(Column("id") == id) + .updateAll(db, Column("attachmentDownloadFailed").set(to: false)) + } + promise(.success(.empty)) + } catch { + promise(.success(.databaseAction(.updateAttachmentFailed(id: id, reason: error.localizedDescription))) + ) + } + } + } + .eraseToAnyPublisher() + case .fileAction(.downloadingAttachmentFileFailed(let id, _)): return Future { promise in Task(priority: .background) { [weak self] in diff --git a/ConversationsClassic/AppCore/Middlewares/FileMiddleware.swift b/ConversationsClassic/AppCore/Middlewares/FileMiddleware.swift index 776d63a..f32f993 100644 --- a/ConversationsClassic/AppCore/Middlewares/FileMiddleware.swift +++ b/ConversationsClassic/AppCore/Middlewares/FileMiddleware.swift @@ -51,7 +51,7 @@ final class FileMiddleware { case .fileAction(.createAttachmentThumbnail(let id, let localUrl)): return Future { [weak self] promise in - if let thumbnailUrl = FileProcessing.shared.createThumbnail(id: id, localUrl: localUrl) { + if let thumbnailUrl = FileProcessing.shared.createThumbnail(localUrl: localUrl) { self?.downloadingMessageIDs.remove(id) promise(.success(.fileAction(.attachmentThumbnailCreated(id: id, thumbnailUrl: thumbnailUrl)))) } else { diff --git a/ConversationsClassic/Helpers/Const.swift b/ConversationsClassic/Helpers/Const.swift index f253696..d1cf5a7 100644 --- a/ConversationsClassic/Helpers/Const.swift +++ b/ConversationsClassic/Helpers/Const.swift @@ -33,7 +33,7 @@ enum Const { static let videoDurationLimit = 60.0 // Upload/download file folder - static let fileFolder = "downloads" + static let fileFolder = "Downloads" // Grid size for gallery preview (3 in a row) static let galleryGridSize = UIScreen.main.bounds.width / 3 diff --git a/ConversationsClassic/View/Screens/Conversation/ConversationMessageContainer.swift b/ConversationsClassic/View/Screens/Conversation/ConversationMessageContainer.swift index 68eb56a..599e4c4 100644 --- a/ConversationsClassic/View/Screens/Conversation/ConversationMessageContainer.swift +++ b/ConversationsClassic/View/Screens/Conversation/ConversationMessageContainer.swift @@ -134,7 +134,9 @@ private struct AttachmentView: View { } } .onTapGesture { - // TODO: Retry download + if let url = message.attachmentRemotePath { + store.dispatch(.fileAction(.downloadAttachmentFile(id: message.id, attachmentRemotePath: url))) + } } } diff --git a/project.yml b/project.yml index e95f55d..8e2ec41 100644 --- a/project.yml +++ b/project.yml @@ -46,6 +46,7 @@ targets: NSMicrophoneUsageDescription: Allow app to take sound from microphone for attachment video NSLocationWhenInUseUsageDescription: Allow app to take your geo to send it in attachment NSLocationAlwaysAndWhenInUseUsageDescription: Allow app to take your geo to send it in attachment + UISupportsDocumentBrowser: true # UIViewControllerBasedStatusBarAppearance: NO # UIStatusBarStyle: UIStatusBarStyleLightContent # NSFaceIDUsageDescription: Required for accessing to account info