Allow dragged feeds between local accounts only

This commit is contained in:
Maurice Parker 2019-05-27 15:11:16 -05:00
parent 324198066e
commit 659c9e5271
2 changed files with 42 additions and 34 deletions

View File

@ -22,6 +22,7 @@ struct PasteboardFeed: Hashable {
// Internal // Internal
static let accountID = "accountID" static let accountID = "accountID"
static let accountType = "accountType"
static let feedID = "feedID" static let feedID = "feedID"
static let editedName = "editedName" static let editedName = "editedName"
} }
@ -32,15 +33,17 @@ struct PasteboardFeed: Hashable {
let name: String? let name: String?
let editedName: String? let editedName: String?
let accountID: String? let accountID: String?
let accountType: AccountType?
let isLocalFeed: Bool 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.url = url.rs_normalizedURL()
self.feedID = feedID self.feedID = feedID
self.homePageURL = homePageURL?.rs_normalizedURL() self.homePageURL = homePageURL?.rs_normalizedURL()
self.name = name self.name = name
self.editedName = editedName self.editedName = editedName
self.accountID = accountID self.accountID = accountID
self.accountType = accountType
self.isLocalFeed = accountID != nil self.isLocalFeed = accountID != nil
} }
@ -57,7 +60,12 @@ struct PasteboardFeed: Hashable {
let feedID = dictionary[Key.feedID] let feedID = dictionary[Key.feedID]
let editedName = dictionary[Key.editedName] 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) { init?(pasteboardItem: NSPasteboardItem) {
@ -86,7 +94,7 @@ struct PasteboardFeed: Hashable {
if let foundType = pasteboardType { if let foundType = pasteboardType {
if let possibleURLString = pasteboardItem.string(forType: foundType) { if let possibleURLString = pasteboardItem.string(forType: foundType) {
if possibleURLString.rs_stringMayBeURL() { 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 return
} }
} }
@ -131,6 +139,9 @@ struct PasteboardFeed: Hashable {
if let accountID = accountID { if let accountID = accountID {
d[PasteboardFeed.Key.accountID] = accountID d[PasteboardFeed.Key.accountID] = accountID
} }
if let accountType = accountType {
d[PasteboardFeed.Key.accountType] = String(accountType.rawValue)
}
return d return d
} }
} }
@ -186,7 +197,7 @@ extension Feed: PasteboardWriterOwner {
private extension FeedPasteboardWriter { private extension FeedPasteboardWriter {
var pasteboardFeed: PasteboardFeed { 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 { var exportDictionary: PasteboardFeedDictionary {

View File

@ -173,7 +173,7 @@ private extension SidebarOutlineDataSource {
guard let dropTargetNode = ancestorThatCanAcceptLocalFeed(parentNode) else { guard let dropTargetNode = ancestorThatCanAcceptLocalFeed(parentNode) else {
return SidebarOutlineDataSource.dragOperationNone return SidebarOutlineDataSource.dragOperationNone
} }
if nodeAndDraggedFeedsDoNotShareAccount(dropTargetNode, Set([draggedFeed])) { if !allParticipantsAreLocalAccounts(dropTargetNode, Set([draggedFeed])) {
return SidebarOutlineDataSource.dragOperationNone return SidebarOutlineDataSource.dragOperationNone
} }
if nodeHasChildRepresentingDraggedFeed(dropTargetNode, draggedFeed) { if nodeHasChildRepresentingDraggedFeed(dropTargetNode, draggedFeed) {
@ -194,7 +194,7 @@ private extension SidebarOutlineDataSource {
guard let dropTargetNode = ancestorThatCanAcceptLocalFeed(parentNode) else { guard let dropTargetNode = ancestorThatCanAcceptLocalFeed(parentNode) else {
return SidebarOutlineDataSource.dragOperationNone return SidebarOutlineDataSource.dragOperationNone
} }
if nodeAndDraggedFeedsDoNotShareAccount(dropTargetNode, draggedFeeds) { if !allParticipantsAreLocalAccounts(dropTargetNode, draggedFeeds) {
return SidebarOutlineDataSource.dragOperationNone return SidebarOutlineDataSource.dragOperationNone
} }
if nodeHasChildRepresentingAnyDraggedFeed(dropTargetNode, draggedFeeds) { if nodeHasChildRepresentingAnyDraggedFeed(dropTargetNode, draggedFeeds) {
@ -219,26 +219,19 @@ private extension SidebarOutlineDataSource {
return nil return nil
} }
private func commonAccountFor(_ nodes: Set<Node>) -> Account? { private func commonAccountsFor(_ nodes: Set<Node>) -> Set<Account> {
// Return the Account if every node has an Account and theyre all the same.
var account: Account? = nil var accounts = Set<Account>()
for node in nodes { for node in nodes {
guard let oneAccount = accountForNode(node) else { guard let oneAccount = accountForNode(node) else {
return nil continue
} }
if account == nil { accounts.insert(oneAccount)
account = oneAccount
} }
else { return accounts
if account != oneAccount {
return nil
}
}
}
return account
} }
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 { guard let feed = node.representedObject as? Feed else {
return return
} }
@ -270,14 +263,15 @@ private extension SidebarOutlineDataSource {
guard let draggedNodes = draggedNodes else { guard let draggedNodes = draggedNodes else {
return false return false
} }
let allReferencedNodes = draggedNodes.union(Set([parentNode]))
guard let account = commonAccountFor(allReferencedNodes) else {
return false
}
BatchUpdate.shared.perform { 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 return true
} }
@ -346,24 +340,27 @@ private extension SidebarOutlineDataSource {
return false return false
} }
func nodeAndDraggedFeedsDoNotShareAccount(_ parentNode: Node, _ draggedFeeds: Set<PasteboardFeed>) -> Bool { func allParticipantsAreLocalAccounts(_ parentNode: Node, _ draggedFeeds: Set<PasteboardFeed>) -> Bool {
let parentAccountId: String?
if let account = parentNode.representedObject as? Account { if let account = parentNode.representedObject as? Account {
parentAccountId = account.accountID if account.type != .onMyMac {
return false
}
} else if let folder = parentNode.representedObject as? Folder { } else if let folder = parentNode.representedObject as? Folder {
parentAccountId = folder.account?.accountID if folder.account?.type != .onMyMac {
return false
}
} else { } else {
return true return false
} }
for draggedFeed in draggedFeeds { for draggedFeed in draggedFeeds {
if draggedFeed.accountID != parentAccountId { if draggedFeed.accountType != .onMyMac {
return true return false
} }
} }
return false return true
} }