From d5edf360fb7d6d0dfdeb99a27ecf0e184d8d902f Mon Sep 17 00:00:00 2001 From: Christoph Hagen Date: Tue, 24 Oct 2023 14:51:08 +0200 Subject: [PATCH] Show classifier download progress --- Caps.xcodeproj/project.pbxproj | 8 +- .../UserInterfaceState.xcuserstate | Bin 47424 -> 53979 bytes .../xcshareddata/xcschemes/Caps.xcscheme | 2 +- Caps/ContentView.swift | 6 +- Caps/Data/Database.swift | 86 +++++++++++++++--- Caps/Views/ClassifierDownloadView.swift | 23 +++++ Caps/Views/SettingsView.swift | 40 +++++++- 7 files changed, 147 insertions(+), 18 deletions(-) create mode 100644 Caps/Views/ClassifierDownloadView.swift diff --git a/Caps.xcodeproj/project.pbxproj b/Caps.xcodeproj/project.pbxproj index 938af63..b4f58df 100644 --- a/Caps.xcodeproj/project.pbxproj +++ b/Caps.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 882C955E2AE7F0DE00657886 /* ClassifierDownloadView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 882C955D2AE7F0DE00657886 /* ClassifierDownloadView.swift */; }; 88C1511C29A11ADF0080EF4F /* CapImagesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88C1511B29A11ADF0080EF4F /* CapImagesView.swift */; }; 88DBE72E285495B100D1573B /* FancyTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88DBE72D285495B100D1573B /* FancyTextField.swift */; }; E20D104A285612AF0019BD91 /* ImageGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20D1049285612AF0019BD91 /* ImageGrid.swift */; }; @@ -52,6 +53,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 882C955D2AE7F0DE00657886 /* ClassifierDownloadView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClassifierDownloadView.swift; sourceTree = ""; }; 88C1511B29A11ADF0080EF4F /* CapImagesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapImagesView.swift; sourceTree = ""; }; 88DBE72D285495B100D1573B /* FancyTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FancyTextField.swift; sourceTree = ""; }; E20D1049285612AF0019BD91 /* ImageGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageGrid.swift; sourceTree = ""; }; @@ -192,6 +194,7 @@ E2EA00CD283EBEB600F7B269 /* SearchField.swift */, E2EA00E4283F69DF00F7B269 /* SettingsStatisticRow.swift */, E2EA00E0283F658E00F7B269 /* SettingsView.swift */, + 882C955D2AE7F0DE00657886 /* ClassifierDownloadView.swift */, E2EA00CB283EB43E00F7B269 /* SortCaseRowView.swift */, E2EA00C6283EAA0100F7B269 /* SortSelectionView.swift */, 88C1511B29A11ADF0080EF4F /* CapImagesView.swift */, @@ -245,7 +248,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1340; - LastUpgradeCheck = 1340; + LastUpgradeCheck = 1500; TargetAttributes = { E25AAC77283D855D006E9E7F = { CreatedOnToolsVersion = 13.4; @@ -327,6 +330,7 @@ E20D105028574E190019BD91 /* CapImage.swift in Sources */, E2EA00ED2841170100F7B269 /* UIImage+Extensions.swift in Sources */, E20D105228589AAC0019BD91 /* FileManager+Extensions.swift in Sources */, + 882C955E2AE7F0DE00657886 /* ClassifierDownloadView.swift in Sources */, E2EA00E5283F69DF00F7B269 /* SettingsStatisticRow.swift in Sources */, E2EA00E1283F658E00F7B269 /* SettingsView.swift in Sources */, ); @@ -371,6 +375,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -431,6 +436,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; diff --git a/Caps.xcodeproj/project.xcworkspace/xcuserdata/imac.xcuserdatad/UserInterfaceState.xcuserstate b/Caps.xcodeproj/project.xcworkspace/xcuserdata/imac.xcuserdatad/UserInterfaceState.xcuserstate index fd9aa49d7b9dc414f028258ac77808c728cec69d..a938d06f55e6d716747e9e7b88493ae80008cbd4 100644 GIT binary patch literal 53979 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

rqbdQCkZQIMU;wvTN_C)lh1Om?DE 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 localClassifierVersion + } let images: ImageCache @@ -146,6 +163,9 @@ final class Database: ObservableObject { folder: imageFolder, server: server, thumbnailSize: CapsApp.thumbnailImageSize) + + self.localClassifierVersion = storedLocalClassifierVersion + self.serverClassifierVersion = storedServerClassifierVersion ensureFolderExistence(gridStorageFolder) loadCaps() @@ -329,7 +349,7 @@ final class Database: ObservableObject { } @discardableResult - func serverHasNewClassifier() async -> Bool { + func updateServerClassifierVersion() async -> Bool { let data: Data let response: URLResponse do { @@ -351,23 +371,29 @@ final class Database: ObservableObject { return false } DispatchQueue.main.async { - self.serverClassifierVersion = serverVersion + self.storedServerClassifierVersion = serverVersion } - guard serverVersion > self.classifierVersion else { - log("No new classifier available (Local: \(classifierVersion) Server: \(serverVersion))") - return false - } - log("New classifier available (Local: \(classifierVersion) Server: \(serverVersion))") return true } @discardableResult func downloadClassifier() async -> Bool { log("Downloading classifier") + + let progress = ClassifierProgress() + DispatchQueue.main.async { + self.classifierDownloadProgress = progress + } + defer { + DispatchQueue.main.async { + self.classifierDownloadProgress = nil + } + } + let tempUrl: URL let response: URLResponse do { - (tempUrl, response) = try await URLSession.shared.download(from: serverClassifierUrl) + (tempUrl, response) = try await URLSession.shared.download(from: serverClassifierUrl, delegate: progress) } catch { log("Failed to download classifier version: \(error)") return false @@ -386,10 +412,10 @@ final class Database: ObservableObject { return false } DispatchQueue.main.async { - self.classifierVersion = self.serverClassifierVersion + self.storedLocalClassifierVersion = self.serverClassifierVersion + log("Downloaded classifier \(self.localClassifierVersion)") self.classifier = nil } - log("Downloaded classifier \(classifierVersion)") return true } @@ -987,6 +1013,44 @@ final class Database: ObservableObject { } } +extension Database { + + final class ClassifierProgress: NSObject, ObservableObject { + + @Published + var bytesLoaded: Double + + @Published + var total: Double + + var percentage: Double { + guard total > 0 else { + return 0.0 + } + return bytesLoaded * 100 / total + } + + init(bytesLoaded: Double = 0, total: Double = 0) { + self.bytesLoaded = bytesLoaded + self.total = total + } + } +} + +extension Database.ClassifierProgress: URLSessionDownloadDelegate { + + func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { + + } + + func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { + DispatchQueue.main.async { + self.bytesLoaded = Double(totalBytesWritten) + self.total = Double(totalBytesExpectedToWrite) + } + } +} + extension Database { static var mock: Database { diff --git a/Caps/Views/ClassifierDownloadView.swift b/Caps/Views/ClassifierDownloadView.swift new file mode 100644 index 0000000..755d003 --- /dev/null +++ b/Caps/Views/ClassifierDownloadView.swift @@ -0,0 +1,23 @@ +import SwiftUI + +struct ClassifierDownloadView: View { + + @ObservedObject + var progress: Database.ClassifierProgress + + var body: some View { + VStack { + ProgressView("Downloading classifier...", value: progress.bytesLoaded, total: Double(progress.total)) + .progressViewStyle(.linear) + HStack { + Text(String(format: "%.0f %%", progress.percentage)) + Spacer() + Text(String(format: "%.1f / %.1f MB", progress.bytesLoaded / 1_000_000, progress.total / 1_000_000 )) + } + } + } +} + +#Preview { + ClassifierDownloadView(progress: .init(bytesLoaded: 12_300_000, total: 24_500_000)) +} diff --git a/Caps/Views/SettingsView.swift b/Caps/Views/SettingsView.swift index eb43920..c8f5414 100644 --- a/Caps/Views/SettingsView.swift +++ b/Caps/Views/SettingsView.swift @@ -42,8 +42,28 @@ struct SettingsView: View { .foregroundColor(.secondary) .padding(.top) Group { - SettingsStatisticRow(label: "Version", value: "\(database.classifierVersion)") + SettingsStatisticRow(label: "Server Version", value: "\(database.serverClassifierVersion)") + SettingsStatisticRow(label: "Local Version", value: "\(database.localClassifierVersion)") SettingsStatisticRow(label: "Recognized caps", value: "\(database.classifierClassCount)") + HStack { + Spacer() + Button(action: updateClassifierVersion) { + Label("Refresh", systemSymbol: .arrowCounterclockwise) + } + .disabled(database.classifierDownloadProgress != nil) + .padding() + if database.localClassifierVersion != database.serverClassifierVersion { + Button(action: downloadNewClassifier) { + Label("Download", systemSymbol: .squareAndArrowDown) + } + .disabled(database.classifierDownloadProgress != nil) + .padding() + } + Spacer() + } + if let progress = database.classifierDownloadProgress { + ClassifierDownloadView(progress: progress) + } }.padding(.horizontal) Text("Storage") .font(.footnote) @@ -56,7 +76,9 @@ struct SettingsView: View { SettingsStatisticRow(label: "Classifier", value: byteString(database.classifierSize)) HStack { Spacer() - Button("Clear image cache", action: clearImageCache) + Button(action: clearImageCache) { + Label("Clear image cache", systemSymbol: .trash) + } .padding() Spacer() } @@ -82,6 +104,20 @@ struct SettingsView: View { } } + private func downloadNewClassifier() { + Task { + // Ensure that correct version is saved + await database.updateServerClassifierVersion() + await database.downloadClassifier() + } + } + + private func updateClassifierVersion() { + Task { + await database.updateServerClassifierVersion() + } + } + private func hide() { isPresented = false }