mirror of
https://github.com/Ranchero-Software/NetNewsWire.git
synced 2024-12-23 16:20:53 +01:00
142 lines
3.4 KiB
Swift
142 lines
3.4 KiB
Swift
//
|
|
// FolderPasteboardWriter.swift
|
|
// NetNewsWire
|
|
//
|
|
// Created by Brent Simmons on 2/11/18.
|
|
// Copyright © 2018 Ranchero Software. All rights reserved.
|
|
//
|
|
|
|
import AppKit
|
|
import Account
|
|
import AppKitExtras
|
|
|
|
typealias PasteboardFolderDictionary = [String: String]
|
|
|
|
@MainActor struct PasteboardFolder: Hashable {
|
|
|
|
private struct Key {
|
|
static let name = "name"
|
|
// Internal
|
|
static let folderID = "folderID"
|
|
static let accountID = "accountID"
|
|
}
|
|
|
|
|
|
let name: String
|
|
let folderID: String?
|
|
let accountID: String?
|
|
|
|
init(name: String, folderID: String?, accountID: String?) {
|
|
self.name = name
|
|
self.folderID = folderID
|
|
self.accountID = accountID
|
|
}
|
|
|
|
// MARK: - Reading
|
|
|
|
init?(dictionary: PasteboardFolderDictionary) {
|
|
guard let name = dictionary[Key.name] else {
|
|
return nil
|
|
}
|
|
|
|
let folderID = dictionary[Key.folderID]
|
|
let accountID = dictionary[Key.accountID]
|
|
|
|
self.init(name: name, folderID: folderID, accountID: accountID)
|
|
}
|
|
|
|
init?(pasteboardItem: NSPasteboardItem) {
|
|
var pasteboardType: NSPasteboard.PasteboardType?
|
|
if pasteboardItem.types.contains(FolderPasteboardWriter.folderUTIInternalType) {
|
|
pasteboardType = FolderPasteboardWriter.folderUTIInternalType
|
|
}
|
|
|
|
if let foundType = pasteboardType {
|
|
if let folderDictionary = pasteboardItem.propertyList(forType: foundType) as? PasteboardFeedDictionary {
|
|
self.init(dictionary: folderDictionary)
|
|
return
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
static func pasteboardFolders(with pasteboard: NSPasteboard) -> Set<PasteboardFolder>? {
|
|
guard let items = pasteboard.pasteboardItems else {
|
|
return nil
|
|
}
|
|
let folders = items.compactMap { PasteboardFolder(pasteboardItem: $0) }
|
|
return folders.isEmpty ? nil : Set(folders)
|
|
}
|
|
|
|
// MARK: - Writing
|
|
|
|
func internalDictionary() -> PasteboardFolderDictionary {
|
|
var d = PasteboardFeedDictionary()
|
|
d[PasteboardFolder.Key.name] = name
|
|
if let folderID = folderID {
|
|
d[PasteboardFolder.Key.folderID] = folderID
|
|
}
|
|
if let accountID = accountID {
|
|
d[PasteboardFolder.Key.accountID] = accountID
|
|
}
|
|
return d
|
|
}
|
|
}
|
|
|
|
extension Folder: PasteboardWriterOwner {
|
|
|
|
public var pasteboardWriter: NSPasteboardWriting {
|
|
return FolderPasteboardWriter(folder: self)
|
|
}
|
|
}
|
|
|
|
@MainActor @objc final class FolderPasteboardWriter: NSObject, NSPasteboardWriting {
|
|
|
|
private let folder: Folder
|
|
static let folderUTIInternal = "com.ranchero.NetNewsWire-Evergreen.internal.folder"
|
|
static let folderUTIInternalType = NSPasteboard.PasteboardType(rawValue: folderUTIInternal)
|
|
|
|
init(folder: Folder) {
|
|
|
|
self.folder = folder
|
|
}
|
|
|
|
// MARK: - NSPasteboardWriting
|
|
|
|
nonisolated func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
|
|
|
|
MainActor.assumeIsolated {
|
|
return [.string, FolderPasteboardWriter.folderUTIInternalType]
|
|
}
|
|
}
|
|
|
|
nonisolated func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
|
|
|
|
MainActor.assumeIsolated {
|
|
let plist: Any?
|
|
|
|
switch type {
|
|
case .string:
|
|
plist = folder.nameForDisplay
|
|
case FolderPasteboardWriter.folderUTIInternalType:
|
|
plist = internalDictionary
|
|
default:
|
|
plist = nil
|
|
}
|
|
|
|
return plist
|
|
}
|
|
}
|
|
}
|
|
|
|
private extension FolderPasteboardWriter {
|
|
var pasteboardFolder: PasteboardFolder {
|
|
return PasteboardFolder(name: folder.name ?? "", folderID: String(folder.folderID), accountID: folder.account?.accountID)
|
|
}
|
|
|
|
var internalDictionary: PasteboardFeedDictionary {
|
|
return pasteboardFolder.internalDictionary()
|
|
}
|
|
}
|