diff --git a/Frameworks/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift b/Frameworks/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift index 698d1d3c2..113e3b763 100644 --- a/Frameworks/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift +++ b/Frameworks/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift @@ -471,4 +471,39 @@ extension NewsBlurAccountDelegate { } } } + + func deleteFeed(for account: Account, with feed: WebFeed, from container: Container?, completion: @escaping (Result) -> Void) { + // This error should never happen + guard let feedID = feed.subscriptionID else { + completion(.failure(NewsBlurError.invalidParameter)) + return + } + + refreshProgress.addToNumberOfTasksAndRemaining(1) + + let folderName = (container as? Folder)?.name + caller.deleteFeed(feedID: feedID, folder: folderName) { result in + self.refreshProgress.completeTask() + + switch result { + case .success: + DispatchQueue.main.async { + account.clearWebFeedMetadata(feed) + account.removeWebFeed(feed) + if let folders = account.folders { + for folder in folders where folderName != nil && folder.name == folderName { + folder.removeWebFeed(feed) + } + } + completion(.success(())) + } + + case .failure(let error): + DispatchQueue.main.async { + let wrappedError = AccountError.wrappedError(error: error, account: account) + completion(.failure(wrappedError)) + } + } + } + } } diff --git a/Frameworks/Account/NewsBlur/Models/NewsBlurFeedChange.swift b/Frameworks/Account/NewsBlur/Models/NewsBlurFeedChange.swift index e3082fe3d..e0d9528a9 100644 --- a/Frameworks/Account/NewsBlur/Models/NewsBlurFeedChange.swift +++ b/Frameworks/Account/NewsBlur/Models/NewsBlurFeedChange.swift @@ -9,7 +9,9 @@ import Foundation enum NewsBlurFeedChange { - case add(String) + case add(String, String?) + case rename(String, String) + case delete(String, String?) } extension NewsBlurFeedChange: NewsBlurDataConvertible { @@ -17,11 +19,21 @@ extension NewsBlurFeedChange: NewsBlurDataConvertible { var postData = URLComponents() postData.queryItems = { switch self { - case .add(let url): + case .add(let url, let folder): return [ URLQueryItem(name: "url", value: url), - URLQueryItem(name: "folder", value: ""), // root folder + folder != nil ? URLQueryItem(name: "folder", value: folder) : nil + ].compactMap { $0 } + case .rename(let feedID, let newName): + return [ + URLQueryItem(name: "feed_id", value: feedID), + URLQueryItem(name: "feed_title", value: newName), ] + case .delete(let feedID, let folder): + return [ + URLQueryItem(name: "feed_id", value: feedID), + folder != nil ? URLQueryItem(name: "in_folder", value: folder) : nil, + ].compactMap { $0 } } }() diff --git a/Frameworks/Account/NewsBlur/NewsBlurAPICaller.swift b/Frameworks/Account/NewsBlur/NewsBlurAPICaller.swift index fc58042e3..b0c07735a 100644 --- a/Frameworks/Account/NewsBlur/NewsBlurAPICaller.swift +++ b/Frameworks/Account/NewsBlur/NewsBlurAPICaller.swift @@ -220,10 +220,10 @@ final class NewsBlurAPICaller: NSObject { ) } - func addURL(_ url: String, completion: @escaping (Result) -> Void) { + func addURL(_ url: String, folder: String?, completion: @escaping (Result) -> Void) { sendUpdates( endpoint: "reader/add_url", - payload: NewsBlurFeedChange.add(url), + payload: NewsBlurFeedChange.add(url, folder), resultType: NewsBlurAddURLResponse.self ) { result in switch result { @@ -234,4 +234,32 @@ final class NewsBlurAPICaller: NSObject { } } } + + func renameFeed(feedID: String, newName: String, completion: @escaping (Result) -> Void) { + sendUpdates( + endpoint: "reader/rename_feed", + payload: NewsBlurFeedChange.rename(feedID, newName) + ) { result in + switch result { + case .success: + completion(.success(())) + case .failure(let error): + completion(.failure(error)) + } + } + } + + func deleteFeed(feedID: String, folder: String? = nil, completion: @escaping (Result) -> Void) { + sendUpdates( + endpoint: "reader/delete_feed", + payload: NewsBlurFeedChange.delete(feedID, folder) + ) { result in + switch result { + case .success: + completion(.success(())) + case .failure(let error): + completion(.failure(error)) + } + } + } } diff --git a/Frameworks/Account/NewsBlur/NewsBlurAccountDelegate.swift b/Frameworks/Account/NewsBlur/NewsBlurAccountDelegate.swift index 96bfebd4e..f7a69454e 100644 --- a/Frameworks/Account/NewsBlur/NewsBlurAccountDelegate.swift +++ b/Frameworks/Account/NewsBlur/NewsBlurAccountDelegate.swift @@ -387,7 +387,7 @@ final class NewsBlurAccountDelegate: AccountDelegate { var feedIDs: [String] = [] for feed in folder.topLevelWebFeeds { - if feed.folderRelationship?.count ?? 0 > 1 { + if (feed.folderRelationship?.count ?? 0) > 1 { clearFolderRelationship(for: feed, withFolderName: folderToRemove) } else if let subscriptionID = feed.subscriptionID { feedIDs.append(subscriptionID) @@ -412,7 +412,8 @@ final class NewsBlurAccountDelegate: AccountDelegate { func createWebFeed(for account: Account, url: String, name: String?, container: Container, completion: @escaping (Result) -> ()) { refreshProgress.addToNumberOfTasksAndRemaining(1) - caller.addURL(url) { result in + let folderName = (container as? Folder)?.name + caller.addURL(url, folder: folderName) { result in self.refreshProgress.completeTask() switch result { @@ -428,14 +429,38 @@ final class NewsBlurAccountDelegate: AccountDelegate { } func renameWebFeed(for account: Account, with feed: WebFeed, to name: String, completion: @escaping (Result) -> ()) { - completion(.success(())) + // This error should never happen + guard let feedID = feed.subscriptionID else { + completion(.failure(NewsBlurError.invalidParameter)) + return + } + + refreshProgress.addToNumberOfTasksAndRemaining(1) + + caller.renameFeed(feedID: feedID, newName: name) { result in + self.refreshProgress.completeTask() + + switch result { + case .success: + DispatchQueue.main.async { + feed.editedName = name + completion(.success(())) + } + + case .failure(let error): + DispatchQueue.main.async { + let wrappedError = AccountError.wrappedError(error: error, account: account) + completion(.failure(wrappedError)) + } + } + } } func addWebFeed(for account: Account, with feed: WebFeed, to container: Container, completion: @escaping (Result) -> ()) { guard let folder = container as? Folder else { DispatchQueue.main.async { if let account = container as? Account { - account.addFeedIfNotInAnyFolder(feed) + account.addWebFeed(feed) } completion(.success(())) } @@ -451,7 +476,7 @@ final class NewsBlurAccountDelegate: AccountDelegate { } func removeWebFeed(for account: Account, with feed: WebFeed, from container: Container, completion: @escaping (Result) -> ()) { - completion(.success(())) + deleteFeed(for: account, with: feed, from: container, completion: completion) } func moveWebFeed(for account: Account, with feed: WebFeed, from: Container, to: Container, completion: @escaping (Result) -> ()) {