From 673f0ce7184e05d699d52d1f9bf30bc22440a308 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Sat, 25 Jul 2020 16:40:04 +0800 Subject: [PATCH] Handles single and multiple sync failures If a single sync failure is encountered a sheet is presented which allows the user to update their credentials. If multiple sync failures are encountered an alert is shown listing the accounts which encountered errors. On iOS, this alert can take the user into Settings, but there is no obvious way to programatically pesent macOS preferences. --- .../Account/Account.xcodeproj/project.pbxproj | 4 + Frameworks/Account/AccountManager.swift | 26 +++ Frameworks/Account/AccountSyncError.swift | 29 +++ .../FixAccountCredentialView.swift | 167 ++++++++++++++++++ Multiplatform/Shared/SceneModel.swift | 13 +- .../Shared/SceneNavigationView.swift | 74 +++++--- .../Shared/Sidebar/SidebarToolbarModel.swift | 6 +- .../Shared/Sidebar/SidebarView.swift | 7 +- .../EditAccountCredentialsModel.swift | 2 + .../EditAccountCredentialsView.swift | 1 - NetNewsWire.xcodeproj/project.pbxproj | 40 +++-- Shared/Timer/AccountRefreshTimer.swift | 4 +- 12 files changed, 328 insertions(+), 45 deletions(-) create mode 100644 Frameworks/Account/AccountSyncError.swift create mode 100644 Multiplatform/Shared/Account Management /FixAccountCredentialView.swift diff --git a/Frameworks/Account/Account.xcodeproj/project.pbxproj b/Frameworks/Account/Account.xcodeproj/project.pbxproj index 9057c3188..c3ba67d5b 100644 --- a/Frameworks/Account/Account.xcodeproj/project.pbxproj +++ b/Frameworks/Account/Account.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 1748B4A724CADA17008F9850 /* AccountSyncError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1748B4A624CADA17008F9850 /* AccountSyncError.swift */; }; 179DB02FFBC17AC9798F0EBC /* NewsBlurStory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB7399814F6FB3247825C /* NewsBlurStory.swift */; }; 179DB0B17A6C51B95ABC1741 /* NewsBlurStoryStatusChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB5B421C5433B45C5F13E /* NewsBlurStoryStatusChange.swift */; }; 179DB28CF49F73A945EBF5DB /* NewsBlurLoginResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB088236E3236010462E8 /* NewsBlurLoginResponse.swift */; }; @@ -267,6 +268,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 1748B4A624CADA17008F9850 /* AccountSyncError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSyncError.swift; sourceTree = ""; }; 179DB088236E3236010462E8 /* NewsBlurLoginResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurLoginResponse.swift; sourceTree = ""; }; 179DB1B909672E0E807B5E8C /* NewsBlurFeed.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurFeed.swift; sourceTree = ""; }; 179DB3CBADAFCF5377DA3D02 /* NewsBlurFeedChange.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurFeedChange.swift; sourceTree = ""; }; @@ -774,6 +776,7 @@ 51BB7B83233531BC008E8144 /* AccountBehaviors.swift */, 51E3EB40229AF61B00645299 /* AccountError.swift */, 846E77531F6F00E300A165E2 /* AccountManager.swift */, + 1748B4A624CADA17008F9850 /* AccountSyncError.swift */, 5170743B232AEDB500A461A3 /* OPMLFile.swift */, 519E84A52433D49000D238B0 /* OPMLNormalizer.swift */, 84AF4EA3222CFDD100F6A800 /* AccountMetadata.swift */, @@ -1183,6 +1186,7 @@ 9E7299D9235062A200DAEFB7 /* FeedlyResourceProviding.swift in Sources */, 51F6C591245DB302001E41CA /* CloudKitReceiveStatusOperation.swift in Sources */, 9E672394236F7CA0000BE141 /* FeedlyRefreshAccessTokenOperation.swift in Sources */, + 1748B4A724CADA17008F9850 /* AccountSyncError.swift in Sources */, 514BF5202391B0DB00902FE8 /* SingleArticleFetcher.swift in Sources */, 9EC688EC232C583300A8D0A2 /* FeedlyAccountDelegate+OAuth.swift in Sources */, 8469F81C1F6DD15E0084783E /* Account.swift in Sources */, diff --git a/Frameworks/Account/AccountManager.swift b/Frameworks/Account/AccountManager.swift index 7b2999529..e02434431 100644 --- a/Frameworks/Account/AccountManager.swift +++ b/Frameworks/Account/AccountManager.swift @@ -247,6 +247,32 @@ public final class AccountManager: UnreadCountProvider { completion?() } } + + public func refreshAll(completion: (() -> Void)? = nil) { + var syncErrors = [AccountSyncError]() + let group = DispatchGroup() + + activeAccounts.forEach { account in + group.enter() + account.refreshAll() { result in + group.leave() + switch result { + case .success: + break + case .failure(let error): + syncErrors.append(AccountSyncError(account: account, error: error)) + } + } + } + + group.notify(queue: DispatchQueue.main) { + if syncErrors.count > 0 { + NotificationCenter.default.post(Notification(name: .AccountsDidFailToSyncWithErrors, object: syncErrors, userInfo: nil)) + } + completion?() + } + + } public func syncArticleStatusAll(completion: (() -> Void)? = nil) { let group = DispatchGroup() diff --git a/Frameworks/Account/AccountSyncError.swift b/Frameworks/Account/AccountSyncError.swift new file mode 100644 index 000000000..efc88da1e --- /dev/null +++ b/Frameworks/Account/AccountSyncError.swift @@ -0,0 +1,29 @@ +// +// AccountSyncError.swift +// Account +// +// Created by Stuart Breckenridge on 24/7/20. +// Copyright © 2020 Ranchero Software, LLC. All rights reserved. +// + +import Foundation +import os.log + +public extension Notification.Name { + static let AccountsDidFailToSyncWithErrors = Notification.Name("AccountsDidFailToSyncWithErrors") +} + +public struct AccountSyncError { + + private static let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "Application") + public let account: Account + public let error: Error + + init(account: Account, error: Error) { + self.account = account + self.error = error + os_log(.error, log: AccountSyncError.log, "%@", error.localizedDescription) + } + +} + diff --git a/Multiplatform/Shared/Account Management /FixAccountCredentialView.swift b/Multiplatform/Shared/Account Management /FixAccountCredentialView.swift new file mode 100644 index 000000000..ecb585d70 --- /dev/null +++ b/Multiplatform/Shared/Account Management /FixAccountCredentialView.swift @@ -0,0 +1,167 @@ +// +// FixAccountCredentialView.swift +// NetNewsWire +// +// Created by Stuart Breckenridge on 24/7/20. +// Copyright © 2020 Ranchero Software. All rights reserved. +// + +import SwiftUI +import Account + +struct FixAccountCredentialView: View { + + let accountSyncError: AccountSyncError + @Environment(\.presentationMode) var presentationMode + @StateObject private var editModel = EditAccountCredentialsModel() + + + var body: some View { + #if os(macOS) + MacForm + .onAppear { + editModel.retrieveCredentials(accountSyncError.account) + } + .onChange(of: editModel.accountCredentialsWereUpdated) { value in + if value == true { + presentationMode.wrappedValue.dismiss() + } + } + .alert(isPresented: $editModel.showError) { + Alert(title: Text("Error Adding Account"), + message: Text(editModel.error.description), + dismissButton: .default(Text("Dismiss"), + action: { + editModel.error = .none + })) + } + .frame(idealWidth: 300, idealHeight: 200, alignment: .top) + .padding() + #else + iOSForm + .onAppear { + editModel.retrieveCredentials(accountSyncError.account) + } + .onChange(of: editModel.accountCredentialsWereUpdated) { value in + if value == true { + presentationMode.wrappedValue.dismiss() + } + } + .alert(isPresented: $editModel.showError) { + Alert(title: Text("Error Adding Account"), + message: Text(editModel.error.description), + dismissButton: .default(Text("Dismiss"), + action: { + editModel.error = .none + })) + } + #endif + + + } + + var MacForm: some View { + Form { + header + HStack(alignment: .center) { + VStack(alignment: .trailing, spacing: 12) { + Text("Username: ") + Text("Password: ") + if accountSyncError.account.type == .freshRSS { + Text("API URL: ") + } + }.frame(width: 75) + + VStack(alignment: .leading, spacing: 12) { + accountFields + } + } + .textFieldStyle(RoundedBorderTextFieldStyle()) + + Spacer() + HStack{ + if editModel.accountIsUpdatingCredentials { + ProgressView("Updating") + } + Spacer() + cancelButton + updateButton + } + }.frame(height: 220) + } + + #if os(iOS) + var iOSForm: some View { + + NavigationView { + List { + Section(header: header, content: { + accountFields + }) + } + .listStyle(InsetGroupedListStyle()) + .navigationBarItems( + leading: + cancelButton + , trailing: + HStack { + if editModel.accountIsUpdatingCredentials { + ProgressView() + .frame(width: 20 , height: 20) + .padding(.horizontal, 4) + } + updateButton + } + + ) + } + } + #endif + + var header: some View { + HStack { + Spacer() + VStack { + Image(rsImage: accountSyncError.account.smallIcon!.image) + .resizable() + .frame(width: 30, height: 30) + Text(accountSyncError.account.nameForDisplay) + Text(accountSyncError.error.localizedDescription) + .multilineTextAlignment(.center) + .lineLimit(3) + .padding(.top, 4) + } + Spacer() + }.padding() + } + + @ViewBuilder + var accountFields: some View { + TextField("Username", text: $editModel.userName) + SecureField("Password", text: $editModel.password) + if accountSyncError.account.type == .freshRSS { + TextField("API URL", text: $editModel.apiUrl) + } + } + + @ViewBuilder + var updateButton: some View { + if accountSyncError.account.type != .freshRSS { + Button("Update", action: { + editModel.updateAccountCredentials(accountSyncError.account) + }).disabled(editModel.userName.count == 0 || editModel.password.count == 0) + } else { + Button("Update", action: { + editModel.updateAccountCredentials(accountSyncError.account) + }).disabled(editModel.userName.count == 0 || editModel.password.count == 0 || editModel.apiUrl.count == 0) + } + } + + var cancelButton: some View { + Button("Cancel", action: { + presentationMode.wrappedValue.dismiss() + }) + } + +} + diff --git a/Multiplatform/Shared/SceneModel.swift b/Multiplatform/Shared/SceneModel.swift index e090e4576..eaebd1fd7 100644 --- a/Multiplatform/Shared/SceneModel.swift +++ b/Multiplatform/Shared/SceneModel.swift @@ -21,8 +21,8 @@ final class SceneModel: ObservableObject { @Published var extractorButtonState: ArticleExtractorButtonState? @Published var openInBrowserButtonState: Bool? @Published var shareButtonState: Bool? - @Published var accountErrorMessage = "" + @Published var accountSyncErrors: [AccountSyncError] = [] var selectedArticles: [Article] { timelineModel.selectedArticles @@ -48,6 +48,7 @@ final class SceneModel: ObservableObject { self.articleIconSchemeHandler = ArticleIconSchemeHandler(sceneModel: self) self.webViewProvider = WebViewProvider(articleIconSchemeHandler: self.articleIconSchemeHandler!) + subscribeToAccountSyncErrors() subscribeToToolbarChangeEvents() } @@ -146,6 +147,16 @@ private extension SceneModel { }.store(in: &cancellables) } + func subscribeToAccountSyncErrors() { + NotificationCenter.default.publisher(for: .AccountsDidFailToSyncWithErrors) + .sink { [weak self] notification in + guard let errors = notification.object as? [AccountSyncError] else { + return + } + self?.accountSyncErrors = errors + }.store(in: &cancellables) + } + // MARK: Button State Updates func updateNextUnreadButtonState(accountManager: AccountManager) { diff --git a/Multiplatform/Shared/SceneNavigationView.swift b/Multiplatform/Shared/SceneNavigationView.swift index 1aeb052cc..7eb989d67 100644 --- a/Multiplatform/Shared/SceneNavigationView.swift +++ b/Multiplatform/Shared/SceneNavigationView.swift @@ -14,8 +14,8 @@ struct SceneNavigationView: View { @StateObject private var sceneModel = SceneModel() @State private var showSheet = false @State private var showShareSheet = false - @State private var showRefreshError = false - @State private var sheetToShow: ToolbarSheets = .none + @State private var sheetToShow: SidebarSheets = .none + @State private var showAccountSyncErrorAlert = false // multiple sync errors #if os(iOS) @Environment(\.horizontalSizeClass) private var horizontalSizeClass @@ -44,31 +44,58 @@ struct SceneNavigationView: View { .onAppear { sceneModel.startup() } - .sheet(isPresented: $showSheet, onDismiss: { sheetToShow = .none }) { - - if sheetToShow == .web { - AddWebFeedView() - } - if sheetToShow == .folder { - AddFolderView() - } - } .onChange(of: sheetToShow) { value in value != .none ? (showSheet = true) : (showSheet = false) } - .onChange(of: showRefreshError) { value in - if !value { - sceneModel.accountErrorMessage = "" + .onReceive(sceneModel.$accountSyncErrors) { errors in + if errors.count == 0 { + showAccountSyncErrorAlert = false + } else { + if errors.count > 1 { + showAccountSyncErrorAlert = true + } else { + sheetToShow = .fixCredentials + } } } - .onReceive(sceneModel.$accountErrorMessage) { message in - if !message.isEmpty { - showRefreshError = true - } - } - .alert(isPresented: $showRefreshError) { - Alert(title: Text("Account Error"), message: Text(verbatim: sceneModel.accountErrorMessage), dismissButton: .default(Text("OK"))) + .sheet(isPresented: $showSheet, + onDismiss: { + sheetToShow = .none + sceneModel.accountSyncErrors = [] + }) { + if sheetToShow == .web { + AddWebFeedView() + } + if sheetToShow == .folder { + AddFolderView() + } + #if os(iOS) + if sheetToShow == .settings { + SettingsView() + } + #endif + if sheetToShow == .fixCredentials { + FixAccountCredentialView(accountSyncError: sceneModel.accountSyncErrors[0]) + } } + .alert(isPresented: $showAccountSyncErrorAlert, content: { + #if os(macOS) + return Alert(title: Text("Account Sync Error"), + message: Text("The following accounts failed to sync: ") + Text(sceneModel.accountSyncErrors.map({ $0.account.nameForDisplay }).joined(separator: ", ")) + Text(". You can update credentials in Preferences"), + dismissButton: .default(Text("Dismiss"))) + #else + return Alert(title: Text("Account Sync Error"), + message: Text("The following accounts failed to sync: ") + Text(sceneModel.accountSyncErrors.map({ $0.account.nameForDisplay }).joined(separator: ", ")) + Text(". You can update credentials in Settings"), + primaryButton: .default(Text("Show Settings"), action: { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: { + sheetToShow = .settings + }) + + }), + secondaryButton: .cancel(Text("Dismiss"))) + + #endif + }) .toolbar { #if os(macOS) @@ -84,7 +111,10 @@ struct SceneNavigationView: View { } ToolbarItem { Button { - AccountManager.shared.refreshAll(errorHandler: handleRefreshError) +// AccountManager.shared.refreshAll(errorHandler: handleRefreshError) + + AccountManager.shared.refreshAll(completion: nil) + } label: { AppAssets.refreshImage } diff --git a/Multiplatform/Shared/Sidebar/SidebarToolbarModel.swift b/Multiplatform/Shared/Sidebar/SidebarToolbarModel.swift index 000066277..d2fe4cea2 100644 --- a/Multiplatform/Shared/Sidebar/SidebarToolbarModel.swift +++ b/Multiplatform/Shared/Sidebar/SidebarToolbarModel.swift @@ -8,14 +8,14 @@ import Foundation -enum ToolbarSheets { - case none, web, twitter, reddit, folder, settings +enum SidebarSheets { + case none, web, twitter, reddit, folder, settings, fixCredentials } class SidebarToolbarModel: ObservableObject { @Published var showSheet: Bool = false - @Published var sheetToShow: ToolbarSheets = .none { + @Published var sheetToShow: SidebarSheets = .none { didSet { sheetToShow != .none ? (showSheet = true) : (showSheet = false) } diff --git a/Multiplatform/Shared/Sidebar/SidebarView.swift b/Multiplatform/Shared/Sidebar/SidebarView.swift index 8308b0fa8..ea674bb8c 100644 --- a/Multiplatform/Shared/Sidebar/SidebarView.swift +++ b/Multiplatform/Shared/Sidebar/SidebarView.swift @@ -26,6 +26,7 @@ struct SidebarView: View { @State private var scrollOffset: CGFloat = 0 @State var pulling: Bool = false @State var refreshing: Bool = false + @ViewBuilder var body: some View { #if os(macOS) @@ -110,7 +111,7 @@ struct SidebarView: View { // Crossing the threshold on the way down, we start the refresh process if !pulling && (scrollOffset > threshold && previousScrollOffset <= threshold) { pulling = true - AccountManager.shared.refreshAll(errorHandler: handleRefreshError) + AccountManager.shared.refreshAll() } // Crossing the threshold on the way UP, we end the refresh @@ -123,10 +124,6 @@ struct SidebarView: View { } } - func handleRefreshError(_ error: Error) { - sceneModel.accountErrorMessage = error.localizedDescription - } - struct RefreshFixedView: View { var body: some View { GeometryReader { proxy in diff --git a/Multiplatform/macOS/Preferences/Preference Panes/Accounts/Account Preferences/Edit Account/EditAccountCredentialsModel.swift b/Multiplatform/macOS/Preferences/Preference Panes/Accounts/Account Preferences/Edit Account/EditAccountCredentialsModel.swift index d01103ecb..28e5c10ea 100644 --- a/Multiplatform/macOS/Preferences/Preference Panes/Accounts/Account Preferences/Edit Account/EditAccountCredentialsModel.swift +++ b/Multiplatform/macOS/Preferences/Preference Panes/Accounts/Account Preferences/Edit Account/EditAccountCredentialsModel.swift @@ -162,7 +162,9 @@ extension EditAccountCredentialsModel { accountIsUpdatingCredentials = true let updateAccount = OAuthAccountAuthorizationOperation(accountType: .feedly) updateAccount.delegate = self + #if os(macOS) updateAccount.presentationAnchor = NSApplication.shared.windows.last + #endif MainThreadOperationQueue.shared.add(updateAccount) } diff --git a/Multiplatform/macOS/Preferences/Preference Panes/Accounts/Account Preferences/Edit Account/EditAccountCredentialsView.swift b/Multiplatform/macOS/Preferences/Preference Panes/Accounts/Account Preferences/Edit Account/EditAccountCredentialsView.swift index 4e7ee9710..34b5dbe04 100644 --- a/Multiplatform/macOS/Preferences/Preference Panes/Accounts/Account Preferences/Edit Account/EditAccountCredentialsView.swift +++ b/Multiplatform/macOS/Preferences/Preference Panes/Accounts/Account Preferences/Edit Account/EditAccountCredentialsView.swift @@ -83,7 +83,6 @@ struct EditAccountCredentialsView: View { } .frame(idealWidth: 300, idealHeight: 200, alignment: .top) .padding() - } } diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 3b0a7d4d7..080b3b84b 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -8,6 +8,10 @@ /* Begin PBXBuildFile section */ 1717535624BADF33004498C6 /* GeneralPreferencesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1717535524BADF33004498C6 /* GeneralPreferencesModel.swift */; }; + 171BCB8C24CB08A3006E22D9 /* FixAccountCredentialView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 171BCB8B24CB08A3006E22D9 /* FixAccountCredentialView.swift */; }; + 171BCB8D24CB08A3006E22D9 /* FixAccountCredentialView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 171BCB8B24CB08A3006E22D9 /* FixAccountCredentialView.swift */; }; + 171BCBAF24CBBFD8006E22D9 /* EditAccountCredentialsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1769E33524BD9621000E1E8E /* EditAccountCredentialsModel.swift */; }; + 171BCBB024CBBFFD006E22D9 /* AccountUpdateErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1769E33724BD97CB000E1E8E /* AccountUpdateErrors.swift */; }; 172199C924AB228900A31D04 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 172199C824AB228900A31D04 /* SettingsView.swift */; }; 172199ED24AB2E0100A31D04 /* SafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 172199EC24AB2E0100A31D04 /* SafariView.swift */; }; 172199F124AB716900A31D04 /* SidebarToolbarModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 172199F024AB716900A31D04 /* SidebarToolbarModifier.swift */; }; @@ -1817,6 +1821,7 @@ /* Begin PBXFileReference section */ 1717535524BADF33004498C6 /* GeneralPreferencesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralPreferencesModel.swift; sourceTree = ""; }; + 171BCB8B24CB08A3006E22D9 /* FixAccountCredentialView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FixAccountCredentialView.swift; sourceTree = ""; }; 172199C824AB228900A31D04 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; 172199EC24AB2E0100A31D04 /* SafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariView.swift; sourceTree = ""; }; 172199F024AB716900A31D04 /* SidebarToolbarModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarToolbarModifier.swift; sourceTree = ""; }; @@ -2555,6 +2560,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 171BCBB124CBD569006E22D9 /* Account Management */ = { + isa = PBXGroup; + children = ( + 171BCB8B24CB08A3006E22D9 /* FixAccountCredentialView.swift */, + ); + path = "Account Management "; + sourceTree = ""; + }; 172199EB24AB228E00A31D04 /* Settings */ = { isa = PBXGroup; children = ( @@ -3106,6 +3119,7 @@ 51E499FB24A9135A00B667CB /* Sidebar */, 514E6C0424AD2B0400AC6F6E /* SwiftUI Extensions */, 51919FCB24AB855000541E64 /* Timeline */, + 171BCBB124CBD569006E22D9 /* Account Management */, ); path = Shared; sourceTree = ""; @@ -4317,46 +4331,46 @@ TargetAttributes = { 51314636235A7BBE00387FDC = { CreatedOnToolsVersion = 11.2; - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = FQLBNX3GP7; LastSwiftMigration = 1120; ProvisioningStyle = Automatic; }; 513C5CE5232571C2003D4054 = { CreatedOnToolsVersion = 11.0; - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = FQLBNX3GP7; ProvisioningStyle = Automatic; }; 518B2ED12351B3DD00400001 = { CreatedOnToolsVersion = 11.2; - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = FQLBNX3GP7; ProvisioningStyle = Automatic; TestTargetID = 840D617B2029031C009BC708; }; 51C0513C24A77DF800194D5E = { CreatedOnToolsVersion = 12.0; - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = FQLBNX3GP7; ProvisioningStyle = Automatic; }; 51C0514324A77DF800194D5E = { CreatedOnToolsVersion = 12.0; - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = FQLBNX3GP7; ProvisioningStyle = Automatic; }; 6581C73220CED60000F4AD34 = { - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = FQLBNX3GP7; ProvisioningStyle = Automatic; }; 65ED3FA2235DEF6C0081F399 = { - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = FQLBNX3GP7; ProvisioningStyle = Automatic; }; 65ED4090235DEF770081F399 = { - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = FQLBNX3GP7; ProvisioningStyle = Automatic; }; 840D617B2029031C009BC708 = { CreatedOnToolsVersion = 9.3; - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = FQLBNX3GP7; ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.BackgroundModes = { @@ -4366,7 +4380,7 @@ }; 849C645F1ED37A5D003D8FC0 = { CreatedOnToolsVersion = 8.2.1; - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = FQLBNX3GP7; ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.HardenedRuntime = { @@ -4376,7 +4390,7 @@ }; 849C64701ED37A5D003D8FC0 = { CreatedOnToolsVersion = 8.2.1; - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = FQLBNX3GP7; ProvisioningStyle = Automatic; TestTargetID = 849C645F1ED37A5D003D8FC0; }; @@ -5185,8 +5199,10 @@ 51E4995C24A875F300B667CB /* ArticleRenderer.swift in Sources */, 51E4992324A8095700B667CB /* URL-Extensions.swift in Sources */, 51E4993624A867E800B667CB /* UserInfoKey.swift in Sources */, + 171BCB8C24CB08A3006E22D9 /* FixAccountCredentialView.swift in Sources */, 51E4990924A808C500B667CB /* WebFeedIconDownloader.swift in Sources */, 51E498F524A8085D00B667CB /* TodayFeedDelegate.swift in Sources */, + 171BCBAF24CBBFD8006E22D9 /* EditAccountCredentialsModel.swift in Sources */, 51B80EDB24BD225200C6C32D /* OpenInSafariActivity.swift in Sources */, 172199F124AB716900A31D04 /* SidebarToolbarModifier.swift in Sources */, 65CBAD5A24AE03C20006DD91 /* ColorPaletteContainerView.swift in Sources */, @@ -5263,6 +5279,7 @@ 6591727F24B5D19500B638E8 /* SettingsDetailAccountView.swift in Sources */, 51E498F924A8085D00B667CB /* SmartFeed.swift in Sources */, 65ACE48824B48020003AE06A /* SettingsLocalAccountView.swift in Sources */, + 171BCBB024CBBFFD006E22D9 /* AccountUpdateErrors.swift in Sources */, 17930ED424AF10EE00A9BA52 /* AddWebFeedView.swift in Sources */, 51E4995124A8734D00B667CB /* ExtensionPointManager.swift in Sources */, 51E4990C24A808C500B667CB /* AuthorAvatarDownloader.swift in Sources */, @@ -5368,6 +5385,7 @@ 1729529724AA1CD000D65E66 /* MacPreferencesView.swift in Sources */, 51E4994C24A8734C00B667CB /* RedditFeedProvider-Extensions.swift in Sources */, 1729529324AA1CAA00D65E66 /* AccountsPreferencesView.swift in Sources */, + 171BCB8D24CB08A3006E22D9 /* FixAccountCredentialView.swift in Sources */, 1769E32D24BD20A0000E1E8E /* AccountDetailView.swift in Sources */, 51919FAD24AA8CCA00541E64 /* UnreadCountView.swift in Sources */, 51E498C924A8085D00B667CB /* PseudoFeed.swift in Sources */, diff --git a/Shared/Timer/AccountRefreshTimer.swift b/Shared/Timer/AccountRefreshTimer.swift index a0ba9dd32..04c944a5a 100644 --- a/Shared/Timer/AccountRefreshTimer.swift +++ b/Shared/Timer/AccountRefreshTimer.swift @@ -73,8 +73,8 @@ class AccountRefreshTimer { lastTimedRefresh = Date() update() - AccountManager.shared.refreshAll(errorHandler: ErrorHandler.log) - + //AccountManager.shared.refreshAll(errorHandler: ErrorHandler.log) + AccountManager.shared.refreshAll(completion: nil) } }