From 82d1e4b63d9dec0ca2b82e773135487fe7b730b3 Mon Sep 17 00:00:00 2001 From: Graeme Arthur Date: Mon, 16 Dec 2024 16:14:46 +0100 Subject: [PATCH 01/12] Switch sync accounts UI --- ...cSettingsViewController+SyncDelegate.swift | 31 +++++++++++++++++++ DuckDuckGo/SyncSettingsViewController.swift | 2 +- DuckDuckGo/UserText.swift | 3 ++ DuckDuckGo/en.lproj/Localizable.strings | 7 +++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift index 23bb29a134..5aebe9dc68 100644 --- a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift +++ b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift @@ -182,6 +182,37 @@ extension SyncSettingsViewController: SyncManagementViewModelDelegate { } } + @MainActor + func handlePairingTwoSeparateAccounts(recoveryKey: SyncCode.RecoveryKey) { + let alertController = UIAlertController( + title: UserText.syncAlertSwitchAccountTitle, + message: UserText.syncAlertSwitchAccountMessage, + preferredStyle: .alert) + alertController.addAction(title: UserText.syncAlertSwitchAccountButton, style: .default) { [weak self] in + Task { [weak self] in + do { + try await self?.syncService.disconnect() + } catch { + // TODO: Send sync_user_switched_logout_error pixel + } + + do { + try await self?.loginAndShowDeviceConnected(recoveryKey: recoveryKey) + } catch { + // TODO: Send sync_user_switched_login_error pixel + } + // TODO: Send sync_user_switched_account_pixel + } + } + alertController.addAction(title: UserText.actionCancel, style: .cancel) + // Gives time to the is syncing view to appear + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in + self?.dismissPresentedViewController { [weak self] in + self?.present(alertController, animated: true, completion: nil) + } + } + } + private func getErrorType(from errorString: String?) -> AsyncErrorType? { guard let errorString = errorString else { return nil diff --git a/DuckDuckGo/SyncSettingsViewController.swift b/DuckDuckGo/SyncSettingsViewController.swift index 925b291897..083573db36 100644 --- a/DuckDuckGo/SyncSettingsViewController.swift +++ b/DuckDuckGo/SyncSettingsViewController.swift @@ -361,7 +361,7 @@ extension SyncSettingsViewController: ScanOrPasteCodeViewModelDelegate { return true } catch { if self.rootView.model.isSyncEnabled { - handleError(.unableToMergeTwoAccounts, error: error, event: .syncLoginExistingAccountError) + handlePairingTwoSeparateAccounts(recoveryKey: recoveryKey) } else { handleError(.unableToSyncToServer, error: error, event: .syncLoginError) } diff --git a/DuckDuckGo/UserText.swift b/DuckDuckGo/UserText.swift index 86a2337975..f0e8764ae4 100644 --- a/DuckDuckGo/UserText.swift +++ b/DuckDuckGo/UserText.swift @@ -961,6 +961,9 @@ But if you *do* want a peek under the hood, you can find more information about static let unknownErrorTryAgainMessage = NSLocalizedString("error.unknown.try.again", value: "An unknown error has occurred", comment: "Generic error message on a dialog for when the cause is not known.") 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 syncAlertSwitchAccountTitle = NSLocalizedString("alert.sync-switch-account-button", value: "Switch to a different Sync?", comment: "Switch account title in alert") + public static let syncAlertSwitchAccountMessage = NSLocalizedString("alert.sync-switch-account-message", value: "This device is already synced, are you sure you want to sync it with a different back up or device? Switching won't remove any data already synced to this.", comment: "Description for switching sync accounts when there's two") + public static let syncAlertSwitchAccountButton = NSLocalizedString("alert.sync-switch-account-button", value: "Switch Account", comment: "Switch account button in alert") 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") diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index d1bf6015ea..e638685034 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -200,6 +200,13 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sync is Paused"; +/* Switch account button in alert + Switch account title in alert */ +"alert.sync-switch-account-button" = "Switch to a different Sync?"; + +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "This device is already synced, are you sure you want to sync it with a different back up or device? Switching won't remove any data already synced to this."; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sync & Backup is temporarily unavailable."; From fed45fe662cb010d494da8eefad61493e9f4d534 Mon Sep 17 00:00:00 2001 From: Graeme Arthur Date: Tue, 17 Dec 2024 10:51:44 +0100 Subject: [PATCH 02/12] Don't prompt to switch when 1 device --- ...cSettingsViewController+SyncDelegate.swift | 34 +++++++++++-------- DuckDuckGo/SyncSettingsViewController.swift | 6 +++- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift index 5aebe9dc68..70a8635dcb 100644 --- a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift +++ b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift @@ -183,26 +183,13 @@ extension SyncSettingsViewController: SyncManagementViewModelDelegate { } @MainActor - func handlePairingTwoSeparateAccounts(recoveryKey: SyncCode.RecoveryKey) { + func promptToSwitchAccounts(recoveryKey: SyncCode.RecoveryKey) { let alertController = UIAlertController( title: UserText.syncAlertSwitchAccountTitle, message: UserText.syncAlertSwitchAccountMessage, preferredStyle: .alert) alertController.addAction(title: UserText.syncAlertSwitchAccountButton, style: .default) { [weak self] in - Task { [weak self] in - do { - try await self?.syncService.disconnect() - } catch { - // TODO: Send sync_user_switched_logout_error pixel - } - - do { - try await self?.loginAndShowDeviceConnected(recoveryKey: recoveryKey) - } catch { - // TODO: Send sync_user_switched_login_error pixel - } - // TODO: Send sync_user_switched_account_pixel - } + self?.switchAccounts(recoveryKey: recoveryKey) } alertController.addAction(title: UserText.actionCancel, style: .cancel) // Gives time to the is syncing view to appear @@ -213,6 +200,23 @@ extension SyncSettingsViewController: SyncManagementViewModelDelegate { } } + func switchAccounts(recoveryKey: SyncCode.RecoveryKey) { + Task { [weak self] in + do { + try await self?.syncService.disconnect() + } catch { + // TODO: Send sync_user_switched_logout_error pixel + } + + do { + try await self?.loginAndShowDeviceConnected(recoveryKey: recoveryKey) + } catch { + // TODO: Send sync_user_switched_login_error pixel + } + // TODO: Send sync_user_switched_account_pixel + } + } + private func getErrorType(from errorString: String?) -> AsyncErrorType? { guard let errorString = errorString else { return nil diff --git a/DuckDuckGo/SyncSettingsViewController.swift b/DuckDuckGo/SyncSettingsViewController.swift index 083573db36..09104e42c7 100644 --- a/DuckDuckGo/SyncSettingsViewController.swift +++ b/DuckDuckGo/SyncSettingsViewController.swift @@ -361,7 +361,11 @@ extension SyncSettingsViewController: ScanOrPasteCodeViewModelDelegate { return true } catch { if self.rootView.model.isSyncEnabled { - handlePairingTwoSeparateAccounts(recoveryKey: recoveryKey) + if rootView.model.devices.count > 1 { + promptToSwitchAccounts(recoveryKey: recoveryKey) + } else { + switchAccounts(recoveryKey: recoveryKey) + } } else { handleError(.unableToSyncToServer, error: error, event: .syncLoginError) } From c359d74afa8289aedf1be65dc1012758f85869dc Mon Sep 17 00:00:00 2001 From: Graeme Arthur Date: Tue, 17 Dec 2024 15:12:52 +0100 Subject: [PATCH 03/12] Fix strings --- DuckDuckGo/UserText.swift | 2 +- DuckDuckGo/en.lproj/Localizable.strings | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/DuckDuckGo/UserText.swift b/DuckDuckGo/UserText.swift index f0e8764ae4..99dede458e 100644 --- a/DuckDuckGo/UserText.swift +++ b/DuckDuckGo/UserText.swift @@ -961,7 +961,7 @@ But if you *do* want a peek under the hood, you can find more information about static let unknownErrorTryAgainMessage = NSLocalizedString("error.unknown.try.again", value: "An unknown error has occurred", comment: "Generic error message on a dialog for when the cause is not known.") 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 syncAlertSwitchAccountTitle = NSLocalizedString("alert.sync-switch-account-button", value: "Switch to a different Sync?", comment: "Switch account title in alert") + public static let syncAlertSwitchAccountTitle = NSLocalizedString("alert.sync-switch-account-title", value: "Switch to a different Sync?", comment: "Switch account title in alert") public static let syncAlertSwitchAccountMessage = NSLocalizedString("alert.sync-switch-account-message", value: "This device is already synced, are you sure you want to sync it with a different back up or device? Switching won't remove any data already synced to this.", comment: "Description for switching sync accounts when there's two") public static let syncAlertSwitchAccountButton = NSLocalizedString("alert.sync-switch-account-button", value: "Switch Account", comment: "Switch account button in alert") public static let syncErrorAlertTitle = NSLocalizedString("alert.sync-error", value: "Sync & Backup Error", comment: "Title for sync error alert") diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index e638685034..d79f6f9164 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -200,13 +200,15 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sync is Paused"; -/* Switch account button in alert - Switch account title in alert */ -"alert.sync-switch-account-button" = "Switch to a different Sync?"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Switch Account"; /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "This device is already synced, are you sure you want to sync it with a different back up or device? Switching won't remove any data already synced to this."; +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Switch to a different Sync?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sync & Backup is temporarily unavailable."; From 13aa365cef06a751426616f47a3bed7aebd4121b Mon Sep 17 00:00:00 2001 From: Graeme Arthur Date: Tue, 17 Dec 2024 16:40:07 +0100 Subject: [PATCH 04/12] Fix another typo FML --- DuckDuckGo/UserText.swift | 2 +- DuckDuckGo/en.lproj/Localizable.strings | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo/UserText.swift b/DuckDuckGo/UserText.swift index 99dede458e..1cfca99a79 100644 --- a/DuckDuckGo/UserText.swift +++ b/DuckDuckGo/UserText.swift @@ -962,7 +962,7 @@ But if you *do* want a peek under the hood, you can find more information about 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 syncAlertSwitchAccountTitle = NSLocalizedString("alert.sync-switch-account-title", value: "Switch to a different Sync?", comment: "Switch account title in alert") - public static let syncAlertSwitchAccountMessage = NSLocalizedString("alert.sync-switch-account-message", value: "This device is already synced, are you sure you want to sync it with a different back up or device? Switching won't remove any data already synced to this.", comment: "Description for switching sync accounts when there's two") + public static let syncAlertSwitchAccountMessage = NSLocalizedString("alert.sync-switch-account-message", value: "This device is already synced, are you sure you want to sync it with a different back up or device? Switching won't remove any data already synced to this device.", comment: "Description for switching sync accounts when there's two") public static let syncAlertSwitchAccountButton = NSLocalizedString("alert.sync-switch-account-button", value: "Switch Account", comment: "Switch account button in alert") 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") diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index d79f6f9164..01b95abd41 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -204,7 +204,7 @@ "alert.sync-switch-account-button" = "Switch Account"; /* Description for switching sync accounts when there's two */ -"alert.sync-switch-account-message" = "This device is already synced, are you sure you want to sync it with a different back up or device? Switching won't remove any data already synced to this."; +"alert.sync-switch-account-message" = "This device is already synced, are you sure you want to sync it with a different back up or device? Switching won't remove any data already synced to this device."; /* Switch account title in alert */ "alert.sync-switch-account-title" = "Switch to a different Sync?"; From b03c8a9271ffa9fd80d80f3717342c82092c1bde Mon Sep 17 00:00:00 2001 From: Graeme Arthur Date: Tue, 17 Dec 2024 17:59:53 +0100 Subject: [PATCH 05/12] Another typo --- DuckDuckGo/UserText.swift | 2 +- DuckDuckGo/en.lproj/Localizable.strings | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo/UserText.swift b/DuckDuckGo/UserText.swift index 1cfca99a79..807c6811a9 100644 --- a/DuckDuckGo/UserText.swift +++ b/DuckDuckGo/UserText.swift @@ -963,7 +963,7 @@ But if you *do* want a peek under the hood, you can find more information about public static let syncPausedAlertLearnMoreButton = NSLocalizedString("alert.sync-paused-alert-learn-more-button", value: "Learn More", comment: "Learn more button in alert") public static let syncAlertSwitchAccountTitle = NSLocalizedString("alert.sync-switch-account-title", value: "Switch to a different Sync?", comment: "Switch account title in alert") public static let syncAlertSwitchAccountMessage = NSLocalizedString("alert.sync-switch-account-message", value: "This device is already synced, are you sure you want to sync it with a different back up or device? Switching won't remove any data already synced to this device.", comment: "Description for switching sync accounts when there's two") - public static let syncAlertSwitchAccountButton = NSLocalizedString("alert.sync-switch-account-button", value: "Switch Account", comment: "Switch account button in alert") + public static let syncAlertSwitchAccountButton = NSLocalizedString("alert.sync-switch-account-button", value: "Switch Sync", comment: "Switch account button in alert") 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") diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index 01b95abd41..4f64c17e10 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -201,7 +201,7 @@ "alert.sync-paused-title" = "Sync is Paused"; /* Switch account button in alert */ -"alert.sync-switch-account-button" = "Switch Account"; +"alert.sync-switch-account-button" = "Switch Sync"; /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "This device is already synced, are you sure you want to sync it with a different back up or device? Switching won't remove any data already synced to this device."; From f838c7aca0dbabed057ae23b372e81c831ae74ed Mon Sep 17 00:00:00 2001 From: Graeme Arthur Date: Thu, 19 Dec 2024 15:22:02 +0100 Subject: [PATCH 06/12] Make switch accounts fun async --- DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift | 5 ++++- DuckDuckGo/SyncSettingsViewController.swift | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift index 70a8635dcb..a9621934d3 100644 --- a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift +++ b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift @@ -190,6 +190,9 @@ extension SyncSettingsViewController: SyncManagementViewModelDelegate { preferredStyle: .alert) alertController.addAction(title: UserText.syncAlertSwitchAccountButton, style: .default) { [weak self] in self?.switchAccounts(recoveryKey: recoveryKey) + Task { + await self?.switchAccounts(recoveryKey: recoveryKey) + } } alertController.addAction(title: UserText.actionCancel, style: .cancel) // Gives time to the is syncing view to appear @@ -200,7 +203,7 @@ extension SyncSettingsViewController: SyncManagementViewModelDelegate { } } - func switchAccounts(recoveryKey: SyncCode.RecoveryKey) { + func switchAccounts(recoveryKey: SyncCode.RecoveryKey) async { Task { [weak self] in do { try await self?.syncService.disconnect() diff --git a/DuckDuckGo/SyncSettingsViewController.swift b/DuckDuckGo/SyncSettingsViewController.swift index 09104e42c7..d34e57c182 100644 --- a/DuckDuckGo/SyncSettingsViewController.swift +++ b/DuckDuckGo/SyncSettingsViewController.swift @@ -364,7 +364,7 @@ extension SyncSettingsViewController: ScanOrPasteCodeViewModelDelegate { if rootView.model.devices.count > 1 { promptToSwitchAccounts(recoveryKey: recoveryKey) } else { - switchAccounts(recoveryKey: recoveryKey) + await switchAccounts(recoveryKey: recoveryKey) } } else { handleError(.unableToSyncToServer, error: error, event: .syncLoginError) From 211cf7a15153bbc8246964f0acec45b130766204 Mon Sep 17 00:00:00 2001 From: Graeme Arthur Date: Thu, 19 Dec 2024 15:23:59 +0100 Subject: [PATCH 07/12] Add pixels --- Core/PixelEvent.swift | 14 ++++++++++++++ .../SyncSettingsViewController+SyncDelegate.swift | 13 ++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/Core/PixelEvent.swift b/Core/PixelEvent.swift index 8e6f1c3beb..5ba31be300 100644 --- a/Core/PixelEvent.swift +++ b/Core/PixelEvent.swift @@ -682,6 +682,13 @@ extension Pixel { case syncSecureStorageDecodingError case syncAccountRemoved(reason: String) + case syncAskUserToSwitchAccount + case syncUserAcceptedSwitchingAccount + case syncUserCancelledSwitchingAccount + case syncUserSwitchedAccount + case syncUserSwitchedLogoutError + case syncUserSwitchedLoginError + case syncGetOtherDevices case syncGetOtherDevicesCopy case syncGetOtherDevicesShare @@ -1620,6 +1627,13 @@ extension Pixel.Event { case .syncSecureStorageDecodingError: return "sync_secure_storage_decoding_error" case .syncAccountRemoved(let reason): return "sync_account_removed_reason_\(reason)" + case .syncAskUserToSwitchAccount: return "sync_ask_user_to_switch_account" + case .syncUserAcceptedSwitchingAccount: return "sync_user_accepted_switching_account" + case .syncUserCancelledSwitchingAccount: return "sync_user_cancelled_switching_account" + case .syncUserSwitchedAccount: return "sync_user_switched_account" + case .syncUserSwitchedLogoutError: return "sync_user_switched_logout_error" + case .syncUserSwitchedLoginError: return "sync_user_switched_login_error" + case .syncGetOtherDevices: return "sync_get_other_devices" case .syncGetOtherDevicesCopy: return "sync_get_other_devices_copy" case .syncGetOtherDevicesShare: return "sync_get_other_devices_share" diff --git a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift index a9621934d3..15ee213021 100644 --- a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift +++ b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift @@ -189,16 +189,19 @@ extension SyncSettingsViewController: SyncManagementViewModelDelegate { message: UserText.syncAlertSwitchAccountMessage, preferredStyle: .alert) alertController.addAction(title: UserText.syncAlertSwitchAccountButton, style: .default) { [weak self] in - self?.switchAccounts(recoveryKey: recoveryKey) Task { + Pixel.fire(pixel: .syncUserAcceptedSwitchingAccount) await self?.switchAccounts(recoveryKey: recoveryKey) } } - alertController.addAction(title: UserText.actionCancel, style: .cancel) + alertController.addAction(title: UserText.actionCancel, style: .cancel) { + Pixel.fire(pixel: .syncUserCancelledSwitchingAccount) + } // Gives time to the is syncing view to appear DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in self?.dismissPresentedViewController { [weak self] in self?.present(alertController, animated: true, completion: nil) + Pixel.fire(pixel: .syncAskUserToSwitchAccount) } } } @@ -208,15 +211,15 @@ extension SyncSettingsViewController: SyncManagementViewModelDelegate { do { try await self?.syncService.disconnect() } catch { - // TODO: Send sync_user_switched_logout_error pixel + Pixel.fire(pixel: .syncUserSwitchedLogoutError) } do { try await self?.loginAndShowDeviceConnected(recoveryKey: recoveryKey) } catch { - // TODO: Send sync_user_switched_login_error pixel + Pixel.fire(pixel: .syncUserSwitchedLoginError) } - // TODO: Send sync_user_switched_account_pixel + Pixel.fire(pixel: .syncUserSwitchedAccount) } } From cd48352590ea72e047f798c6e8b2a22b95f4e251 Mon Sep 17 00:00:00 2001 From: Graeme Arthur Date: Thu, 19 Dec 2024 18:02:54 +0100 Subject: [PATCH 08/12] Add tests --- ...cSettingsViewController+SyncDelegate.swift | 22 ++--- DuckDuckGo/SyncSettingsViewController.swift | 14 ++- DuckDuckGoTests/MockDDGSyncing.swift | 7 +- ...SyncSettingsViewControllerErrorTests.swift | 94 ++++++++++++++++++- 4 files changed, 117 insertions(+), 20 deletions(-) diff --git a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift index 15ee213021..6c6343bfe2 100644 --- a/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift +++ b/DuckDuckGo/SyncSettingsViewController+SyncDelegate.swift @@ -207,20 +207,18 @@ extension SyncSettingsViewController: SyncManagementViewModelDelegate { } func switchAccounts(recoveryKey: SyncCode.RecoveryKey) async { - Task { [weak self] in - do { - try await self?.syncService.disconnect() - } catch { - Pixel.fire(pixel: .syncUserSwitchedLogoutError) - } + do { + try await syncService.disconnect() + } catch { + Pixel.fire(pixel: .syncUserSwitchedLogoutError) + } - do { - try await self?.loginAndShowDeviceConnected(recoveryKey: recoveryKey) - } catch { - Pixel.fire(pixel: .syncUserSwitchedLoginError) - } - Pixel.fire(pixel: .syncUserSwitchedAccount) + do { + try await loginAndShowDeviceConnected(recoveryKey: recoveryKey) + } catch { + Pixel.fire(pixel: .syncUserSwitchedLoginError) } + Pixel.fire(pixel: .syncUserSwitchedAccount) } private func getErrorType(from errorString: String?) -> AsyncErrorType? { diff --git a/DuckDuckGo/SyncSettingsViewController.swift b/DuckDuckGo/SyncSettingsViewController.swift index d34e57c182..0f4ca0f613 100644 --- a/DuckDuckGo/SyncSettingsViewController.swift +++ b/DuckDuckGo/SyncSettingsViewController.swift @@ -361,11 +361,7 @@ extension SyncSettingsViewController: ScanOrPasteCodeViewModelDelegate { return true } catch { if self.rootView.model.isSyncEnabled { - if rootView.model.devices.count > 1 { - promptToSwitchAccounts(recoveryKey: recoveryKey) - } else { - await switchAccounts(recoveryKey: recoveryKey) - } + await handleTwoSyncAccountsFoundDuringRecovery(recoveryKey) } else { handleError(.unableToSyncToServer, error: error, event: .syncLoginError) } @@ -406,6 +402,14 @@ extension SyncSettingsViewController: ScanOrPasteCodeViewModelDelegate { return false } + func handleTwoSyncAccountsFoundDuringRecovery(_ recoveryKey: SyncCode.RecoveryKey) async { + if rootView.model.devices.count > 1 { + promptToSwitchAccounts(recoveryKey: recoveryKey) + } else { + await switchAccounts(recoveryKey: recoveryKey) + } + } + func dismissVCAndShowRecoveryPDF() { self.navigationController?.topViewController?.dismiss(animated: true, completion: self.showRecoveryPDF) } diff --git a/DuckDuckGoTests/MockDDGSyncing.swift b/DuckDuckGoTests/MockDDGSyncing.swift index 3c7e9e4a69..b1bcd046f8 100644 --- a/DuckDuckGoTests/MockDDGSyncing.swift +++ b/DuckDuckGoTests/MockDDGSyncing.swift @@ -71,8 +71,13 @@ final class MockDDGSyncing: DDGSyncing { func createAccount(deviceName: String, deviceType: String) async throws { } + var stubLogin: [RegisteredDevice] = [] + lazy var spyLogin: (SyncCode.RecoveryKey, String, String) throws -> [RegisteredDevice] = { _, _, _ in + return self.stubLogin + } + func login(_ recoveryKey: SyncCode.RecoveryKey, deviceName: String, deviceType: String) async throws -> [RegisteredDevice] { - return [] + return try spyLogin(recoveryKey, deviceName, deviceType) } func remoteConnect() throws -> RemoteConnecting { diff --git a/DuckDuckGoTests/SyncSettingsViewControllerErrorTests.swift b/DuckDuckGoTests/SyncSettingsViewControllerErrorTests.swift index 0233f92598..cab863e20d 100644 --- a/DuckDuckGoTests/SyncSettingsViewControllerErrorTests.swift +++ b/DuckDuckGoTests/SyncSettingsViewControllerErrorTests.swift @@ -21,15 +21,18 @@ import XCTest @testable import DuckDuckGo import Core import Combine -import DDGSync +@testable import DDGSync import Persistence import Common +import SyncUI final class SyncSettingsViewControllerErrorTests: XCTestCase { var cancellables: Set! var vc: SyncSettingsViewController! var errorHandler: CapturingSyncPausedStateManager! + var ddgSyncing: MockDDGSyncing! + var testRecoveryCode = "eyJyZWNvdmVyeSI6eyJ1c2VyX2lkIjoiMDZGODhFNzEtNDFBRS00RTUxLUE2UkRtRkEwOTcwMDE5QkYwIiwicHJpbWFyeV9rZXkiOiI1QTk3U3dsQVI5RjhZakJaU09FVXBzTktnSnJEYnE3aWxtUmxDZVBWazgwPSJ9fQ==" @MainActor override func setUpWithError() throws { @@ -46,7 +49,7 @@ final class SyncSettingsViewControllerErrorTests: XCTestCase { model: model, readOnly: true, options: [:]) - let ddgSyncing = MockDDGSyncing(authState: .active, isSyncInProgress: false) + ddgSyncing = MockDDGSyncing(authState: .active, isSyncInProgress: false) let bookmarksAdapter = SyncBookmarksAdapter( database: database, favoritesDisplayModeStorage: MockFavoritesDisplayModeStoring(), @@ -162,6 +165,93 @@ final class SyncSettingsViewControllerErrorTests: XCTestCase { await fulfillment(of: [expectation], timeout: 5.0) XCTAssertTrue(errorHandler.syncDidTurnOffCalled) } + + func test_syncCodeEntered_accountAlreadyExists_oneDevice_disconnectsThenLogsInAgain() async { + await setUpWithSingleDevice(id: "1") + + var secondLoginCalled = false + + ddgSyncing.spyLogin = { [weak self] _, _, _ in + guard let self else { return [] } + ddgSyncing.spyLogin = { [weak self] _, _, _ in + secondLoginCalled = true + guard let self else { return [] } + // Assert disconnect was called first + XCTAssert(ddgSyncing.disconnectCalled) + return [RegisteredDevice(id: "1", name: "iPhone", type: "iPhone"), RegisteredDevice(id: "2", name: "Macbook Pro", type: "Macbook Pro")] + } + throw SyncError.accountAlreadyExists + } + + _ = await vc.syncCodeEntered(code: testRecoveryCode) + + XCTAssert(secondLoginCalled) + } + + func test_syncCodeEntered_accountAlreadyExists_oneDevice_updatesDevicesWithReturnedDevices() async throws { + await setUpWithSingleDevice(id: "1") + + ddgSyncing.spyLogin = { [weak self] _, _, _ in + self?.ddgSyncing.spyLogin = { _, _, _ in + return [RegisteredDevice(id: "1", name: "iPhone", type: "iPhone"), RegisteredDevice(id: "2", name: "Macbook Pro", type: "Macbook Pro")] + } + throw SyncError.accountAlreadyExists + } + + _ = await vc.syncCodeEntered(code: testRecoveryCode) + + let deviceIDs = await vc.viewModel?.devices.flatMap(\.id) + XCTAssertEqual(deviceIDs, ["1", "2"]) + } + + func test_switchAccounts_disconnectsThenLogsInAgain() async throws { + var loginCalled = false + + ddgSyncing.spyLogin = { [weak self] _, _, _ in + guard let self else { return [] } + // Assert disconnect before returning from login to ensure correct order + XCTAssert(ddgSyncing.disconnectCalled) + loginCalled = true + return [RegisteredDevice(id: "1", name: "iPhone", type: "iPhone"), RegisteredDevice(id: "2", name: "Macbook Pro", type: "Macbook Pro")] + } + + guard let syncCode = try? SyncCode.decodeBase64String(testRecoveryCode), + let recoveryKey = syncCode.recovery else { + XCTFail("Could not create RecoveryKey from code") + return + } + + await vc.switchAccounts(recoveryKey: recoveryKey) + + XCTAssert(loginCalled) + } + + func test_switchAccounts_updatesDevicesWithReturnedDevices() async throws { + ddgSyncing.spyLogin = { [weak self] _, _, _ in + guard let self else { return [] } + // Assert disconnect before returning from login to ensure correct order + XCTAssert(ddgSyncing.disconnectCalled) + return [RegisteredDevice(id: "1", name: "iPhone", type: "iPhone"), RegisteredDevice(id: "2", name: "Macbook Pro", type: "Macbook Pro")] + } + + guard let syncCode = try? SyncCode.decodeBase64String(testRecoveryCode), + let recoveryKey = syncCode.recovery else { + XCTFail("Could not create RecoveryKey from code") + return + } + + await vc.switchAccounts(recoveryKey: recoveryKey) + + let deviceIDs = await vc.viewModel?.devices.flatMap(\.id) + XCTAssertEqual(deviceIDs, ["1", "2"]) + } + + @MainActor + private func setUpWithSingleDevice(id: String) { + ddgSyncing.account = SyncAccount(deviceId: id, deviceName: "iPhone", deviceType: "iPhone", userId: "", primaryKey: Data(), secretKey: Data(), token: nil, state: .active) + ddgSyncing.registeredDevices = [RegisteredDevice(id: id, name: "iPhone", type: "iPhone")] + vc.viewModel?.devices = [SyncSettingsViewModel.Device(id: id, name: "iPhone", type: "iPhone", isThisDevice: true)] + } } class MockFavoritesDisplayModeStoring: MockFavoriteDisplayModeStorage {} From 2f7bef283653bcd385168fdf2cb9eb0a65d114f4 Mon Sep 17 00:00:00 2001 From: Graeme Arthur Date: Thu, 19 Dec 2024 18:23:06 +0100 Subject: [PATCH 09/12] Make func private --- DuckDuckGo/SyncSettingsViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DuckDuckGo/SyncSettingsViewController.swift b/DuckDuckGo/SyncSettingsViewController.swift index 0f4ca0f613..6927fd10d8 100644 --- a/DuckDuckGo/SyncSettingsViewController.swift +++ b/DuckDuckGo/SyncSettingsViewController.swift @@ -402,7 +402,7 @@ extension SyncSettingsViewController: ScanOrPasteCodeViewModelDelegate { return false } - func handleTwoSyncAccountsFoundDuringRecovery(_ recoveryKey: SyncCode.RecoveryKey) async { + private func handleTwoSyncAccountsFoundDuringRecovery(_ recoveryKey: SyncCode.RecoveryKey) async { if rootView.model.devices.count > 1 { promptToSwitchAccounts(recoveryKey: recoveryKey) } else { From 7abdb5cf938d10ae94e7465fe91c09f258e22176 Mon Sep 17 00:00:00 2001 From: Anya Mallon Date: Fri, 20 Dec 2024 10:51:29 +0100 Subject: [PATCH 10/12] First round of translations --- DuckDuckGo/bg.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/cs.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/da.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/de.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/el.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/es.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/et.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/fi.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/fr.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/hr.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/hu.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/it.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/lt.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/lv.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/nb.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/nl.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/pl.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/pt.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/ro.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/ru.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/sk.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/sl.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/sv.lproj/Localizable.strings | 6 ++++++ DuckDuckGo/tr.lproj/Localizable.strings | 6 ++++++ 24 files changed, 144 insertions(+) diff --git a/DuckDuckGo/bg.lproj/Localizable.strings b/DuckDuckGo/bg.lproj/Localizable.strings index cd11e8d970..d4f5f22559 100644 --- a/DuckDuckGo/bg.lproj/Localizable.strings +++ b/DuckDuckGo/bg.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Синхронизирането е на пауза"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Това устройство вече е синхронизирано, сигурни ли сте, че искате да го синхронизирате с друго резервно копие или устройство? Превключването няма да изтрие данните, които вече са синхронизирани с това устройство."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Превключване към друго синхронизиране?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sync & Backup временно не е налична."; diff --git a/DuckDuckGo/cs.lproj/Localizable.strings b/DuckDuckGo/cs.lproj/Localizable.strings index 7676ec73c4..fb1184b0cd 100644 --- a/DuckDuckGo/cs.lproj/Localizable.strings +++ b/DuckDuckGo/cs.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synchronizace je pozastavená"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Tohle zařízení už je synchronizované. Opravdu ho chceš synchronizovat s jinou zálohou nebo zařízením? Přepnutím se nesmažou žádná data, která už s tímto zařízením byla synchronizována."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Přepnout synchronizaci?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Funkce Sync & Backup je dočasně nedostupná."; diff --git a/DuckDuckGo/da.lproj/Localizable.strings b/DuckDuckGo/da.lproj/Localizable.strings index 20065306df..a04412f9fb 100644 --- a/DuckDuckGo/da.lproj/Localizable.strings +++ b/DuckDuckGo/da.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synkronisering er sat på pause"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Denne enhed er allerede synkroniseret. Er du sikker på, at du vil synkronisere den med en anden sikkerhedskopi eller enhed? Et skifte fjerner ikke data, der allerede er synkroniseret til denne enhed."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Skift til en anden synkronisering?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sync & Backup er midlertidigt utilgængelig."; diff --git a/DuckDuckGo/de.lproj/Localizable.strings b/DuckDuckGo/de.lproj/Localizable.strings index 6d6b3fe1b7..1471daff1c 100644 --- a/DuckDuckGo/de.lproj/Localizable.strings +++ b/DuckDuckGo/de.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synchronisierung angehalten"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Dieses Gerät ist bereits synchronisiert. Bist du sicher, dass du es mit einem anderen Back-up oder Gerät synchronisieren möchtest? Beim Wechsel werden keine bereits mit diesem Gerät synchronisierten Daten entfernt."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Zu einer anderen Synchronisierung wechseln?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sync & Backup ist vorübergehend nicht verfügbar."; diff --git a/DuckDuckGo/el.lproj/Localizable.strings b/DuckDuckGo/el.lproj/Localizable.strings index ab107a549f..ad0c21a863 100644 --- a/DuckDuckGo/el.lproj/Localizable.strings +++ b/DuckDuckGo/el.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Ο συγχρονισμός έχει τεθεί σε παύση"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Η συσκευή αυτή είναι ήδη συγχρονισμένη. Θέλετε σίγουρα να τη συγχρονίσετε με ένα διαφορετικό αντίγραφο ασφαλείας ή συσκευή; Η αλλαγή δεν θα αφαιρέσει δεδομένα που έχουν ήδη συγχρονιστεί σε αυτήν τη συσκευή."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Αλλαγή σε διαφορετικό συγχρονισμό;"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Το Sync & Backup είναι προσωρινά μη διαθέσιμο."; diff --git a/DuckDuckGo/es.lproj/Localizable.strings b/DuckDuckGo/es.lproj/Localizable.strings index 832c808345..43142a9e21 100644 --- a/DuckDuckGo/es.lproj/Localizable.strings +++ b/DuckDuckGo/es.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "La sincronización está en pausa"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Este dispositivo ya está sincronizado. ¿Seguro que deseas sincronizarlo con una copia de seguridad o con un dispositivo diferente? Cambiar no eliminará ningún dato ya sincronizado en este dispositivo."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "¿Cambiar a una sincronización diferente?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "La sincronización y la copia de seguridad no están disponibles temporalmente."; diff --git a/DuckDuckGo/et.lproj/Localizable.strings b/DuckDuckGo/et.lproj/Localizable.strings index debc2d270a..4c9f39abc6 100644 --- a/DuckDuckGo/et.lproj/Localizable.strings +++ b/DuckDuckGo/et.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sünkroonimine on peatatud"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "See seade on juba sünkroonitud, kas soovid kindlasti seda sünkroonida teise varukoopia või seadmega? Vahetamine ei eemalda selle seadmega juba sünkroonitud andmeid."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Kas lülituda teisele Sync'ile?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sync & Backup pole ajutiselt saadaval."; diff --git a/DuckDuckGo/fi.lproj/Localizable.strings b/DuckDuckGo/fi.lproj/Localizable.strings index 8b910b5bff..39f6ca9db9 100644 --- a/DuckDuckGo/fi.lproj/Localizable.strings +++ b/DuckDuckGo/fi.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synkronointi on keskeytetty"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Tämä laite on jo synkronoitu. Haluatko varmasti synkronoida sen toisen varmuuskopion tai laitteen kanssa? Vaihtaminen ei poista tähän laitteeseen jo synkronoituja tietoja."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Vaihdetaanko toiseen synkronointiin?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Synkronointi ja varmuuskopiointi on tilapäisesti poissa käytöstä."; diff --git a/DuckDuckGo/fr.lproj/Localizable.strings b/DuckDuckGo/fr.lproj/Localizable.strings index 37dc6fbcdf..51fc6ffe13 100644 --- a/DuckDuckGo/fr.lproj/Localizable.strings +++ b/DuckDuckGo/fr.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "La synchronisation est suspendue"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Cet appareil est déjà synchronisé. Voulez-vous vraiment le synchroniser avec une autre sauvegarde ou un autre appareil ? Ce changement ne supprimera aucune donnée déjà synchronisée sur cet appareil."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Passer à une autre synchronisation ?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sync & Backup est temporairement indisponible."; diff --git a/DuckDuckGo/hr.lproj/Localizable.strings b/DuckDuckGo/hr.lproj/Localizable.strings index 5c79140a66..55055bcd92 100644 --- a/DuckDuckGo/hr.lproj/Localizable.strings +++ b/DuckDuckGo/hr.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sinkronizacija je pauzirana"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Ovaj je uređaj već sinkroniziran. Jesi li siguran da ga želiš sinkronizirati s drugom sigurnosnom kopijom ili uređajem? Prebacivanjem se neće ukloniti nijedan podatak koji je već sinkroniziran s ovim uređajem."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Prijeđi na drugu sinkronizaciju?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sinkronizacija i sigurnosno kopiranje Sync & Backup privremeno su nedostupni."; diff --git a/DuckDuckGo/hu.lproj/Localizable.strings b/DuckDuckGo/hu.lproj/Localizable.strings index fa1d7a213b..4e7035328d 100644 --- a/DuckDuckGo/hu.lproj/Localizable.strings +++ b/DuckDuckGo/hu.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "A szinkronizálás szünetel"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Ez az eszköz már szinkronizálva van. Biztosan szinkronizálni szeretnéd egy másik biztonsági mentéssel vagy eszközzel? A váltás nem távolítja el ezzel az eszközzel már szinkronizált adatokat."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Átváltasz egy másik szinkronizációs lehetőségre?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "A szinkronizálás és biztonsági mentés átmenetileg nem érhető el."; diff --git a/DuckDuckGo/it.lproj/Localizable.strings b/DuckDuckGo/it.lproj/Localizable.strings index 546e285a6f..d51f5833aa 100644 --- a/DuckDuckGo/it.lproj/Localizable.strings +++ b/DuckDuckGo/it.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sync è in pausa"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Questo dispositivo è già sincronizzato. Vuoi davvero sincronizzarlo con un backup o un dispositivo diverso? L'operazione non rimuoverà alcun dato già sincronizzato su questo dispositivo."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Vuoi passare a una sincronizzazione diversa?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sync & Backup non è temporaneamente disponibile."; diff --git a/DuckDuckGo/lt.lproj/Localizable.strings b/DuckDuckGo/lt.lproj/Localizable.strings index ec407015d1..90579ff351 100644 --- a/DuckDuckGo/lt.lproj/Localizable.strings +++ b/DuckDuckGo/lt.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sinchronizavimas pristabdytas"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Šis įrenginys jau sinchronizuotas, ar tikrai norite jį sinchronizuoti su kita atsargine kopija ar įrenginiu? Perjungiant nebus pašalinti jokie duomenys, jau sinchronizuoti su šiuo įrenginiu."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Perjungti į kitą sinchronizaciją?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sinchronizavimas ir atsarginės kopijos kūrimas laikinai nepasiekiami."; diff --git a/DuckDuckGo/lv.lproj/Localizable.strings b/DuckDuckGo/lv.lproj/Localizable.strings index 636cfb7053..053018aaba 100644 --- a/DuckDuckGo/lv.lproj/Localizable.strings +++ b/DuckDuckGo/lv.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sinhronizācija ir apturēta"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Šī ierīce jau ir sinhronizēta, vai tiešām vēlies to sinhronizēt ar citu dublēšanas sistēmu vai ierīci? Pārslēdzot netiks dzēsti dati, kas jau ir sinhronizēti ar šo ierīci."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Vai pārslēgt uz citu sinhronizāciju?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sync & Backup uz laiku nav pieejams."; diff --git a/DuckDuckGo/nb.lproj/Localizable.strings b/DuckDuckGo/nb.lproj/Localizable.strings index ccd9ca0330..b50b9f1c31 100644 --- a/DuckDuckGo/nb.lproj/Localizable.strings +++ b/DuckDuckGo/nb.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synkronisering er satt på pause"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Denne enheten er allerede synkronisert. Er du sikker på at du vil synkronisere den med en annen sikkerhetskopi eller enhet? Data som allerede er synkronisert med denne enheten, fjernes ikke hvis du bytter."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Vil du bytte til en annen synkronisering?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sync & Backup er midlertidig utilgjengelig."; diff --git a/DuckDuckGo/nl.lproj/Localizable.strings b/DuckDuckGo/nl.lproj/Localizable.strings index 08efcd53a0..7a1ec0208c 100644 --- a/DuckDuckGo/nl.lproj/Localizable.strings +++ b/DuckDuckGo/nl.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synchronisatie is gepauzeerd"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Dit apparaat is al gesynchroniseerd, weet je zeker dat je het met een andere back-up of een ander apparaat wilt synchroniseren? Als je overschakelt, worden er geen gegevens verwijderd die al met dit apparaat zijn gesynchroniseerd."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Overschakelen naar een andere synchronisatie?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "'Synchronisatie en back-up' is tijdelijk niet beschikbaar."; diff --git a/DuckDuckGo/pl.lproj/Localizable.strings b/DuckDuckGo/pl.lproj/Localizable.strings index c91457fda0..e2662507d2 100644 --- a/DuckDuckGo/pl.lproj/Localizable.strings +++ b/DuckDuckGo/pl.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synchronizacja jest wstrzymana"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "To urządzenie jest już synchronizowane, czy na pewno chcesz je synchronizować z inną kopią zapasową lub urządzeniem? Przełączenie nie usunie żadnych danych już zsynchronizowanych z tym urządzeniem."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Przełączyć na inną synchronizację?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Funkcja Sync & Backup jest tymczasowo niedostępna."; diff --git a/DuckDuckGo/pt.lproj/Localizable.strings b/DuckDuckGo/pt.lproj/Localizable.strings index 5cf8042b4a..3baac297f8 100644 --- a/DuckDuckGo/pt.lproj/Localizable.strings +++ b/DuckDuckGo/pt.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "A sincronização está em pausa"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Este dispositivo já está sincronizado, tens a certeza de que queres sincronizá-lo com uma cópia de segurança ou um dispositivo diferente? A mudança não vai remover nenhum dado já sincronizado com este dispositivo."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Mudar para uma sincronização diferente?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "O Sync & Backup está temporariamente indisponível."; diff --git a/DuckDuckGo/ro.lproj/Localizable.strings b/DuckDuckGo/ro.lproj/Localizable.strings index 9bfa277d90..5eff988766 100644 --- a/DuckDuckGo/ro.lproj/Localizable.strings +++ b/DuckDuckGo/ro.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sincronizarea este întreruptă"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Acest dispozitiv este deja sincronizat, sigur dorești să-l sincronizezi cu o altă copie de rezervă sau alt dispozitiv? Schimbarea nu va șterge datele deja sincronizate cu acest dispozitiv."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Treci la o altă sincronizare?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sync & Backup sunt temporar indisponibile."; diff --git a/DuckDuckGo/ru.lproj/Localizable.strings b/DuckDuckGo/ru.lproj/Localizable.strings index 660e9b547e..b0c6db822d 100644 --- a/DuckDuckGo/ru.lproj/Localizable.strings +++ b/DuckDuckGo/ru.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Синхронизация приостановлена"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Это устройство уже синхронизировано. Действительно синхронизировать его с другой резервной копией или устройством? Переключение не приведет к удалению данных, синхронизированных с этим устройством ранее."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Переключиться на другую синхронизацию?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Функция «Синхронизация и резервное копирование» временно недоступна."; diff --git a/DuckDuckGo/sk.lproj/Localizable.strings b/DuckDuckGo/sk.lproj/Localizable.strings index e8cd577412..326f5b33f6 100644 --- a/DuckDuckGo/sk.lproj/Localizable.strings +++ b/DuckDuckGo/sk.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synchronizácia bola pozastavená."; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Toto zariadenie je už synchronizované. Naozaj ho že chceš synchronizovať s inou zálohou alebo zariadením? Prepínanie neodstráni žiadne údaje, ktoré už boli synchronizované s týmto zariadením."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Prepnúť na inú synchronizáciu?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Služba Sync & Backup je dočasne nedostupná."; diff --git a/DuckDuckGo/sl.lproj/Localizable.strings b/DuckDuckGo/sl.lproj/Localizable.strings index eb3046fb6b..ff52fea2d2 100644 --- a/DuckDuckGo/sl.lproj/Localizable.strings +++ b/DuckDuckGo/sl.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sinhronizacija je začasno zaustavljena"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Ta naprava je že sinhronizirana, ste prepričani, da jo želite sinhronizirati z drugo varnostno kopijo ali napravo? Preklop ne bo odstranil nobenih podatkov, ki so že sinhronizirani s to napravo."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Želite preklopiti na drugo sinhronizacijo?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sinhronizacija in varnostno kopiranje sta začasno nedostopna."; diff --git a/DuckDuckGo/sv.lproj/Localizable.strings b/DuckDuckGo/sv.lproj/Localizable.strings index 77e833357c..2bded7bc9c 100644 --- a/DuckDuckGo/sv.lproj/Localizable.strings +++ b/DuckDuckGo/sv.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synkroniseringen är pausad"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Den här enheten är redan synkroniserad. Är du säker på att du vill synkronisera den med en annan säkerhetskopia eller enhet? Att byta tar inte bort några data som redan har synkroniserats med den här enheten."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Byt till en annan synkronisering?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Sync & Backup är inte tillgängligt just nu."; diff --git a/DuckDuckGo/tr.lproj/Localizable.strings b/DuckDuckGo/tr.lproj/Localizable.strings index d787a57ece..54c07d7bdc 100644 --- a/DuckDuckGo/tr.lproj/Localizable.strings +++ b/DuckDuckGo/tr.lproj/Localizable.strings @@ -181,6 +181,12 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Senkronizasyon Duraklatıldı"; +/* Description for switching sync accounts when there's two */ +"alert.sync-switch-account-message" = "Bu cihaz zaten senkronize edilmiş. Farklı bir yedekleme veya cihazla senkronize etmek istediğinden emin misin? Senkronizasyonu değiştirmek, bu cihazla önceden senkronize edilmiş verileri kaldırmayacaktır."; + +/* Switch account title in alert */ +"alert.sync-switch-account-title" = "Farklı bir Senkronizasyona mı geçmek istiyorsunuz?"; + /* Description for alert shown when sync error occurs because of too many requests */ "alert.sync-too-many-requests-error-description" = "Senkronizasyon ve Yedekleme geçici olarak kullanılamıyor."; From 33eca4252e304ef9251b256a82309166e871e679 Mon Sep 17 00:00:00 2001 From: Anya Mallon Date: Fri, 20 Dec 2024 11:20:23 +0100 Subject: [PATCH 11/12] Second round of translations --- DuckDuckGo/bg.lproj/Localizable.strings | 3 +++ DuckDuckGo/cs.lproj/Localizable.strings | 3 +++ DuckDuckGo/da.lproj/Localizable.strings | 3 +++ DuckDuckGo/de.lproj/Localizable.strings | 3 +++ DuckDuckGo/el.lproj/Localizable.strings | 3 +++ DuckDuckGo/es.lproj/Localizable.strings | 3 +++ DuckDuckGo/et.lproj/Localizable.strings | 3 +++ DuckDuckGo/fi.lproj/Localizable.strings | 3 +++ DuckDuckGo/fr.lproj/Localizable.strings | 3 +++ DuckDuckGo/hr.lproj/Localizable.strings | 3 +++ DuckDuckGo/hu.lproj/Localizable.strings | 3 +++ DuckDuckGo/it.lproj/Localizable.strings | 3 +++ DuckDuckGo/lt.lproj/Localizable.strings | 3 +++ DuckDuckGo/lv.lproj/Localizable.strings | 3 +++ DuckDuckGo/nb.lproj/Localizable.strings | 3 +++ DuckDuckGo/nl.lproj/Localizable.strings | 3 +++ DuckDuckGo/pl.lproj/Localizable.strings | 3 +++ DuckDuckGo/pt.lproj/Localizable.strings | 3 +++ DuckDuckGo/ro.lproj/Localizable.strings | 3 +++ DuckDuckGo/ru.lproj/Localizable.strings | 3 +++ DuckDuckGo/sk.lproj/Localizable.strings | 3 +++ DuckDuckGo/sl.lproj/Localizable.strings | 3 +++ DuckDuckGo/sv.lproj/Localizable.strings | 3 +++ DuckDuckGo/tr.lproj/Localizable.strings | 3 +++ 24 files changed, 72 insertions(+) diff --git a/DuckDuckGo/bg.lproj/Localizable.strings b/DuckDuckGo/bg.lproj/Localizable.strings index d4f5f22559..3fc146e9d8 100644 --- a/DuckDuckGo/bg.lproj/Localizable.strings +++ b/DuckDuckGo/bg.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Синхронизирането е на пауза"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Превключване на синхронизирането"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Това устройство вече е синхронизирано, сигурни ли сте, че искате да го синхронизирате с друго резервно копие или устройство? Превключването няма да изтрие данните, които вече са синхронизирани с това устройство."; diff --git a/DuckDuckGo/cs.lproj/Localizable.strings b/DuckDuckGo/cs.lproj/Localizable.strings index fb1184b0cd..171dcadf69 100644 --- a/DuckDuckGo/cs.lproj/Localizable.strings +++ b/DuckDuckGo/cs.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synchronizace je pozastavená"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Přepnout synchronizaci"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Tohle zařízení už je synchronizované. Opravdu ho chceš synchronizovat s jinou zálohou nebo zařízením? Přepnutím se nesmažou žádná data, která už s tímto zařízením byla synchronizována."; diff --git a/DuckDuckGo/da.lproj/Localizable.strings b/DuckDuckGo/da.lproj/Localizable.strings index a04412f9fb..630cfd0826 100644 --- a/DuckDuckGo/da.lproj/Localizable.strings +++ b/DuckDuckGo/da.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synkronisering er sat på pause"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Skift synkronisering"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Denne enhed er allerede synkroniseret. Er du sikker på, at du vil synkronisere den med en anden sikkerhedskopi eller enhed? Et skifte fjerner ikke data, der allerede er synkroniseret til denne enhed."; diff --git a/DuckDuckGo/de.lproj/Localizable.strings b/DuckDuckGo/de.lproj/Localizable.strings index 1471daff1c..1b4fa26626 100644 --- a/DuckDuckGo/de.lproj/Localizable.strings +++ b/DuckDuckGo/de.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synchronisierung angehalten"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Synchronisierung wechseln"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Dieses Gerät ist bereits synchronisiert. Bist du sicher, dass du es mit einem anderen Back-up oder Gerät synchronisieren möchtest? Beim Wechsel werden keine bereits mit diesem Gerät synchronisierten Daten entfernt."; diff --git a/DuckDuckGo/el.lproj/Localizable.strings b/DuckDuckGo/el.lproj/Localizable.strings index ad0c21a863..42af0ad06a 100644 --- a/DuckDuckGo/el.lproj/Localizable.strings +++ b/DuckDuckGo/el.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Ο συγχρονισμός έχει τεθεί σε παύση"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Αλλαγή συγχρονισμού"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Η συσκευή αυτή είναι ήδη συγχρονισμένη. Θέλετε σίγουρα να τη συγχρονίσετε με ένα διαφορετικό αντίγραφο ασφαλείας ή συσκευή; Η αλλαγή δεν θα αφαιρέσει δεδομένα που έχουν ήδη συγχρονιστεί σε αυτήν τη συσκευή."; diff --git a/DuckDuckGo/es.lproj/Localizable.strings b/DuckDuckGo/es.lproj/Localizable.strings index 43142a9e21..a6708c70ae 100644 --- a/DuckDuckGo/es.lproj/Localizable.strings +++ b/DuckDuckGo/es.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "La sincronización está en pausa"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Cambiar sincronización"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Este dispositivo ya está sincronizado. ¿Seguro que deseas sincronizarlo con una copia de seguridad o con un dispositivo diferente? Cambiar no eliminará ningún dato ya sincronizado en este dispositivo."; diff --git a/DuckDuckGo/et.lproj/Localizable.strings b/DuckDuckGo/et.lproj/Localizable.strings index 4c9f39abc6..7ec238ad1d 100644 --- a/DuckDuckGo/et.lproj/Localizable.strings +++ b/DuckDuckGo/et.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sünkroonimine on peatatud"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Synci lülitamine"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "See seade on juba sünkroonitud, kas soovid kindlasti seda sünkroonida teise varukoopia või seadmega? Vahetamine ei eemalda selle seadmega juba sünkroonitud andmeid."; diff --git a/DuckDuckGo/fi.lproj/Localizable.strings b/DuckDuckGo/fi.lproj/Localizable.strings index 39f6ca9db9..e39357759b 100644 --- a/DuckDuckGo/fi.lproj/Localizable.strings +++ b/DuckDuckGo/fi.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synkronointi on keskeytetty"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Vaihda synkronointi"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Tämä laite on jo synkronoitu. Haluatko varmasti synkronoida sen toisen varmuuskopion tai laitteen kanssa? Vaihtaminen ei poista tähän laitteeseen jo synkronoituja tietoja."; diff --git a/DuckDuckGo/fr.lproj/Localizable.strings b/DuckDuckGo/fr.lproj/Localizable.strings index 51fc6ffe13..16c9ec6bc2 100644 --- a/DuckDuckGo/fr.lproj/Localizable.strings +++ b/DuckDuckGo/fr.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "La synchronisation est suspendue"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Changer de synchronisation"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Cet appareil est déjà synchronisé. Voulez-vous vraiment le synchroniser avec une autre sauvegarde ou un autre appareil ? Ce changement ne supprimera aucune donnée déjà synchronisée sur cet appareil."; diff --git a/DuckDuckGo/hr.lproj/Localizable.strings b/DuckDuckGo/hr.lproj/Localizable.strings index 55055bcd92..e883cb987d 100644 --- a/DuckDuckGo/hr.lproj/Localizable.strings +++ b/DuckDuckGo/hr.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sinkronizacija je pauzirana"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Prebaci sinkronizaciju"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Ovaj je uređaj već sinkroniziran. Jesi li siguran da ga želiš sinkronizirati s drugom sigurnosnom kopijom ili uređajem? Prebacivanjem se neće ukloniti nijedan podatak koji je već sinkroniziran s ovim uređajem."; diff --git a/DuckDuckGo/hu.lproj/Localizable.strings b/DuckDuckGo/hu.lproj/Localizable.strings index 4e7035328d..764607c998 100644 --- a/DuckDuckGo/hu.lproj/Localizable.strings +++ b/DuckDuckGo/hu.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "A szinkronizálás szünetel"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Váltás másik szinkronizálási lehetőségre"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Ez az eszköz már szinkronizálva van. Biztosan szinkronizálni szeretnéd egy másik biztonsági mentéssel vagy eszközzel? A váltás nem távolítja el ezzel az eszközzel már szinkronizált adatokat."; diff --git a/DuckDuckGo/it.lproj/Localizable.strings b/DuckDuckGo/it.lproj/Localizable.strings index d51f5833aa..9e17f2ac86 100644 --- a/DuckDuckGo/it.lproj/Localizable.strings +++ b/DuckDuckGo/it.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sync è in pausa"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Cambia sincronizzazione"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Questo dispositivo è già sincronizzato. Vuoi davvero sincronizzarlo con un backup o un dispositivo diverso? L'operazione non rimuoverà alcun dato già sincronizzato su questo dispositivo."; diff --git a/DuckDuckGo/lt.lproj/Localizable.strings b/DuckDuckGo/lt.lproj/Localizable.strings index 90579ff351..36fed6c8ee 100644 --- a/DuckDuckGo/lt.lproj/Localizable.strings +++ b/DuckDuckGo/lt.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sinchronizavimas pristabdytas"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Perjungti sinchronizavimą"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Šis įrenginys jau sinchronizuotas, ar tikrai norite jį sinchronizuoti su kita atsargine kopija ar įrenginiu? Perjungiant nebus pašalinti jokie duomenys, jau sinchronizuoti su šiuo įrenginiu."; diff --git a/DuckDuckGo/lv.lproj/Localizable.strings b/DuckDuckGo/lv.lproj/Localizable.strings index 053018aaba..563258b4df 100644 --- a/DuckDuckGo/lv.lproj/Localizable.strings +++ b/DuckDuckGo/lv.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sinhronizācija ir apturēta"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Pārslēgt sinhronizāciju"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Šī ierīce jau ir sinhronizēta, vai tiešām vēlies to sinhronizēt ar citu dublēšanas sistēmu vai ierīci? Pārslēdzot netiks dzēsti dati, kas jau ir sinhronizēti ar šo ierīci."; diff --git a/DuckDuckGo/nb.lproj/Localizable.strings b/DuckDuckGo/nb.lproj/Localizable.strings index b50b9f1c31..54807b5739 100644 --- a/DuckDuckGo/nb.lproj/Localizable.strings +++ b/DuckDuckGo/nb.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synkronisering er satt på pause"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Bytt synkronisering"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Denne enheten er allerede synkronisert. Er du sikker på at du vil synkronisere den med en annen sikkerhetskopi eller enhet? Data som allerede er synkronisert med denne enheten, fjernes ikke hvis du bytter."; diff --git a/DuckDuckGo/nl.lproj/Localizable.strings b/DuckDuckGo/nl.lproj/Localizable.strings index 7a1ec0208c..4d14feec38 100644 --- a/DuckDuckGo/nl.lproj/Localizable.strings +++ b/DuckDuckGo/nl.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synchronisatie is gepauzeerd"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Schakelen tussen synchronisatie"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Dit apparaat is al gesynchroniseerd, weet je zeker dat je het met een andere back-up of een ander apparaat wilt synchroniseren? Als je overschakelt, worden er geen gegevens verwijderd die al met dit apparaat zijn gesynchroniseerd."; diff --git a/DuckDuckGo/pl.lproj/Localizable.strings b/DuckDuckGo/pl.lproj/Localizable.strings index e2662507d2..3d70694854 100644 --- a/DuckDuckGo/pl.lproj/Localizable.strings +++ b/DuckDuckGo/pl.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synchronizacja jest wstrzymana"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Przełącz synchronizację"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "To urządzenie jest już synchronizowane, czy na pewno chcesz je synchronizować z inną kopią zapasową lub urządzeniem? Przełączenie nie usunie żadnych danych już zsynchronizowanych z tym urządzeniem."; diff --git a/DuckDuckGo/pt.lproj/Localizable.strings b/DuckDuckGo/pt.lproj/Localizable.strings index 3baac297f8..d7fd5575ae 100644 --- a/DuckDuckGo/pt.lproj/Localizable.strings +++ b/DuckDuckGo/pt.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "A sincronização está em pausa"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Mudar sincronização"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Este dispositivo já está sincronizado, tens a certeza de que queres sincronizá-lo com uma cópia de segurança ou um dispositivo diferente? A mudança não vai remover nenhum dado já sincronizado com este dispositivo."; diff --git a/DuckDuckGo/ro.lproj/Localizable.strings b/DuckDuckGo/ro.lproj/Localizable.strings index 5eff988766..ada6250d0c 100644 --- a/DuckDuckGo/ro.lproj/Localizable.strings +++ b/DuckDuckGo/ro.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sincronizarea este întreruptă"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Comută sincronizarea"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Acest dispozitiv este deja sincronizat, sigur dorești să-l sincronizezi cu o altă copie de rezervă sau alt dispozitiv? Schimbarea nu va șterge datele deja sincronizate cu acest dispozitiv."; diff --git a/DuckDuckGo/ru.lproj/Localizable.strings b/DuckDuckGo/ru.lproj/Localizable.strings index b0c6db822d..54545dafb0 100644 --- a/DuckDuckGo/ru.lproj/Localizable.strings +++ b/DuckDuckGo/ru.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Синхронизация приостановлена"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Переключить синхронизацию"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Это устройство уже синхронизировано. Действительно синхронизировать его с другой резервной копией или устройством? Переключение не приведет к удалению данных, синхронизированных с этим устройством ранее."; diff --git a/DuckDuckGo/sk.lproj/Localizable.strings b/DuckDuckGo/sk.lproj/Localizable.strings index 326f5b33f6..635635fd28 100644 --- a/DuckDuckGo/sk.lproj/Localizable.strings +++ b/DuckDuckGo/sk.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synchronizácia bola pozastavená."; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Prepnutie synchronizácie"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Toto zariadenie je už synchronizované. Naozaj ho že chceš synchronizovať s inou zálohou alebo zariadením? Prepínanie neodstráni žiadne údaje, ktoré už boli synchronizované s týmto zariadením."; diff --git a/DuckDuckGo/sl.lproj/Localizable.strings b/DuckDuckGo/sl.lproj/Localizable.strings index ff52fea2d2..04dd067fad 100644 --- a/DuckDuckGo/sl.lproj/Localizable.strings +++ b/DuckDuckGo/sl.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Sinhronizacija je začasno zaustavljena"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Preklop sinhronizacije"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Ta naprava je že sinhronizirana, ste prepričani, da jo želite sinhronizirati z drugo varnostno kopijo ali napravo? Preklop ne bo odstranil nobenih podatkov, ki so že sinhronizirani s to napravo."; diff --git a/DuckDuckGo/sv.lproj/Localizable.strings b/DuckDuckGo/sv.lproj/Localizable.strings index 2bded7bc9c..59b3ea8dab 100644 --- a/DuckDuckGo/sv.lproj/Localizable.strings +++ b/DuckDuckGo/sv.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Synkroniseringen är pausad"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Byt synkronisering"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Den här enheten är redan synkroniserad. Är du säker på att du vill synkronisera den med en annan säkerhetskopia eller enhet? Att byta tar inte bort några data som redan har synkroniserats med den här enheten."; diff --git a/DuckDuckGo/tr.lproj/Localizable.strings b/DuckDuckGo/tr.lproj/Localizable.strings index 54c07d7bdc..2ff2ddd704 100644 --- a/DuckDuckGo/tr.lproj/Localizable.strings +++ b/DuckDuckGo/tr.lproj/Localizable.strings @@ -181,6 +181,9 @@ /* Title for alert shown when sync paused for an error */ "alert.sync-paused-title" = "Senkronizasyon Duraklatıldı"; +/* Switch account button in alert */ +"alert.sync-switch-account-button" = "Senkronizasyonu Değiştir"; + /* Description for switching sync accounts when there's two */ "alert.sync-switch-account-message" = "Bu cihaz zaten senkronize edilmiş. Farklı bir yedekleme veya cihazla senkronize etmek istediğinden emin misin? Senkronizasyonu değiştirmek, bu cihazla önceden senkronize edilmiş verileri kaldırmayacaktır."; From 97b29afdbd254e939fd0c3e610536ad43d2a5274 Mon Sep 17 00:00:00 2001 From: Graeme Arthur Date: Fri, 20 Dec 2024 11:43:52 +0100 Subject: [PATCH 12/12] back up -> backup --- DuckDuckGo/UserText.swift | 2 +- DuckDuckGo/en.lproj/Localizable.strings | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo/UserText.swift b/DuckDuckGo/UserText.swift index 807c6811a9..9e19eef81c 100644 --- a/DuckDuckGo/UserText.swift +++ b/DuckDuckGo/UserText.swift @@ -962,7 +962,7 @@ But if you *do* want a peek under the hood, you can find more information about 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 syncAlertSwitchAccountTitle = NSLocalizedString("alert.sync-switch-account-title", value: "Switch to a different Sync?", comment: "Switch account title in alert") - public static let syncAlertSwitchAccountMessage = NSLocalizedString("alert.sync-switch-account-message", value: "This device is already synced, are you sure you want to sync it with a different back up or device? Switching won't remove any data already synced to this device.", comment: "Description for switching sync accounts when there's two") + public static let syncAlertSwitchAccountMessage = NSLocalizedString("alert.sync-switch-account-message", value: "This device is already synced, are you sure you want to sync it with a different backup or device? Switching won't remove any data already synced to this device.", comment: "Description for switching sync accounts when there's two") public static let syncAlertSwitchAccountButton = NSLocalizedString("alert.sync-switch-account-button", value: "Switch Sync", comment: "Switch account button in alert") 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") diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index 4f64c17e10..1296b3253b 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -204,7 +204,7 @@ "alert.sync-switch-account-button" = "Switch Sync"; /* Description for switching sync accounts when there's two */ -"alert.sync-switch-account-message" = "This device is already synced, are you sure you want to sync it with a different back up or device? Switching won't remove any data already synced to this device."; +"alert.sync-switch-account-message" = "This device is already synced, are you sure you want to sync it with a different backup or device? Switching won't remove any data already synced to this device."; /* Switch account title in alert */ "alert.sync-switch-account-title" = "Switch to a different Sync?";