Skip to content

Commit

Permalink
Display warning icon in Sync Settings cell when data syncing is disab…
Browse files Browse the repository at this point in the history
  • Loading branch information
ayoy authored Dec 21, 2023
1 parent 4240dd5 commit c17809f
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 10 deletions.
1 change: 1 addition & 0 deletions Core/UserDefaultsPropertyWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public struct UserDefaultsWrapper<T> {
case syncIsEligibleForFaviconsFetcherOnboarding = "com.duckduckgo.ios.sync-is-eligible-for-favicons-fetcher-onboarding"
case syncDidPresentFaviconsFetcherOnboarding = "com.duckduckgo.ios.sync-did-present-favicons-fetcher-onboarding"
case syncDidMigrateToImprovedListsHandling = "com.duckduckgo.ios.sync-did-migrate-to-improved-lists-handling"
case syncDidShowSyncPausedByFeatureFlagAlert = "com.duckduckgo.ios.sync-did-show-sync-paused-by-feature-flag-alert"

case networkProtectionDebugOptionAlwaysOnDisabled = "com.duckduckgo.network-protection.always-on.disabled"
case networkProtectionWaitlistTermsAndConditionsAccepted = "com.duckduckgo.ios.vpn.terms-and-conditions-accepted"
Expand Down
40 changes: 40 additions & 0 deletions DuckDuckGo/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,13 @@ class MainViewController: UIViewController {
private var favoritesViewModel: FavoritesListInteracting
let syncService: DDGSyncing
let syncDataProviders: SyncDataProviders

@UserDefaultsWrapper(key: .syncDidShowSyncPausedByFeatureFlagAlert, defaultValue: false)
private var syncDidShowSyncPausedByFeatureFlagAlert: Bool

private var localUpdatesCancellable: AnyCancellable?
private var syncUpdatesCancellable: AnyCancellable?
private var syncFeatureFlagsCancellable: AnyCancellable?
private var favoritesDisplayModeCancellable: AnyCancellable?
private var emailCancellables = Set<AnyCancellable>()

Expand Down Expand Up @@ -349,6 +354,21 @@ class MainViewController: UIViewController {
selector: #selector(showSyncPausedError),
name: SyncCredentialsAdapter.credentialsSyncLimitReached,
object: nil)
syncFeatureFlagsCancellable = syncService.featureFlagsPublisher
.dropFirst()
.map { $0.contains(.dataSyncing) }
.receive(on: DispatchQueue.main)
.sink { [weak self] isDataSyncingAvailable in
guard let self else {
return
}
if isDataSyncingAvailable {
self.syncDidShowSyncPausedByFeatureFlagAlert = false
} else if self.syncService.authState == .active, !self.syncDidShowSyncPausedByFeatureFlagAlert {
self.showSyncPausedByFeatureFlagAlert()
self.syncDidShowSyncPausedByFeatureFlagAlert = true
}
}
}

@objc private func showSyncPausedError(_ notification: Notification) {
Expand Down Expand Up @@ -378,6 +398,26 @@ class MainViewController: UIViewController {
}
}

private func showSyncPausedByFeatureFlagAlert(upgradeRequired: Bool = false) {
let title = UserText.syncPausedTitle
let description = upgradeRequired ? UserText.syncUnavailableMessageUpgradeRequired : UserText.syncUnavailableMessage
if self.presentedViewController is SyncSettingsViewController {
return
}
self.presentedViewController?.dismiss(animated: true)
let alert = UIAlertController(title: title,
message: description,
preferredStyle: .alert)
if syncService.featureFlags.contains(.userInterface) {
let learnMoreAction = UIAlertAction(title: UserText.syncPausedAlertLearnMoreButton, style: .default) { _ in
self.segueToSettingsSync()
}
alert.addAction(learnMoreAction)
}
alert.addAction(UIAlertAction(title: UserText.syncPausedAlertOkButton, style: .cancel))
self.present(alert, animated: true)
}

func registerForSettingsChangeNotifications() {
NotificationCenter.default.addObserver(self, selector:
#selector(onAddressBarPositionChanged),
Expand Down
5 changes: 3 additions & 2 deletions DuckDuckGo/SettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class SettingsViewController: UITableViewController {
}

private var shouldShowSyncCell: Bool {
return syncService.featureFlags.contains(.userInterface) || internalUserDecider.isInternalUser
return syncService.featureFlags.contains(.userInterface)
}

private var shouldShowTextSizeCell: Bool {
Expand Down Expand Up @@ -260,7 +260,8 @@ class SettingsViewController: UITableViewController {

private func configureSyncCell() {
syncCell.textLabel?.text = "Sync & Backup"
if SyncBookmarksAdapter.isSyncBookmarksPaused || SyncCredentialsAdapter.isSyncCredentialsPaused {
let isDataSyncingDisabled = !syncService.featureFlags.contains(.dataSyncing) && syncService.authState == .active
if SyncBookmarksAdapter.isSyncBookmarksPaused || SyncCredentialsAdapter.isSyncCredentialsPaused || isDataSyncingDisabled {
syncCell.textLabel?.text = "⚠️ " + "Sync & Backup"
}
syncCell.isHidden = !shouldShowSyncCell
Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/UserText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,9 @@ But if you *do* want a peek under the hood, you can find more information about
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 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")
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")

static let preemptiveCrashTitle = NSLocalizedString("error.preemptive-crash.title", value: "App issue detected", comment: "Alert title")
static let preemptiveCrashBody = NSLocalizedString("error.preemptive-crash.body", value: "Looks like there's an issue with the app and it needs to close. Please reopen to continue.", comment: "Alert message")
Expand Down
9 changes: 9 additions & 0 deletions DuckDuckGo/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,15 @@ But if you *do* want a peek under the hood, you can find more information about
/* No comment provided by engineer. */
"sync.remove-device.message" = "\"%@\" will no longer be able to access your synced data.";

/* Data syncing unavailable warning message */
"sync.warning.data.syncing.disabled" = "Sorry, but Sync & Backup is currently unavailable. Please try again later.";

/* Data syncing unavailable warning message */
"sync.warning.data.syncing.disabled.upgrade.required" = "Sorry, but Sync & Backup is no longer available in this app version. Please update DuckDuckGo to the latest version to continue.";

/* Title of the warning message */
"sync.warning.sync.paused" = "Sync & Backup is Paused";

/* Accessibility label on remove button */
"tab.close.home" = "Close home tab";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,10 @@ struct UserText {
static let fetchFaviconsOnboardingButtonTitle = NSLocalizedString("fetch.favicons.onboarding.button.title", value: "Keep Bookmarks Icons Updated", comment: "Fetch Favicons Onboarding - Button Title")

// Sync Feature Flags
static let serviceUnavailable = NSLocalizedString("sync.warning.service.unavailable", value: "Service Unavailable", comment: "Title of the warning message")
static let warningSyncDisabled = NSLocalizedString("sync.warning.sync.disabled", value: "We apologize, but the service is currently unavailable. Please try again later.", comment: "Sync unavailable warning message")
static let warningAccountCreationDisabled = NSLocalizedString("sync.warning.account.creation.disabled", value: "We apologize, but new account creation is currently unavailable for this service. Please try again later.", comment: "Sync unavailable warning message")
static let syncUnavailableTitle = NSLocalizedString("sync.warning.sync.unavailable", value: "Sync & Backup is Unavailable", comment: "Title of the warning message")
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")

// swiftlint:enable line_length
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,8 @@ extension SyncSettingsView {

@ViewBuilder
fileprivate func syncUnavailableViewWhileLoggedOut() -> some View {
if !model.isDataSyncingAvailable || !model.isConnectingDevicesAvailable {
SyncWarningMessageView(title: UserText.serviceUnavailable, message: UserText.warningSyncDisabled)
} else if !model.isAccountCreationAvailable {
SyncWarningMessageView(title: UserText.serviceUnavailable, message: UserText.warningAccountCreationDisabled)
if !model.isDataSyncingAvailable || !model.isConnectingDevicesAvailable || !model.isAccountCreationAvailable {
SyncWarningMessageView(title: UserText.syncUnavailableTitle, message: UserText.syncUnavailableMessage)
} else {
EmptyView()
}
Expand Down Expand Up @@ -182,7 +180,7 @@ extension SyncSettingsView {
if model.isDataSyncingAvailable {
EmptyView()
} else {
SyncWarningMessageView(title: UserText.serviceUnavailable, message: UserText.warningSyncDisabled)
SyncWarningMessageView(title: UserText.syncPausedTitle, message: UserText.syncUnavailableMessage)
}
}

Expand Down

0 comments on commit c17809f

Please sign in to comment.