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
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 {

View File

@ -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<Node>) -> Account? {
// Return the Account if every node has an Account and theyre all the same.
var account: Account? = nil
private func commonAccountsFor(_ nodes: Set<Node>) -> Set<Account> {
var accounts = Set<Account>()
for node in nodes {
guard let oneAccount = accountForNode(node) else {
return nil
continue
}
if account == nil {
account = oneAccount
accounts.insert(oneAccount)
}
else {
if account != oneAccount {
return nil
}
}
}
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<PasteboardFeed>) -> Bool {
func allParticipantsAreLocalAccounts(_ parentNode: Node, _ draggedFeeds: Set<PasteboardFeed>) -> 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
}