From 6ca34d51367c7fcf4a983e635fb859ced1c2ed36 Mon Sep 17 00:00:00 2001 From: Chris Brind Date: Mon, 9 Dec 2024 16:20:52 +0000 Subject: [PATCH 1/7] add settings pixels definitions and start of firing implementations --- Core/PixelEvent.swift | 43 +++++++++++++++++++++++++++- DuckDuckGo/EmailProtectionView.swift | 8 +++++- DuckDuckGo/PrivateSearchView.swift | 3 ++ DuckDuckGo/SettingsGeneralView.swift | 3 ++ 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/Core/PixelEvent.swift b/Core/PixelEvent.swift index 48d2f36ac4..603e0d48e5 100644 --- a/Core/PixelEvent.swift +++ b/Core/PixelEvent.swift @@ -759,6 +759,8 @@ extension Pixel { // MARK: Pixel Experiment case pixelExperimentEnrollment + + // MARK: Settings case settingsPresented case settingsSetAsDefault case settingsVoiceSearchOn @@ -775,6 +777,25 @@ extension Pixel { case settingsAddressBarSelectorPressed 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 @@ -956,7 +977,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" 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/PrivateSearchView.swift b/DuckDuckGo/PrivateSearchView.swift index 43190bb81e..6a8f5797d4 100644 --- a/DuckDuckGo/PrivateSearchView.swift +++ b/DuckDuckGo/PrivateSearchView.swift @@ -69,6 +69,9 @@ struct PrivateSearchViewSettings: View { webLinkIndicator: true, isButton: true) } + .onFirstAppear { + Pixel.fire(pixel: .settingsPrivateSearchOpen) + } } } 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) + } } } From 5a7d079753cad8ab12e254a8314c7b387ef5a045 Mon Sep 17 00:00:00 2001 From: Chris Brind Date: Tue, 10 Dec 2024 14:39:59 +0000 Subject: [PATCH 2/7] nearly all pixels --- Core/PixelEvent.swift | 5 +++++ DuckDuckGo/HomeRowInstructionsViewController.swift | 1 + DuckDuckGo/SettingsAppearanceView.swift | 3 +++ DuckDuckGo/SettingsDataClearingView.swift | 3 +++ DuckDuckGo/SettingsViewModel.swift | 5 +++++ DuckDuckGo/SyncSettingsViewController.swift | 5 +++++ DuckDuckGo/WidgetEducationView.swift | 6 +++++- 7 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Core/PixelEvent.swift b/Core/PixelEvent.swift index 603e0d48e5..829d66a2b7 100644 --- a/Core/PixelEvent.swift +++ b/Core/PixelEvent.swift @@ -777,6 +777,8 @@ extension Pixel { case settingsAddressBarSelectorPressed case settingsAccessibilityOpen case settingsAccessiblityTextZoom + + #warning("NEW PIXELS - remove this comment") case settingsPrivateSearchOpen case settingsEmailProtectionOpen case settingsEmailProtectionEnable @@ -795,6 +797,7 @@ extension Pixel { case settingsAutomaticallyClearDataOff case settingsNextStepsAddAppToDock case settingsNextStepsAddWidget + case settingsMoreSearchSettings // Web pixels @@ -1684,6 +1687,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/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/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/SettingsViewModel.swift b/DuckDuckGo/SettingsViewModel.swift index 935eb18ca5..0dc4844a12 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 } @@ -802,6 +806,7 @@ extension SettingsViewModel { queue: .main) { [weak self] _ in guard let settings = self?.appSettings else { return } self?.state.autoclearDataEnabled = (AutoClearSettingsModel(settings: settings) != nil) + Pixel.fire(pixel: self?.state.autoclearDataEnabled == true ? .settingsAutomaticallyClearDataOn : .settingsAutomaticallyClearDataOff) } textZoomObserver = NotificationCenter.default.addObserver(forName: AppUserDefaults.Notifications.textZoomChange, diff --git a/DuckDuckGo/SyncSettingsViewController.swift b/DuckDuckGo/SyncSettingsViewController.swift index 0c88d0719a..1e88dea707 100644 --- a/DuckDuckGo/SyncSettingsViewController.swift +++ b/DuckDuckGo/SyncSettingsViewController.swift @@ -243,6 +243,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 { From c43a7e160fe6d54c81f13f85a391dfb282bfb832 Mon Sep 17 00:00:00 2001 From: Chris Brind Date: Wed, 11 Dec 2024 15:18:57 +0000 Subject: [PATCH 3/7] add pixel for more search settings and move private search open to right place --- DuckDuckGo/PrivateSearchView.swift | 6 +++--- DuckDuckGo/SettingsViewModel.swift | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/DuckDuckGo/PrivateSearchView.swift b/DuckDuckGo/PrivateSearchView.swift index 6a8f5797d4..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) + } } } @@ -69,9 +72,6 @@ struct PrivateSearchViewSettings: View { webLinkIndicator: true, isButton: true) } - .onFirstAppear { - Pixel.fire(pixel: .settingsPrivateSearchOpen) - } } } diff --git a/DuckDuckGo/SettingsViewModel.swift b/DuckDuckGo/SettingsViewModel.swift index 0dc4844a12..4c01350156 100644 --- a/DuckDuckGo/SettingsViewModel.swift +++ b/DuckDuckGo/SettingsViewModel.swift @@ -592,6 +592,7 @@ extension SettingsViewModel { } func openMoreSearchSettings() { + Pixel.fire(pixel: .settingsMoreSearchSettings) UIApplication.shared.open(URL.searchSettings) } From 4236ccf8c32a30fdb5886d9b27baaad431d51073 Mon Sep 17 00:00:00 2001 From: Chris Brind Date: Wed, 11 Dec 2024 15:24:21 +0000 Subject: [PATCH 4/7] clean up --- Core/PixelEvent.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/PixelEvent.swift b/Core/PixelEvent.swift index 829d66a2b7..16ebe2e28d 100644 --- a/Core/PixelEvent.swift +++ b/Core/PixelEvent.swift @@ -778,7 +778,6 @@ extension Pixel { case settingsAccessibilityOpen case settingsAccessiblityTextZoom - #warning("NEW PIXELS - remove this comment") case settingsPrivateSearchOpen case settingsEmailProtectionOpen case settingsEmailProtectionEnable @@ -796,8 +795,7 @@ extension Pixel { case settingsAutomaticallyClearDataOn case settingsAutomaticallyClearDataOff case settingsNextStepsAddAppToDock - case settingsNextStepsAddWidget - + case settingsNextStepsAddWidget case settingsMoreSearchSettings // Web pixels From f5c17a64eda9b6e9f151154d521cfdd888ef8e02 Mon Sep 17 00:00:00 2001 From: Chris Brind Date: Wed, 11 Dec 2024 15:27:01 +0000 Subject: [PATCH 5/7] swiftlint --- Core/PixelEvent.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/PixelEvent.swift b/Core/PixelEvent.swift index 16ebe2e28d..fd56ad863d 100644 --- a/Core/PixelEvent.swift +++ b/Core/PixelEvent.swift @@ -795,7 +795,7 @@ extension Pixel { case settingsAutomaticallyClearDataOn case settingsAutomaticallyClearDataOff case settingsNextStepsAddAppToDock - case settingsNextStepsAddWidget + case settingsNextStepsAddWidget case settingsMoreSearchSettings // Web pixels From 7b7a682665fe7adbe2e37a26f3a145865d0193f4 Mon Sep 17 00:00:00 2001 From: Chris Brind Date: Wed, 11 Dec 2024 17:53:50 +0000 Subject: [PATCH 6/7] new pixels for source of tab manager open and renaming for transparency --- Core/PixelEvent.swift | 16 ++++++++++++---- DuckDuckGo/MainViewController.swift | 11 +++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Core/PixelEvent.swift b/Core/PixelEvent.swift index fd56ad863d..e121667e8f 100644 --- a/Core/PixelEvent.swift +++ b/Core/PixelEvent.swift @@ -60,7 +60,11 @@ extension Pixel { case tabSwitcherClickCloseTab case tabSwitcherSwipeCloseTab case tabSwitchLongPressNewTab - case tabSwitcherOpenDaily + case tabSwitcherOpenedDaily + + case tabSwitcherOpenedFromSerp + case tabSwitcherOpenedFromWebsite + case tabSwitcherOpenedFromNewTabPage case settingsDoNotSellShown case settingsDoNotSellOn @@ -118,7 +122,7 @@ extension Pixel { case tabBarForwardPressed case bookmarksButtonPressed case tabBarBookmarksLongPressed - case tabBarTabSwitcherPressed + case tabBarTabSwitcherOpened case homeScreenShown case homeScreenEditFavorite @@ -969,7 +973,11 @@ extension Pixel.Event { case .tabSwitcherClickCloseTab: return "m_tab_manager_close_tab_click" case .tabSwitcherSwipeCloseTab: return "m_tab_manager_close_tab_swipe" case .tabSwitchLongPressNewTab: return "m_tab_manager_long_press_new_tab" - case .tabSwitcherOpenDaily: return "m_tab_manager_clicked_daily" + case .tabSwitcherOpenedDaily: return "m_tab_manager_opened_daily" + + case .tabSwitcherOpenedFromSerp: return "m_tab_manager_open_from_serp" + case .tabSwitcherOpenedFromWebsite: return "m_tab_manager_open_from_website" + case .tabSwitcherOpenedFromNewTabPage: return "m_tab_manager_open_from_newtabpage" case .settingsDoNotSellShown: return "ms_dns" case .settingsDoNotSellOn: return "ms_dns_on" @@ -1049,7 +1057,7 @@ extension Pixel.Event { case .tabBarForwardPressed: return "mt_fw" case .bookmarksButtonPressed: return "mt_bm" case .tabBarBookmarksLongPressed: return "mt_bl" - case .tabBarTabSwitcherPressed: return "mt_tb" + case .tabBarTabSwitcherOpened: return "m_tab_manager_opened" case .bookmarkLaunchList: return "m_bookmark_launch_list" case .bookmarkLaunchScored: return "m_bookmark_launch_scored" diff --git a/DuckDuckGo/MainViewController.swift b/DuckDuckGo/MainViewController.swift index 2ee59fc07f..6363b39257 100644 --- a/DuckDuckGo/MainViewController.swift +++ b/DuckDuckGo/MainViewController.swift @@ -2574,8 +2574,15 @@ extension MainViewController: TabSwitcherButtonDelegate { } func showTabSwitcher(_ button: TabSwitcherButton) { - Pixel.fire(pixel: .tabBarTabSwitcherPressed) - DailyPixel.fireDaily(.tabSwitcherOpenDaily, withAdditionalParameters: TabSwitcherOpenDailyPixel().parameters(with: tabManager.model.tabs)) + Pixel.fire(pixel: .tabBarTabSwitcherOpened) + DailyPixel.fireDaily(.tabSwitcherOpenedDaily, withAdditionalParameters: TabSwitcherOpenDailyPixel().parameters(with: tabManager.model.tabs)) + if currentTab?.url?.isDuckDuckGoSearch == true { + Pixel.fire(pixel: .tabSwitcherOpenedFromSerp) + } else if currentTab?.url != nil { + Pixel.fire(pixel: .tabSwitcherOpenedFromWebsite) + } else { + Pixel.fire(pixel: .tabSwitcherOpenedFromNewTabPage) + } performCancel() showTabSwitcher() From 2a5f8247b8da22cdb05b27d4e4f17bd37b7c1c35 Mon Sep 17 00:00:00 2001 From: Chris Brind Date: Thu, 12 Dec 2024 13:09:36 +0000 Subject: [PATCH 7/7] remove stray merge artifact --- DuckDuckGo/SettingsViewModel.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/DuckDuckGo/SettingsViewModel.swift b/DuckDuckGo/SettingsViewModel.swift index 7e97c13f64..cfdc9ae43c 100644 --- a/DuckDuckGo/SettingsViewModel.swift +++ b/DuckDuckGo/SettingsViewModel.swift @@ -817,7 +817,6 @@ extension SettingsViewModel { queue: .main) { [weak self] _ in guard let settings = self?.appSettings else { return } self?.state.autoclearDataEnabled = (AutoClearSettingsModel(settings: settings) != nil) - Pixel.fire(pixel: self?.state.autoclearDataEnabled == true ? .settingsAutomaticallyClearDataOn : .settingsAutomaticallyClearDataOff) } textZoomObserver = NotificationCenter.default.addObserver(forName: AppUserDefaults.Notifications.textZoomChange,