nextcloud-desktop/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareViewController.swift
Claudio Cambra 820c7e4bd1 Add outlet for share view table view
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
2024-04-17 16:11:50 +08:00

109 lines
3.8 KiB
Swift

//
// ShareViewController.swift
// FileProviderUIExt
//
// Created by Claudio Cambra on 21/2/24.
//
import AppKit
import FileProvider
import OSLog
import QuickLookThumbnailing
class ShareViewController: NSViewController {
let itemIdentifiers: [NSFileProviderItemIdentifier]
@IBOutlet weak var fileNameIcon: NSImageView!
@IBOutlet weak var fileNameLabel: NSTextField!
@IBOutlet weak var descriptionLabel: NSTextField!
@IBOutlet weak var closeButton: NSButton!
@IBOutlet weak var tableView: NSTableView!
public override var nibName: NSNib.Name? {
return NSNib.Name(self.className)
}
var actionViewController: DocumentActionViewController! {
return parent as? DocumentActionViewController
}
init(_ itemIdentifiers: [NSFileProviderItemIdentifier]) {
self.itemIdentifiers = itemIdentifiers
super.init(nibName: nil, bundle: nil)
guard let firstItem = itemIdentifiers.first else {
Logger.shareViewController.error("called without items")
closeAction(self)
return
}
Task {
await processItemIdentifier(firstItem)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@IBAction func closeAction(_ sender: Any) {
actionViewController.extensionContext.completeRequest()
}
private func processItemIdentifier(_ itemIdentifier: NSFileProviderItemIdentifier) async {
guard let manager = NSFileProviderManager(for: actionViewController.domain) else {
fatalError("NSFileProviderManager isn't expected to fail")
}
do {
let itemUrl = try await manager.getUserVisibleURL(for: itemIdentifier)
await updateDisplay(itemUrl: itemUrl)
} catch let error {
let errorString = "Error processing item: \(error)"
Logger.shareViewController.error("\(errorString)")
fileNameLabel.stringValue = "Unknown item"
descriptionLabel.stringValue = errorString
}
}
private func updateDisplay(itemUrl: URL) async {
fileNameLabel.stringValue = itemUrl.lastPathComponent
let request = QLThumbnailGenerator.Request(
fileAt: itemUrl,
size: CGSize(width: 128, height: 128),
scale: 1.0,
representationTypes: .icon
)
let generator = QLThumbnailGenerator.shared
let fileThumbnail = await withCheckedContinuation { continuation in
generator.generateRepresentations(for: request) { thumbnail, type, error in
if thumbnail == nil || error != nil {
Logger.shareViewController.error("Could not get thumbnail: \(error)")
}
continuation.resume(returning: thumbnail)
}
}
fileNameIcon.image = fileThumbnail?.nsImage
}
private func serviceConnection(url: URL) async throws -> FPUIExtensionService {
let services = try await FileManager().fileProviderServicesForItem(at: url)
guard let service = services[fpUiExtensionServiceName] else {
Logger.shareViewController.error("Couldn't get service, required service not present")
throw NSFileProviderError(.providerNotFound)
}
let connection: NSXPCConnection
connection = try await service.fileProviderConnection()
connection.remoteObjectInterface = NSXPCInterface(with: FPUIExtensionService.self)
connection.interruptionHandler = {
Logger.shareViewController.error("Service connection interrupted")
}
connection.resume()
guard let proxy = connection.remoteObjectProxy as? FPUIExtensionService else {
throw NSFileProviderError(.serverUnreachable)
}
return proxy
}
}