From 9408959ea665684379ab9b2cbb3c6352305e328b Mon Sep 17 00:00:00 2001 From: Sabrina Tardio Date: Thu, 21 Dec 2023 17:00:01 +0100 Subject: [PATCH 1/4] update errors --- DuckDuckGo/SettingsViewController.swift | 2 +- ...cSettingsViewController+SyncDelegate.swift | 30 +++++++----- DuckDuckGo/SyncSettingsViewController.swift | 46 +++++++++++-------- DuckDuckGo/UserText.swift | 14 +++--- DuckDuckGo/en.lproj/Localizable.strings | 22 +++++---- 5 files changed, 70 insertions(+), 44 deletions(-) diff --git a/DuckDuckGo/SettingsViewController.swift b/DuckDuckGo/SettingsViewController.swift index be726a9d4b..1845d6a5de 100644 --- a/DuckDuckGo/SettingsViewController.swift +++ b/DuckDuckGo/SettingsViewController.swift @@ -264,7 +264,7 @@ class SettingsViewController: UITableViewController { if SyncBookmarksAdapter.isSyncBookmarksPaused || SyncCredentialsAdapter.isSyncCredentialsPaused || isDataSyncingDisabled { syncCell.textLabel?.text = "⚠️ " + "Sync & Backup" } - syncCell.isHidden = !shouldShowSyncCell + syncCell.isHidden = false } private func configureVoiceSearchCell() { diff --git a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift index d525348690..d6f4d8d3b3 100644 --- a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift +++ b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift @@ -61,23 +61,25 @@ extension SyncSettingsViewController: SyncManagementViewModelDelegate { self.refreshDevices() navigationController?.topViewController?.dismiss(animated: true, completion: showRecoveryPDF) } catch { - handleError(SyncError.unableToSync, error: error) + handleError(SyncError.unableToSyncToServer, error: error) } } } @MainActor - func handleError(_ type: SyncError, error: Error) { + func handleError(_ type: SyncError, error: Error?) { let alertController = UIAlertController( title: type.title, - message: type.description + "\n" + error.localizedDescription, + message: type.description + "\n" + (error?.localizedDescription ?? ""), preferredStyle: .alert) let okAction = UIAlertAction(title: UserText.syncPausedAlertOkButton, style: .default, handler: nil) alertController.addAction(okAction) - if type == .unableToSync { - // Give time to the is syncing view to appear + if type == .unableToSyncToServer || + type == .unableToSyncWithDevice || + type == .unableToMergeTwoAccounts { + // Gives time to the is syncing view to appear DispatchQueue.main.asyncAfter(deadline: .now() + 1) { self.dismissPresentedViewController { [weak self] in self?.present(alertController, animated: true, completion: nil) @@ -283,12 +285,14 @@ private class PortraitNavigationController: UINavigationController { } enum SyncError { - case unableToSync - case unableToGetDevices + case unableToSyncToServer + case unableToSyncWithDevice + case unableToMergeTwoAccounts case unableToUpdateDeviceName case unableToTurnSyncOff case unableToDeleteData case unableToRemoveDevice + case unableToCreateRecoveryPdf var title: String { return UserText.syncErrorAlertTitle @@ -296,10 +300,12 @@ enum SyncError { var description: String { switch self { - case .unableToSync: - return UserText.unableToSyncDescription - case .unableToGetDevices: - return UserText.unableToGetDevicesDescription + case .unableToSyncToServer: + return UserText.unableToSyncToServerDescription + case .unableToSyncWithDevice: + return UserText.unableToSyncWithOtherDeviceDescription + case .unableToMergeTwoAccounts: + return UserText.unableToMergeTwoAccountsErrorDescription case .unableToUpdateDeviceName: return UserText.unableToUpdateDeviceNameDescription case .unableToTurnSyncOff: @@ -308,6 +314,8 @@ enum SyncError { return UserText.unableToDeleteDataDescription case .unableToRemoveDevice: return UserText.unableToRemoveDeviceDescription + case .unableToCreateRecoveryPdf: + return UserText.unableToCreateRecoveryPDF } } } diff --git a/DuckDuckGo/SyncSettingsViewController.swift b/DuckDuckGo/SyncSettingsViewController.swift index 4a72c25aba..d10d7163ec 100644 --- a/DuckDuckGo/SyncSettingsViewController.swift +++ b/DuckDuckGo/SyncSettingsViewController.swift @@ -248,7 +248,7 @@ extension SyncSettingsViewController: ScanOrPasteCodeViewModelDelegate { self.startPolling() return self.connector?.code } catch { - self.handleError(SyncError.unableToSync, error: error) + self.handleError(SyncError.unableToSyncToServer, error: error) return nil } } @@ -274,34 +274,45 @@ extension SyncSettingsViewController: ScanOrPasteCodeViewModelDelegate { return } } catch { - handleError(SyncError.unableToSync, error: error) + handleError(SyncError.unableToSyncWithDevice, error: error) } } } func syncCodeEntered(code: String) async -> Bool { var shouldShowSyncEnabled = true - do { - guard let syncCode = try? SyncCode.decodeBase64String(code) else { - return false - } - if let recoveryKey = syncCode.recovery { - dismissPresentedViewController() - showPreparingSync() + guard let syncCode = try? SyncCode.decodeBase64String(code) else { + return false + } + if let recoveryKey = syncCode.recovery { + dismissPresentedViewController() + showPreparingSync() + do { try await loginAndShowDeviceConnected(recoveryKey: recoveryKey) return true - } else if let connectKey = syncCode.connect { - dismissPresentedViewController() - showPreparingSync() - if syncService.account == nil { + } catch { + if self.rootView.model.isSyncEnabled { + handleError(.unableToMergeTwoAccounts, error: nil) + } else { + handleError(.unableToSyncToServer, error: nil) + } + } + } else if let connectKey = syncCode.connect { + dismissPresentedViewController() + showPreparingSync() + if syncService.account == nil { + do { try await syncService.createAccount(deviceName: deviceName, deviceType: deviceType) Pixel.fire(pixel: .syncSignupConnect, includedParameters: [.appVersion]) self.dismissVCAndShowRecoveryPDF() shouldShowSyncEnabled = false rootView.model.syncEnabled(recoveryCode: recoveryCode) + } catch { + handleError(.unableToSyncToServer, error: error) } + } + do { try await syncService.transmitRecoveryKey(connectKey) - self.rootView.model.$devices .removeDuplicates() .dropFirst() @@ -312,12 +323,11 @@ extension SyncSettingsViewController: ScanOrPasteCodeViewModelDelegate { self.dismissVCAndShowRecoveryPDF() } }.store(in: &cancellables) - - return true + } catch { + handleError(.unableToSyncWithDevice, error: error) } - } catch { - handleError(SyncError.unableToSync, error: error) + return true } return false } diff --git a/DuckDuckGo/UserText.swift b/DuckDuckGo/UserText.swift index 88f5f98999..78896b9e00 100644 --- a/DuckDuckGo/UserText.swift +++ b/DuckDuckGo/UserText.swift @@ -860,13 +860,15 @@ But if you *do* want a peek under the hood, you can find more information about static let syncCredentialsPausedAlertDescription = NSLocalizedString("alert.sync-credentials-paused-description", value: "You have exceeded the passwords sync limit. Try deleting some passwords. Until this is resolved your passwords will not be backed up.", comment: "Description for alert shown when sync credentials paused for too many items") public static let syncPausedAlertOkButton = NSLocalizedString("alert.sync-paused-alert-ok-button", value: "OK", comment: "Confirmation button in alert") public static let syncPausedAlertLearnMoreButton = NSLocalizedString("alert.sync-paused-alert-learn-more-button", value: "Learn More", comment: "Learn more button in alert") - public static let syncErrorAlertTitle = NSLocalizedString("alert.sync-error", value: "Sync Error", comment: "Title for sync error alert") - public static let unableToSyncDescription = NSLocalizedString("alert.unable-to-sync-description", value: "Unable to sync.", comment: "Description for unable to sync error") - public static let unableToGetDevicesDescription = NSLocalizedString("alert.unable-to-get-devices-description", value: "Unable to retrieve the list of connected devices.", comment: "Description for unable to get devices error") - public static let unableToUpdateDeviceNameDescription = NSLocalizedString("alert.unable-to-update-device-name-description", value: "Unable to update the name of the device.", comment: "Description for unable to update device name error") - public static let unableToTurnSyncOffDescription = NSLocalizedString("alert.unable-to-turn-sync-off-description", value: "Unable to turn sync off.", comment: "Description for unable to turn sync off error") + public static let syncErrorAlertTitle = NSLocalizedString("alert.sync-error", value: "Sync & Backup Error", comment: "Title for sync error alert") + public static let unableToSyncToServerDescription = NSLocalizedString("alert.unable-to-sync-to-server-description", value: "Unable to connect to the server.", comment: "Description for unable to sync to server error") + public static let unableToSyncWithOtherDeviceDescription = NSLocalizedString("alert.unable-to-sync-with-other-device-description", value: "Unable to Sync with another device.", comment: "Description for unable to sync with another device error") + public static let unableToMergeTwoAccountsErrorDescription = NSLocalizedString("alert.unable-to-merge-two-accounts-description", value: "To pair these devices, turn off Sync & Backup on one device then tap \"Sync with Another Device\" on the other device.", comment: "Description for unable to merge two accounts error") + public static let unableToUpdateDeviceNameDescription = NSLocalizedString("alert.unable-to-update-device-name-description", value: "Unable to update the device name.", comment: "Description for unable to update device name error") + public static let unableToTurnSyncOffDescription = NSLocalizedString("alert.unable-to-turn-sync-off-description", value: "Unable to turn Sync & Backup off.", comment: "Description for unable to turn sync off error") public static let unableToDeleteDataDescription = NSLocalizedString("alert.unable-to-delete-data-description", value: "Unable to delete data on the server.", comment: "Description for unable to delete data error") - public static let unableToRemoveDeviceDescription = NSLocalizedString("alert.unable-to-remove-device-description", value: "Unable to remove the specified device from the synchronized devices.", comment: "Description for unable to remove device error") + public static let unableToRemoveDeviceDescription = NSLocalizedString("alert.unable-to-remove-device-description", value: "Unable to remove this device from Sync & Backup.", comment: "Description for unable to remove device error") + public static let unableToCreateRecoveryPDF = NSLocalizedString("alert.unable-to-create-recovery-pdf-description", value: "Unable to create the recovery PDF. ", comment: "Description for unable to create recovery pdf error") static let syncPausedTitle = NSLocalizedString("sync.warning.sync.paused", value: "Sync & Backup is Paused", comment: "Title of the warning message") static let syncUnavailableMessage = NSLocalizedString("sync.warning.data.syncing.disabled", value: "Sorry, but Sync & Backup is currently unavailable. Please try again later.", comment: "Data syncing unavailable warning message") static let syncUnavailableMessageUpgradeRequired = NSLocalizedString("sync.warning.data.syncing.disabled.upgrade.required", value: "Sorry, but Sync & Backup is no longer available in this app version. Please update DuckDuckGo to the latest version to continue.", comment: "Data syncing unavailable warning message") diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index 692c00ba01..dbbc366d23 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -140,7 +140,7 @@ "alert.sync-credentials-paused-title" = "Passwords Sync is Paused"; /* Title for sync error alert */ -"alert.sync-error" = "Sync Error"; +"alert.sync-error" = "Sync & Backup Error"; /* Learn more button in alert */ "alert.sync-paused-alert-learn-more-button" = "Learn More"; @@ -163,23 +163,29 @@ /* Save Favorite action */ "alert.title.save.favorite" = "Save Favorite"; +/* Description for unable to create recovery pdf error */ +"alert.unable-to-create-recovery-pdf-description" = "Unable to create the recovery PDF. "; + /* Description for unable to delete data error */ "alert.unable-to-delete-data-description" = "Unable to delete data on the server."; -/* Description for unable to get devices error */ -"alert.unable-to-get-devices-description" = "Unable to retrieve the list of connected devices."; +/* Description for unable to merge two accounts error */ +"alert.unable-to-merge-two-accounts-description" = "To pair these devices, turn off Sync & Backup on one device then tap \"Sync with Another Device\" on the other device."; /* Description for unable to remove device error */ -"alert.unable-to-remove-device-description" = "Unable to remove the specified device from the synchronized devices."; +"alert.unable-to-remove-device-description" = "Unable to remove this device from Sync & Backup."; + +/* Description for unable to sync to server error */ +"alert.unable-to-sync-to-server-description" = "Unable to connect to the server."; -/* Description for unable to sync error */ -"alert.unable-to-sync-description" = "Unable to sync."; +/* Description for unable to sync with another device error */ +"alert.unable-to-sync-with-other-device-description" = "Unable to Sync with another device."; /* Description for unable to turn sync off error */ -"alert.unable-to-turn-sync-off-description" = "Unable to turn sync off."; +"alert.unable-to-turn-sync-off-description" = "Unable to turn Sync & Backup off."; /* Description for unable to update device name error */ -"alert.unable-to-update-device-name-description" = "Unable to update the name of the device."; +"alert.unable-to-update-device-name-description" = "Unable to update the device name."; /* Shown on authentication screen */ "app.authentication.unlock" = "Unlock DuckDuckGo."; From 3cd21e5a9f87ffdabc56415c93be1df656274dda Mon Sep 17 00:00:00 2001 From: Sabrina Tardio Date: Thu, 21 Dec 2023 17:02:06 +0100 Subject: [PATCH 2/4] remove unwanted change --- DuckDuckGo/SettingsViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DuckDuckGo/SettingsViewController.swift b/DuckDuckGo/SettingsViewController.swift index 1845d6a5de..be726a9d4b 100644 --- a/DuckDuckGo/SettingsViewController.swift +++ b/DuckDuckGo/SettingsViewController.swift @@ -264,7 +264,7 @@ class SettingsViewController: UITableViewController { if SyncBookmarksAdapter.isSyncBookmarksPaused || SyncCredentialsAdapter.isSyncCredentialsPaused || isDataSyncingDisabled { syncCell.textLabel?.text = "⚠️ " + "Sync & Backup" } - syncCell.isHidden = false + syncCell.isHidden = !shouldShowSyncCell } private func configureVoiceSearchCell() { From 36db9d1f255b5feff8637c6dc59292c35ca6aae6 Mon Sep 17 00:00:00 2001 From: Sabrina Tardio Date: Fri, 22 Dec 2023 12:52:40 +0100 Subject: [PATCH 3/4] solve lint error --- DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift | 2 +- DuckDuckGo/SyncSettingsViewController.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift index d6f4d8d3b3..454a46ab04 100644 --- a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift +++ b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift @@ -76,7 +76,7 @@ extension SyncSettingsViewController: SyncManagementViewModelDelegate { let okAction = UIAlertAction(title: UserText.syncPausedAlertOkButton, style: .default, handler: nil) alertController.addAction(okAction) - if type == .unableToSyncToServer || + if type == .unableToSyncToServer || type == .unableToSyncWithDevice || type == .unableToMergeTwoAccounts { // Gives time to the is syncing view to appear diff --git a/DuckDuckGo/SyncSettingsViewController.swift b/DuckDuckGo/SyncSettingsViewController.swift index d10d7163ec..86cb9f8b95 100644 --- a/DuckDuckGo/SyncSettingsViewController.swift +++ b/DuckDuckGo/SyncSettingsViewController.swift @@ -294,7 +294,7 @@ extension SyncSettingsViewController: ScanOrPasteCodeViewModelDelegate { if self.rootView.model.isSyncEnabled { handleError(.unableToMergeTwoAccounts, error: nil) } else { - handleError(.unableToSyncToServer, error: nil) + handleError(.unableToSyncToServer, error: error) } } } else if let connectKey = syncCode.connect { From 9c1ff8d0e7285dc23358eb5707cfcc6e9752323c Mon Sep 17 00:00:00 2001 From: Dominik Kapusta Date: Tue, 2 Jan 2024 15:50:01 +0100 Subject: [PATCH 4/4] Don't add newline if error is nil --- DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift index 454a46ab04..fca50e7b02 100644 --- a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift +++ b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift @@ -70,7 +70,7 @@ extension SyncSettingsViewController: SyncManagementViewModelDelegate { func handleError(_ type: SyncError, error: Error?) { let alertController = UIAlertController( title: type.title, - message: type.description + "\n" + (error?.localizedDescription ?? ""), + message: [type.description, error?.localizedDescription].compactMap({ $0 }).joined(separator: "\n"), preferredStyle: .alert) let okAction = UIAlertAction(title: UserText.syncPausedAlertOkButton, style: .default, handler: nil)