diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 10771270d..efd613342 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -257,8 +257,6 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, feed.unreadCount = unreadCount } } - - self.dirty = true } } @@ -286,9 +284,27 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, @objc func unreadCountDidChange(_ note: Notification) { + // Update the unread count if it’s a direct child. + // If the object is owned by this account, then mark dirty — + // since unread counts are saved to disk along with other feed info. + if let object = note.object { + if objectIsChild(object as AnyObject) { updateUnreadCount() + self.dirty = true + return + } + + if let feed = object as? Feed { + if feed.account === self { + self.dirty = true + } + } + if let folder = object as? Folder { + if folder.account === self { + self.dirty = true + } } } } @@ -318,6 +334,8 @@ private extension Account { struct Key { static let children = "children" + static let userInfo = "userInfo" + static let unreadCount = "unreadCount" } func object(with diskObject: [String: Any]) -> AnyObject? { @@ -338,6 +356,15 @@ private extension Account { return } children = objects(with: childrenArray) + + if let savedUnreadCount = d[Key.unreadCount] as? Int { + DispatchQueue.main.async { + self.unreadCount = savedUnreadCount + } + } + + let userInfo = d[Key.userInfo] as? NSDictionary + delegate.update(account: self, withUserInfo: userInfo) } func diskDictionary() -> NSDictionary { @@ -355,6 +382,12 @@ private extension Account { var d = [String: Any]() d[Key.children] = diskObjects as NSArray + d[Key.unreadCount] = unreadCount + + if let userInfo = delegate.userInfo(for: self) { + d[Key.userInfo] = userInfo + } + return d as NSDictionary } diff --git a/Frameworks/Account/AccountDelegate.swift b/Frameworks/Account/AccountDelegate.swift index 5b47aff2b..9a28022b8 100644 --- a/Frameworks/Account/AccountDelegate.swift +++ b/Frameworks/Account/AccountDelegate.swift @@ -17,4 +17,14 @@ public protocol AccountDelegate { var refreshProgress: DownloadProgress { get } func refreshAll(for: Account) + + // Called at the end of initializing an Account using data from disk. + // Delegate has complete control over what goes in userInfo and what it means. + // Called even if userInfo is nil, since the delegate might have other + // things to do at init time anyway. + func update(account: Account, withUserInfo: NSDictionary?) + + // Saved to disk with other Account data. Could be called at any time. + // And called many times. + func userInfo(for: Account) -> NSDictionary? } diff --git a/Frameworks/Account/Container.swift b/Frameworks/Account/Container.swift index 7b8e006f9..0c14dec1d 100644 --- a/Frameworks/Account/Container.swift +++ b/Frameworks/Account/Container.swift @@ -39,7 +39,7 @@ public extension Container { func hasAtLeastOneFeed() -> Bool { for child in children { - if let feed = child as? Feed { + if child is Feed { return true } if let folder = child as? Folder { diff --git a/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift b/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift index 65b2d8d2e..50cbb48b4 100644 --- a/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift +++ b/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift @@ -24,4 +24,16 @@ final class LocalAccountDelegate: AccountDelegate { refresher.refreshFeeds(account.flattenedFeeds()) } + + // MARK: Disk + + func update(account: Account, withUserInfo: NSDictionary?) { + + account.nameForDisplay = NSLocalizedString("On My Mac", comment: "Local Account Name") + } + + func userInfo(for: Account) -> NSDictionary? { + + return nil + } }