aboutsummaryrefslogtreecommitdiff
path: root/Hotline/macOS/Files/FilePreviewQuickLookView.swift
diff options
context:
space:
mode:
authorRuben Beltran del Rio <git@r.bdr.sh>2025-11-27 23:38:04 +0100
committerRuben Beltran del Rio <git@r.bdr.sh>2025-11-27 23:38:04 +0100
commit213710bf5bd6413c747bf126db50816ef5de5a6e (patch)
tree912f8cf87955a08077c92fea8ad934f50b7ab975 /Hotline/macOS/Files/FilePreviewQuickLookView.swift
parentf466b21dc02f78c984ba6748e703f6780a7a0db4 (diff)
parent6a95b53616a4abfa306ddce43151cf4fefbd20ed (diff)
Merge remote-tracking branch 'upstream/main'
Diffstat (limited to 'Hotline/macOS/Files/FilePreviewQuickLookView.swift')
-rw-r--r--Hotline/macOS/Files/FilePreviewQuickLookView.swift114
1 files changed, 114 insertions, 0 deletions
diff --git a/Hotline/macOS/Files/FilePreviewQuickLookView.swift b/Hotline/macOS/Files/FilePreviewQuickLookView.swift
new file mode 100644
index 0000000..a504a7a
--- /dev/null
+++ b/Hotline/macOS/Files/FilePreviewQuickLookView.swift
@@ -0,0 +1,114 @@
+import SwiftUI
+import UniformTypeIdentifiers
+
+struct FilePreviewQuickLookView: View {
+ enum FilePreviewFocus: Hashable {
+ case window
+ }
+
+ @Environment(\.controlActiveState) private var controlActiveState
+ @Environment(\.colorScheme) private var colorScheme
+ @Environment(\.dismiss) private var dismiss
+
+ @Binding var info: PreviewFileInfo?
+ @State private var preview: FilePreviewState? = nil
+
+ @FocusState private var focusField: FilePreviewFocus?
+
+ var body: some View {
+ Group {
+ if self.preview?.state != .loaded {
+ VStack(alignment: .center, spacing: 0) {
+ Spacer()
+ ProgressView(value: max(0.0, min(1.0, self.preview?.progress ?? 0.0)))
+ .focusable(false)
+ .progressViewStyle(.circular)
+ .controlSize(.extraLarge)
+ .frame(maxWidth: 300, alignment: .center)
+ .padding(.bottom, 48)
+ Spacer()
+ }
+ .background(Color(nsColor: .textBackgroundColor))
+ .frame(minWidth: 350, maxWidth: .infinity, minHeight: 150, maxHeight: .infinity)
+ .padding()
+ }
+ else {
+ if let fileURL = self.preview?.fileURL {
+ QuickLookPreviewView(fileURL: fileURL)
+ .frame(minWidth: 400, maxWidth: .infinity, minHeight: 400, maxHeight: .infinity)
+ }
+ else {
+ VStack(alignment: .center, spacing: 0) {
+ Spacer()
+
+ Image(systemName: "eye.trianglebadge.exclamationmark")
+ .resizable()
+ .scaledToFit()
+ .frame(maxWidth: .infinity)
+ .frame(height: 48)
+ .padding(.bottom)
+ Group {
+ Text("This file type is not previewable")
+ .bold()
+ Text("Try downloading and opening this file in another application.")
+ .foregroundStyle(Color.secondary)
+ }
+ .font(.system(size: 14.0))
+ .frame(maxWidth: 300)
+ .multilineTextAlignment(.center)
+
+ Spacer()
+ Spacer()
+ }
+ .frame(minWidth: 350, maxWidth: .infinity, minHeight: 150, maxHeight: .infinity)
+ .padding()
+ }
+ }
+ }
+ .focusable()
+ .focusEffectDisabled()
+ .background(Color(nsColor: .textBackgroundColor))
+ .focused(self.$focusField, equals: .window)
+ .navigationTitle(self.info?.name ?? "File Preview")
+ .applyNavigationDocumentIfPresent(self.preview?.fileURL)
+ .toolbar {
+ if let fileURL = self.preview?.fileURL {
+ if let info = info {
+ ToolbarItem(placement: .primaryAction) {
+ Button {
+ FileManager.default.copyToDownloads(from: fileURL, using: info.name, bounceDock: true)
+ } label: {
+ Label("Download File...", systemImage: "arrow.down")
+ }
+ .help("Download File")
+ }
+ }
+ }
+ }
+ .task {
+ if let info = self.info {
+ self.preview = FilePreviewState(info: info)
+ self.preview?.download()
+ }
+ }
+ .onAppear {
+ guard self.info != nil else {
+ self.dismiss()
+ return
+ }
+
+ self.focusField = .window
+ }
+ .onDisappear {
+ self.preview?.cancel()
+ self.preview?.cleanup()
+ self.dismiss()
+ }
+ .onChange(of: self.preview?.state) {
+ if self.preview?.state == .failed {
+ self.dismiss()
+ }
+ }
+ .preferredColorScheme(.dark)
+ }
+}