mirror of
https://github.com/Ranchero-Software/NetNewsWire.git
synced 2024-12-25 17:12:23 +01:00
Create and use CombinedRefreshProgress, which reports refresh progress across all accounts. Used by the status view.
This commit is contained in:
parent
7ddc09c2ec
commit
b77569f38b
@ -10,6 +10,7 @@ import Cocoa
|
|||||||
import RSCore
|
import RSCore
|
||||||
import Data
|
import Data
|
||||||
import RSWeb
|
import RSWeb
|
||||||
|
import Account
|
||||||
|
|
||||||
final class StatusBarView: NSView {
|
final class StatusBarView: NSView {
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ final class StatusBarView: NSView {
|
|||||||
progressLabel.font = NSFont.monospacedDigitSystemFont(ofSize: progressLabelFontSize, weight: NSFont.Weight.regular)
|
progressLabel.font = NSFont.monospacedDigitSystemFont(ofSize: progressLabelFontSize, weight: NSFont.Weight.regular)
|
||||||
progressLabel.stringValue = ""
|
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)
|
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) {
|
@objc dynamic func progressDidChange(_ notification: Notification) {
|
||||||
|
|
||||||
// guard let progress = notification.userInfo?[progressKey] as? DownloadProgress else {
|
let progress = AccountManager.shared.combinedRefreshProgress
|
||||||
// return
|
updateProgressIndicator(progress)
|
||||||
// }
|
updateProgressLabel(progress)
|
||||||
// updateProgressIndicator(progress)
|
|
||||||
// updateProgressLabel(progress)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Notifications
|
// MARK: Notifications
|
||||||
@ -120,7 +119,7 @@ private extension StatusBarView {
|
|||||||
progressIndicator.startAnimation(self)
|
progressIndicator.startAnimation(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateProgressIndicator(_ progress: DownloadProgress) {
|
func updateProgressIndicator(_ progress: CombinedRefreshProgress) {
|
||||||
|
|
||||||
if progress.isComplete {
|
if progress.isComplete {
|
||||||
stopProgressIfNeeded()
|
stopProgressIfNeeded()
|
||||||
@ -140,7 +139,7 @@ private extension StatusBarView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateProgressLabel(_ progress: DownloadProgress) {
|
func updateProgressLabel(_ progress: CombinedRefreshProgress) {
|
||||||
|
|
||||||
if progress.isComplete {
|
if progress.isComplete {
|
||||||
progressLabel.stringValue = ""
|
progressLabel.stringValue = ""
|
||||||
|
@ -11,11 +11,13 @@ import RSCore
|
|||||||
import Data
|
import Data
|
||||||
import RSParser
|
import RSParser
|
||||||
import Database
|
import Database
|
||||||
|
import RSWeb
|
||||||
|
|
||||||
public extension Notification.Name {
|
public extension Notification.Name {
|
||||||
|
|
||||||
public static let AccountRefreshDidBegin = Notification.Name(rawValue: "AccountRefreshDidBegin")
|
public static let AccountRefreshDidBegin = Notification.Name(rawValue: "AccountRefreshDidBegin")
|
||||||
public static let AccountRefreshDidFinish = Notification.Name(rawValue: "AccountRefreshDidFinish")
|
public static let AccountRefreshDidFinish = Notification.Name(rawValue: "AccountRefreshDidFinish")
|
||||||
|
public static let AccountRefreshProgressDidChange = Notification.Name(rawValue: "AccountRefreshProgressDidChange")
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum AccountType: Int {
|
public enum AccountType: Int {
|
||||||
@ -49,12 +51,18 @@ public final class Account: DisplayNameProvider, Hashable {
|
|||||||
NotificationCenter.default.post(name: .AccountRefreshDidBegin, object: self)
|
NotificationCenter.default.post(name: .AccountRefreshDidBegin, object: self)
|
||||||
}
|
}
|
||||||
else {
|
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 {
|
var hasAtLeastOneFeed: Bool {
|
||||||
get {
|
get {
|
||||||
return !feedIDDictionary.isEmpty
|
return !feedIDDictionary.isEmpty
|
||||||
@ -181,6 +189,14 @@ public final class Account: DisplayNameProvider, Hashable {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - For use by delegate
|
||||||
|
|
||||||
|
func noteProgressDidChange() {
|
||||||
|
|
||||||
|
refreshInProgress = refreshProgress.numberRemaining > 0
|
||||||
|
NotificationCenter.default.post(name: .AccountRefreshProgressDidChange, object: self)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Equatable
|
// MARK: - Equatable
|
||||||
|
|
||||||
public class func ==(lhs: Account, rhs: Account) -> Bool {
|
public class func ==(lhs: Account, rhs: Account) -> Bool {
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
846E77591F6F03E300A165E2 /* Feed+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846E77581F6F03E300A165E2 /* Feed+Account.swift */; };
|
846E77591F6F03E300A165E2 /* Feed+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846E77581F6F03E300A165E2 /* Feed+Account.swift */; };
|
||||||
848935001F62484F00CEBD24 /* Account.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848934F61F62484F00CEBD24 /* Account.framework */; };
|
848935001F62484F00CEBD24 /* Account.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848934F61F62484F00CEBD24 /* Account.framework */; };
|
||||||
848935051F62485000CEBD24 /* AccountTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848935041F62485000CEBD24 /* AccountTests.swift */; };
|
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 */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@ -120,6 +121,7 @@
|
|||||||
848935041F62485000CEBD24 /* AccountTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTests.swift; sourceTree = "<group>"; };
|
848935041F62485000CEBD24 /* AccountTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTests.swift; sourceTree = "<group>"; };
|
||||||
848935061F62485000CEBD24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
848935061F62485000CEBD24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
848935101F62486800CEBD24 /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; };
|
848935101F62486800CEBD24 /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; };
|
||||||
|
84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombinedRefreshProgress.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -228,6 +230,7 @@
|
|||||||
848935101F62486800CEBD24 /* Account.swift */,
|
848935101F62486800CEBD24 /* Account.swift */,
|
||||||
841974241F6DDCE4006346C4 /* AccountDelegate.swift */,
|
841974241F6DDCE4006346C4 /* AccountDelegate.swift */,
|
||||||
841974001F6DD1EC006346C4 /* Folder.swift */,
|
841974001F6DD1EC006346C4 /* Folder.swift */,
|
||||||
|
84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */,
|
||||||
846E77551F6F03B200A165E2 /* Extensions */,
|
846E77551F6F03B200A165E2 /* Extensions */,
|
||||||
841974141F6DD4FF006346C4 /* Container */,
|
841974141F6DD4FF006346C4 /* Container */,
|
||||||
8419742B1F6DDE84006346C4 /* LocalAccount */,
|
8419742B1F6DDE84006346C4 /* LocalAccount */,
|
||||||
@ -451,6 +454,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
846E77571F6F03D600A165E2 /* Article+Account.swift in Sources */,
|
846E77571F6F03D600A165E2 /* Article+Account.swift in Sources */,
|
||||||
|
84C3654A1F899F3B001EC85C /* CombinedRefreshProgress.swift in Sources */,
|
||||||
8469F81C1F6DD15E0084783E /* Account.swift in Sources */,
|
8469F81C1F6DD15E0084783E /* Account.swift in Sources */,
|
||||||
846E77451F6EF9B900A165E2 /* Container.swift in Sources */,
|
846E77451F6EF9B900A165E2 /* Container.swift in Sources */,
|
||||||
8419741A1F6DD583006346C4 /* Account+Container.swift in Sources */,
|
8419741A1F6DD583006346C4 /* Account+Container.swift in Sources */,
|
||||||
|
@ -7,11 +7,13 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import RSWeb
|
||||||
|
|
||||||
public protocol AccountDelegate {
|
public protocol AccountDelegate {
|
||||||
|
|
||||||
// Local account does not; some synced accounts might.
|
// Local account does not; some synced accounts might.
|
||||||
var supportsSubFolders: Bool { get }
|
var supportsSubFolders: Bool { get }
|
||||||
|
var refreshProgress: DownloadProgress { get }
|
||||||
|
|
||||||
init(account: Account)
|
init(account: Account)
|
||||||
|
|
||||||
|
@ -53,6 +53,13 @@ public final class AccountManager: UnreadCountProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var combinedRefreshProgress: CombinedRefreshProgress {
|
||||||
|
get {
|
||||||
|
let downloadProgressArray = accounts.map { $0.refreshProgress }
|
||||||
|
return CombinedRefreshProgress(downloadProgressArray: downloadProgressArray)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
|
|
||||||
// The local "On My Mac" account must always exist, even if it's empty.
|
// The local "On My Mac" account must always exist, even if it's empty.
|
||||||
|
44
Frameworks/Account/CombinedRefreshProgress.swift
Normal file
44
Frameworks/Account/CombinedRefreshProgress.swift
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import RSWeb
|
||||||
|
|
||||||
final class LocalAccountDelegate: AccountDelegate {
|
final class LocalAccountDelegate: AccountDelegate {
|
||||||
|
|
||||||
@ -14,6 +15,12 @@ final class LocalAccountDelegate: AccountDelegate {
|
|||||||
private let refresher = LocalAccountRefresher()
|
private let refresher = LocalAccountRefresher()
|
||||||
private weak var account: Account?
|
private weak var account: Account?
|
||||||
|
|
||||||
|
var refreshProgress: DownloadProgress {
|
||||||
|
get {
|
||||||
|
return refresher.progress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init(account: Account) {
|
init(account: Account) {
|
||||||
|
|
||||||
self.account = account
|
self.account = account
|
||||||
@ -34,11 +41,6 @@ final class LocalAccountDelegate: AccountDelegate {
|
|||||||
|
|
||||||
@objc func downloadProgressDidChange(_ note: Notification) {
|
@objc func downloadProgressDidChange(_ note: Notification) {
|
||||||
|
|
||||||
if refresher.progress.numberRemaining < 1 {
|
account?.noteProgressDidChange()
|
||||||
account?.refreshInProgress = false
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
account?.refreshInProgress = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user