Enable copy between local accounts.
This commit is contained in:
parent
659c9e5271
commit
c7b61f7d87
@ -143,8 +143,10 @@ final class LocalAccountDelegate: AccountDelegate {
|
|||||||
func addFeed(for account: Account, to container: Container, with feed: Feed, completion: @escaping (Result<Void, Error>) -> Void) {
|
func addFeed(for account: Account, to container: Container, with feed: Feed, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
if let folder = container as? Folder {
|
if let folder = container as? Folder {
|
||||||
folder.addFeed(feed)
|
folder.addFeed(feed)
|
||||||
|
feed.account = folder.account
|
||||||
} else if let account = container as? Account {
|
} else if let account = container as? Account {
|
||||||
account.addFeed(feed)
|
account.addFeed(feed)
|
||||||
|
feed.account = account
|
||||||
}
|
}
|
||||||
completion(.success(()))
|
completion(.success(()))
|
||||||
}
|
}
|
||||||
|
@ -179,14 +179,15 @@ private extension SidebarOutlineDataSource {
|
|||||||
if nodeHasChildRepresentingDraggedFeed(dropTargetNode, draggedFeed) {
|
if nodeHasChildRepresentingDraggedFeed(dropTargetNode, draggedFeed) {
|
||||||
return SidebarOutlineDataSource.dragOperationNone
|
return SidebarOutlineDataSource.dragOperationNone
|
||||||
}
|
}
|
||||||
|
let dragOperation: NSDragOperation = localFeedsDropOperation(dropTargetNode, Set([draggedFeed]))
|
||||||
if parentNode == dropTargetNode && index == NSOutlineViewDropOnItemIndex {
|
if parentNode == dropTargetNode && index == NSOutlineViewDropOnItemIndex {
|
||||||
return .move
|
return dragOperation
|
||||||
}
|
}
|
||||||
let updatedIndex = indexWhereDraggedFeedWouldAppear(dropTargetNode, draggedFeed)
|
let updatedIndex = indexWhereDraggedFeedWouldAppear(dropTargetNode, draggedFeed)
|
||||||
if parentNode !== dropTargetNode || index != updatedIndex {
|
if parentNode !== dropTargetNode || index != updatedIndex {
|
||||||
outlineView.setDropItem(dropTargetNode, dropChildIndex: updatedIndex)
|
outlineView.setDropItem(dropTargetNode, dropChildIndex: updatedIndex)
|
||||||
}
|
}
|
||||||
return .move
|
return dragOperation
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateLocalFeedsDrop(_ outlineView: NSOutlineView, _ draggedFeeds: Set<PasteboardFeed>, _ parentNode: Node, _ index: Int) -> NSDragOperation {
|
func validateLocalFeedsDrop(_ outlineView: NSOutlineView, _ draggedFeeds: Set<PasteboardFeed>, _ parentNode: Node, _ index: Int) -> NSDragOperation {
|
||||||
@ -203,8 +204,19 @@ private extension SidebarOutlineDataSource {
|
|||||||
if parentNode !== dropTargetNode || index != NSOutlineViewDropOnItemIndex {
|
if parentNode !== dropTargetNode || index != NSOutlineViewDropOnItemIndex {
|
||||||
outlineView.setDropItem(dropTargetNode, dropChildIndex: NSOutlineViewDropOnItemIndex)
|
outlineView.setDropItem(dropTargetNode, dropChildIndex: NSOutlineViewDropOnItemIndex)
|
||||||
}
|
}
|
||||||
|
return localFeedsDropOperation(dropTargetNode, draggedFeeds)
|
||||||
|
}
|
||||||
|
|
||||||
|
func localFeedsDropOperation(_ dropTargetNode: Node, _ draggedFeeds: Set<PasteboardFeed>) -> NSDragOperation {
|
||||||
|
if allParticipantsAreSameAccount(dropTargetNode, draggedFeeds) {
|
||||||
return .move
|
return .move
|
||||||
}
|
}
|
||||||
|
if NSApplication.shared.currentEvent?.modifierFlags.contains(.option) ?? false {
|
||||||
|
return .copy
|
||||||
|
} else {
|
||||||
|
return .move
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func accountForNode(_ node: Node) -> Account? {
|
private func accountForNode(_ node: Node) -> Account? {
|
||||||
if let account = node.representedObject as? Account {
|
if let account = node.representedObject as? Account {
|
||||||
@ -231,12 +243,34 @@ private extension SidebarOutlineDataSource {
|
|||||||
return accounts
|
return accounts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func copy(node: Node, to parentNode: Node) {
|
||||||
|
guard let feed = node.representedObject as? Feed else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let destination = parentNode.representedObject as? Container
|
||||||
|
|
||||||
|
BatchUpdate.shared.start()
|
||||||
|
destination?.addFeed(feed) { result in
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
BatchUpdate.shared.end()
|
||||||
|
break
|
||||||
|
case .failure(let error):
|
||||||
|
BatchUpdate.shared.end()
|
||||||
|
NSApplication.shared.presentError(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func move(node: Node, to parentNode: Node) {
|
private func move(node: Node, to parentNode: Node) {
|
||||||
guard let feed = node.representedObject as? Feed else {
|
guard let feed = node.representedObject as? Feed else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let source = node.parent?.representedObject as? Container
|
let source = node.parent?.representedObject as? Container
|
||||||
let destination = parentNode.representedObject as? Container
|
let destination = parentNode.representedObject as? Container
|
||||||
|
|
||||||
BatchUpdate.shared.start()
|
BatchUpdate.shared.start()
|
||||||
source?.removeFeed(feed) { result in
|
source?.removeFeed(feed) { result in
|
||||||
switch result {
|
switch result {
|
||||||
@ -256,6 +290,7 @@ private extension SidebarOutlineDataSource {
|
|||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
NSApplication.shared.presentError(error)
|
NSApplication.shared.presentError(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +300,17 @@ private extension SidebarOutlineDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BatchUpdate.shared.perform {
|
BatchUpdate.shared.perform {
|
||||||
draggedNodes.forEach { move(node: $0, to: parentNode) }
|
|
||||||
|
draggedNodes.forEach { node in
|
||||||
|
if sameAccount(node, parentNode) {
|
||||||
|
move(node: node, to: parentNode)
|
||||||
|
} else if NSApplication.shared.currentEvent?.modifierFlags.contains(.option) ?? false {
|
||||||
|
copy(node: node, to: parentNode)
|
||||||
|
} else {
|
||||||
|
move(node: node, to: parentNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let allReferencedNodes = draggedNodes.union(Set([parentNode]))
|
let allReferencedNodes = draggedNodes.union(Set([parentNode]))
|
||||||
@ -364,6 +409,41 @@ private extension SidebarOutlineDataSource {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func allParticipantsAreSameAccount(_ parentNode: Node, _ draggedFeeds: Set<PasteboardFeed>) -> Bool {
|
||||||
|
guard let parentAccountID = nodeAccountID(parentNode) else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for draggedFeed in draggedFeeds {
|
||||||
|
if draggedFeed.accountID != parentAccountID {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func sameAccount(_ node: Node, _ parentNode: Node) -> Bool {
|
||||||
|
if let accountID = nodeAccountID(node), let parentAccountID = nodeAccountID(parentNode) {
|
||||||
|
if accountID == parentAccountID {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func nodeAccountID(_ node: Node) -> String? {
|
||||||
|
if let account = node.representedObject as? Account {
|
||||||
|
return account.accountID
|
||||||
|
} else if let folder = node.representedObject as? Folder {
|
||||||
|
return folder.account?.accountID
|
||||||
|
} else if let feed = node.representedObject as? Feed {
|
||||||
|
return feed.account?.accountID
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func nodeHasChildRepresentingAnyDraggedFeed(_ parentNode: Node, _ draggedFeeds: Set<PasteboardFeed>) -> Bool {
|
func nodeHasChildRepresentingAnyDraggedFeed(_ parentNode: Node, _ draggedFeeds: Set<PasteboardFeed>) -> Bool {
|
||||||
for node in parentNode.childNodes {
|
for node in parentNode.childNodes {
|
||||||
if nodeRepresentsAnyDraggedFeed(node, draggedFeeds) {
|
if nodeRepresentsAnyDraggedFeed(node, draggedFeeds) {
|
||||||
|
@ -47,8 +47,7 @@ protocol SidebarDelegate: class {
|
|||||||
sidebarCellAppearance = SidebarCellAppearance(fontSize: AppDefaults.sidebarFontSize)
|
sidebarCellAppearance = SidebarCellAppearance(fontSize: AppDefaults.sidebarFontSize)
|
||||||
|
|
||||||
outlineView.dataSource = dataSource
|
outlineView.dataSource = dataSource
|
||||||
outlineView.setDraggingSourceOperationMask(.move, forLocal: true)
|
outlineView.setDraggingSourceOperationMask([.move, .copy], forLocal: true)
|
||||||
outlineView.setDraggingSourceOperationMask(.copy, forLocal: false)
|
|
||||||
outlineView.registerForDraggedTypes([FeedPasteboardWriter.feedUTIInternalType, FeedPasteboardWriter.feedUTIType, .URL, .string])
|
outlineView.registerForDraggedTypes([FeedPasteboardWriter.feedUTIInternalType, FeedPasteboardWriter.feedUTIType, .URL, .string])
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user