From da24cf9c91691df454c2cbed6023ea1117e1d66c Mon Sep 17 00:00:00 2001 From: Alin Panaitiu Date: Sat, 6 Jul 2024 17:10:48 +0300 Subject: [PATCH] Allow disabling floating results UI --- Clop/ClopApp.swift | 73 ++++++++++++++++++++---------------- Clop/Optimisable.swift | 2 +- Clop/OptimisationUtils.swift | 14 +++---- Clop/SettingsView.swift | 17 +++++++-- ReleaseNotes/2.6.0.md | 1 + 5 files changed, 64 insertions(+), 43 deletions(-) diff --git a/Clop/ClopApp.swift b/Clop/ClopApp.swift index 3a8f425..7f107ae 100644 --- a/Clop/ClopApp.swift +++ b/Clop/ClopApp.swift @@ -527,6 +527,15 @@ class AppDelegate: AppDelegateParent { KM.reinitHotkeys() } .store(in: &observers) + pub(.enableFloatingResults) + .sink { + if $0.newValue { + showFloatingThumbnails(force: true) + } else { + floatingResultsWindow.close() + } + } + .store(in: &observers) if finishedOnboarding { initOptimisers() @@ -935,6 +944,38 @@ class FileOptimisationWatcher { startedWatchingAt.timeIntervalSinceNow > -30 && Defaults[.launchCount] == 1 } + static func waitForModificationDateToSettle(_ path: String) async { + guard let attrs = try? fm.attributesOfItem(atPath: path), let date = attrs[.modificationDate] as? Date else { + log.warning("Failed to get modification date of \(path)") + return + } + + log.debug("Waiting for modification date of \(path) to settle") + log.debug("Initial modification date: \(date)") + var lastDate = date + while true { + do { + try await Task.sleep(nanoseconds: 300_000_000) // 300ms + } catch { + log.error("Failed to sleep: \(error)") + return + } + + guard let attrs = try? fm.attributesOfItem(atPath: path), let date = attrs[.modificationDate] as? Date else { + log.warning("Failed to get modification date of \(path)") + return + } + + guard date != lastDate else { + log.debug("Modification date of \(path) settled at \(date)") + return + } + + log.debug("Modification date of \(path) is still changing: \(lastDate) -> \(date)") + lastDate = date + } + } + func isAddedFile(event: EonilFSEventsEvent) -> Bool { guard let flag = event.flag, let path = event.path.existingFilePath, let stem = path.stem, !stem.starts(with: ".") else { return false @@ -1018,38 +1059,6 @@ class FileOptimisationWatcher { watching = true } - static func waitForModificationDateToSettle(_ path: String) async { - guard let attrs = try? fm.attributesOfItem(atPath: path), let date = attrs[.modificationDate] as? Date else { - log.warning("Failed to get modification date of \(path)") - return - } - - log.debug("Waiting for modification date of \(path) to settle") - log.debug("Initial modification date: \(date)") - var lastDate = date - while true { - do { - try await Task.sleep(nanoseconds: 300_000_000) // 300ms - } catch { - log.error("Failed to sleep: \(error)") - return - } - - guard let attrs = try? fm.attributesOfItem(atPath: path), let date = attrs[.modificationDate] as? Date else { - log.warning("Failed to get modification date of \(path)") - return - } - - guard date != lastDate else { - log.debug("Modification date of \(path) settled at \(date)") - return - } - - log.debug("Modification date of \(path) is still changing: \(lastDate) -> \(date)") - lastDate = date - } - } - func hasSpuriousEvent(_ event: EonilFSEventsEvent) -> Bool { guard withinSafeMeasureTime, !justAddedFiles.isEmpty else { return false diff --git a/Clop/Optimisable.swift b/Clop/Optimisable.swift index 0f26943..fa091ac 100644 --- a/Clop/Optimisable.swift +++ b/Clop/Optimisable.swift @@ -58,7 +58,7 @@ class Optimisable { let proc: Process? = if let shortcut { optimiser.runShortcut(shortcut, outFile: shortcutOutFile, url: path.url) } else { - optimiser.runAutomation(outFile: shortcutOutFile, source: source, url: path.url, type: (self is PDF ? .pdf : (.video(UTType.from(filePath: path) ?? .mpeg4Movie)))) + optimiser.runAutomation(outFile: shortcutOutFile, source: source, url: path.url, type: self is PDF ? .pdf : .video(UTType.from(filePath: path) ?? .mpeg4Movie)) } guard let proc else { return nil } diff --git a/Clop/OptimisationUtils.swift b/Clop/OptimisationUtils.swift index e425ca2..110e94e 100644 --- a/Clop/OptimisationUtils.swift +++ b/Clop/OptimisationUtils.swift @@ -433,13 +433,6 @@ final class QuickLooker: QLPreviewPanelDataSource { @Published var originalURL: URL? @Published var startingURL: URL? @Published var convertedFromURL: URL? - var comparisonOriginalURL: URL? { - if let startingURL, startingURL != url, fm.fileExists(atPath: startingURL.path) { return startingURL } - if let originalURL, originalURL != url, fm.fileExists(atPath: originalURL.path) { return originalURL } - if let convertedFromURL, convertedFromURL != url, fm.fileExists(atPath: convertedFromURL.path) { return convertedFromURL } - return nil - } - @Published var downscaleFactor = 1.0 @Published var changePlaybackSpeedFactor = 1.0 @Published var aggressive = false @@ -470,6 +463,13 @@ final class QuickLooker: QLPreviewPanelDataSource { var isComparing = false + var comparisonOriginalURL: URL? { + if let startingURL, startingURL != url, fm.fileExists(atPath: startingURL.path) { return startingURL } + if let originalURL, originalURL != url, fm.fileExists(atPath: originalURL.path) { return originalURL } + if let convertedFromURL, convertedFromURL != url, fm.fileExists(atPath: convertedFromURL.path) { return convertedFromURL } + return nil + } + @Published var editing = false { didSet { guard editing != oldValue else { diff --git a/Clop/SettingsView.swift b/Clop/SettingsView.swift index 88695bc..fa33550 100644 --- a/Clop/SettingsView.swift +++ b/Clop/SettingsView.swift @@ -771,6 +771,7 @@ struct AboutSettingsView: View { } struct FloatingSettingsView: View { + @Default(.enableFloatingResults) var enableFloatingResults @Default(.showFloatingHatIcon) var showFloatingHatIcon @Default(.showImages) var showImages @Default(.showCompactImages) var showCompactImages @@ -790,6 +791,12 @@ struct FloatingSettingsView: View { var settings: some View { Form { + Toggle(isOn: $enableFloatingResults) { + Text("Show floating results").regular(13) + + Text("\n\nDisabling this will make Clop run in an UI-less mode, but keep optimising files in the background") + .round(10, weight: .regular) + .foregroundColor(.secondary) + } Section(header: SectionHeader(title: "Layout")) { Picker("Position on screen", selection: $floatingResultsCorner) { Text("Bottom right").tag(ScreenCorner.bottomRight) @@ -803,7 +810,7 @@ struct FloatingSettingsView: View { .round(10, weight: .regular) .foregroundColor(.secondary) } - } + }.disabled(!enableFloatingResults) Section(header: SectionHeader(title: "Full layout")) { Toggle("Show hat icon", isOn: $showFloatingHatIcon) @@ -835,7 +842,7 @@ struct FloatingSettingsView: View { Text("same as non-clipboard").tag(-1) Text("never").tag(0) }.disabled(!autoHideFloatingResults).padding(.leading, 20) - } + }.disabled(!enableFloatingResults) Section(header: SectionHeader(title: "Compact layout")) { Toggle("Show images", isOn: $showCompactImages) @@ -855,7 +862,7 @@ struct FloatingSettingsView: View { Text("30 minutes").tag(1800) Text("never").tag(0) } - } + }.disabled(!enableFloatingResults) } .frame(maxWidth: 380).fixedSize() @@ -872,10 +879,14 @@ struct FloatingSettingsView: View { CompactPreview() .frame(width: THUMB_SIZE.width + 60, height: 450, alignment: .center) .background(RoundedRectangle(cornerRadius: 8, style: .continuous).stroke(Color.gray.opacity(0.2), lineWidth: 2)) + .disabled(!enableFloatingResults) + .saturation(enableFloatingResults ? 1 : 0.5) } else { FloatingPreview() .frame(width: THUMB_SIZE.width + 60, height: 450, alignment: .center) .background(RoundedRectangle(cornerRadius: 8, style: .continuous).stroke(Color.gray.opacity(0.2), lineWidth: 2)) + .disabled(!enableFloatingResults) + .saturation(enableFloatingResults ? 1 : 0.5) } Picker("", selection: $compact) { Text("Compact").tag(true) diff --git a/ReleaseNotes/2.6.0.md b/ReleaseNotes/2.6.0.md index 2e512ab..6d93868 100644 --- a/ReleaseNotes/2.6.0.md +++ b/ReleaseNotes/2.6.0.md @@ -3,6 +3,7 @@ - Use the new [Jpegli](https://opensource.googleblog.com/2024/04/introducing-jpegli-new-jpeg-coding-library.html?hnid=39920644) perceptive encoder from Google for even smaller JPEG images - Update `ffmpeg` to version 7.0 - Allow configuring the location where Clop stores temporary files and backups and when to clean up files +- Allow disabling floating results UI ## Improvements