Convert createFolder to async await.

This commit is contained in:
Brent Simmons 2024-03-26 22:18:48 -07:00
parent 91b0e7158a
commit c68738bf64
12 changed files with 109 additions and 58 deletions

View File

@ -620,8 +620,8 @@ public enum FetchType {
delegate.restoreFeed(for: self, feed: feed, container: container, completion: completion)
}
public func addFolder(_ name: String, completion: @escaping (Result<Folder, Error>) -> Void) {
delegate.createFolder(for: self, name: name, completion: completion)
public func addFolder(_ name: String) async throws -> Folder {
try await delegate.createFolder(for: self, name: name)
}
public func removeFolder(_ folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {

View File

@ -32,7 +32,7 @@ import Secrets
func importOPML(for account:Account, opmlFile: URL) async throws
func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> Void)
func createFolder(for account: Account, name: String) async throws -> Folder
func renameFolder(for account: Account, with folder: Folder, to name: String, completion: @escaping (Result<Void, Error>) -> Void)
func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result<Void, Error>) -> Void)

View File

@ -332,7 +332,22 @@ enum CloudKitAccountDelegateError: LocalizedError {
}
}
func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> Void) {
func createFolder(for account: Account, name: String) async throws -> Folder {
try await withCheckedThrowingContinuation { continuation in
self.createFolder(for: account, name: name) { result in
switch result {
case .success(let folder):
continuation.resume(returning: folder)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
private func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> Void) {
refreshProgress.addToNumberOfTasksAndRemaining(1)
accountZone.createFolder(name: name) { result in
self.refreshProgress.completeTask()

View File

@ -339,12 +339,12 @@ final class FeedbinAccountDelegate: AccountDelegate {
}
func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> Void) {
if let folder = account.ensureFolder(with: name) {
completion(.success(folder))
} else {
completion(.failure(FeedbinAccountDelegateError.invalidParameter))
func createFolder(for account: Account, name: String) async throws -> Folder {
guard let folder = account.ensureFolder(with: name) else {
throw FeedbinAccountDelegateError.invalidParameter
}
return folder
}
func renameFolder(for account: Account, with folder: Folder, to name: String, completion: @escaping (Result<Void, Error>) -> Void) {

View File

@ -304,8 +304,24 @@ final class FeedlyAccountDelegate: AccountDelegate {
}
}
func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> Void) {
func createFolder(for account: Account, name: String) async throws -> Folder {
try await withCheckedThrowingContinuation { continuation in
self.createFolder(for: account, name: name) { result in
switch result {
case .success(let folder):
continuation.resume(returning: folder)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
private func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> Void) {
let progress = refreshProgress
progress.addToNumberOfTasksAndRemaining(1)

View File

@ -117,14 +117,14 @@ final class LocalAccountDelegate: AccountDelegate {
completion(.success(()))
}
func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> Void) {
if let folder = account.ensureFolder(with: name) {
completion(.success(folder))
} else {
completion(.failure(FeedbinAccountDelegateError.invalidParameter))
func createFolder(for account: Account, name: String) async throws -> Folder {
guard let folder = account.ensureFolder(with: name) else {
throw LocalAccountDelegateError.invalidParameter
}
return folder
}
func renameFolder(for account: Account, with folder: Folder, to name: String, completion: @escaping (Result<Void, Error>) -> Void) {
folder.name = name
completion(.success(()))

View File

@ -396,7 +396,22 @@ final class NewsBlurAccountDelegate: AccountDelegate {
func importOPML(for account: Account, opmlFile: URL) async throws {
}
func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> ()) {
func createFolder(for account: Account, name: String) async throws -> Folder {
try await withCheckedThrowingContinuation { continuation in
self.createFolder(for: account, name: name) { result in
switch result {
case .success(let folder):
continuation.resume(returning: folder)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
private func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> ()) {
self.refreshProgress.addToNumberOfTasksAndRemaining(1)
caller.addFolder(named: name) { result in

View File

@ -340,15 +340,15 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
func importOPML(for account:Account, opmlFile: URL) async throws {
}
func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> Void) {
if let folder = account.ensureFolder(with: name) {
completion(.success(folder))
} else {
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
func createFolder(for account: Account, name: String) async throws -> Folder {
guard let folder = account.ensureFolder(with: name) else {
throw ReaderAPIAccountDelegateError.invalidParameter
}
return folder
}
func renameFolder(for account: Account, with folder: Folder, to name: String, completion: @escaping (Result<Void, Error>) -> Void) {
refreshProgress.addToNumberOfTasksAndRemaining(1)

View File

@ -88,6 +88,7 @@ extension AddFolderWindowController: NSTextFieldDelegate {
private extension AddFolderWindowController {
private func addFolderIfNeeded() {
guard let menuItem = accountPopupButton.selectedItem else {
return
}
@ -100,11 +101,10 @@ private extension AddFolderWindowController {
return
}
account.addFolder(folderName) { result in
switch result {
case .success:
break
case .failure(let error):
Task { @MainActor in
do {
_ = try await account.addFolder(folderName)
} catch {
NSApplication.shared.presentError(error)
}
}

View File

@ -424,14 +424,17 @@ private extension SidebarOutlineDataSource {
}
func copyFolderBetweenAccounts(node: Node, to parentNode: Node) {
guard let folder = node.representedObject as? Folder,
let destinationAccount = nodeAccount(parentNode) else {
return
}
destinationAccount.addFolder(folder.name ?? "") { result in
switch result {
case .success(let destinationFolder):
Task { @MainActor in
do {
let destinationFolder = try await destinationAccount.addFolder(folder.name ?? "")
for feed in folder.topLevelFeeds {
if let existingFeed = destinationAccount.existingFeed(withURL: feed.url) {
destinationAccount.addFeed(existingFeed, to: destinationFolder) { result in
@ -453,11 +456,11 @@ private extension SidebarOutlineDataSource {
}
}
}
case .failure(let error):
} catch {
NSApplication.shared.presentError(error)
}
}
}
func acceptLocalFoldersDrop(_ outlineView: NSOutlineView, _ draggedFolders: Set<PasteboardFolder>, _ parentNode: Node, _ index: Int) -> Bool {

View File

@ -66,33 +66,33 @@ import Core
tell account X to make new folder at end with properties {name:"new folder name"}
*/
@MainActor class func handleCreateElement(command:NSCreateCommand) -> Any? {
guard command.isCreateCommand(forClass:"fold") else { return nil }
let name = command.property(forKey:"name") as? String ?? ""
guard command.isCreateCommand(forClass:"fold") else { return nil }
let name = command.property(forKey:"name") as? String ?? ""
// some combination of the tell target and the location specifier ("in" or "at")
// identifies where the new folder should be created
let (account, folder) = command.accountAndFolderForNewChild()
guard folder == nil else {
print("support for folders within folders is NYI");
return nil
}
// some combination of the tell target and the location specifier ("in" or "at")
// identifies where the new folder should be created
let (account, folder) = command.accountAndFolderForNewChild()
guard folder == nil else {
print("support for folders within folders is NYI");
return nil
}
command.suspendExecution()
account.addFolder(name) { result in
switch result {
case .success(let folder):
Task { @MainActor in
do {
let folder = try await account.addFolder(name)
let scriptableAccount = ScriptableAccount(account)
let scriptableFolder = ScriptableFolder(folder, container:scriptableAccount)
command.resumeExecution(withResult:scriptableFolder.objectSpecifier)
case .failure:
} catch {
command.resumeExecution(withResult:nil)
}
}
return nil
}
return nil
}
// MARK: --- Scriptable elements ---
@objc(feeds)

View File

@ -76,14 +76,16 @@ class AddFolderViewController: UITableViewController {
}
@IBAction func add(_ sender: Any) {
guard let folderName = nameTextField.text else {
return
}
selectedAccount.addFolder(folderName) { result in
switch result {
case .success:
Task { @MainActor in
do {
_ = try await selectedAccount.addFolder(folderName)
self.dismiss(animated: true)
case .failure(let error):
} catch {
self.presentError(error)
self.dismiss(animated: true)
}