Skip to content

Commit

Permalink
Experiment Contextual onboarding (#3160)
Browse files Browse the repository at this point in the history
Task/Issue URL: https://app.asana.com/0/72649045549333/1207585462837397/f

**Description**:
Add an experiment to show a contextual onboarding.
  • Loading branch information
alessandroboron authored Aug 5, 2024
1 parent 2f0187f commit ba79715
Show file tree
Hide file tree
Showing 124 changed files with 8,760 additions and 349 deletions.
4 changes: 4 additions & 0 deletions Core/Pixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ public struct PixelParameters {

// Autofill
public static let countBucket = "count_bucket"

// Privacy Dashboard
public static let daysSinceInstall = "daysSinceInstall"
public static let fromOnboarding = "from_onboarding"
}

public struct PixelValues {
Expand Down
68 changes: 44 additions & 24 deletions Core/PixelEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ extension Pixel {
case forgetAllDataCleared

case privacyDashboardOpened

case privacyDashboardFirstTimeOpenedUnique

case dashboardProtectionAllowlistAdd
case dashboardProtectionAllowlistRemove

Expand Down Expand Up @@ -142,18 +143,27 @@ extension Pixel {
case onboardingIntroShownUnique
case onboardingIntroComparisonChartShownUnique
case onboardingIntroChooseBrowserCTAPressed

case daxDialogsSerp
case daxDialogsWithoutTrackers
case onboardingContextualSearchOptionTappedUnique
case onboardingContextualSearchCustomUnique
case onboardingContextualSiteOptionTappedUnique
case onboardingContextualSiteCustomUnique
case onboardingContextualSecondSiteVisitUnique
case onboardingContextualTrySearchUnique
case onboardingContextualTryVisitSiteUnique

case daxDialogsSerpUnique
case daxDialogsWithoutTrackersUnique
case daxDialogsWithoutTrackersFollowUp
case daxDialogsWithTrackers
case daxDialogsSiteIsMajor
case daxDialogsSiteOwnedByMajor
case daxDialogsHidden
case daxDialogsFireEducationShown
case daxDialogsFireEducationConfirmed
case daxDialogsFireEducationCancelled

case daxDialogsWithTrackersUnique
case daxDialogsSiteIsMajorUnique
case daxDialogsSiteOwnedByMajorUnique
case daxDialogsHiddenUnique
case daxDialogsFireEducationShownUnique
case daxDialogsFireEducationConfirmedUnique
case daxDialogsFireEducationCancelledUnique
case daxDialogsEndOfJourneyTabUnique
case daxDialogsEndOfJourneyNewTabUnique

case widgetsOnboardingCTAPressed
case widgetsOnboardingDeclineOptionPressed
case widgetsOnboardingMovedToBackground
Expand Down Expand Up @@ -759,7 +769,8 @@ extension Pixel.Event {
case .forgetAllDataCleared: return "mf_dc"

case .privacyDashboardOpened: return "mp"

case .privacyDashboardFirstTimeOpenedUnique: return "m_privacy_dashboard_first_time_used_unique"

case .dashboardProtectionAllowlistAdd: return "mp_wla"
case .dashboardProtectionAllowlistRemove: return "mp_wlr"

Expand Down Expand Up @@ -865,18 +876,27 @@ extension Pixel.Event {
case .onboardingIntroShownUnique: return "m_preonboarding_intro_shown_unique"
case .onboardingIntroComparisonChartShownUnique: return "m_preonboarding_comparison_chart_shown_unique"
case .onboardingIntroChooseBrowserCTAPressed: return "m_preonboarding_choose_browser_pressed"

case .daxDialogsSerp: return "m_dx_s"
case .daxDialogsWithoutTrackers: return "m_dx_wo"
case .onboardingContextualSearchOptionTappedUnique: return "m_onboarding_search_option_tapped_unique"
case .onboardingContextualSiteOptionTappedUnique: return "m_onboarding_visit_site_option_tapped_unique"
case .onboardingContextualSecondSiteVisitUnique: return "m_second_sitevisit_unique"
case .onboardingContextualSearchCustomUnique: return "m_onboarding_search_custom_unique"
case .onboardingContextualSiteCustomUnique: return "m_onboarding_visit_site_custom_unique"
case .onboardingContextualTrySearchUnique: return "m_dx_try_a_search_unique"
case .onboardingContextualTryVisitSiteUnique: return "m_dx_try_visit_site_unique"

case .daxDialogsSerpUnique: return "m_dx_s_unique"
case .daxDialogsWithoutTrackersUnique: return "m_dx_wo_unique"
case .daxDialogsWithoutTrackersFollowUp: return "m_dx_wof"
case .daxDialogsWithTrackers: return "m_dx_wt"
case .daxDialogsSiteIsMajor: return "m_dx_sm"
case .daxDialogsSiteOwnedByMajor: return "m_dx_so"
case .daxDialogsHidden: return "m_dx_h"
case .daxDialogsFireEducationShown: return "m_dx_fe_s"
case .daxDialogsFireEducationConfirmed: return "m_dx_fe_co"
case .daxDialogsFireEducationCancelled: return "m_dx_fe_ca"

case .daxDialogsWithTrackersUnique: return "m_dx_wt_unique"
case .daxDialogsSiteIsMajorUnique: return "m_dx_sm_unique"
case .daxDialogsSiteOwnedByMajorUnique: return "m_dx_so_unique"
case .daxDialogsHiddenUnique: return "m_dx_h_unique"
case .daxDialogsFireEducationShownUnique: return "m_dx_fe_s_unique"
case .daxDialogsFireEducationConfirmedUnique: return "m_dx_fe_co_unique"
case .daxDialogsFireEducationCancelledUnique: return "m_dx_fe_ca_unique"
case .daxDialogsEndOfJourneyTabUnique: return "m_dx_end_tab_unique"
case .daxDialogsEndOfJourneyNewTabUnique: return "m_dx_end_new_tab_unique"

case .widgetsOnboardingCTAPressed: return "m_o_w_a"
case .widgetsOnboardingDeclineOptionPressed: return "m_o_w_d"
case .widgetsOnboardingMovedToBackground: return "m_o_w_b"
Expand Down
16 changes: 13 additions & 3 deletions Core/TimerInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,25 @@ public protocol TimerInterface: AnyObject {
extension Timer: TimerInterface {}

public protocol TimerCreating: AnyObject {
func makeTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @escaping @Sendable (TimerInterface) -> Void) -> TimerInterface
func makeTimer(withTimeInterval interval: TimeInterval, repeats: Bool, on runLoop: RunLoop, block: @escaping @Sendable (TimerInterface) -> Void) -> TimerInterface
}

public extension TimerCreating {

func makeTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @escaping @Sendable (TimerInterface) -> Void) -> TimerInterface {
makeTimer(withTimeInterval: interval, repeats: repeats, on: .main, block: block)
}

}

public final class TimerFactory: TimerCreating {

public init() {}

public func makeTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @escaping @Sendable (TimerInterface) -> Void) -> TimerInterface {
Timer.scheduledTimer(withTimeInterval: interval, repeats: repeats, block: block)
public func makeTimer(withTimeInterval interval: TimeInterval, repeats: Bool, on runLoop: RunLoop, block: @escaping @Sendable (TimerInterface) -> Void) -> TimerInterface {
let timer = Timer(timeInterval: interval, repeats: repeats, block: block)
runLoop.add(timer, forMode: .common)
return timer
}

}
5 changes: 5 additions & 0 deletions Core/UserDefaultsPropertyWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@ public struct UserDefaultsWrapper<T> {
case daxBrowsingMajorTrackingSiteShown = "com.duckduckgo.ios.daxOnboardingBrowsingMajorTrackingSiteShown"
case daxBrowsingOwnedByMajorTrackingSiteShown = "com.duckduckgo.ios.daxOnboardingBrowsingOwnedByMajorTrackingSiteShown"
case daxFireButtonEducationShownOrExpired = "com.duckduckgo.ios.daxfireButtonEducationShownOrExpired"
case daxFireMessageExperimentShown = "com.duckduckgo.ios.fireMessageShown"
case fireButtonPulseDateShown = "com.duckduckgo.ios.fireButtonPulseDateShown"
case privacyButtonPulseShown = "com.duckduckgo.ios.privacyButtonPulseShown"
case daxBrowsingFinalDialogShown = "com.duckduckgo.ios.daxOnboardingFinalDialogSeen"
case daxLastVisitedOnboardingWebsite = "com.duckduckgo.ios.daxOnboardingLastVisitedWebsite"
case daxLastShownContextualOnboardingDialogType = "com.duckduckgo.ios.daxLastShownContextualOnboardingDialogType"

case notFoundCache = "com.duckduckgo.ios.favicons.notFoundCache"
case faviconSizeNeedsMigration = "com.duckduckgo.ios.favicons.sizeNeedsMigration"
Expand Down
Loading

0 comments on commit ba79715

Please sign in to comment.