Implement macOS share button

This commit is contained in:
Maurice Parker
2020-07-14 17:10:53 -05:00
parent cea168380f
commit 31068f90a0
5 changed files with 166 additions and 4 deletions

View File

@@ -0,0 +1,32 @@
//
// SharingServiceDelegate.swift
// NetNewsWire
//
// Created by Maurice Parker on 9/7/18.
// Copyright © 2018 Ranchero Software. All rights reserved.
//
import AppKit
@objc final class SharingServiceDelegate: NSObject, NSSharingServiceDelegate {
weak var window: NSWindow?
init(_ window: NSWindow?) {
self.window = window
}
func sharingService(_ sharingService: NSSharingService, willShareItems items: [Any]) {
sharingService.subject = items
.compactMap { item in
let writer = item as? ArticlePasteboardWriter
return writer?.article.title
}
.joined(separator: ", ")
}
func sharingService(_ sharingService: NSSharingService, sourceWindowForShareItems items: [Any], sharingContentScope: UnsafeMutablePointer<NSSharingService.SharingContentScope>) -> NSWindow? {
return window
}
}

View File

@@ -0,0 +1,54 @@
//
// SharingServicePickerDelegate.swift
// NetNewsWire
//
// Created by Brent Simmons on 2/17/18.
// Copyright © 2018 Ranchero Software. All rights reserved.
//
import AppKit
import RSCore
@objc final class SharingServicePickerDelegate: NSObject, NSSharingServicePickerDelegate {
private let sharingServiceDelegate: SharingServiceDelegate
private let completion: (() -> Void)?
init(_ window: NSWindow?, completion: (() -> Void)?) {
self.sharingServiceDelegate = SharingServiceDelegate(window)
self.completion = completion
}
func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, sharingServicesForItems items: [Any], proposedSharingServices proposedServices: [NSSharingService]) -> [NSSharingService] {
return proposedServices + SharingServicePickerDelegate.customSharingServices(for: items)
}
func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, delegateFor sharingService: NSSharingService) -> NSSharingServiceDelegate? {
return sharingServiceDelegate
}
func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, didChoose service: NSSharingService?) {
completion?()
}
static func customSharingServices(for items: [Any]) -> [NSSharingService] {
let customServices = ExtensionPointManager.shared.activeSendToCommands.compactMap { (sendToCommand) -> NSSharingService? in
guard let object = items.first else {
return nil
}
guard sendToCommand.canSendObject(object, selectedText: nil) else {
return nil
}
let image = sendToCommand.image ?? NSImage()
return NSSharingService(title: sendToCommand.title, image: image, alternateImage: nil) {
sendToCommand.sendObject(object, selectedText: nil)
}
}
return customServices
}
}

View File

@@ -0,0 +1,56 @@
//
// SharingServiceView.swift
// Multiplatform macOS
//
// Created by Maurice Parker on 7/14/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import SwiftUI
import AppKit
import Articles
class SharingServiceController: NSViewController {
var sharingServicePickerDelegate: SharingServicePickerDelegate? = nil
var articles = [Article]()
var completion: (() -> Void)? = nil
override func loadView() {
view = NSView()
}
override func viewDidAppear() {
guard let anchor = view.superview?.superview else { return }
sharingServicePickerDelegate = SharingServicePickerDelegate(self.view.window, completion: completion)
let sortedArticles = articles.sortedByDate(.orderedAscending)
let items = sortedArticles.map { ArticlePasteboardWriter(article: $0) }
let sharingServicePicker = NSSharingServicePicker(items: items)
sharingServicePicker.delegate = sharingServicePickerDelegate
sharingServicePicker.show(relativeTo: anchor.bounds, of: anchor, preferredEdge: .minY)
}
}
struct SharingServiceView: NSViewControllerRepresentable {
var articles: [Article]
@Binding var showing: Bool
func makeNSViewController(context: Context) -> SharingServiceController {
let controller = SharingServiceController()
controller.articles = articles
controller.completion = {
showing = false
}
return controller
}
func updateNSViewController(_ nsViewController: SharingServiceController, context: Context) {
}
}