diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewIdentifier.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewIdentifier.swift index e6d8172bb..9173f70e4 100644 --- a/iOS/MasterFeed/Cell/MasterFeedTableViewIdentifier.swift +++ b/iOS/MasterFeed/Cell/MasterFeedTableViewIdentifier.swift @@ -18,6 +18,7 @@ final class MasterFeedTableViewIdentifier: NSObject, NSCopying { let isEditable: Bool let isPsuedoFeed: Bool + let isAccount: Bool let isFolder: Bool let isWebFeed: Bool @@ -26,6 +27,19 @@ final class MasterFeedTableViewIdentifier: NSObject, NSCopying { let unreadCount: Int let childCount: Int + var account: Account? { + if isAccount, let containerID = containerID { + return AccountManager.shared.existingContainer(with: containerID) as? Account + } + if isFolder, let parentContainerID = parentContainerID { + return AccountManager.shared.existingContainer(with: parentContainerID) as? Account + } + if isWebFeed, let feedID = feedID { + return (AccountManager.shared.existingFeed(with: feedID) as? WebFeed)?.account + } + return nil + } + init(node: Node, unreadCount: Int) { let feed = node.representedObject as! Feed self.feedID = feed.feedID @@ -34,6 +48,7 @@ final class MasterFeedTableViewIdentifier: NSObject, NSCopying { self.isEditable = !(node.representedObject is PseudoFeed) self.isPsuedoFeed = node.representedObject is PseudoFeed + self.isAccount = node.representedObject is Account self.isFolder = node.representedObject is Folder self.isWebFeed = node.representedObject is WebFeed self.nameForDisplay = feed.nameForDisplay diff --git a/iOS/MasterFeed/MasterFeedViewController+Drop.swift b/iOS/MasterFeed/MasterFeedViewController+Drop.swift index 8692e3020..32fab4f7d 100644 --- a/iOS/MasterFeed/MasterFeedViewController+Drop.swift +++ b/iOS/MasterFeed/MasterFeedViewController+Drop.swift @@ -22,10 +22,24 @@ extension MasterFeedViewController: UITableViewDropDelegate { destIndexPath.section > 0, tableView.hasActiveDrag, let destIdentifier = dataSource.itemIdentifier(for: destIndexPath), + let destAccount = destIdentifier.account, let destCell = tableView.cellForRow(at: destIndexPath) else { return UITableViewDropProposal(operation: .forbidden) } + + // Validate account specific behaviors... + if destAccount.behaviors.contains(.disallowFeedInRootFolder) && destIdentifier.isAccount { + return UITableViewDropProposal(operation: .forbidden) + } + if destAccount.behaviors.contains(.disallowFeedInMultipleFolders), + let sourceFeedID = (session.localDragSession?.items.first?.localObject as? MasterFeedTableViewIdentifier)?.feedID, + let sourceWebFeed = AccountManager.shared.existingFeed(with: sourceFeedID) as? WebFeed, + sourceWebFeed.account?.accountID != destAccount.accountID && destAccount.hasWebFeed(withURL: sourceWebFeed.url) { + return UITableViewDropProposal(operation: .forbidden) + } + + // Determine the correct drop proposal if destIdentifier.isFolder { if session.location(in: destCell).y >= 0 { return UITableViewDropProposal(operation: .move, intent: .insertIntoDestinationIndexPath)