Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show alert and display warning icon in Sync Settings when data syncing is disabled #1996

Merged
merged 3 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions DuckDuckGo/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,35 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel
}

subscribeSyncQueueToScreenLockedNotifications()
subscribeToSyncFeatureFlags(syncService)
}

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

private func subscribeToSyncFeatureFlags(_ syncService: DDGSync) {
syncFeatureFlagsCancellable = syncService.featureFlagsPublisher
.dropFirst()
.map { $0.contains(.dataSyncing) }
.receive(on: DispatchQueue.main)
.sink { [weak self, weak syncService] isDataSyncingAvailable in
if isDataSyncingAvailable {
self?.syncDidShowSyncPausedByFeatureFlagAlert = false
} else if syncService?.authState == .active, self?.syncDidShowSyncPausedByFeatureFlagAlert == false {
let isSyncUIVisible = syncService?.featureFlags.contains(.userInterface) == true
let alert = NSAlert.dataSyncingDisabledByFeatureFlag(showLearnMore: isSyncUIVisible)
let response = alert.runModal()
self?.syncDidShowSyncPausedByFeatureFlagAlert = true

switch response {
case .alertSecondButtonReturn:
alert.window.sheetParent?.endSheet(alert.window)
WindowControllersManager.shared.showPreferencesTab(withSelectedPane: .sync)
default:
break
}
}
}
}

private func subscribeSyncQueueToScreenLockedNotifications() {
Expand Down
12 changes: 12 additions & 0 deletions DuckDuckGo/Common/Extensions/NSAlertExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,18 @@ extension NSAlert {
return alert
}

static func dataSyncingDisabledByFeatureFlag(showLearnMore: Bool, upgradeRequired: Bool = false) -> NSAlert {
let alert = NSAlert()
alert.messageText = UserText.syncPausedTitle
alert.informativeText = upgradeRequired ? UserText.syncUnavailableMessageUpgradeRequired : UserText.syncUnavailableMessage
alert.alertStyle = .warning
alert.addButton(withTitle: UserText.ok)
if showLearnMore {
alert.addButton(withTitle: UserText.learnMore)
}
return alert
}

static func customConfigurationAlert(configurationUrl: String) -> NSAlert {
let alert = NSAlert()
alert.messageText = "Set custom configuration URL:"
Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/Common/Localizables/UserText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,9 @@ struct UserText {
static let syncBookmarkPausedAlertDescription = NSLocalizedString("alert.sync-bookmarks-paused-description", value: "You have exceeded the bookmarks sync limit. Try deleting some bookmarks. Until this is resolved your bookmarks will not be backed up.", comment: "Description for alert shown when sync bookmarks paused for too many items")
static let syncCredentialsPausedAlertTitle = NSLocalizedString("alert.sync-credentials-paused-title", value: "Passwords Sync is Paused", comment: "Title for alert shown when sync credentials paused for too many items")
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")
static let syncPausedTitle = NSLocalizedString("alert.sync.warning.sync-paused", value: "Sync & Backup is Paused", comment: "Title of the warning message")
static let syncUnavailableMessage = NSLocalizedString("alert.sync.warning.sync-unavailable-message", value: "Sorry, but Sync & Backup is currently unavailable. Please try again later.", comment: "Data syncing unavailable warning message")
static let syncUnavailableMessageUpgradeRequired = NSLocalizedString("alert.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 defaultBrowser = NSLocalizedString("preferences.default-browser", value: "Default Browser", comment: "Show default browser preferences")
static let appearance = NSLocalizedString("preferences.appearance", value: "Appearance", comment: "Show appearance preferences")
static let privacy = NSLocalizedString("preferences.privacy", value: "Privacy", comment: "Show privacy browser preferences")
Expand Down
1 change: 1 addition & 0 deletions DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ public struct UserDefaultsWrapper<T> {
case syncIsEligibleForFaviconsFetcherOnboarding = "sync.is-eligible-for-favicons-fetcher-onboarding"
case syncDidPresentFaviconsFetcherOnboarding = "sync.did-present-favicons-fetcher-onboarding"
case syncDidMigrateToImprovedListsHandling = "sync.did-migrate-to-improved-lists-handling"
case syncDidShowSyncPausedByFeatureFlagAlert = "sync.did-show-sync-paused-by-feature-flag-alert"
}

enum RemovedKeys: String, CaseIterable {
Expand Down
5 changes: 4 additions & 1 deletion DuckDuckGo/Preferences/Model/PreferencesSection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,17 @@ enum PreferencePaneIdentifier: String, Equatable, Hashable, Identifiable {
self.init(rawValue: path)
}

@MainActor
var displayName: String {
switch self {
case .general:
return UserText.general
case .sync:
let isSyncBookmarksPaused = UserDefaults.standard.bool(forKey: UserDefaultsWrapper<Bool>.Key.syncBookmarksPaused.rawValue)
let isSyncCredentialsPaused = UserDefaults.standard.bool(forKey: UserDefaultsWrapper<Bool>.Key.syncCredentialsPaused.rawValue)
if isSyncBookmarksPaused || isSyncCredentialsPaused {
let syncService = NSApp.delegateTyped.syncService
let isDataSyncingDisabled = syncService?.featureFlags.contains(.dataSyncing) == false && syncService?.authState == .active
if isSyncBookmarksPaused || isSyncCredentialsPaused || isDataSyncingDisabled {
return UserText.sync + " ⚠️"
}
return UserText.sync
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ struct SyncEnabledView<ViewModel>: View where ViewModel: ManagementViewModel {
if model.isDataSyncingAvailable {
EmptyView()
} else {
SyncWarningMessage(title: UserText.serviceUnavailable, message: UserText.warningSyncDisabled)
SyncWarningMessage(title: UserText.syncPausedTitle, message: UserText.syncUnavailableMessage)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,8 @@ struct SyncSetupView<ViewModel>: View where ViewModel: ManagementViewModel {

@ViewBuilder
fileprivate func syncUnavailableView() -> some View {
if !model.isDataSyncingAvailable || !model.isConnectingDevicesAvailable {
SyncWarningMessage(title: UserText.serviceUnavailable, message: UserText.warningSyncDisabled)
.padding(.top, 16)
} else if !model.isAccountCreationAvailable {
SyncWarningMessage(title: UserText.serviceUnavailable, message: UserText.warningAccountCreationDisabled)
if !model.isDataSyncingAvailable || !model.isConnectingDevicesAvailable || !model.isAccountCreationAvailable {
SyncWarningMessage(title: UserText.syncUnavailableTitle, message: UserText.syncUnavailableMessage)
.padding(.top, 16)
} else {
EmptyView()
Expand Down
7 changes: 4 additions & 3 deletions LocalPackages/SyncUI/Sources/SyncUI/internal/UserText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ enum UserText {
static let keepFaviconsUpdated = NSLocalizedString("prefrences.sync.keep-favicons-updated", value: "Keep Bookmarks Icons Updated", comment: "Title of the confirmation button for favicons fetching")

// 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.sync-unavailable-message", 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")
}
Loading