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

Add Sync feature flags #2279

Merged
merged 10 commits into from
Dec 20, 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
4 changes: 2 additions & 2 deletions Core/AppPrivacyConfigurationDataProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import BrowserServicesKit
final public class AppPrivacyConfigurationDataProvider: EmbeddedDataProvider {

public struct Constants {
public static let embeddedDataETag = "\"f4e8436ab9977e1a8a9d6ee600fc353e\""
public static let embeddedDataSHA = "86b3a7bece52da74f7d267c2b522ac929d363a384cacc013f2b2d057ee1e386c"
public static let embeddedDataETag = "\"388dd0526e94f80473728c0bfbb48b39\""
public static let embeddedDataSHA = "f7b9ae8860ff84f33e602b40d0938776d2d9327115b4ddfe09fc0fa09b5e1ff1"
}

public var embeddedDataEtag: String {
Expand Down
4 changes: 3 additions & 1 deletion Core/FeatureFlag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ public enum FeatureFlag: String {
extension FeatureFlag: FeatureFlagSourceProviding {
public var source: FeatureFlagSource {
switch self {
case .debugMenu, .sync, .appTrackingProtection:
case .debugMenu, .appTrackingProtection:
return .internalOnly
case .sync:
return .remoteReleasable(.subfeature(SyncSubfeature.level0ShowSync))
bwaresiak marked this conversation as resolved.
Show resolved Hide resolved
case .networkProtection:
return .remoteReleasable(.feature(.networkProtection))
case .networkProtectionWaitlistAccess:
Expand Down
73 changes: 63 additions & 10 deletions Core/ios-config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"readme": "https://github.com/duckduckgo/privacy-configuration",
"version": 1702917767277,
"version": 1703026028516,
"features": {
"adClickAttribution": {
"readme": "https://help.duckduckgo.com/duckduckgo-help-pages/privacy/web-tracking-protections/#3rd-party-tracker-loading-protection",
Expand Down Expand Up @@ -2956,11 +2956,14 @@
]
},
{
"domain": "orange.fr",
"domain": "oceanofcompressed.xyz",
"rules": [
{
"selector": ".tag-rm",
"type": "hide-empty"
"type": "disable-default"
},
{
"selector": "#sticky-ads",
"type": "hide"
}
]
},
Expand All @@ -2977,6 +2980,15 @@
}
]
},
{
"domain": "orange.fr",
"rules": [
{
"selector": ".tag-rm",
"type": "hide-empty"
}
]
},
{
"domain": "ouest-france.fr",
"rules": [
Expand Down Expand Up @@ -3788,7 +3800,7 @@
]
},
"state": "enabled",
"hash": "81d363bc5cd7d76de1aa11d5b0f8e27d"
"hash": "182ef21a9dcfd3a160468f851c4b1789"
},
"exceptionHandler": {
"exceptions": [
Expand Down Expand Up @@ -4502,6 +4514,25 @@
"state": "disabled",
"hash": "5e792dd491428702bc0104240fbce0ce"
},
"sync": {
"exceptions": [],
"state": "internal",
"features": {
"level0ShowSync": {
"state": "enabled"
},
"level1AllowDataSyncing": {
"state": "enabled"
},
"level2AllowSetupFlows": {
"state": "enabled"
},
"level3AllowCreateAccount": {
"state": "enabled"
}
},
"hash": "92673fe625ae2b888a4b0bfa9a974ce4"
},
"trackerAllowlist": {
"state": "enabled",
"settings": {
Expand Down Expand Up @@ -4764,6 +4795,12 @@
"wxii12.com",
"wyff4.com"
]
},
{
"rule": "z-na.amazon-adsystem.com/widgets/onejs",
"domains": [
"oceanofcompressed.xyz"
]
}
]
},
Expand Down Expand Up @@ -5522,8 +5559,7 @@
{
"rule": "app.five9.com",
"domains": [
"gmsdnv.com",
"machiassavings.bank"
"<all>"
]
}
]
Expand Down Expand Up @@ -6058,7 +6094,13 @@
{
"rule": "api.hubspot.com/livechat-public/v1/message/public",
"domains": [
"pippintitle.com"
"<all>"
]
},
{
"rule": "js.hubspot.com/web-interactives-embed.js",
"domains": [
"<all>"
]
},
{
Expand Down Expand Up @@ -6367,6 +6409,16 @@
}
]
},
"media.net": {
"rules": [
{
"rule": "contextual.media.net/dmedianet.js",
"domains": [
"oceanofcompressed.xyz"
]
}
]
},
"mediavine.com": {
"rules": [
{
Expand Down Expand Up @@ -6825,7 +6877,8 @@
{
"rule": "secure.quantserve.com/quant.js",
"domains": [
"aternos.org"
"aternos.org",
"oceanofcompressed.xyz"
]
}
]
Expand Down Expand Up @@ -7510,7 +7563,7 @@
"domain": "sundancecatalog.com"
}
],
"hash": "163c9ec4fc3bdb9dbfc75e70839a31d7"
"hash": "c1968268cb8a82bf532443edd17d9499"
},
"trackingCookies1p": {
"settings": {
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9221,7 +9221,7 @@
repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit";
requirement = {
kind = exactVersion;
version = 96.0.0;
version = 97.0.0;
};
};
C14882EB27F211A000D59F0C /* XCRemoteSwiftPackageReference "SwiftSoup" */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/DuckDuckGo/BrowserServicesKit",
"state" : {
"revision" : "e5c9e31b19b3cf78e2b704a60882ba24b9bc680d",
"version" : "96.0.0"
"revision" : "d671accf1bf7097c4e7f5cd55cd1c6dfa005cf92",
"version" : "97.0.0"
}
},
{
Expand Down
8 changes: 7 additions & 1 deletion DuckDuckGo/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@
errorEvents: preMigrationErrorHandling
)

