diff --git a/Evergreen/MainWindow/StatusBar/StatusBarView.swift b/Evergreen/MainWindow/StatusBar/StatusBarView.swift index dba1991e7..b4e7220a5 100644 --- a/Evergreen/MainWindow/StatusBar/StatusBarView.swift +++ b/Evergreen/MainWindow/StatusBar/StatusBarView.swift @@ -10,6 +10,7 @@ import Cocoa import RSCore import Data import RSWeb +import Account final class StatusBarView: NSView { @@ -36,7 +37,7 @@ final class StatusBarView: NSView { progressLabel.font = NSFont.monospacedDigitSystemFont(ofSize: progressLabelFontSize, weight: NSFont.Weight.regular) progressLabel.stringValue = "" -// NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(timelineSelectionDidChange(_:)), name: .TimelineSelectionDidChange, object: nil) } @@ -45,11 +46,9 @@ final class StatusBarView: NSView { @objc dynamic func progressDidChange(_ notification: Notification) { -// guard let progress = notification.userInfo?[progressKey] as? DownloadProgress else { -// return -// } -// updateProgressIndicator(progress) -// updateProgressLabel(progress) + let progress = AccountManager.shared.combinedRefreshProgress + updateProgressIndicator(progress) + updateProgressLabel(progress) } // MARK: Notifications @@ -120,7 +119,7 @@ private extension StatusBarView { progressIndicator.startAnimation(self) } - func updateProgressIndicator(_ progress: DownloadProgress) { + func updateProgressIndicator(_ progress: CombinedRefreshProgress) { if progress.isComplete { stopProgressIfNeeded() @@ -140,7 +139,7 @@ private extension StatusBarView { } } - func updateProgressLabel(_ progress: DownloadProgress) { + func updateProgressLabel(_ progress: CombinedRefreshProgress) { if progress.isComplete { progressLabel.stringValue = "" diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 1af63ffdf..be3d835bf 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -11,11 +11,13 @@ import RSCore import Data import RSParser import Database +import RSWeb public extension Notification.Name { public static let AccountRefreshDidBegin = Notification.Name(rawValue: "AccountRefreshDidBegin") public static let AccountRefreshDidFinish = Notification.Name(rawValue: "AccountRefreshDidFinish") + public static let AccountRefreshProgressDidChange = Notification.Name(rawValue: "AccountRefreshProgressDidChange") } public enum AccountType: Int { @@ -49,12 +51,18 @@ public final class Account: DisplayNameProvider, Hashable { NotificationCenter.default.post(name: .AccountRefreshDidBegin, object: self) } else { - NotificationCenter.default.post(name: .AccountRefreshDidFinish, object: self) + NotificationCenter.default.post(name: .AccountRefreshProgressDidChange, object: self) } } } } + var refreshProgress: DownloadProgress { + get { + return delegate.refreshProgress + } + } + var hasAtLeastOneFeed: Bool { get { return !feedIDDictionary.isEmpty @@ -180,7 +188,15 @@ public final class Account: DisplayNameProvider, Hashable { // TODO } - + + // MARK: - For use by delegate + + func noteProgressDidChange() { + + refreshInProgress = refreshProgress.numberRemaining > 0 + NotificationCenter.default.post(name: .AccountRefreshProgressDidChange, object: self) + } + // MARK: - Equatable public class func ==(lhs: Account, rhs: Account) -> Bool { diff --git a/Frameworks/Account/Account.xcodeproj/project.pbxproj b/Frameworks/Account/Account.xcodeproj/project.pbxproj index d0e0df4df..3199dbe02 100644 --- a/Frameworks/Account/Account.xcodeproj/project.pbxproj +++ b/Frameworks/Account/Account.xcodeproj/project.pbxproj @@ -24,6 +24,7 @@ 846E77591F6F03E300A165E2 /* Feed+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846E77581F6F03E300A165E2 /* Feed+Account.swift */; }; 848935001F62484F00CEBD24 /* Account.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848934F61F62484F00CEBD24 /* Account.framework */; }; 848935051F62485000CEBD24 /* AccountTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848935041F62485000CEBD24 /* AccountTests.swift */; }; + 84C3654A1F899F3B001EC85C /* CombinedRefreshProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -120,6 +121,7 @@ 848935041F62485000CEBD24 /* AccountTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTests.swift; sourceTree = ""; }; 848935061F62485000CEBD24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 848935101F62486800CEBD24 /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = ""; }; + 84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombinedRefreshProgress.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -228,6 +230,7 @@ 848935101F62486800CEBD24 /* Account.swift */, 841974241F6DDCE4006346C4 /* AccountDelegate.swift */, 841974001F6DD1EC006346C4 /* Folder.swift */, + 84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */, 846E77551F6F03B200A165E2 /* Extensions */, 841974141F6DD4FF006346C4 /* Container */, 8419742B1F6DDE84006346C4 /* LocalAccount */, @@ -451,6 +454,7 @@ buildActionMask = 2147483647; files = ( 846E77571F6F03D600A165E2 /* Article+Account.swift in Sources */, + 84C3654A1F899F3B001EC85C /* CombinedRefreshProgress.swift in Sources */, 8469F81C1F6DD15E0084783E /* Account.swift in Sources */, 846E77451F6EF9B900A165E2 /* Container.swift in Sources */, 8419741A1F6DD583006346C4 /* Account+Container.swift in Sources */, diff --git a/Frameworks/Account/AccountDelegate.swift b/Frameworks/Account/AccountDelegate.swift index 14dadad56..d5be3f027 100644 --- a/Frameworks/Account/AccountDelegate.swift +++ b/Frameworks/Account/AccountDelegate.swift @@ -7,11 +7,13 @@ // import Foundation +import RSWeb public protocol AccountDelegate { // Local account does not; some synced accounts might. var supportsSubFolders: Bool { get } + var refreshProgress: DownloadProgress { get } init(account: Account) diff --git a/Frameworks/Account/AccountManager.swift b/Frameworks/Account/AccountManager.swift index 97fe2f0ed..b971334a5 100644 --- a/Frameworks/Account/AccountManager.swift +++ b/Frameworks/Account/AccountManager.swift @@ -52,7 +52,14 @@ public final class AccountManager: UnreadCountProvider { return false } } - + + public var combinedRefreshProgress: CombinedRefreshProgress { + get { + let downloadProgressArray = accounts.map { $0.refreshProgress } + return CombinedRefreshProgress(downloadProgressArray: downloadProgressArray) + } + } + public init() { // The local "On My Mac" account must always exist, even if it's empty. diff --git a/Frameworks/Account/CombinedRefreshProgress.swift b/Frameworks/Account/CombinedRefreshProgress.swift new file mode 100644 index 000000000..f9f5cb52d --- /dev/null +++ b/Frameworks/Account/CombinedRefreshProgress.swift @@ -0,0 +1,44 @@ +// +// CombinedRefreshProgress.swift +// Account +// +// Created by Brent Simmons on 10/7/17. +// Copyright © 2017 Ranchero Software, LLC. All rights reserved. +// + +import Foundation +import RSWeb + +// Combines the refresh progress of mutliple accounts into one struct, +// for use by refresh status view and so on. + +public struct CombinedRefreshProgress { + + public let numberOfTasks: Int + public let numberRemaining: Int + public let numberCompleted: Int + public let isComplete: Bool + + init(numberOfTasks: Int, numberRemaining: Int, numberCompleted: Int) { + + self.numberOfTasks = max(numberOfTasks, 0) + self.numberRemaining = max(numberRemaining, 0) + self.numberCompleted = max(numberCompleted, 0) + self.isComplete = numberRemaining < 1 + } + + public init(downloadProgressArray: [DownloadProgress]) { + + var numberOfTasks = 0 + var numberRemaining = 0 + var numberCompleted = 0 + + for downloadProgress in downloadProgressArray { + numberOfTasks += downloadProgress.numberOfTasks + numberRemaining += downloadProgress.numberRemaining + numberCompleted += downloadProgress.numberCompleted + } + + self.init(numberOfTasks: numberOfTasks, numberRemaining: numberRemaining, numberCompleted: numberCompleted) + } +} diff --git a/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift b/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift index 2232a2d56..a2aa81fcd 100644 --- a/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift +++ b/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift @@ -7,6 +7,7 @@ // import Foundation +import RSWeb final class LocalAccountDelegate: AccountDelegate { @@ -14,6 +15,12 @@ final class LocalAccountDelegate: AccountDelegate { private let refresher = LocalAccountRefresher() private weak var account: Account? + var refreshProgress: DownloadProgress { + get { + return refresher.progress + } + } + init(account: Account) { self.account = account @@ -34,11 +41,6 @@ final class LocalAccountDelegate: AccountDelegate { @objc func downloadProgressDidChange(_ note: Notification) { - if refresher.progress.numberRemaining < 1 { - account?.refreshInProgress = false - } - else { - account?.refreshInProgress = true - } + account?.noteProgressDidChange() } }