From eba6c364da1e6001c750b91fea161fc9835d075f Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Fri, 11 Nov 2022 17:16:42 -0600 Subject: [PATCH] Change how we display progress per #3566. --- .../CloudKit/CloudKitAccountDelegate.swift | 5 + .../Account/CombinedRefreshProgress.swift | 44 ++++- .../Feedbin/FeedbinAccountDelegate.swift | 1 + .../Feedly/FeedlyAccountDelegate.swift | 1 + .../LocalAccount/LocalAccountDelegate.swift | 2 + .../NewsBlur/NewsBlurAccountDelegate.swift | 1 + .../ReaderAPI/ReaderAPIAccountDelegate.swift | 1 + Mac/Base.lproj/MainWindow.storyboard | 8 +- .../Sidebar/SidebarStatusBarView.swift | 28 ++-- NetNewsWire.xcodeproj/project.pbxproj | 16 +- .../xcshareddata/swiftpm/Package.resolved | 4 +- iOS/MasterFeed/MasterFeedViewController.swift | 23 ++- iOS/MasterFeed/RefreshProgressView.swift | 150 +++++++++++------- iOS/MasterFeed/RefreshProgressView.xib | 61 ------- .../MasterTimelineViewController.swift | 21 ++- .../RoundedProgressView.swift | 21 --- 16 files changed, 179 insertions(+), 208 deletions(-) delete mode 100644 iOS/MasterFeed/RefreshProgressView.xib delete mode 100644 iOS/UIKit Extensions/RoundedProgressView.swift diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift index bcd4689bf..80e522bfd 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift @@ -426,6 +426,7 @@ final class CloudKitAccountDelegate: AccountDelegate, Logging { func accountDidInitialize(_ account: Account) { self.account = account + refreshProgress.name = account.nameForDisplay accountZone.delegate = CloudKitAcountZoneDelegate(account: account, refreshProgress: refreshProgress, articlesZone: articlesZone) articlesZone.delegate = CloudKitArticlesZoneDelegate(account: account, database: database, articlesZone: articlesZone) @@ -484,6 +485,7 @@ private extension CloudKitAccountDelegate { completion(.failure(error)) } + refreshProgress.isIndeterminate = true refreshProgress.addToNumberOfTasksAndRemaining(3) accountZone.fetchChangesInZone() { result in self.refreshProgress.completeTask() @@ -495,6 +497,7 @@ private extension CloudKitAccountDelegate { case .success: self.refreshArticleStatus(for: account) { result in self.refreshProgress.completeTask() + self.refreshProgress.isIndeterminate = false switch result { case .success: @@ -522,6 +525,7 @@ private extension CloudKitAccountDelegate { func standardRefreshAll(for account: Account, completion: @escaping (Result) -> Void) { let intialWebFeedsCount = account.flattenedWebFeeds().count + refreshProgress.isIndeterminate = true refreshProgress.addToNumberOfTasksAndRemaining(3 + intialWebFeedsCount) func fail(_ error: Error) { @@ -542,6 +546,7 @@ private extension CloudKitAccountDelegate { switch result { case .success: self.refreshProgress.completeTask() + self.refreshProgress.isIndeterminate = false self.combinedRefresh(account, webFeeds) { result in self.sendArticleStatus(for: account, showProgress: true) { _ in self.refreshProgress.clear() diff --git a/Account/Sources/Account/CombinedRefreshProgress.swift b/Account/Sources/Account/CombinedRefreshProgress.swift index 803fb9e1c..d4885cc3d 100644 --- a/Account/Sources/Account/CombinedRefreshProgress.swift +++ b/Account/Sources/Account/CombinedRefreshProgress.swift @@ -18,25 +18,63 @@ public struct CombinedRefreshProgress { public let numberRemaining: Int public let numberCompleted: Int public let isComplete: Bool + public let isIndeterminate: Bool + public let label: String - init(numberOfTasks: Int, numberRemaining: Int, numberCompleted: Int) { + init(numberOfTasks: Int, numberRemaining: Int, numberCompleted: Int, isIndeterminate: Bool, label: String) { self.numberOfTasks = max(numberOfTasks, 0) self.numberRemaining = max(numberRemaining, 0) self.numberCompleted = max(numberCompleted, 0) self.isComplete = numberRemaining < 1 + self.isIndeterminate = isIndeterminate + self.label = label } public init(downloadProgressArray: [DownloadProgress]) { + var numberOfDownloadsPossible = 0 + var numberOfDownloadsActive = 0 var numberOfTasks = 0 var numberRemaining = 0 var numberCompleted = 0 - + var isIndeterminate = false + var isInprecise = false + for downloadProgress in downloadProgressArray { + numberOfDownloadsPossible += 1 + numberOfDownloadsActive += downloadProgress.isComplete ? 0 : 1 numberOfTasks += downloadProgress.numberOfTasks numberRemaining += downloadProgress.numberRemaining numberCompleted += downloadProgress.numberCompleted + + if downloadProgress.isIndeterminate { + isIndeterminate = true + } + + if !downloadProgress.isPrecise { + isInprecise = true + } } - self.init(numberOfTasks: numberOfTasks, numberRemaining: numberRemaining, numberCompleted: numberCompleted) + var label = "" + + if numberOfDownloadsActive > 0 { + if isInprecise { + if numberOfDownloadsActive == 1 { + if let activeName = downloadProgressArray.first(where: { $0.isComplete == false })?.name { + let formatString = NSLocalizedString("Refreshing %@", comment: "Status bar progress") + label = NSString(format: formatString as NSString, activeName) as String + } + } else { + let formatString = NSLocalizedString("Refreshing %@ accounts", comment: "Status bar progress") + label = NSString(format: formatString as NSString, NSNumber(value: numberOfDownloadsActive)) as String + } + } else { + let formatString = NSLocalizedString("%@ of %@", comment: "Status bar progress") + label = NSString(format: formatString as NSString, NSNumber(value: numberCompleted), NSNumber(value: numberOfTasks)) as String + } + } + + self.init(numberOfTasks: numberOfTasks, numberRemaining: numberRemaining, numberCompleted: numberCompleted, isIndeterminate: isIndeterminate, label: label) } + } diff --git a/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift b/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift index 334f02e4b..7b364e237 100644 --- a/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift +++ b/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift @@ -576,6 +576,7 @@ final class FeedbinAccountDelegate: AccountDelegate, Logging { func accountDidInitialize(_ account: Account) { credentials = try? account.retrieveCredentials(type: .basic) + refreshProgress.name = account.nameForDisplay } func accountWillBeDeleted(_ account: Account) { diff --git a/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift b/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift index ba4f133d3..4294c4726 100644 --- a/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift +++ b/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift @@ -527,6 +527,7 @@ final class FeedlyAccountDelegate: AccountDelegate, Logging { func accountDidInitialize(_ account: Account) { initializedAccount = account credentials = try? account.retrieveCredentials(type: .oauthAccessToken) + refreshProgress.name = account.nameForDisplay } func accountWillBeDeleted(_ account: Account) { diff --git a/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift b/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift index d19608c36..cfe18af77 100644 --- a/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift +++ b/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift @@ -222,6 +222,8 @@ final class LocalAccountDelegate: AccountDelegate, Logging { func accountDidInitialize(_ account: Account) { self.account = account + refreshProgress.name = account.nameForDisplay + refreshProgress.isPrecise = true } func accountWillBeDeleted(_ account: Account) { diff --git a/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift b/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift index 37966a2af..443ffb535 100644 --- a/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift +++ b/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift @@ -603,6 +603,7 @@ final class NewsBlurAccountDelegate: AccountDelegate, Logging { func accountDidInitialize(_ account: Account) { credentials = try? account.retrieveCredentials(type: .newsBlurSessionId) + refreshProgress.name = account.nameForDisplay } func accountWillBeDeleted(_ account: Account) { diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index 4cd9e8658..813317083 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -628,6 +628,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate, Logging { func accountDidInitialize(_ account: Account) { credentials = try? account.retrieveCredentials(type: .readerAPIKey) + refreshProgress.name = account.nameForDisplay } func accountWillBeDeleted(_ account: Account) { diff --git a/Mac/Base.lproj/MainWindow.storyboard b/Mac/Base.lproj/MainWindow.storyboard index 323606b38..310a1b4c7 100644 --- a/Mac/Base.lproj/MainWindow.storyboard +++ b/Mac/Base.lproj/MainWindow.storyboard @@ -1,8 +1,8 @@ - + - + @@ -175,9 +175,9 @@ -