Skip to content

Commit

Permalink
Alessandro/onboarding copy and private search options (#3349)
Browse files Browse the repository at this point in the history
Task/Issue URL: https://app.asana.com/0/72649045549333/1208241563982253

**Description**:
1. Remove anonymous searches Option 3 for Highlights experiment.
2. Update anonymous search Surprise Me to search for “baby ducklings” for both US and International.
3. Update copy throughout the App for Highlights experiment.
  • Loading branch information
alessandroboron authored Sep 12, 2024
1 parent 29e2b79 commit e4e52c2
Show file tree
Hide file tree
Showing 15 changed files with 436 additions and 42 deletions.
12 changes: 12 additions & 0 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,9 @@
9FDEC7BC2C91204900C7A692 /* AppIconPickerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7BB2C91204900C7A692 /* AppIconPickerViewModel.swift */; };
9FDEC7BF2C91264C00C7A692 /* OnboardingAddressBarPositionPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7BE2C91264C00C7A692 /* OnboardingAddressBarPositionPicker.swift */; };
9FDEC7C12C9127F100C7A692 /* OnboardingAddressBarPositionPickerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7C02C9127F100C7A692 /* OnboardingAddressBarPositionPickerViewModel.swift */; };
9FDEC7B62C8FDFD600C7A692 /* OnboardingManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7B52C8FDFD600C7A692 /* OnboardingManagerMock.swift */; };
9FDEC7B82C9004D600C7A692 /* OnboardingIntroViewModel+Copy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7B72C9004D600C7A692 /* OnboardingIntroViewModel+Copy.swift */; };
9FDEC7BA2C9006E000C7A692 /* BrowserComparisonModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7B92C9006E000C7A692 /* BrowserComparisonModelTests.swift */; };
9FE05CEE2C36424E00D9046B /* OnboardingPixelReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FE05CED2C36424E00D9046B /* OnboardingPixelReporter.swift */; };
9FE05CF12C36468A00D9046B /* OnboardingPixelReporterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FE05CEF2C3642F900D9046B /* OnboardingPixelReporterTests.swift */; };
9FE08BD32C2A5B88001D5EBC /* OnboardingTextStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FE08BD22C2A5B88001D5EBC /* OnboardingTextStyles.swift */; };
Expand Down Expand Up @@ -2509,6 +2512,9 @@
9FDEC7BB2C91204900C7A692 /* AppIconPickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIconPickerViewModel.swift; sourceTree = "<group>"; };
9FDEC7BE2C91264C00C7A692 /* OnboardingAddressBarPositionPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingAddressBarPositionPicker.swift; sourceTree = "<group>"; };
9FDEC7C02C9127F100C7A692 /* OnboardingAddressBarPositionPickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingAddressBarPositionPickerViewModel.swift; sourceTree = "<group>"; };
9FDEC7B52C8FDFD600C7A692 /* OnboardingManagerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingManagerMock.swift; sourceTree = "<group>"; };
9FDEC7B72C9004D600C7A692 /* OnboardingIntroViewModel+Copy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OnboardingIntroViewModel+Copy.swift"; sourceTree = "<group>"; };
9FDEC7B92C9006E000C7A692 /* BrowserComparisonModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserComparisonModelTests.swift; sourceTree = "<group>"; };
9FE05CED2C36424E00D9046B /* OnboardingPixelReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingPixelReporter.swift; sourceTree = "<group>"; };
9FE05CEF2C3642F900D9046B /* OnboardingPixelReporterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingPixelReporterTests.swift; sourceTree = "<group>"; };
9FE08BD22C2A5B88001D5EBC /* OnboardingTextStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingTextStyles.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4674,6 +4680,7 @@
children = (
9FE08BDB2C2A88FA001D5EBC /* OnboardingIntroViewController.swift */,
9FB0271C2C293619009EA190 /* OnboardingIntroViewModel.swift */,
9FDEC7B72C9004D600C7A692 /* OnboardingIntroViewModel+Copy.swift */,
9FB0271A2C2927D0009EA190 /* OnboardingView.swift */,
9F9EE4D32C37BB1300D4118E /* OnboardingView+Landing.swift */,
9FB027112C2526DD009EA190 /* OnboardingView+IntroDialogContent.swift */,
Expand All @@ -4700,6 +4707,7 @@
9F7CFF772C86E3E10012833E /* OnboardingManagerTests.swift */,
9F7CFF7C2C89B69A0012833E /* AppIconPickerViewModelTests.swift */,
9FDEC7B32C8FD62F00C7A692 /* OnboardingAddressBarPositionPickerViewModelTests.swift */,
9FDEC7B92C9006E000C7A692 /* BrowserComparisonModelTests.swift */,
);
name = Onboarding;
sourceTree = "<group>";
Expand Down Expand Up @@ -4753,6 +4761,7 @@
9F4CC5142C47AD08006A96EB /* ContextualOnboardingPresenterMock.swift */,
9F6933182C59BB0300CD6A5D /* OnboardingPixelReporterMock.swift */,
9F6933202C5B9A5B00CD6A5D /* OnboardingHostingControllerMock.swift */,
9FDEC7B52C8FDFD600C7A692 /* OnboardingManagerMock.swift */,
);
name = Mocks;
sourceTree = "<group>";
Expand Down Expand Up @@ -7666,6 +7675,7 @@
F1617C191E573EA800DEDCAF /* TabSwitcherDelegate.swift in Sources */,
4B5C462A2AF2A6E6002A4432 /* VPNIntents.swift in Sources */,
310742A62848CD780012660B /* BackForwardMenuHistoryItem.swift in Sources */,
9FDEC7B82C9004D600C7A692 /* OnboardingIntroViewModel+Copy.swift in Sources */,
858566FB252E55D6007501B8 /* ImageCacheDebugViewController.swift in Sources */,
D6E0C1832B7A2B1E00D5E1E9 /* DesktopDownloadView.swift in Sources */,
1E7A71172934EB6400B7EA19 /* OmniBarNotificationAnimator.swift in Sources */,
Expand Down Expand Up @@ -7849,7 +7859,9 @@
1E1D8B5D2994FFE100C96994 /* AutoconsentMessageProtocolTests.swift in Sources */,
85C11E532090B23A00BFFEB4 /* UserDefaultsHomeRowReminderStorageTests.swift in Sources */,
F1DA2F7D1EBCF23700313F51 /* ExternalUrlSchemeTests.swift in Sources */,
9FDEC7B62C8FDFD600C7A692 /* OnboardingManagerMock.swift in Sources */,
F198D78E1E39762C0088DA8A /* StringExtensionTests.swift in Sources */,
9FDEC7BA2C9006E000C7A692 /* BrowserComparisonModelTests.swift in Sources */,
31B1FA87286EFC5C00CA3C1C /* XCTestCaseExtension.swift in Sources */,
D62EC3BC2C2470E000FC9D04 /* DuckPlayerTests.swift in Sources */,
1E8146AE28C8ABF400D1AF63 /* PrivacyIconLogicTests.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,28 @@ extension BrowsersComparisonModel.PrivacyFeature {
case blockCreepyAds
case eraseBrowsingData

// Remove it once Highlights experiment finishes
static var onboardingManager: OnboardingHighlightsManaging = OnboardingManager()

var title: String {
switch self {
case .privateSearch:
UserText.DaxOnboardingExperiment.BrowsersComparison.Features.privateSearch
case .blockThirdPartyTrackers:
Self.onboardingManager.isOnboardingHighlightsEnabled ?
UserText.HighlightsOnboardingExperiment.BrowsersComparison.Features.trackerBlockers :
UserText.DaxOnboardingExperiment.BrowsersComparison.Features.trackerBlockers
case .blockCookiePopups:
Self.onboardingManager.isOnboardingHighlightsEnabled ?
UserText.HighlightsOnboardingExperiment.BrowsersComparison.Features.cookiePopups:
UserText.DaxOnboardingExperiment.BrowsersComparison.Features.cookiePopups
case .blockCreepyAds:
Self.onboardingManager.isOnboardingHighlightsEnabled ?
UserText.HighlightsOnboardingExperiment.BrowsersComparison.Features.creepyAds :
UserText.DaxOnboardingExperiment.BrowsersComparison.Features.creepyAds
case .eraseBrowsingData:
Self.onboardingManager.isOnboardingHighlightsEnabled ?
UserText.HighlightsOnboardingExperiment.BrowsersComparison.Features.eraseBrowsingData:
UserText.DaxOnboardingExperiment.BrowsersComparison.Features.eraseBrowsingData
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import DuckUI

struct OnboardingTrySearchDialog: View {
let title = UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingTryASearchTitle
let message = NSAttributedString(string: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingTryASearchMessage)
let message: String
let viewModel: OnboardingSearchSuggestionsViewModel

var body: some View {
Expand All @@ -33,7 +33,7 @@ struct OnboardingTrySearchDialog: View {
ContextualDaxDialogContent(
title: title,
titleFont: Font(UIFont.daxTitle3()),
message: message,
message: NSAttributedString(string: message),
list: viewModel.itemsList,
listAction: viewModel.listItemPressed
)
Expand Down Expand Up @@ -95,8 +95,8 @@ struct OnboardingFireButtonDialogContent: View {
}

struct OnboardingFirstSearchDoneDialog: View {
let message = NSAttributedString(string: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFirstSearchDoneMessage)
let cta = UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingGotItButton
let message: String

@State private var showNextScreen: Bool = false

Expand All @@ -112,7 +112,7 @@ struct OnboardingFirstSearchDoneDialog: View {
OnboardingTryVisitingSiteDialogContent(viewModel: viewModel)
} else {
ContextualDaxDialogContent(
message: message,
message: NSAttributedString(string: message),
customActionView: AnyView(
OnboardingCTAButton(title: cta) {
gotItAction()
Expand Down Expand Up @@ -185,7 +185,7 @@ struct OnboardingTrackersDoneDialog: View {

struct OnboardingFinalDialog: View {
let title = UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFinalScreenTitle
let message = NSAttributedString(string: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFinalScreenMessage)
let message: String
let cta = UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFinalScreenButton

let highFiveAction: () -> Void
Expand All @@ -196,7 +196,7 @@ struct OnboardingFinalDialog: View {
ContextualDaxDialogContent(
title: title,
titleFont: Font(UIFont.daxTitle3()),
message: message,
message: NSAttributedString(string: message),
customActionView: AnyView(
OnboardingCTAButton(
title: cta,
Expand Down Expand Up @@ -226,7 +226,7 @@ struct OnboardingCTAButton: View {
// MARK: - Preview

#Preview("Try Search") {
OnboardingTrySearchDialog(viewModel: OnboardingSearchSuggestionsViewModel(suggestedSearchesProvider: OnboardingSuggestedSearchesProvider(), pixelReporter: OnboardingPixelReporter()))
OnboardingTrySearchDialog(message: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingTryASearchMessage, viewModel: OnboardingSearchSuggestionsViewModel(suggestedSearchesProvider: OnboardingSuggestedSearchesProvider(), pixelReporter: OnboardingPixelReporter()))
.padding()
}

Expand All @@ -248,12 +248,12 @@ struct OnboardingCTAButton: View {
}

#Preview("First Search Dialog") {
OnboardingFirstSearchDoneDialog(shouldFollowUp: true, viewModel: OnboardingSiteSuggestionsViewModel(title: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingTryASiteTitle, suggestedSitesProvider: OnboardingSuggestedSitesProvider(surpriseItemTitle: UserText.DaxOnboardingExperiment.ContextualOnboarding.tryASearchOptionSurpriseMeTitle), pixelReporter: OnboardingPixelReporter()), gotItAction: {})
OnboardingFirstSearchDoneDialog(message: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFirstSearchDoneMessage, shouldFollowUp: true, viewModel: OnboardingSiteSuggestionsViewModel(title: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingTryASiteTitle, suggestedSitesProvider: OnboardingSuggestedSitesProvider(surpriseItemTitle: UserText.DaxOnboardingExperiment.ContextualOnboarding.tryASearchOptionSurpriseMeTitle), pixelReporter: OnboardingPixelReporter()), gotItAction: {})
.padding()
}

#Preview("Final Dialog") {
OnboardingFinalDialog(highFiveAction: {})
OnboardingFinalDialog(message: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFinalScreenMessage, highFiveAction: {})
.padding()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@ final class NewTabDaxDialogFactory: NewTabDaxDialogProvider {
private var delegate: OnboardingNavigationDelegate?
private let contextualOnboardingLogic: ContextualOnboardingLogic
private let onboardingPixelReporter: OnboardingPixelReporting
private let onboardingManager: OnboardingHighlightsManaging

init(
delegate: OnboardingNavigationDelegate?,
contextualOnboardingLogic: ContextualOnboardingLogic,
onboardingPixelReporter: OnboardingPixelReporting
onboardingPixelReporter: OnboardingPixelReporting,
onboardingManager: OnboardingHighlightsManaging = OnboardingManager()
) {
self.delegate = delegate
self.contextualOnboardingLogic = contextualOnboardingLogic
self.onboardingPixelReporter = onboardingPixelReporter
self.onboardingManager = onboardingManager
}

@ViewBuilder
Expand All @@ -60,8 +63,9 @@ final class NewTabDaxDialogFactory: NewTabDaxDialogProvider {

private func createInitialDialog() -> some View {
let viewModel = OnboardingSearchSuggestionsViewModel(suggestedSearchesProvider: OnboardingSuggestedSearchesProvider(), delegate: delegate, pixelReporter: onboardingPixelReporter)
let message = onboardingManager.isOnboardingHighlightsEnabled ? UserText.HighlightsOnboardingExperiment.ContextualOnboarding.onboardingTryASearchMessage : UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingTryASearchMessage
return FadeInView {
OnboardingTrySearchDialog(viewModel: viewModel)
OnboardingTrySearchDialog(message: message, viewModel: viewModel)
.onboardingDaxDialogStyle()
}
.onboardingContextualBackgroundStyle()
Expand Down Expand Up @@ -92,8 +96,10 @@ final class NewTabDaxDialogFactory: NewTabDaxDialogProvider {
}

private func createFinalDialog(onDismiss: @escaping () -> Void) -> some View {
FadeInView {
OnboardingFinalDialog(highFiveAction: {
let message = onboardingManager.isOnboardingHighlightsEnabled ? UserText.HighlightsOnboardingExperiment.ContextualOnboarding.onboardingFinalScreenMessage : UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFinalScreenMessage

return FadeInView {
OnboardingFinalDialog(message: message, highFiveAction: {
onDismiss()
})
.onboardingDaxDialogStyle()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,20 @@ final class ExperimentContextualDaxDialogsFactory: ContextualDaxDialogsFactory {
private let contextualOnboardingSettings: ContextualOnboardingSettings
private let contextualOnboardingPixelReporter: OnboardingPixelReporting
private let contextualOnboardingSiteSuggestionsProvider: OnboardingSuggestionsItemsProviding
private let onboardingManager: OnboardingHighlightsManaging

init(
contextualOnboardingLogic: ContextualOnboardingLogic,
contextualOnboardingSettings: ContextualOnboardingSettings = DefaultDaxDialogsSettings(),
contextualOnboardingPixelReporter: OnboardingPixelReporting,
contextualOnboardingSiteSuggestionsProvider: OnboardingSuggestionsItemsProviding = OnboardingSuggestedSitesProvider(surpriseItemTitle: UserText.DaxOnboardingExperiment.ContextualOnboarding.tryASearchOptionSurpriseMeTitle)
contextualOnboardingSiteSuggestionsProvider: OnboardingSuggestionsItemsProviding = OnboardingSuggestedSitesProvider(surpriseItemTitle: UserText.DaxOnboardingExperiment.ContextualOnboarding.tryASearchOptionSurpriseMeTitle),
onboardingManager: OnboardingHighlightsManaging = OnboardingManager()
) {
self.contextualOnboardingSettings = contextualOnboardingSettings
self.contextualOnboardingLogic = contextualOnboardingLogic
self.contextualOnboardingPixelReporter = contextualOnboardingPixelReporter
self.contextualOnboardingSiteSuggestionsProvider = contextualOnboardingSiteSuggestionsProvider
self.onboardingManager = onboardingManager
}

func makeView(for spec: DaxDialogs.BrowsingSpec, delegate: ContextualOnboardingDelegate, onSizeUpdate: @escaping () -> Void) -> UIHostingController<AnyView> {
Expand Down Expand Up @@ -122,7 +125,9 @@ final class ExperimentContextualDaxDialogsFactory: ContextualDaxDialogsFactory {
}
}

return OnboardingFirstSearchDoneDialog(shouldFollowUp: shouldFollowUpToWebsiteSearch, viewModel: viewModel, gotItAction: gotItAction)
let message = onboardingManager.isOnboardingHighlightsEnabled ? UserText.HighlightsOnboardingExperiment.ContextualOnboarding.onboardingFirstSearchDoneMessage : UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFirstSearchDoneMessage

return OnboardingFirstSearchDoneDialog(message: message, shouldFollowUp: shouldFollowUpToWebsiteSearch, viewModel: viewModel, gotItAction: gotItAction)
.onFirstAppear { [weak self] in
self?.contextualOnboardingPixelReporter.trackScreenImpression(event: afterSearchPixelEvent)
}
Expand Down Expand Up @@ -164,7 +169,9 @@ final class ExperimentContextualDaxDialogsFactory: ContextualDaxDialogsFactory {
}

private func endOfJourneyDialog(delegate: ContextualOnboardingDelegate, pixelName: Pixel.Event) -> some View {
OnboardingFinalDialog(highFiveAction: { [weak delegate] in
let message = onboardingManager.isOnboardingHighlightsEnabled ? UserText.HighlightsOnboardingExperiment.ContextualOnboarding.onboardingFinalScreenMessage : UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFinalScreenMessage

return OnboardingFinalDialog(message: message, highFiveAction: { [weak delegate] in
delegate?.didTapDismissContextualOnboardingAction()
})
.onFirstAppear { [weak self] in
Expand Down
Loading

0 comments on commit e4e52c2

Please sign in to comment.