diff --git a/ios/App/App/plugins/AbsDownloader.swift b/ios/App/App/plugins/AbsDownloader.swift index b7f7330c..ab80a33c 100644 --- a/ios/App/App/plugins/AbsDownloader.swift +++ b/ios/App/App/plugins/AbsDownloader.swift @@ -34,7 +34,25 @@ public class AbsDownloader: CAPPlugin, URLSessionDownloadDelegate { } public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { - NSLog("Received download status \(downloadTask.taskDescription ?? "Unknown Task"): \(totalBytesWritten)") + // Find the download item + guard let downloadItemPartId = downloadTask.taskDescription else { return } + let downloadItem = Database.shared.getDownloadItem(downloadItemPartId: downloadItemPartId) + guard let downloadItem = downloadItem else { + NSLog("Download item part (%@) not found!", downloadItemPartId) + return + } + + // Calculate the download percentage + let percentDownloaded = (Double(totalBytesWritten) / Double(totalBytesExpectedToWrite)) * 100 + NSLog("Received download status \(downloadItemPartId): \(percentDownloaded)") + Database.shared.updateDownloadItemPartPercent(downloadItemPartId: downloadItemPartId, percent: percentDownloaded) + let downloadItemPart = downloadItem.downloadItemParts.filter { part in + part.id == downloadItemPartId + }.first + + // Notify the UI + NSLog("Download progress: \(downloadItemPart?.progress ?? 0)") + try! notifyListeners("onItemDownloadUpdate", data: downloadItem.asDictionary()) } @objc func downloadLibraryItem(_ call: CAPPluginCall) { @@ -47,16 +65,17 @@ public class AbsDownloader: CAPPlugin, URLSessionDownloadDelegate { ApiClient.getLibraryItemWithProgress(libraryItemId: libraryItemId, episodeId: episodeId) { libraryItem in if (libraryItem == nil) { NSLog("Library item not found") + call.resolve(["error": "Library item not found"]) } else { NSLog("Got library item from server \(libraryItem!.id)") do { try self.startLibraryItemDownload(libraryItem!) - //Database.shared.saveLocalLibraryItem(localLibraryItem: localLibraryItem) + call.resolve() } catch { NSLog("Failed to download \(error)") + call.resolve(["error": "Failed to download"]) } } - call.resolve() } } diff --git a/ios/App/Shared/models/DownloadItem.swift b/ios/App/Shared/models/DownloadItem.swift index c0c9923d..afd534db 100644 --- a/ios/App/Shared/models/DownloadItem.swift +++ b/ios/App/Shared/models/DownloadItem.swift @@ -28,6 +28,10 @@ struct DownloadItem: Realmable, Codable { static func indexedProperties() -> [String] { ["libraryItemId"] } + + private enum CodingKeys : String, CodingKey { + case id, libraryItemId, episodeId, userMediaProgress, serverConnectionConfigId, serverAddress, serverUserId, mediaType, itemTitle, downloadItemParts + } } extension DownloadItem { @@ -58,17 +62,20 @@ struct DownloadItemPart: Realmable, Codable { var uri: String? var destinationUri: String? var finalDestinationUri: String? - var downloadId: Int? - var progress: Int = 0 + var progress: Double = 0 var task: URLSessionDownloadTask! - private enum CodingKeys : String, CodingKey { - case id, progress + static func primaryKey() -> String? { + return "id" } static func ignoredProperties() -> [String] { ["task"] } + + private enum CodingKeys : String, CodingKey { + case id, filename, completed, moved, failed, progress + } } extension DownloadItemPart { diff --git a/ios/App/Shared/util/Database.swift b/ios/App/Shared/util/Database.swift index 45f5a98b..c5cb4313 100644 --- a/ios/App/Shared/util/Database.swift +++ b/ios/App/Shared/util/Database.swift @@ -169,6 +169,20 @@ class Database { } } + public func updateDownloadItemPartPercent(downloadItemPartId: String, percent: Double) { + Database.realmQueue.sync { + try! instance.write { + let part = instance.object(ofType: DownloadItemPart.self, forPrimaryKey: downloadItemPartId) + guard var part = part else { + NSLog("downloadItemPartId not found (\(downloadItemPartId)") + return + } + part.progress = percent + instance.add(part, update: .modified) + } + } + } + public func getDeviceSettings() -> DeviceSettings { return Database.realmQueue.sync { return instance.objects(DeviceSettings.self).first ?? getDefaultDeviceSettings()