mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Convert removeFolder to async/await.
This commit is contained in:
@@ -638,8 +638,8 @@ public enum FetchType {
|
||||
try await delegate.createFolder(for: self, name: name)
|
||||
}
|
||||
|
||||
public func removeFolder(_ folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
delegate.removeFolder(for: self, with: folder, completion: completion)
|
||||
public func removeFolder(_ folder: Folder) async throws {
|
||||
try await delegate.removeFolder(for: self, with: folder)
|
||||
}
|
||||
|
||||
public func renameFolder(_ folder: Folder, to name: String) async throws {
|
||||
|
||||
@@ -34,7 +34,7 @@ import Secrets
|
||||
|
||||
func createFolder(for account: Account, name: String) async throws -> Folder
|
||||
func renameFolder(for account: Account, with folder: Folder, to name: String) async throws
|
||||
func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result<Void, Error>) -> Void)
|
||||
func removeFolder(for account: Account, with folder: Folder) async throws
|
||||
|
||||
func createFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result<Feed, Error>) -> Void)
|
||||
func renameFeed(for account: Account, feed: Feed, name: String) async throws
|
||||
|
||||
@@ -321,67 +321,65 @@ public enum FeedbinAccountDelegateError: String, Error {
|
||||
}
|
||||
}
|
||||
|
||||
func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func removeFolder(for account: Account, with folder: Folder) async throws {
|
||||
|
||||
// Feedbin uses tags and if at least one feed isn't tagged, then the folder doesn't exist on their system
|
||||
guard folder.hasAtLeastOneFeed() else {
|
||||
account.removeFolder(folder)
|
||||
completion(.success(()))
|
||||
try await account.removeFolder(folder)
|
||||
return
|
||||
}
|
||||
|
||||
let group = DispatchGroup()
|
||||
|
||||
for feed in folder.topLevelFeeds {
|
||||
|
||||
if feed.folderRelationship?.count ?? 0 > 1 {
|
||||
|
||||
if let feedTaggingID = feed.folderRelationship?[folder.name ?? ""] {
|
||||
group.enter()
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
||||
caller.deleteTagging(taggingID: feedTaggingID) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
group.leave()
|
||||
switch result {
|
||||
case .success:
|
||||
DispatchQueue.main.async {
|
||||
self.clearFolderRelationship(for: feed, withFolderName: folder.name ?? "")
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
|
||||
let group = DispatchGroup()
|
||||
|
||||
for feed in folder.topLevelFeeds {
|
||||
|
||||
if feed.folderRelationship?.count ?? 0 > 1 {
|
||||
|
||||
if let feedTaggingID = feed.folderRelationship?[folder.name ?? ""] {
|
||||
group.enter()
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
||||
caller.deleteTagging(taggingID: feedTaggingID) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
group.leave()
|
||||
switch result {
|
||||
case .success:
|
||||
DispatchQueue.main.async {
|
||||
self.clearFolderRelationship(for: feed, withFolderName: folder.name ?? "")
|
||||
}
|
||||
case .failure(let error):
|
||||
self.logger.error("Remove feed error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if let subscriptionID = feed.externalID {
|
||||
group.enter()
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
||||
caller.deleteSubscription(subscriptionID: subscriptionID) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
group.leave()
|
||||
switch result {
|
||||
case .success:
|
||||
DispatchQueue.main.async {
|
||||
account.clearFeedMetadata(feed)
|
||||
}
|
||||
case .failure(let error):
|
||||
self.logger.error("Remove feed error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
case .failure(let error):
|
||||
self.logger.error("Remove feed error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if let subscriptionID = feed.externalID {
|
||||
group.enter()
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
||||
caller.deleteSubscription(subscriptionID: subscriptionID) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
group.leave()
|
||||
switch result {
|
||||
case .success:
|
||||
DispatchQueue.main.async {
|
||||
account.clearFeedMetadata(feed)
|
||||
}
|
||||
case .failure(let error):
|
||||
self.logger.error("Remove feed error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
account.removeFolder(folder)
|
||||
continuation.resume()
|
||||
}
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
account.removeFolder(folder)
|
||||
completion(.success(()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func createFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result<Feed, Error>) -> Void) {
|
||||
|
||||
@@ -177,9 +177,8 @@ final class LocalAccountDelegate: AccountDelegate, Logging {
|
||||
folder.name = name
|
||||
}
|
||||
|
||||
func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
account.removeFolder(folder)
|
||||
completion(.success(()))
|
||||
func removeFolder(for account: Account, with folder: Folder) async throws {
|
||||
try await account.removeFolder(folder)
|
||||
}
|
||||
|
||||
func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
@@ -398,10 +398,9 @@ final class NewsBlurAccountDelegate: AccountDelegate, Logging {
|
||||
}
|
||||
}
|
||||
|
||||
func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result<Void, Error>) -> ()) {
|
||||
func removeFolder(for account: Account, with folder: Folder) async throws {
|
||||
guard let folderToRemove = folder.name else {
|
||||
completion(.failure(NewsBlurError.invalidParameter))
|
||||
return
|
||||
throw NewsBlurError.invalidParameter
|
||||
}
|
||||
|
||||
var feedIDs: [String] = []
|
||||
@@ -415,15 +414,17 @@ final class NewsBlurAccountDelegate: AccountDelegate, Logging {
|
||||
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
||||
|
||||
caller.removeFolder(named: folderToRemove, feedIDs: feedIDs) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
caller.removeFolder(named: folderToRemove, feedIDs: feedIDs) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
|
||||
switch result {
|
||||
case .success:
|
||||
account.removeFolder(folder)
|
||||
completion(.success(()))
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
switch result {
|
||||
case .success:
|
||||
account.removeFolder(folder)
|
||||
continuation.resume()
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,72 +320,70 @@ public enum ReaderAPIAccountDelegateError: LocalizedError {
|
||||
}
|
||||
}
|
||||
|
||||
func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func removeFolder(for account: Account, with folder: Folder) async throws {
|
||||
|
||||
let group = DispatchGroup()
|
||||
|
||||
for feed in folder.topLevelFeeds {
|
||||
|
||||
if feed.folderRelationship?.count ?? 0 > 1 {
|
||||
|
||||
if let feedExternalID = feed.externalID {
|
||||
group.enter()
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
||||
caller.deleteTagging(subscriptionID: feedExternalID, tagName: folder.nameForDisplay) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
group.leave()
|
||||
switch result {
|
||||
case .success:
|
||||
DispatchQueue.main.async {
|
||||
self.clearFolderRelationship(for: feed, folderExternalID: folder.externalID)
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
let group = DispatchGroup()
|
||||
|
||||
for feed in folder.topLevelFeeds {
|
||||
|
||||
if feed.folderRelationship?.count ?? 0 > 1 {
|
||||
|
||||
if let feedExternalID = feed.externalID {
|
||||
group.enter()
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
||||
caller.deleteTagging(subscriptionID: feedExternalID, tagName: folder.nameForDisplay) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
group.leave()
|
||||
switch result {
|
||||
case .success:
|
||||
Task { @MainActor in
|
||||
self.clearFolderRelationship(for: feed, folderExternalID: folder.externalID)
|
||||
}
|
||||
case .failure(let error):
|
||||
self.logger.error("Remove feed error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if let subscriptionID = feed.externalID {
|
||||
group.enter()
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
||||
caller.deleteSubscription(subscriptionID: subscriptionID) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
group.leave()
|
||||
switch result {
|
||||
case .success:
|
||||
Task { @MainActor in
|
||||
account.clearFeedMetadata(feed)
|
||||
}
|
||||
case .failure(let error):
|
||||
self.logger.error("Remove feed error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
case .failure(let error):
|
||||
self.logger.error("Remove feed error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if let subscriptionID = feed.externalID {
|
||||
group.enter()
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
||||
caller.deleteSubscription(subscriptionID: subscriptionID) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
group.leave()
|
||||
switch result {
|
||||
case .success:
|
||||
DispatchQueue.main.async {
|
||||
account.clearFeedMetadata(feed)
|
||||
}
|
||||
case .failure(let error):
|
||||
self.logger.error("Remove feed error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
if self.variant == .theOldReader {
|
||||
account.removeFolder(folder)
|
||||
completion(.success(()))
|
||||
} else {
|
||||
self.caller.deleteTag(folderExternalID: folder.externalID) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
account.removeFolder(folder)
|
||||
completion(.success(()))
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
if self.variant == .theOldReader {
|
||||
account.removeFolder(folder)
|
||||
continuation.resume()
|
||||
} else {
|
||||
self.caller.deleteTag(folderExternalID: folder.externalID) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
account.removeFolder(folder)
|
||||
continuation.resume()
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func createFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result<Feed, Error>) -> Void) {
|
||||
|
||||
@@ -328,58 +328,62 @@ final class CloudKitAccountDelegate: AccountDelegate, Logging {
|
||||
}
|
||||
}
|
||||
|
||||
func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(2)
|
||||
accountZone.findFeedExternalIDs(for: folder) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
switch result {
|
||||
case .success(let feedExternalIDs):
|
||||
func removeFolder(for account: Account, with folder: Folder) async throws {
|
||||
|
||||
let feeds = feedExternalIDs.compactMap { account.existingFeed(withExternalID: $0) }
|
||||
let group = DispatchGroup()
|
||||
var errorOccurred = false
|
||||
|
||||
for feed in feeds {
|
||||
group.enter()
|
||||
self.removeFeedFromCloud(for: account, with: feed, from: folder) { [weak self] result in
|
||||
group.leave()
|
||||
if case .failure(let error) = result {
|
||||
self?.logger.error("Remove folder, remove feed error: \(error.localizedDescription, privacy: .public)")
|
||||
errorOccurred = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.global(qos: .background)) {
|
||||
DispatchQueue.main.async {
|
||||
guard !errorOccurred else {
|
||||
self.refreshProgress.completeTask()
|
||||
completion(.failure(CloudKitAccountDelegateError.unknown))
|
||||
return
|
||||
}
|
||||
|
||||
self.accountZone.removeFolder(folder) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
switch result {
|
||||
case .success:
|
||||
account.removeFolder(folder)
|
||||
completion(.success(()))
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(2)
|
||||
|
||||
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, Error>) -> Void in
|
||||
|
||||
accountZone.findFeedExternalIDs(for: folder) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
switch result {
|
||||
case .success(let feedExternalIDs):
|
||||
|
||||
let feeds = feedExternalIDs.compactMap { account.existingFeed(withExternalID: $0) }
|
||||
let group = DispatchGroup()
|
||||
var errorOccurred = false
|
||||
|
||||
for feed in feeds {
|
||||
group.enter()
|
||||
self.removeFeedFromCloud(for: account, with: feed, from: folder) { [weak self] result in
|
||||
group.leave()
|
||||
if case .failure(let error) = result {
|
||||
self?.logger.error("Remove folder, remove feed error: \(error.localizedDescription, privacy: .public)")
|
||||
errorOccurred = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.global(qos: .background)) {
|
||||
DispatchQueue.main.async {
|
||||
guard !errorOccurred else {
|
||||
self.refreshProgress.completeTask()
|
||||
continuation.resume(throwing: CloudKitAccountDelegateError.unknown)
|
||||
return
|
||||
}
|
||||
|
||||
self.accountZone.removeFolder(folder) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
switch result {
|
||||
case .success:
|
||||
account.removeFolder(folder)
|
||||
continuation.resume()
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case .failure(let error):
|
||||
self.refreshProgress.completeTask()
|
||||
self.refreshProgress.completeTask()
|
||||
self.processAccountError(account, error)
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
|
||||
case .failure(let error):
|
||||
self.refreshProgress.completeTask()
|
||||
self.refreshProgress.completeTask()
|
||||
self.processAccountError(account, error)
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
@@ -292,25 +292,25 @@ final class FeedlyAccountDelegate: AccountDelegate, Logging {
|
||||
}
|
||||
}
|
||||
|
||||
func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func removeFolder(for account: Account, with folder: Folder) async throws {
|
||||
guard let id = folder.externalID else {
|
||||
return DispatchQueue.main.async {
|
||||
completion(.failure(FeedlyAccountDelegateError.unableToRemoveFolder(folder.nameForDisplay)))
|
||||
}
|
||||
throw FeedlyAccountDelegateError.unableToRemoveFolder(folder.nameForDisplay)
|
||||
}
|
||||
|
||||
let progress = refreshProgress
|
||||
progress.addToNumberOfTasksAndRemaining(1)
|
||||
|
||||
caller.deleteCollection(with: id) { result in
|
||||
progress.completeTask()
|
||||
|
||||
switch result {
|
||||
case .success:
|
||||
account.removeFolder(folder)
|
||||
completion(.success(()))
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
caller.deleteCollection(with: id) { result in
|
||||
progress.completeTask()
|
||||
|
||||
switch result {
|
||||
case .success:
|
||||
account.removeFolder(folder)
|
||||
continuation.resume()
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,9 +69,10 @@ import RSCore
|
||||
|
||||
func deleteElement(_ element:ScriptingObject) {
|
||||
if let scriptableFolder = element as? ScriptableFolder {
|
||||
BatchUpdate.shared.perform {
|
||||
account.removeFolder(scriptableFolder.folder) { result in
|
||||
}
|
||||
BatchUpdate.shared.start()
|
||||
Task { @MainActor in
|
||||
try? await account.removeFolder(scriptableFolder.folder)
|
||||
BatchUpdate.shared.end()
|
||||
}
|
||||
} else if let scriptableFeed = element as? ScriptableFeed {
|
||||
BatchUpdate.shared.perform {
|
||||
|
||||
@@ -163,12 +163,16 @@ private struct SidebarItemSpecifier {
|
||||
} else if let folder = folder {
|
||||
|
||||
BatchUpdate.shared.start()
|
||||
account?.removeFolder(folder) { result in
|
||||
Task { @MainActor in
|
||||
do {
|
||||
try await account?.removeFolder(folder)
|
||||
} catch {
|
||||
errorHandler(error)
|
||||
}
|
||||
|
||||
BatchUpdate.shared.end()
|
||||
completion()
|
||||
self.checkResult(result)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user