bookmarksDatabase.loadStore { [weak self] context, error in

Check warning on line 193 in DuckDuckGo/AppDelegate.swift

View workflow job for this annotation

GitHub Actions / Unit Tests

variable 'self' was written to, but never read
guard let context = context else {
if let error = error {
Pixel.fire(pixel: .bookmarksCouldNotLoadDatabase,
Expand Down Expand Up @@ -283,7 +283,13 @@
favoritesDisplayModeStorage: FavoritesDisplayModeStorage()
)

let syncService = DDGSync(dataProvidersSource: syncDataProviders, errorEvents: SyncErrorHandler(), log: .syncLog, environment: environment)
let syncService = DDGSync(
dataProvidersSource: syncDataProviders,
errorEvents: SyncErrorHandler(),
privacyConfigurationManager: ContentBlocking.shared.privacyConfigurationManager,
log: .syncLog,
environment: environment
)
syncService.initializeIfNeeded()
self.syncService = syncService

Expand Down
3 changes: 2 additions & 1 deletion DuckDuckGo/FaviconsFetcherOnboarding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ final class FaviconsFetcherOnboarding {
}

private var shouldPresentOnboarding: Bool {
!didPresentFaviconsFetchingOnboarding
syncService.featureFlags.contains(.userInterface)
&& !didPresentFaviconsFetchingOnboarding
&& !syncBookmarksAdapter.isFaviconsFetchingEnabled
&& syncBookmarksAdapter.isEligibleForFaviconsFetcherOnboarding
}
Expand Down
2 changes: 1 addition & 1 deletion 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 featureFlagger.isFeatureOn(.sync)
return syncService.featureFlags.contains(.userInterface) || internalUserDecider.isInternalUser
}

private var shouldShowTextSizeCell: Bool {
Expand Down
14 changes: 14 additions & 0 deletions DuckDuckGo/SyncSettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class SyncSettingsViewController: UIHostingController<SyncSettingsView> {
setUpFaviconsFetcherSwitch(viewModel)
setUpFavoritesDisplayModeSwitch(viewModel, appSettings)
setUpSyncPaused(viewModel, appSettings)
setUpSyncFeatureFlags(viewModel)
refreshForState(syncService.authState)

syncService.authStatePublisher
Expand All @@ -87,6 +88,19 @@ class SyncSettingsViewController: UIHostingController<SyncSettingsView> {
fatalError("init(coder:) has not been implemented")
}

private func setUpSyncFeatureFlags(_ viewModel: SyncSettingsViewModel) {
syncService.featureFlagsPublisher.prepend(syncService.featureFlags)
.removeDuplicates()
.receive(on: DispatchQueue.main)
.sink { featureFlags in
viewModel.isDataSyncingAvailable = featureFlags.contains(.dataSyncing)
viewModel.isConnectingDevicesAvailable = featureFlags.contains(.connectFlows)
viewModel.isAccountCreationAvailable = featureFlags.contains(.accountCreation)
viewModel.isAccountRecoveryAvailable = featureFlags.contains(.accountRecovery)
}
.store(in: &cancellables)
}

private func setUpFaviconsFetcherSwitch(_ viewModel: SyncSettingsViewModel) {
viewModel.isFaviconsFetchingEnabled = syncBookmarksAdapter.isFaviconsFetchingEnabled

Expand Down
2 changes: 1 addition & 1 deletion LocalPackages/DuckUI/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ let package = Package(
targets: ["DuckUI"])
],
dependencies: [
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "96.0.0"),
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "97.0.0"),
],
targets: [
.target(
Expand Down
2 changes: 1 addition & 1 deletion LocalPackages/SyncUI/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ let package = Package(
],
dependencies: [
.package(path: "../DuckUI"),
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "96.0.0"),
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "97.0.0"),
.package(url: "https://github.com/duckduckgo/DesignResourcesKit", exact: "2.0.0")
],
targets: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ public class SyncSettingsViewModel: ObservableObject {
@Published var isBusy = false
@Published var recoveryCode = ""

@Published public var isDataSyncingAvailable: Bool = true
@Published public var isConnectingDevicesAvailable: Bool = true
@Published public var isAccountCreationAvailable: Bool = true
@Published public var isAccountRecoveryAvailable: Bool = true

public weak var delegate: SyncManagementViewModelDelegate?
private(set) var isOnDevEnvironment: Bool
private(set) var switchToProdEnvironment: () -> Void = {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct UserText {
static let turnSyncOffSectionHeader = NSLocalizedString("turn.sync.off.section.header", value: "Sync Enabled", comment: "Turn Sync Off - Section Header")
static let turnSyncOffSectionFooter = NSLocalizedString("turn.sync.off.section.footer", value: "Bookmarks and passwords are currently synced across your devices.", comment: "Turn Sync Off - Section Footer")
// Sync Paused Errors
static let syncLimitExceededTitle = NSLocalizedString("sync.limit.exceeded.title", value: "⚠️ Sync Paused", comment: "Sync Paused Errors - Title")
static let syncLimitExceededTitle = NSLocalizedString("sync.limit.exceeded.title", value: "Sync Paused", comment: "Sync Paused Errors - Title")
static let bookmarksLimitExceededDescription = NSLocalizedString("bookmarks.limit.exceeded.description", value: "Bookmark limit exceeded. Delete some to resume syncing.", comment: "Sync Paused Errors - Bookmarks Limit Exceeded Description")
static let credentialsLimitExceededDescription = NSLocalizedString("credentials.limit.exceeded.description", value: "Logins limit exceeded. Delete some to resume syncing.", comment: "Sync Paused Errors - Credentials Limit Exceeded Description")
static let bookmarksLimitExceededAction = NSLocalizedString("bookmarks.limit.exceeded.action", value: "Manage Bookmarks", comment: "Sync Paused Errors - Bookmarks Limit Exceeded Action")
Expand Down Expand Up @@ -159,6 +159,10 @@ struct UserText {
static let fetchFaviconsOnboardingMessage = NSLocalizedString("fetch.favicons.onboarding.message", value: "Do you want this device to automatically download icons for any new bookmarks synced from your other devices? This will expose the download to your network any time a bookmark is synced.", comment: "Fetch Favicons Onboarding - Message")
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")

// swiftlint:enable line_length
}
Loading
Loading