Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
diegoreymendez committed Mar 21, 2024
1 parent 65fa647 commit 0fdd141
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 19 deletions.
16 changes: 13 additions & 3 deletions DuckDuckGo/Menus/MainMenuActions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import Common
import WebKit
import Configuration
import History
import PixelKit
import VPNPrivacyPro

// Actions are sent to objects of responder chain

Expand Down Expand Up @@ -717,11 +719,19 @@ extension MainViewController {
let state = internalUserDecider.isInternalUser
internalUserDecider.debugSetInternalUserState(!state)

// Aid to transition VPN from waitlist to subscription
// by resetting this we allow users to go back to waitlist
// and re-test.
clearPrivacyProState()
}

/// Clears the PrivacyPro state to make testing easier.
///
private func clearPrivacyProState() {
resetThankYouModalChecks(nil)
UserDefaults.netP.networkProtectionEntitlementsExpired = false

// Clear pixel data
DailyPixel.clearLastFireDate(pixel: .privacyProEnabled)
Pixel.shared?.clearRepetitions(for: .privacyProBetaUserThankYouDBP)
Pixel.shared?.clearRepetitions(for: .privacyProBetaUserThankYouVPN)
}

@objc func resetDailyPixels(_ sender: Any?) {
Expand Down
4 changes: 4 additions & 0 deletions DuckDuckGo/Statistics/DailyPixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ final class DailyPixel {
storage.set(Date(), forKey: pixel.name)
}

static func clearLastFireDate(pixel: Pixel.Event) {
storage.removeObject(forKey: pixel.name)
}

}

private extension Pixel.Event {
Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/Statistics/Pixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ final class Pixel {
onComplete: onComplete)
}

func clearRepetitions(for event: Pixel.Event) {
store().removeValue(forKey: event.name)
}
}

