diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 579a34783..a39389716 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -21,6 +21,8 @@ import os.log // Main thread only. public extension Notification.Name { + static let UserDidAddAccount = Notification.Name("UserDidAddAccount") + static let UserDidDeleteAccount = Notification.Name("UserDidDeleteAccount") static let AccountRefreshDidBegin = Notification.Name(rawValue: "AccountRefreshDidBegin") static let AccountRefreshDidFinish = Notification.Name(rawValue: "AccountRefreshDidFinish") static let AccountRefreshProgressDidChange = Notification.Name(rawValue: "AccountRefreshProgressDidChange") @@ -54,6 +56,7 @@ public enum FetchType { public final class Account: DisplayNameProvider, UnreadCountProvider, Container, Hashable { public struct UserInfoKey { + public static let account = "account" // UserDidAddAccount, UserDidDeleteAccount public static let newArticles = "newArticles" // AccountDidDownloadArticles public static let updatedArticles = "updatedArticles" // AccountDidDownloadArticles public static let statuses = "statuses" // StatusesDidChange diff --git a/Frameworks/Account/AccountManager.swift b/Frameworks/Account/AccountManager.swift index 0b5e71b20..52e847e5c 100644 --- a/Frameworks/Account/AccountManager.swift +++ b/Frameworks/Account/AccountManager.swift @@ -12,10 +12,6 @@ import Articles // Main thread only. -public extension Notification.Name { - static let AccountsDidChange = Notification.Name("AccountsDidChange") -} - public final class AccountManager: UnreadCountProvider { public static let shared = AccountManager() @@ -115,7 +111,9 @@ public final class AccountManager: UnreadCountProvider { let account = Account(dataFolder: accountFolder, type: type, accountID: accountID)! accountsDictionary[accountID] = account - NotificationCenter.default.post(name: .AccountsDidChange, object: self) + var userInfo = [String: Any]() + userInfo[Account.UserInfoKey.account] = account + NotificationCenter.default.post(name: .UserDidAddAccount, object: self, userInfo: userInfo) return account } @@ -137,7 +135,10 @@ public final class AccountManager: UnreadCountProvider { } updateUnreadCount() - NotificationCenter.default.post(name: .AccountsDidChange, object: self) + + var userInfo = [String: Any]() + userInfo[Account.UserInfoKey.account] = account + NotificationCenter.default.post(name: .UserDidDeleteAccount, object: self, userInfo: userInfo) } public func existingAccount(with accountID: String) -> Account? { diff --git a/Mac/MainWindow/Sidebar/SidebarViewController.swift b/Mac/MainWindow/Sidebar/SidebarViewController.swift index bf5dc2ca8..77150e73b 100644 --- a/Mac/MainWindow/Sidebar/SidebarViewController.swift +++ b/Mac/MainWindow/Sidebar/SidebarViewController.swift @@ -52,8 +52,9 @@ protocol SidebarDelegate: class { NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(containerChildrenDidChange(_:)), name: .ChildrenDidChange, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChangeNotification(_:)), name: .AccountsDidChange, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(accountStateDidChangeNotification(_:)), name: .AccountStateDidChange, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .UserDidAddAccount, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .UserDidDeleteAccount, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(accountStateDidChange(_:)), name: .AccountStateDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(userDidAddFeed(_:)), name: .UserDidAddFeed, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(batchUpdateDidPerform(_:)), name: .BatchUpdateDidPerform, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil) @@ -95,11 +96,11 @@ protocol SidebarDelegate: class { rebuildTreeAndRestoreSelection() } - @objc func accountsDidChangeNotification(_ notification: Notification) { + @objc func accountsDidChange(_ notification: Notification) { rebuildTreeAndRestoreSelection() } - @objc func accountStateDidChangeNotification(_ notification: Notification) { + @objc func accountStateDidChange(_ notification: Notification) { rebuildTreeAndRestoreSelection() } diff --git a/Mac/MainWindow/Timeline/TimelineViewController.swift b/Mac/MainWindow/Timeline/TimelineViewController.swift index 8ed4c09be..54fef9c54 100644 --- a/Mac/MainWindow/Timeline/TimelineViewController.swift +++ b/Mac/MainWindow/Timeline/TimelineViewController.swift @@ -169,7 +169,8 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(accountDidDownloadArticles(_:)), name: .AccountDidDownloadArticles, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(accountStateDidChange(_:)), name: .AccountStateDidChange, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .AccountsDidChange, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .UserDidAddAccount, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .UserDidDeleteAccount, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(containerChildrenDidChange(_:)), name: .ChildrenDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil) DistributedNotificationCenter.default.addObserver(self, selector: #selector(appleInterfaceThemeChanged), name: .AppleInterfaceThemeChangedNotification, object: nil) diff --git a/Mac/Preferences/Accounts/AccountsPreferencesViewController.swift b/Mac/Preferences/Accounts/AccountsPreferencesViewController.swift index 4fa3af338..061d20bdf 100644 --- a/Mac/Preferences/Accounts/AccountsPreferencesViewController.swift +++ b/Mac/Preferences/Accounts/AccountsPreferencesViewController.swift @@ -25,8 +25,9 @@ final class AccountsPreferencesViewController: NSViewController { tableView.dataSource = self NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange(_:)), name: .DisplayNameDidChange, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChangeNotification(_:)), name: .AccountsDidChange, object: nil) - + NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .UserDidAddAccount, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .UserDidDeleteAccount, object: nil) + showController(AccountsAddViewController()) // Fix tableView frame — for some reason IB wants it 1pt wider than the clip view. This leads to unwanted horizontal scrolling. @@ -72,7 +73,7 @@ final class AccountsPreferencesViewController: NSViewController { tableView.reloadData() } - @objc func accountsDidChangeNotification(_ note: Notification) { + @objc func accountsDidChange(_ note: Notification) { updateSortedAccounts() tableView.reloadData() } diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift index 08a709d12..b6260a7c4 100644 --- a/iOS/SceneCoordinator.swift +++ b/iOS/SceneCoordinator.swift @@ -267,8 +267,9 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider { NotificationCenter.default.addObserver(self, selector: #selector(batchUpdateDidPerform(_:)), name: .BatchUpdateDidPerform, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange(_:)), name: .DisplayNameDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(accountStateDidChange(_:)), name: .AccountStateDidChange, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .AccountsDidChange, object: nil) - + NotificationCenter.default.addObserver(self, selector: #selector(userDidAddAccount(_:)), name: .UserDidAddAccount, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(userDidDeleteAccount(_:)), name: .UserDidDeleteAccount, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(accountDidDownloadArticles(_:)), name: .AccountDidDownloadArticles, object: nil) @@ -341,10 +342,10 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider { } @objc func containerChildrenDidChange(_ note: Notification) { - rebuildBackingStores() if timelineFetcherContainsAnyPseudoFeed() || timelineFetcherContainsAnyFolder() { fetchAndReplaceArticlesAsync() {} } + rebuildBackingStores() } @objc func batchUpdateDidPerform(_ notification: Notification) { @@ -362,11 +363,31 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider { rebuildBackingStores() } - @objc func accountsDidChange(_ note: Notification) { + @objc func userDidAddAccount(_ note: Notification) { if timelineFetcherContainsAnyPseudoFeed() { fetchAndReplaceArticlesSync() } - rebuildBackingStores() + + rebuildBackingStores() { + if let account = note.userInfo?[Account.UserInfoKey.account] as? Account, + let node = self.treeController.rootNode.childNodeRepresentingObject(account) { + self.expandedNodes.append(node) + } + } + } + + @objc func userDidDeleteAccount(_ note: Notification) { + if timelineFetcherContainsAnyPseudoFeed() { + fetchAndReplaceArticlesSync() + } + + rebuildBackingStores() { + if let account = note.userInfo?[Account.UserInfoKey.account] as? Account, + let node = self.treeController.rootNode.childNodeRepresentingObject(account), + let nodeIndex = self.expandedNodes.firstIndex(of: node) { + self.expandedNodes.remove(at: nodeIndex) + } + } } @objc func userDefaultsDidChange(_ note: Notification) { @@ -374,7 +395,6 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider { } @objc func accountDidDownloadArticles(_ note: Notification) { - guard let feeds = note.userInfo?[Account.UserInfoKey.feeds] as? Set else { return } @@ -383,7 +403,6 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider { if shouldFetchAndMergeArticles { queueFetchAndMergeArticles() } - } // MARK: API @@ -1031,9 +1050,10 @@ private extension SceneCoordinator { unreadCount = count } - func rebuildBackingStores() { + func rebuildBackingStores(_ updateExpandedNodes: (() -> Void)? = nil) { if !animatingChanges && !BatchUpdate.shared.isPerforming { treeController.rebuild() + updateExpandedNodes?() rebuildShadowTable() masterFeedViewController.reloadFeeds() } diff --git a/iOS/Settings/SettingsView.swift b/iOS/Settings/SettingsView.swift index d9c8b40ee..3636dcaed 100644 --- a/iOS/Settings/SettingsView.swift +++ b/iOS/Settings/SettingsView.swift @@ -186,7 +186,8 @@ struct SettingsView : View { let objectWillChange = ObservableObjectPublisher() init() { - NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .AccountsDidChange, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .UserDidAddAccount, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .UserDidDeleteAccount, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange(_:)), name: .DisplayNameDidChange, object: nil) }