Private
Public Access
1
0

osx: implements quicklook

This commit is contained in:
2025-09-12 18:17:58 -07:00
parent 87e986707d
commit 1a5f13f2b8
5 changed files with 143 additions and 14 deletions

View File

@@ -0,0 +1,39 @@
//
// PreviewPanel.swift
// Kordophone
//
// Created by James Magahern on 9/12/25.
//
import AppKit
import QuickLook
import QuickLookUI
internal class PreviewPanel
{
static let shared = PreviewPanel()
private var displayedURL: URL? = nil
private var impl: QLPreviewPanel { QLPreviewPanel.shared() }
private init() {
impl.dataSource = self
}
public func show(url: URL) {
self.displayedURL = url
impl.makeKeyAndOrderFront(self)
}
}
extension PreviewPanel: QLPreviewPanelDataSource
{
func numberOfPreviewItems(in panel: QLPreviewPanel!) -> Int {
1
}
func previewPanel(_ panel: QLPreviewPanel!, previewItemAt index: Int) -> (any QLPreviewItem)! {
return displayedURL! as NSURL
}
}

View File

@@ -90,7 +90,8 @@ struct ImageItemView: View
@Environment(\.xpcClient) var xpcClient
@State private var containerWidth: CGFloat? = nil
@State private var isDownloadingFullAttachment: Bool = false
private var aspectRatio: CGFloat {
attachment.size?.aspectRatio ?? 1.0
}
@@ -102,17 +103,36 @@ struct ImageItemView: View
var body: some View {
BubbleView(sender: sender, date: date) {
let maxWidth = CGFloat.minimum(.imageMaxWidth, containerWidth ?? .imageMaxWidth)
if let img {
Image(nsImage: img)
.resizable()
.scaledToFit()
.frame(maxWidth: maxWidth)
} else {
Rectangle()
.fill(.gray.opacity(0.4))
.frame(width: preferredWidth, height: preferredWidth / aspectRatio)
.frame(maxWidth: maxWidth)
Group {
if let img {
Image(nsImage: img)
.resizable()
.scaledToFit()
.frame(maxWidth: maxWidth)
} else {
Rectangle()
.fill(.gray.opacity(0.4))
.frame(width: preferredWidth, height: preferredWidth / aspectRatio)
.frame(maxWidth: maxWidth)
}
}
// Download indicator
.overlay {
if isDownloadingFullAttachment {
ZStack {
Rectangle()
.fill(.black.opacity(0.2))
ProgressView()
.progressViewStyle(.circular)
}
}
}
}
.onTapGesture(count: 2) {
openAttachment()
}
.onGeometryChange(for: CGFloat.self,
of: { $0.size.width },
@@ -136,6 +156,24 @@ struct ImageItemView: View
}
}
}
private func openAttachment() {
Task {
var path = attachment.fullsizePath
if !attachment.isFullsizeDownloaded {
isDownloadingFullAttachment = true
try await xpcClient.downloadAttachment(attachmentId: attachment.id, preview: false, awaitCompletion: true)
// Need to re-fetch this -- the extension may have changed.
let info = try await xpcClient.getAttachmentInfo(attachmentId: attachment.id)
path = info.path
isDownloadingFullAttachment = false
}
PreviewPanel.shared.show(url: URL(filePath: path))
}
}
}
struct PlaceholderImageItemView: View