diff --git a/Delta/Launch/LaunchViewController.swift b/Delta/Launch/LaunchViewController.swift index d4b7de3..cf66c3f 100644 --- a/Delta/Launch/LaunchViewController.swift +++ b/Delta/Launch/LaunchViewController.swift @@ -55,7 +55,7 @@ extension LaunchViewController } let isSyncingManagerStarted = RSTLaunchCondition(condition: { self.didAttemptStartingSyncManager }) { (completionHandler) in - SyncManager.shared.start { (error) in + SyncManager.shared.syncCoordinator.start { (error) in self.didAttemptStartingSyncManager = true completionHandler(nil) } diff --git a/Delta/Settings/Syncing/SyncingServicesViewController.swift b/Delta/Settings/Syncing/SyncingServicesViewController.swift index 8f8f6e8..8e3f591 100644 --- a/Delta/Settings/Syncing/SyncingServicesViewController.swift +++ b/Delta/Settings/Syncing/SyncingServicesViewController.swift @@ -33,11 +33,23 @@ extension SyncingServicesViewController { case service case account - case signOut + case authenticate } } class SyncingServicesViewController: UITableViewController +{ + func isSectionHidden(_ section: Section) -> Bool + { + switch section + { + case .account: return SyncManager.shared.syncCoordinator.account == nil + default: return false + } + } +} + +extension SyncingServicesViewController { override func numberOfSections(in tableView: UITableView) -> Int { @@ -56,7 +68,20 @@ class SyncingServicesViewController: UITableViewController let service = SyncingService.allCases[indexPath.row] cell.accessoryType = (service == Settings.syncingService) ? .checkmark : .none - case .account, .signOut: break + case .account: + cell.textLabel?.text = SyncManager.shared.syncCoordinator.account?.name ?? NSLocalizedString("Unknown Account", comment: "") + + case .authenticate: + if SyncManager.shared.syncCoordinator.isAuthenticated + { + cell.textLabel?.textColor = .red + cell.textLabel?.text = NSLocalizedString("Sign Out", comment: "") + } + else + { + cell.textLabel?.textColor = .deltaPurple + cell.textLabel?.text = NSLocalizedString("Sign In", comment: "") + } } return cell @@ -71,32 +96,109 @@ class SyncingServicesViewController: UITableViewController if Settings.syncingService == .none && self.tableView.numberOfSections > 1 { - self.tableView.deleteSections(IndexSet(integersIn: Section.account.rawValue ... Section.signOut.rawValue), with: .fade) + self.tableView.deleteSections(IndexSet(integersIn: Section.account.rawValue ... Section.authenticate.rawValue), with: .fade) } else if Settings.syncingService != .none && self.tableView.numberOfSections == 1 { - self.tableView.insertSections(IndexSet(integersIn: Section.account.rawValue ... Section.signOut.rawValue), with: .fade) + self.tableView.insertSections(IndexSet(integersIn: Section.account.rawValue ... Section.authenticate.rawValue), with: .fade) } self.tableView.reloadSections(IndexSet(integer: Section.service.rawValue), with: .none) - if Settings.syncingService != .none && !SyncManager.shared.isAuthenticated + case .account: break + + case .authenticate: + if SyncManager.shared.syncCoordinator.isAuthenticated { - SyncManager.shared.authenticate(presentingViewController: self) { (error) in - print("Authenticated with error:", error as Any) + SyncManager.shared.syncCoordinator.deauthenticate { (result) in + DispatchQueue.main.async { + do + { + try result.verify() + self.tableView.reloadData() + } + catch + { + let alertController = UIAlertController(title: NSLocalizedString("Failed to Sign Out", comment: ""), error: error) + self.present(alertController, animated: true, completion: nil) + } + } + } + } + else + { + SyncManager.shared.syncCoordinator.authenticate(presentingViewController: self) { (result) in + DispatchQueue.main.async { + do + { + try result.verify() + self.tableView.reloadData() + } + catch + { + + let alertController = UIAlertController(title: NSLocalizedString("Failed to Sign In", comment: ""), error: error) + self.present(alertController, animated: true, completion: nil) + } + } } } - - case .account, .signOut: break } } - override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - switch Section.allCases[indexPath.section] + let section = Section.allCases[section] + + if self.isSectionHidden(section) { - case .service: return super.tableView(tableView, heightForRowAt: indexPath) - case .account, .signOut: return (Settings.syncingService == .none) ? 0 : super.tableView(tableView, heightForRowAt: indexPath) + return 0 + } + else + { + return super.tableView(tableView, numberOfRowsInSection: section.rawValue) + } + } + + override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? + { + let section = Section.allCases[section] + + if self.isSectionHidden(section) + { + return nil + } + else + { + return super.tableView(tableView, titleForHeaderInSection: section.rawValue) + } + } + + override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat + { + let section = Section.allCases[section] + + if self.isSectionHidden(section) + { + return 1 + } + else + { + return super.tableView(tableView, heightForHeaderInSection: section.rawValue) + } + } + + override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat + { + let section = Section.allCases[section] + + if self.isSectionHidden(section) + { + return 1 + } + else + { + return super.tableView(tableView, heightForFooterInSection: section.rawValue) } } } diff --git a/Delta/Syncing/SyncManager.swift b/Delta/Syncing/SyncManager.swift index d4b6fcc..24ddd12 100644 --- a/Delta/Syncing/SyncManager.swift +++ b/Delta/Syncing/SyncManager.swift @@ -56,8 +56,6 @@ final class SyncManager private(set) var previousSyncResult: SyncResult? - private(set) var isAuthenticated = false - let syncCoordinator = SyncCoordinator(service: DriveService.shared, persistentContainer: DatabaseManager.shared) private init() @@ -70,58 +68,9 @@ final class SyncManager extension SyncManager { - func start(completionHandler: @escaping (Error?) -> Void) - { - self.syncCoordinator.start { (result) in - do - { - _ = try result.verify() - - self.syncCoordinator.service.authenticateInBackground { (result) in - do - { - _ = try result.verify() - - self.isAuthenticated = true - } - catch AuthenticationError.noSavedCredentials - { - // Ignore - } - catch - { - return completionHandler(error) - } - - completionHandler(nil) - } - } - catch - { - completionHandler(error) - } - } - } - - func authenticate(presentingViewController: UIViewController, completionHandler: @escaping (Error?) -> Void) - { - guard !self.isAuthenticated else { return completionHandler(nil) } - - self.service.authenticate(withPresentingViewController: presentingViewController) { (result) in - switch result - { - case .success: - self.isAuthenticated = true - completionHandler(nil) - - case .failure(let error): completionHandler(error) - } - } - } - func sync() { - guard self.isAuthenticated else { return } + guard Settings.syncingService != .none else { return } self.syncCoordinator.sync() } diff --git a/External/Harmony b/External/Harmony index c5e7c42..920a343 160000 --- a/External/Harmony +++ b/External/Harmony @@ -1 +1 @@ -Subproject commit c5e7c42f6af20791e65097c7ce2f69774bee8b14 +Subproject commit 920a34311389cd4e3248b62f27f594058539b28b