From 52343e228da18fdc28d5adb6cd90cdfe48b1ce72 Mon Sep 17 00:00:00 2001 From: Christopher Brind Date: Thu, 12 Dec 2024 12:06:51 +0000 Subject: [PATCH] re-add settings pixels (#3716) Task/Issue URL: https://app.asana.com/0/392891325557410/1207818776591137/f Tech Design URL: CC: **Description**: Add pixels for various actions and views in settings. **Steps to test this PR**: 1. Go through the list of pixels in the linked Asana task and check they fire at the correct time 2. A pixel fired when a view is opened should not fire again if the user pops the stack back to that view 3. None of the pixels should have any addition parameters other than the default (ie app version) --- Core/PixelEvent.swift | 46 ++++++++++++++++++- .../AutoClearSettingsViewController.swift | 9 +++- DuckDuckGo/EmailProtectionView.swift | 8 +++- .../HomeRowInstructionsViewController.swift | 1 + DuckDuckGo/PrivateSearchView.swift | 3 ++ DuckDuckGo/SettingsAppearanceView.swift | 3 ++ DuckDuckGo/SettingsDataClearingView.swift | 3 ++ DuckDuckGo/SettingsGeneralView.swift | 3 ++ DuckDuckGo/SettingsViewModel.swift | 5 ++ DuckDuckGo/SyncSettingsViewController.swift | 5 ++ DuckDuckGo/WidgetEducationView.swift | 6 ++- 11 files changed, 88 insertions(+), 4 deletions(-) diff --git a/Core/PixelEvent.swift b/Core/PixelEvent.swift index 29eadee0f7..1ed63812bc 100644 --- a/Core/PixelEvent.swift +++ b/Core/PixelEvent.swift @@ -773,6 +773,8 @@ extension Pixel { // MARK: Pixel Experiment case pixelExperimentEnrollment + + // MARK: Settings case settingsPresented case settingsSetAsDefault case settingsVoiceSearchOn @@ -790,6 +792,26 @@ extension Pixel { case settingsAccessibilityOpen case settingsAccessiblityTextZoom + case settingsPrivateSearchOpen + case settingsEmailProtectionOpen + case settingsEmailProtectionEnable + case settingsGeneralOpen + case settingsSyncOpen + case settingsAppearanceOpen + case settingsThemeSelectorPressed + case settingsAddressBarTopSelected + case settingsAddressBarBottomSelected + case settingsShowFullURLOn + case settingsShowFullURLOff + case settingsDataClearingOpen + case settingsFireButtonSelectorPressed + case settingsDataClearingClearDataOpen + case settingsAutomaticallyClearDataOn + case settingsAutomaticallyClearDataOff + case settingsNextStepsAddAppToDock + case settingsNextStepsAddWidget + case settingsMoreSearchSettings + // Web pixels case privacyProOfferMonthlyPriceClick case privacyProOfferYearlyPriceClick @@ -970,7 +992,27 @@ extension Pixel.Event { case .settingsAutoconsentShown: return "m_settings_autoconsent_shown" case .settingsAutoconsentOn: return "m_settings_autoconsent_on" case .settingsAutoconsentOff: return "m_settings_autoconsent_off" - + + case .settingsPrivateSearchOpen: return "m_settings_private_search_open" + case .settingsEmailProtectionOpen: return "m_settings_email_protection_open" + case .settingsEmailProtectionEnable: return "m_settings_email_protection_enable" + case .settingsGeneralOpen: return "m_settings_general_open" + case .settingsSyncOpen: return "m_settings_sync_open" + case .settingsAppearanceOpen: return "m_settings_appearance_open" + case .settingsThemeSelectorPressed: return "m_settings_theme_selector_pressed" + case .settingsAddressBarTopSelected: return "m_settings_address_bar_top_selected" + case .settingsAddressBarBottomSelected: return "m_settings_address_bar_bottom_selected" + case .settingsShowFullURLOn: return "m_settings_show_full_url_on" + case .settingsShowFullURLOff: return "m_settings_show_full_url_off" + case .settingsDataClearingOpen: return "m_settings_data_clearing_open" + case .settingsFireButtonSelectorPressed: return "m_settings_fire_button_selector_pressed" + case .settingsDataClearingClearDataOpen: return "m_settings_data_clearing_clear_data_open" + case .settingsAutomaticallyClearDataOn: return "m_settings_automatically_clear_data_on" + case .settingsAutomaticallyClearDataOff: return "m_settings_automatically_clear_data_off" + case .settingsNextStepsAddAppToDock: return "m_settings_next_steps_add_app_to_dock" + case .settingsNextStepsAddWidget: return "m_settings_next_steps_add_widget" + case .settingsMoreSearchSettings: return "m_settings_more_search_settings" + case .browsingMenuOpened: return "mb" case .browsingMenuNewTab: return "mb_tb" case .browsingMenuAddToBookmarks: return "mb_abk" @@ -1673,6 +1715,8 @@ extension Pixel.Event { // MARK: Pixel Experiment case .pixelExperimentEnrollment: return "pixel_experiment_enrollment" + + // MARK: Settings case .settingsPresented: return "m_settings_presented" case .settingsSetAsDefault: return "m_settings_set_as_default" case .settingsVoiceSearchOn: return "m_settings_voice_search_on" diff --git a/DuckDuckGo/AutoClearSettingsViewController.swift b/DuckDuckGo/AutoClearSettingsViewController.swift index 14c4178ac0..a5c4eb934a 100644 --- a/DuckDuckGo/AutoClearSettingsViewController.swift +++ b/DuckDuckGo/AutoClearSettingsViewController.swift @@ -55,7 +55,12 @@ class AutoClearSettingsViewController: UITableViewController { decorate() } - + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + Pixel.fire(pixel: .settingsDataClearingClearDataOpen) + } + private func loadClearDataSettings() -> AutoClearSettingsModel? { return AutoClearSettingsModel(settings: appSettings) } @@ -152,6 +157,8 @@ class AutoClearSettingsViewController: UITableViewController { } @IBAction func onClearDataToggled(_ sender: UISwitch) { + Pixel.fire(pixel: sender.isOn ? .settingsAutomaticallyClearDataOn : .settingsAutomaticallyClearDataOff) + if sender.isOn { clearDataSettings = AutoClearSettingsModel() tableView.insertSections(.init(integersIn: Sections.action.rawValue...Sections.timing.rawValue), with: .fade) diff --git a/DuckDuckGo/EmailProtectionView.swift b/DuckDuckGo/EmailProtectionView.swift index 022d4f4b3a..f20fc29f89 100644 --- a/DuckDuckGo/EmailProtectionView.swift +++ b/DuckDuckGo/EmailProtectionView.swift @@ -56,6 +56,9 @@ struct EmailProtectionView: View { .onChange(of: viewModel.shouldShowEmailAlert) { value in shouldShowEmailAlert = value } + .onFirstAppear { + Pixel.fire(pixel: .settingsEmailProtectionOpen) + } } } @@ -90,7 +93,10 @@ struct EmailProtectionViewSettings: View { // Enable Email Protection Section { SettingsCellView(label: UserText.enableEmailProtection, - action: { viewModel.openEmailProtection() }, + action: { + viewModel.openEmailProtection() + Pixel.fire(pixel: .settingsEmailProtectionEnable) + }, webLinkIndicator: true, isButton: true) } diff --git a/DuckDuckGo/HomeRowInstructionsViewController.swift b/DuckDuckGo/HomeRowInstructionsViewController.swift index 20356827a9..d40b4a2383 100644 --- a/DuckDuckGo/HomeRowInstructionsViewController.swift +++ b/DuckDuckGo/HomeRowInstructionsViewController.swift @@ -60,6 +60,7 @@ class HomeRowInstructionsViewController: UIViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) HomeRowReminder().setShown() + Pixel.fire(pixel: .settingsNextStepsAddAppToDock) } @IBAction func dismiss() { diff --git a/DuckDuckGo/PrivateSearchView.swift b/DuckDuckGo/PrivateSearchView.swift index 43190bb81e..cf00930e85 100644 --- a/DuckDuckGo/PrivateSearchView.swift +++ b/DuckDuckGo/PrivateSearchView.swift @@ -40,6 +40,9 @@ struct PrivateSearchView: View { .applySettingsListModifiers(title: UserText.privateSearch, displayMode: .inline, viewModel: viewModel) + .onFirstAppear { + Pixel.fire(pixel: .settingsPrivateSearchOpen) + } } } diff --git a/DuckDuckGo/SettingsAppearanceView.swift b/DuckDuckGo/SettingsAppearanceView.swift index e29a2d2169..2a1dfcd4ae 100644 --- a/DuckDuckGo/SettingsAppearanceView.swift +++ b/DuckDuckGo/SettingsAppearanceView.swift @@ -58,5 +58,8 @@ struct SettingsAppearanceView: View { .applySettingsListModifiers(title: UserText.settingsAppearanceSection, displayMode: .inline, viewModel: viewModel) + .onFirstAppear { + Pixel.fire(pixel: .settingsAppearanceOpen) + } } } diff --git a/DuckDuckGo/SettingsDataClearingView.swift b/DuckDuckGo/SettingsDataClearingView.swift index 5a73902537..5054381edc 100644 --- a/DuckDuckGo/SettingsDataClearingView.swift +++ b/DuckDuckGo/SettingsDataClearingView.swift @@ -54,5 +54,8 @@ struct SettingsDataClearingView: View { .applySettingsListModifiers(title: UserText.dataClearing, displayMode: .inline, viewModel: viewModel) + .onFirstAppear { + Pixel.fire(pixel: .settingsDataClearingOpen) + } } } diff --git a/DuckDuckGo/SettingsGeneralView.swift b/DuckDuckGo/SettingsGeneralView.swift index 427ec3bfc3..115c88a0fb 100644 --- a/DuckDuckGo/SettingsGeneralView.swift +++ b/DuckDuckGo/SettingsGeneralView.swift @@ -89,5 +89,8 @@ struct SettingsGeneralView: View { .applySettingsListModifiers(title: UserText.general, displayMode: .inline, viewModel: viewModel) + .onFirstAppear { + Pixel.fire(pixel: .settingsGeneralOpen) + } } } diff --git a/DuckDuckGo/SettingsViewModel.swift b/DuckDuckGo/SettingsViewModel.swift index 6808303d43..cfdc9ae43c 100644 --- a/DuckDuckGo/SettingsViewModel.swift +++ b/DuckDuckGo/SettingsViewModel.swift @@ -109,6 +109,7 @@ final class SettingsViewModel: ObservableObject { Binding( get: { self.state.appTheme }, set: { + Pixel.fire(pixel: .settingsThemeSelectorPressed) self.state.appTheme = $0 ThemeManager.shared.enableTheme(with: $0) } @@ -118,6 +119,7 @@ final class SettingsViewModel: ObservableObject { Binding( get: { self.state.fireButtonAnimation }, set: { + Pixel.fire(pixel: .settingsFireButtonSelectorPressed) self.appSettings.currentFireButtonAnimation = $0 self.state.fireButtonAnimation = $0 NotificationCenter.default.post(name: AppUserDefaults.Notifications.currentFireButtonAnimationChange, object: self) @@ -138,6 +140,7 @@ final class SettingsViewModel: ObservableObject { self.state.addressBar.position }, set: { + Pixel.fire(pixel: $0 == .top ? .settingsAddressBarTopSelected : .settingsAddressBarBottomSelected) self.appSettings.currentAddressBarPosition = $0 self.state.addressBar.position = $0 } @@ -148,6 +151,7 @@ final class SettingsViewModel: ObservableObject { Binding( get: { self.state.showsFullURL }, set: { + Pixel.fire(pixel: $0 ? .settingsShowFullURLOn : .settingsShowFullURLOff) self.state.showsFullURL = $0 self.appSettings.showFullSiteAddress = $0 } @@ -598,6 +602,7 @@ extension SettingsViewModel { } func openMoreSearchSettings() { + Pixel.fire(pixel: .settingsMoreSearchSettings) UIApplication.shared.open(URL.searchSettings) } diff --git a/DuckDuckGo/SyncSettingsViewController.swift b/DuckDuckGo/SyncSettingsViewController.swift index c71fc4d0f9..925b291897 100644 --- a/DuckDuckGo/SyncSettingsViewController.swift +++ b/DuckDuckGo/SyncSettingsViewController.swift @@ -244,6 +244,11 @@ class SyncSettingsViewController: UIHostingController { syncService.scheduler.requestSyncImmediately() } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + Pixel.fire(pixel: .settingsSyncOpen) + } + func updateOptions() { syncService.scheduler.requestSyncImmediately() } diff --git a/DuckDuckGo/WidgetEducationView.swift b/DuckDuckGo/WidgetEducationView.swift index b4bbca2e2c..81095e78b8 100644 --- a/DuckDuckGo/WidgetEducationView.swift +++ b/DuckDuckGo/WidgetEducationView.swift @@ -72,7 +72,11 @@ struct WidgetEducationView: View { .padding(.horizontal) .padding(.top, Const.Padding.top) } - }.navigationBarTitle(navBarTitle, displayMode: .inline) + } + .navigationBarTitle(navBarTitle, displayMode: .inline) + .onFirstAppear { + Pixel.fire(pixel: .settingsNextStepsAddWidget) + } } private var secondParagraphText: Text {