From 659c9e5271fd41fb816008c59aa84d5ac6e53b70 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Mon, 27 May 2019 15:11:16 -0500 Subject: [PATCH] Allow dragged feeds between local accounts only --- Mac/MainWindow/Sidebar/PasteboardFeed.swift | 19 +++++-- .../Sidebar/SidebarOutlineDataSource.swift | 57 +++++++++---------- 2 files changed, 42 insertions(+), 34 deletions(-) diff --git a/Mac/MainWindow/Sidebar/PasteboardFeed.swift b/Mac/MainWindow/Sidebar/PasteboardFeed.swift index 03cf72a6e..5e0bc89e3 100644 --- a/Mac/MainWindow/Sidebar/PasteboardFeed.swift +++ b/Mac/MainWindow/Sidebar/PasteboardFeed.swift @@ -22,6 +22,7 @@ struct PasteboardFeed: Hashable { // Internal static let accountID = "accountID" + static let accountType = "accountType" static let feedID = "feedID" static let editedName = "editedName" } @@ -32,15 +33,17 @@ struct PasteboardFeed: Hashable { let name: String? let editedName: String? let accountID: String? + let accountType: AccountType? let isLocalFeed: Bool - init(url: String, feedID: String?, homePageURL: String?, name: String?, editedName: String?, accountID: String?) { + init(url: String, feedID: String?, homePageURL: String?, name: String?, editedName: String?, accountID: String?, accountType: AccountType?) { self.url = url.rs_normalizedURL() self.feedID = feedID self.homePageURL = homePageURL?.rs_normalizedURL() self.name = name self.editedName = editedName self.accountID = accountID + self.accountType = accountType self.isLocalFeed = accountID != nil } @@ -57,7 +60,12 @@ struct PasteboardFeed: Hashable { let feedID = dictionary[Key.feedID] let editedName = dictionary[Key.editedName] - self.init(url: url, feedID: feedID, homePageURL: homePageURL, name: name, editedName: editedName, accountID: accountID) + var accountType: AccountType? = nil + if let accountTypeString = dictionary[Key.accountType], let accountTypeInt = Int(accountTypeString) { + accountType = AccountType(rawValue: accountTypeInt) + } + + self.init(url: url, feedID: feedID, homePageURL: homePageURL, name: name, editedName: editedName, accountID: accountID, accountType: accountType) } init?(pasteboardItem: NSPasteboardItem) { @@ -86,7 +94,7 @@ struct PasteboardFeed: Hashable { if let foundType = pasteboardType { if let possibleURLString = pasteboardItem.string(forType: foundType) { if possibleURLString.rs_stringMayBeURL() { - self.init(url: possibleURLString, feedID: nil, homePageURL: nil, name: nil, editedName: nil, accountID: nil) + self.init(url: possibleURLString, feedID: nil, homePageURL: nil, name: nil, editedName: nil, accountID: nil, accountType: nil) return } } @@ -131,6 +139,9 @@ struct PasteboardFeed: Hashable { if let accountID = accountID { d[PasteboardFeed.Key.accountID] = accountID } + if let accountType = accountType { + d[PasteboardFeed.Key.accountType] = String(accountType.rawValue) + } return d } } @@ -186,7 +197,7 @@ extension Feed: PasteboardWriterOwner { private extension FeedPasteboardWriter { var pasteboardFeed: PasteboardFeed { - return PasteboardFeed(url: feed.url, feedID: feed.feedID, homePageURL: feed.homePageURL, name: feed.name, editedName: feed.editedName, accountID: feed.account?.accountID) + return PasteboardFeed(url: feed.url, feedID: feed.feedID, homePageURL: feed.homePageURL, name: feed.name, editedName: feed.editedName, accountID: feed.account?.accountID, accountType: feed.account?.type) } var exportDictionary: PasteboardFeedDictionary { diff --git a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift index 08f4f833b..f2a44feff 100644 --- a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift +++ b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift @@ -173,7 +173,7 @@ private extension SidebarOutlineDataSource { guard let dropTargetNode = ancestorThatCanAcceptLocalFeed(parentNode) else { return SidebarOutlineDataSource.dragOperationNone } - if nodeAndDraggedFeedsDoNotShareAccount(dropTargetNode, Set([draggedFeed])) { + if !allParticipantsAreLocalAccounts(dropTargetNode, Set([draggedFeed])) { return SidebarOutlineDataSource.dragOperationNone } if nodeHasChildRepresentingDraggedFeed(dropTargetNode, draggedFeed) { @@ -194,7 +194,7 @@ private extension SidebarOutlineDataSource { guard let dropTargetNode = ancestorThatCanAcceptLocalFeed(parentNode) else { return SidebarOutlineDataSource.dragOperationNone } - if nodeAndDraggedFeedsDoNotShareAccount(dropTargetNode, draggedFeeds) { + if !allParticipantsAreLocalAccounts(dropTargetNode, draggedFeeds) { return SidebarOutlineDataSource.dragOperationNone } if nodeHasChildRepresentingAnyDraggedFeed(dropTargetNode, draggedFeeds) { @@ -219,26 +219,19 @@ private extension SidebarOutlineDataSource { return nil } - private func commonAccountFor(_ nodes: Set) -> Account? { - // Return the Account if every node has an Account and they’re all the same. - var account: Account? = nil + private func commonAccountsFor(_ nodes: Set) -> Set { + + var accounts = Set() for node in nodes { guard let oneAccount = accountForNode(node) else { - return nil - } - if account == nil { - account = oneAccount - } - else { - if account != oneAccount { - return nil - } + continue } + accounts.insert(oneAccount) } - return account + return accounts } - private func move(node: Node, to parentNode: Node, account: Account) { + private func move(node: Node, to parentNode: Node) { guard let feed = node.representedObject as? Feed else { return } @@ -270,14 +263,15 @@ private extension SidebarOutlineDataSource { guard let draggedNodes = draggedNodes else { return false } - let allReferencedNodes = draggedNodes.union(Set([parentNode])) - guard let account = commonAccountFor(allReferencedNodes) else { - return false - } + BatchUpdate.shared.perform { - draggedNodes.forEach { move(node: $0, to: parentNode, account: account) } + draggedNodes.forEach { move(node: $0, to: parentNode) } } - account.structureDidChange() + + let allReferencedNodes = draggedNodes.union(Set([parentNode])) + let accounts = commonAccountsFor(allReferencedNodes) + accounts.forEach { $0.structureDidChange() } + return true } @@ -346,24 +340,27 @@ private extension SidebarOutlineDataSource { return false } - func nodeAndDraggedFeedsDoNotShareAccount(_ parentNode: Node, _ draggedFeeds: Set) -> Bool { + func allParticipantsAreLocalAccounts(_ parentNode: Node, _ draggedFeeds: Set) -> Bool { - let parentAccountId: String? if let account = parentNode.representedObject as? Account { - parentAccountId = account.accountID + if account.type != .onMyMac { + return false + } } else if let folder = parentNode.representedObject as? Folder { - parentAccountId = folder.account?.accountID + if folder.account?.type != .onMyMac { + return false + } } else { - return true + return false } for draggedFeed in draggedFeeds { - if draggedFeed.accountID != parentAccountId { - return true + if draggedFeed.accountType != .onMyMac { + return false } } - return false + return true }