diff --git a/Configuration/BuildNumber.xcconfig b/Configuration/BuildNumber.xcconfig index 9ba329c56c..58a5e5422c 100644 --- a/Configuration/BuildNumber.xcconfig +++ b/Configuration/BuildNumber.xcconfig @@ -1 +1 @@ -CURRENT_PROJECT_VERSION = 293 +CURRENT_PROJECT_VERSION = 295 diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index cb8f57f37b..37275f265a 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -14684,7 +14684,7 @@ repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 202.2.0; + version = 202.3.0; }; }; 9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 767783c47a..eb4bb56f1a 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/BrowserServicesKit", "state" : { - "revision" : "d39d04cf36b8522f894eebc3e11ee5fe65d880fa", - "version" : "202.2.0" + "revision" : "7b78b46340c9981b9774352be08c3c28b3a19011", + "version" : "202.3.0" } }, { @@ -75,7 +75,7 @@ { "identity" : "lottie-spm", "kind" : "remoteSourceControl", - "location" : "https://github.com/airbnb/lottie-spm.git", + "location" : "https://github.com/airbnb/lottie-spm", "state" : { "revision" : "1d29eccc24cc8b75bff9f6804155112c0ffc9605", "version" : "4.4.3" diff --git a/DuckDuckGo/Application/AppDelegate.swift b/DuckDuckGo/Application/AppDelegate.swift index f305ac5739..8bce0390f3 100644 --- a/DuckDuckGo/Application/AppDelegate.swift +++ b/DuckDuckGo/Application/AppDelegate.swift @@ -97,7 +97,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate { public let subscriptionManager: SubscriptionManager public let subscriptionUIHandler: SubscriptionUIHandling - public let subscriptionCookieManager: SubscriptionCookieManaging + private let subscriptionCookieManager: SubscriptionCookieManaging + private var subscriptionCookieManagerFeatureFlagCancellable: AnyCancellable? // MARK: - Freemium DBP public let freemiumDBPFeature: FreemiumDBPFeature @@ -325,6 +326,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate { freemiumDBPFeature.subscribeToDependencyUpdates() } + // swiftlint:disable:next cyclomatic_complexity func applicationDidFinishLaunching(_ notification: Notification) { guard NSApp.runType.requiresEnvironment else { return } defer { @@ -367,6 +369,30 @@ final class AppDelegate: NSObject, NSApplicationDelegate { subscriptionManager.loadInitialData() + let privacyConfigurationManager = ContentBlocking.shared.privacyConfigurationManager + + // Enable subscriptionCookieManager if feature flag is present + if privacyConfigurationManager.privacyConfig.isSubfeatureEnabled(PrivacyProSubfeature.setAccessTokenCookieForSubscriptionDomains) { + subscriptionCookieManager.enableSettingSubscriptionCookie() + } + + // Keep track of feature flag changes + subscriptionCookieManagerFeatureFlagCancellable = privacyConfigurationManager.updatesPublisher + .sink { [weak self, weak privacyConfigurationManager] in + guard let self, let privacyConfigurationManager else { return } + + let isEnabled = privacyConfigurationManager.privacyConfig.isSubfeatureEnabled(PrivacyProSubfeature.setAccessTokenCookieForSubscriptionDomains) + + Task { [weak self] in + if isEnabled { + self?.subscriptionCookieManager.enableSettingSubscriptionCookie() + await self?.subscriptionCookieManager.refreshSubscriptionCookie() + } else { + await self?.subscriptionCookieManager.disableSettingSubscriptionCookie() + } + } + } + if [.normal, .uiTests].contains(NSApp.runType) { stateRestorationManager.applicationDidFinishLaunching() } diff --git a/DuckDuckGo/Common/Extensions/NSViewExtension.swift b/DuckDuckGo/Common/Extensions/NSViewExtension.swift index 2e81660afc..c17edf489f 100644 --- a/DuckDuckGo/Common/Extensions/NSViewExtension.swift +++ b/DuckDuckGo/Common/Extensions/NSViewExtension.swift @@ -85,6 +85,12 @@ extension NSView { set { isHidden = !newValue } } + var isVisible: Bool { + guard !isHiddenOrHasHiddenAncestor, + let window, window.isVisible else { return false } + return true + } + func makeMeFirstResponder() { guard let window = window else { Logger.general.error("\(self.className): Window not available") diff --git a/DuckDuckGo/Common/Extensions/WKWebViewConfigurationExtensions.swift b/DuckDuckGo/Common/Extensions/WKWebViewConfigurationExtensions.swift index 090e9c3121..9a89e51e4f 100644 --- a/DuckDuckGo/Common/Extensions/WKWebViewConfigurationExtensions.swift +++ b/DuckDuckGo/Common/Extensions/WKWebViewConfigurationExtensions.swift @@ -119,7 +119,7 @@ extension NSPopover { // https://app.asana.com/0/1201037661562251/1206407295280737/f @objc(swizzled_showRelativeToRect:ofView:preferredEdge:) private dynamic func swizzled_show(relativeTo positioningRect: NSRect, of positioningView: NSView, preferredEdge: NSRectEdge) { - if positioningView.superview == nil { + if positioningView.window == nil { var observer: Cancellable? observer = positioningView.observe(\.window) { positioningView, _ in if positioningView.window != nil { diff --git a/DuckDuckGo/MainWindow/MainWindowController.swift b/DuckDuckGo/MainWindow/MainWindowController.swift index 5911d9c289..a21f293ae6 100644 --- a/DuckDuckGo/MainWindow/MainWindowController.swift +++ b/DuckDuckGo/MainWindow/MainWindowController.swift @@ -74,8 +74,12 @@ final class MainWindowController: NSWindowController { return false #elseif REVIEW if Application.runType == .uiTests { + Application.appDelegate.onboardingStateMachine.state = .onboardingCompleted return false } else { + if Application.runType == .uiTestsOnboarding { + Application.appDelegate.onboardingStateMachine.state = .onboardingCompleted + } let onboardingIsComplete = OnboardingViewModel.isOnboardingFinished || LocalStatisticsStore().waitlistUnlocked return !onboardingIsComplete } diff --git a/DuckDuckGo/NavigationBar/View/AddressBarButtonsViewController.swift b/DuckDuckGo/NavigationBar/View/AddressBarButtonsViewController.swift index 44e6cf951e..63766e5838 100644 --- a/DuckDuckGo/NavigationBar/View/AddressBarButtonsViewController.swift +++ b/DuckDuckGo/NavigationBar/View/AddressBarButtonsViewController.swift @@ -61,7 +61,7 @@ final class AddressBarButtonsViewController: NSViewController { @IBOutlet weak var imageButtonWrapper: NSView! @IBOutlet weak var imageButton: NSButton! @IBOutlet weak var clearButton: NSButton! - @IBOutlet weak var buttonsContainer: NSStackView! + @IBOutlet private weak var buttonsContainer: NSStackView! @IBOutlet weak var animationWrapperView: NSView! var trackerAnimationView1: LottieAnimationView! @@ -72,7 +72,7 @@ final class AddressBarButtonsViewController: NSViewController { @IBOutlet weak var notificationAnimationView: NavigationBarBadgeAnimationView! - @IBOutlet weak var permissionButtons: NSView! + @IBOutlet private weak var permissionButtons: NSView! @IBOutlet weak var cameraButton: PermissionButton! { didSet { cameraButton.isHidden = true @@ -368,7 +368,7 @@ final class AddressBarButtonsViewController: NSViewController { return } } - guard button.isShown, permissionButtons.isShown else { return } + guard button.isVisible else { return } (popover.contentViewController as? PermissionAuthorizationViewController)?.query = query popover.show(relativeTo: button.bounds, of: button, preferredEdge: .maxY) diff --git a/DuckDuckGo/Subscription/SubscriptionCookieManageEventPixelMapping.swift b/DuckDuckGo/Subscription/SubscriptionCookieManageEventPixelMapping.swift index c18cf2e6d4..fc5128756d 100644 --- a/DuckDuckGo/Subscription/SubscriptionCookieManageEventPixelMapping.swift +++ b/DuckDuckGo/Subscription/SubscriptionCookieManageEventPixelMapping.swift @@ -24,21 +24,18 @@ import Subscription enum SubscriptionCookieManagerPixel: PixelKitEventV2 { case missingTokenOnSignIn - case missingCookieOnSignOut - case cookieRefreshedWithUpdate - case cookieRefreshedWithDelete + case cookieRefreshedWithAccessToken + case cookieRefreshedWithEmptyValue case failedToSetSubscriptionCookie var name: String { switch self { case .missingTokenOnSignIn: return "m_mac_privacy-pro_subscription-cookie-missing_token_on_sign_in" - case .missingCookieOnSignOut: - return "m_mac_privacy-pro_subscription-cookie-missing_cookie_on_sign_out" - case .cookieRefreshedWithUpdate: - return "m_mac_privacy-pro_subscription-cookie-refreshed_with_update" - case .cookieRefreshedWithDelete: - return "m_mac_privacy-pro_subscription-cookie-refreshed_with_delete" + case .cookieRefreshedWithAccessToken: + return "m_mac_privacy-pro_subscription-cookie-refreshed_with_access_token" + case .cookieRefreshedWithEmptyValue: + return "m_mac_privacy-pro_subscription-cookie-refreshed_with_empty_value" case .failedToSetSubscriptionCookie: return "m_mac_privacy-pro_subscription-cookie-failed_to_set_subscription_cookie" } @@ -61,12 +58,10 @@ public final class SubscriptionCookieManageEventPixelMapping: EventMapping