diff --git a/Account/Sources/Account/Account.swift b/Account/Sources/Account/Account.swift index 207291695..32413938b 100644 --- a/Account/Sources/Account/Account.swift +++ b/Account/Sources/Account/Account.swift @@ -651,8 +651,8 @@ public enum FetchType { delegate.renameFolder(for: self, with: folder, to: name, completion: completion) } - public func restoreFolder(_ folder: Folder, completion: @escaping (Result) -> Void) { - delegate.restoreFolder(for: self, folder: folder, completion: completion) + public func restoreFolder(_ folder: Folder) async throws { + try await delegate.restoreFolder(for: self, folder: folder) } func clearFeedMetadata(_ feed: Feed) { diff --git a/Account/Sources/Account/AccountDelegate.swift b/Account/Sources/Account/AccountDelegate.swift index 0f9686c9f..b1f962741 100644 --- a/Account/Sources/Account/AccountDelegate.swift +++ b/Account/Sources/Account/AccountDelegate.swift @@ -43,7 +43,7 @@ import Secrets func moveFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) - func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) + func restoreFolder(for account: Account, folder: Folder) async throws func markArticles(for account: Account, articles: Set
, statusKey: ArticleStatus.Key, flag: Bool) async throws // Called at the end of account’s init method. diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift index cb34f1322..e00c4abbb 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift @@ -435,7 +435,21 @@ enum CloudKitAccountDelegateError: LocalizedError { } - func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) { + func restoreFolder(for account: Account, folder: Folder) async throws { + + try await withCheckedThrowingContinuation { continuation in + self.restoreFolder(for: account, folder: folder) { result in + switch result { + case .success: + continuation.resume() + case .failure(let error): + continuation.resume(throwing: error) + } + } + } + } + + private func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) { guard let name = folder.name else { completion(.failure(LocalAccountDelegateError.invalidParameter)) return diff --git a/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift b/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift index 068f05376..7119b594c 100644 --- a/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift +++ b/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift @@ -575,7 +575,21 @@ final class FeedbinAccountDelegate: AccountDelegate { } - func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) { + func restoreFolder(for account: Account, folder: Folder) async throws { + + try await withCheckedThrowingContinuation { continuation in + self.restoreFolder(for: account, folder: folder) { result in + switch result { + case .success: + continuation.resume() + case .failure(let error): + continuation.resume(throwing: error) + } + } + } + } + + private func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) { let group = DispatchGroup() diff --git a/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift b/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift index e2759c1b5..ca807d6d0 100644 --- a/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift +++ b/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift @@ -555,7 +555,21 @@ final class FeedlyAccountDelegate: AccountDelegate { } } - @MainActor func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) { + func restoreFolder(for account: Account, folder: Folder) async throws { + + try await withCheckedThrowingContinuation { continuation in + self.restoreFolder(for: account, folder: folder) { result in + switch result { + case .success: + continuation.resume() + case .failure(let error): + continuation.resume(throwing: error) + } + } + } + } + + private func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) { let group = DispatchGroup() for feed in folder.topLevelFeeds { diff --git a/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift b/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift index 74510912e..9c81dbc8a 100644 --- a/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift +++ b/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift @@ -135,9 +135,8 @@ final class LocalAccountDelegate: AccountDelegate { completion(.success(())) } - func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) { + func restoreFolder(for account: Account, folder: Folder) async throws { account.addFolder(folder) - completion(.success(())) } func markArticles(for account: Account, articles: Set
, statusKey: ArticleStatus.Key, flag: Bool) async throws { diff --git a/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift b/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift index 40914eb26..a677e65cf 100644 --- a/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift +++ b/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift @@ -603,7 +603,21 @@ final class NewsBlurAccountDelegate: AccountDelegate { } } - func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> ()) { + func restoreFolder(for account: Account, folder: Folder) async throws { + + try await withCheckedThrowingContinuation { continuation in + self.restoreFolder(for: account, folder: folder) { result in + switch result { + case .success: + continuation.resume() + case .failure(let error): + continuation.resume(throwing: error) + } + } + } + } + + private func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> ()) { guard let folderName = folder.name else { completion(.failure(NewsBlurError.invalidParameter)) return diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index b4a6af595..1420a94f5 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -627,7 +627,21 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } - func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) { + func restoreFolder(for account: Account, folder: Folder) async throws { + + try await withCheckedThrowingContinuation { continuation in + self.restoreFolder(for: account, folder: folder) { result in + switch result { + case .success: + continuation.resume() + case .failure(let error): + continuation.resume(throwing: error) + } + } + } + } + + private func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) { let group = DispatchGroup() diff --git a/Shared/Commands/DeleteCommand.swift b/Shared/Commands/DeleteCommand.swift index 4119de2f1..7a9fee033 100644 --- a/Shared/Commands/DeleteCommand.swift +++ b/Shared/Commands/DeleteCommand.swift @@ -46,7 +46,7 @@ import Core } func perform() { - + let group = DispatchGroup() itemSpecifiers.forEach { group.enter() @@ -54,14 +54,14 @@ import Core group.leave() } } - + group.notify(queue: DispatchQueue.main) { self.treeController?.rebuild() self.registerUndo() } - + } - + func undo() { itemSpecifiers.forEach { $0.restore() } registerRedo() @@ -137,36 +137,36 @@ import Core self.account = account! self.path = ContainerPath(account: account!, folders: node.containingFolders()) - + self.errorHandler = errorHandler - + } func delete(completion: @escaping () -> Void) { if let feed = feed { - + guard let container = path.resolveContainer() else { completion() return } - + BatchUpdate.shared.start() account?.removeFeed(feed, from: container) { result in BatchUpdate.shared.end() completion() self.checkResult(result) } - + } else if let folder = folder { - + BatchUpdate.shared.start() account?.removeFolder(folder) { result in BatchUpdate.shared.end() completion() self.checkResult(result) } - + } } @@ -185,31 +185,36 @@ import Core guard let account = account, let feed = feed, let container = path.resolveContainer() else { return } - + BatchUpdate.shared.start() account.restoreFeed(feed, container: container) { result in BatchUpdate.shared.end() self.checkResult(result) } - + } private func restoreFolder() { - guard let account = account, let folder = folder else { + guard let account, let folder else { return } - - BatchUpdate.shared.start() - account.restoreFolder(folder) { result in - BatchUpdate.shared.end() - self.checkResult(result) + + Task { @MainActor in + BatchUpdate.shared.start() + do { + try await account.restoreFolder(folder) + BatchUpdate.shared.end() + + } catch { + BatchUpdate.shared.end() + self.errorHandler(error) + } } - } private func checkResult(_ result: Result) { - + switch result { case .success: break @@ -218,11 +223,11 @@ import Core } } - + } private extension Node { - + func parentFolder() -> Folder? { guard let parentNode = self.parent else {