public func pixelAssertionFailure(_ message: @autoclosure () -> String = String(), file: StaticString = #fileID, line: UInt = #line) {
Expand Down
8 changes: 7 additions & 1 deletion DuckDuckGo/Statistics/PixelEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ extension Pixel {
case dataBrokerProtectionErrorWhenFetchingSubscriptionAuthTokenAfterSignIn

// Subscription
case privacyProEnabled
case privacyProBetaUserThankYouVPN
case privacyProBetaUserThankYouDBP
case privacyProSubscriptionActive
case privacyProOfferScreenImpression
case privacyProPurchaseAttempt
Expand Down Expand Up @@ -651,6 +654,10 @@ extension Pixel.Event {
case .defaultRequestedFromOnboarding: return "m_mac_default_requested_from_onboarding"

// MARK: - Subscription
case .privacyProEnabled: return
"m_mac_\(appDistribution)_privacy-pro_enabled"
case .privacyProBetaUserThankYouVPN: return "m_mac_\(appDistribution)_privacy-pro_promotion-dialog_shown_vpn_u"
case .privacyProBetaUserThankYouDBP: return "m_mac_\(appDistribution)_privacy-pro_promotion-dialog_shown_dbp_u"
case .privacyProSubscriptionActive: return "m_mac_\(appDistribution)_privacy-pro_app_subscription_active"
case .privacyProOfferScreenImpression: return "m_mac_\(appDistribution)_privacy-pro_offer_screen_impression"
case .privacyProPurchaseAttempt: return "m_mac_\(appDistribution)_privacy-pro_terms-conditions_subscribe_click"
Expand Down Expand Up @@ -693,7 +700,6 @@ extension Pixel.Event {
case .toggleProtectionsDailyCount: return "m_mac_toggle-protections-daily-count"
case .toggleReportDoNotSend: return "m_mac_toggle-report-do-not-send"
case .toggleReportDismiss: return "m_mac_toggle-report-dismiss"

}
}
}
Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/Statistics/PixelParameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ extension Pixel.Event {
.defaultRequestedFromHomepageSetupView,
.defaultRequestedFromSettings,
.defaultRequestedFromOnboarding,
.privacyProEnabled,
.privacyProBetaUserThankYouVPN,
.privacyProBetaUserThankYouDBP,
.privacyProSubscriptionActive,
.privacyProOfferScreenImpression,
.privacyProPurchaseAttempt,
Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/Waitlist/NetworkProtectionFeatureVisibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ import NetworkExtension
import NetworkProtection
import NetworkProtectionUI
import LoginItems
import PixelKit

#if SUBSCRIPTION
import Subscription
import VPNPrivacyPro
#endif

protocol NetworkProtectionFeatureVisibility {
Expand Down Expand Up @@ -173,6 +175,7 @@ struct DefaultNetworkProtectionVisibility: NetworkProtectionFeatureVisibility {
return false
}

PixelKit.fire(VPNPrivacyProPixel.vpnBetaStoppedWhenPrivacyProEnabled, frequency: .dailyAndContinuous)
defaults.vpnLegacyUserAccessDisabledOnce = true
await featureDisabler.disable(keepAuthToken: true, uninstallSystemExtension: false)
return true
Expand Down
12 changes: 8 additions & 4 deletions DuckDuckGo/Waitlist/Views/WaitlistThankYouPromptPresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

import AppKit
import Foundation
import PixelKit
import VPNPrivacyPro

final class WaitlistThankYouPromptPresenter {

Expand Down Expand Up @@ -53,23 +51,29 @@ final class WaitlistThankYouPromptPresenter {
// If the user tested both, the PIR prompt will be displayed.
@MainActor
func presentThankYouPromptIfNecessary(in window: NSWindow) {
// Wiring this here since it's mostly useful for rolling out PrivacyPro, and should
// go away once PPro is fully rolled out.
if NSApp.delegateTyped.subscriptionFeatureAvailability.isFeatureAvailable {
DailyPixel.fire(pixel: .privacyProEnabled, frequency: .dailyOnly)
}

guard canShowPromptCheck() else {
return
}

if isPIRBetaTester() {
saveDidShowPromptCheck()
Pixel.fire(Pixel.Event.privacyProBetaUserThankYouDBP, limitTo: .initial)
presentPIRThankYouPrompt(in: window)
} else if isVPNBetaTester() {
saveDidShowPromptCheck()
Pixel.fire(Pixel.Event.privacyProBetaUserThankYouVPN, limitTo: .initial)
presentVPNThankYouPrompt(in: window)
}
}

@MainActor
func presentVPNThankYouPrompt(in window: NSWindow) {
PixelKit.fire(VPNPrivacyProPixel.vpnBetaThankYouShown)

let thankYouModalView = WaitlistBetaThankYouDialogViewController(copy: .vpn)
let thankYouWindowController = thankYouModalView.wrappedInWindowController()
if let thankYouWindow = thankYouWindowController.window {
Expand Down
2 changes: 2 additions & 0 deletions DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import PixelKit

#if SUBSCRIPTION
import Subscription
import VPNPrivacyPro
#endif

@objc(Application)
Expand Down Expand Up @@ -376,6 +377,7 @@ final class DuckDuckGoVPNAppDelegate: NSObject, NSApplicationDelegate {
let isConnected = await self.tunnelController.isConnected
if isConnected {
await self.tunnelController.stop()
PixelKit.fire(VPNPrivacyProPixel.vpnAccessRevokedDialogShown, frequency: .dailyAndContinuous)
DistributedNotificationCenter.default().post(.showExpiredEntitlementNotification)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,20 @@ public enum VPNPrivacyProPixel: PixelKitEventV2 {
///
case vpnBetaStoppedWhenPrivacyProEnabled

/// Fired only once when the thank you alert is shown.
///
case vpnBetaThankYouShown

public var name: String {
switch self {
case .vpnAccessRevokedDialogShown:
return "vpn_access_revoked_dialog_shown"
case .vpnBetaStoppedWhenPrivacyProEnabled:
return "vpn_beta_stopped_when_privacy_pro_enabled"
case .vpnBetaThankYouShown:
return "privacy_pro_promotion_dialog_shown"
}
}

public var error: Error? {
nil
}

public var parameters: [String : String]? {
public var parameters: [String: String]? {
nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,5 @@ final class VPNPrivacyProPixelTests: XCTestCase {
and: .expect(pixelName: "m_mac_vpn_beta_stopped_when_privacy_pro_enabled"),
file: #filePath,
line: #line)
fire(VPNPrivacyProPixel.vpnBetaThankYouShown,
and: .expect(pixelName: "m_mac_privacy_pro_promotion_dialog_shown"),
file: #filePath,
line: #line)
}
}

0 comments on commit 0fdd141

Please sign in to comment.