From 3f3dbca952411fac9dad3459b3f5b70bd8c05cef Mon Sep 17 00:00:00 2001 From: Graeme Arthur Date: Fri, 1 Dec 2023 09:05:32 +0100 Subject: [PATCH 01/22] Use design system fonts throughout NetP (#2211) --- DuckDuckGo/NetworkProtectionInviteView.swift | 6 ++--- DuckDuckGo/NetworkProtectionStatusView.swift | 23 +++++++++---------- .../NetworkProtectionVPNLocationView.swift | 10 ++++---- ...etworkProtectionVPNNotificationsView.swift | 4 ++-- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/DuckDuckGo/NetworkProtectionInviteView.swift b/DuckDuckGo/NetworkProtectionInviteView.swift index 424b7ef79e..c45c98eb58 100644 --- a/DuckDuckGo/NetworkProtectionInviteView.swift +++ b/DuckDuckGo/NetworkProtectionInviteView.swift @@ -102,11 +102,11 @@ private struct NetworkProtectionInviteMessageView: View where Content: .scaledToFit() .frame(height: 102.5) Text(messageData.title) - .font(.system(size: 22, weight: .semibold)) + .daxTitle2() .multilineTextAlignment(.center) .foregroundColor(.textPrimary) Text(messageData.message) - .font(.system(size: 16)) + .daxBodyRegular() .multilineTextAlignment(.center) .foregroundColor(.textSecondary) .padding(.bottom, 16) @@ -114,7 +114,7 @@ private struct NetworkProtectionInviteMessageView: View where Content: Spacer() Text(UserText.netPInviteOnlyMessage) .foregroundColor(.textSecondary) - .font(.system(size: 13)) + .daxFootnoteRegular() .multilineTextAlignment(.center) } .padding(24) diff --git a/DuckDuckGo/NetworkProtectionStatusView.swift b/DuckDuckGo/NetworkProtectionStatusView.swift index 93c335afdb..976bef8fa1 100644 --- a/DuckDuckGo/NetworkProtectionStatusView.swift +++ b/DuckDuckGo/NetworkProtectionStatusView.swift @@ -56,10 +56,10 @@ struct NetworkProtectionStatusView: View { HStack { VStack(alignment: .leading, spacing: 4) { Text(UserText.netPStatusViewTitle) - .font(.system(size: 16)) + .daxBodyRegular() .foregroundColor(.textPrimary) Text(statusModel.statusMessage) - .font(.system(size: 13)) + .daxFootnoteRegular() .foregroundColor(.textSecondary) } @@ -92,11 +92,11 @@ struct NetworkProtectionStatusView: View { .frame(height: 96) .padding(8) Text(statusModel.headerTitle) - .font(.system(size: 17, weight: .semibold)) + .daxHeadline() .multilineTextAlignment(.center) .foregroundColor(.textPrimary) Text(UserText.netPStatusHeaderMessage) - .font(.system(size: 13)) + .daxFootnoteRegular() .multilineTextAlignment(.center) .foregroundColor(.textSecondary) .padding(.bottom, 8) @@ -137,10 +137,10 @@ struct NetworkProtectionStatusView: View { private func settings() -> some View { Section { NavigationLink(UserText.netPVPNSettingsTitle, destination: NetworkProtectionVPNSettingsView()) - .font(.system(size: 16)) + .daxBodyRegular() .foregroundColor(.textPrimary) NavigationLink(UserText.netPVPNNotificationsTitle, destination: NetworkProtectionVPNNotificationsView()) - .font(.system(size: 16)) + .daxBodyRegular() .foregroundColor(.textPrimary) } header: { Text(UserText.netPStatusViewSettingsSectionTitle).foregroundColor(.textSecondary) @@ -155,7 +155,7 @@ struct NetworkProtectionStatusView: View { Text("\(UserText.netPInviteOnlyMessage) [\(UserText.netPStatusViewShareFeedback)](https://form.asana.com/?k=_wNLt6YcT5ILpQjDuW0Mxw&d=137249556945)") .foregroundColor(.textSecondary) .accentColor(Color.controlColor) - .font(.system(size: 13)) + .daxFootnoteRegular() .padding(.top, 6) } } @@ -169,12 +169,11 @@ private struct NetworkProtectionErrorView: View { HStack { Image("Alert-Color-16") Text(title) - .font(.system(size: 16)) + .daxBodyBold() .foregroundColor(.primary) - .bold() } Text(message) - .font(.system(size: 16)) + .daxBodyRegular() .foregroundColor(.primary) } .listRowBackground(Color.cellBackground) @@ -190,11 +189,11 @@ private struct NetworkProtectionServerItemView: View { HStack(spacing: 16) { Image(imageID) Text(title) - .font(.system(size: 16)) + .daxBodyRegular() .foregroundColor(.textPrimary) Spacer(minLength: 2) Text(value) - .font(.system(size: 16)) + .daxBodyRegular() .foregroundColor(.textSecondary) } .listRowBackground(Color.cellBackground) diff --git a/DuckDuckGo/NetworkProtectionVPNLocationView.swift b/DuckDuckGo/NetworkProtectionVPNLocationView.swift index 31425e33d7..717f295629 100644 --- a/DuckDuckGo/NetworkProtectionVPNLocationView.swift +++ b/DuckDuckGo/NetworkProtectionVPNLocationView.swift @@ -53,7 +53,7 @@ struct NetworkProtectionVPNLocationView: View { }, label: { Text(UserText.netPPreferredLocationNearest) .foregroundStyle(Color.textPrimary) - .font(.system(size: 16)) + .daxBodyRegular() } ) } header: { @@ -62,7 +62,7 @@ struct NetworkProtectionVPNLocationView: View { } footer: { Text(UserText.netPVPNLocationRecommendedSectionFooter) .foregroundStyle(Color.textSecondary) - .font(.system(size: 13)) + .daxFootnoteRegular() .padding(.top, 6) } } @@ -115,11 +115,11 @@ private struct CountryItem: View { Text(itemModel.emoji) VStack(alignment: .leading, spacing: 4) { Text(itemModel.title) - .font(.system(size: 16)) + .daxBodyRegular() .foregroundStyle(Color.textPrimary) if let subtitle = itemModel.subtitle { Text(subtitle) - .font(.system(size: 13)) + .daxFootnoteRegular() .foregroundStyle(Color.textSecondary) } } @@ -178,7 +178,7 @@ private struct MenuItem: View { action: action, label: { HStack(spacing: 12) { - Text(title) + Text(title).daxBodyRegular() Spacer() Image(systemName: "checkmark") .if(!isSelected) { diff --git a/DuckDuckGo/NetworkProtectionVPNNotificationsView.swift b/DuckDuckGo/NetworkProtectionVPNNotificationsView.swift index d5b0d22fd2..9d6897017f 100644 --- a/DuckDuckGo/NetworkProtectionVPNNotificationsView.swift +++ b/DuckDuckGo/NetworkProtectionVPNNotificationsView.swift @@ -58,7 +58,7 @@ struct NetworkProtectionVPNNotificationsView: View { } footer: { Text(UserText.netPTurnOnNotificationsSectionFooter) .foregroundColor(.textSecondary) - .font(.system(size: 13)) + .daxFootnoteRegular() .padding(.top, 6) } } @@ -74,7 +74,7 @@ struct NetworkProtectionVPNNotificationsView: View { } footer: { Text(UserText.netPVPNAlertsToggleSectionFooter) .foregroundColor(.textSecondary) - .font(.system(size: 13)) + .daxFootnoteRegular() .padding(.top, 6) } } From c73d7deac9f4e66f32a1482e52c8b7f1c9f1acf1 Mon Sep 17 00:00:00 2001 From: Christopher Brind Date: Fri, 1 Dec 2023 10:24:28 +0000 Subject: [PATCH 02/22] new pixels for toolbars and share sheet (#2208) Task/Issue URL: https://app.asana.com/0/414235014887631/1205953072928854/f Tech Design URL: CC: Description: New pixels for iOS toolbars project. Address Bar AddressBarSettingsPressed: New pixel m_addressbar_settings AddressBarRefreshPressed: This is the m_r pixel and is only called from the address bar so already exists AddressBarShieldPressed: This is the mp pixel so already exists AddressBarSharePressed: This was one pixel with a parameter, but I'm splitting into two new ones for clarity: new pixel: m_addressbar_share from the address bar new pixel: m_browsingmenu_share from the menu pixel removed: mb_sh has been removed Share Sheet Share result New pixel m_sharesheet_result_success when success is true New pixel m_sharesheet_result_fail when success is false ShareSheetCopy: new pixel m_sharesheet_activity_copy ShareSheetAddBookmark: new pixel m_sharesheet_activity_addbookmark ShareSheetAddFavorite: new pixel m_sharesheet_activity_addfavorite ShareSheetFindinPage: new pixel m_sharesheet_activity_findinpage ShareSheetPrint: new pixel m_sharesheet_activity_print ShareSheetAddToReadingList: new pixel m_sharesheet_activity_addtoreadinglist Also includes adding app version by default to the pixels as part of privacy triage: https://app.asana.com/0/69071770703008/1206042861558143/f --- Core/Pixel.swift | 3 +- Core/PixelEvent.swift | 30 +++++++++++++- DuckDuckGo/MainViewController.swift | 2 +- DuckDuckGo/OmniBar.swift | 2 + ...bViewControllerBrowsingMenuExtension.swift | 40 ++++++++++++++++--- 5 files changed, 67 insertions(+), 10 deletions(-) diff --git a/Core/Pixel.swift b/Core/Pixel.swift index 5c24bee78b..229598fd36 100644 --- a/Core/Pixel.swift +++ b/Core/Pixel.swift @@ -214,13 +214,14 @@ extension Pixel { public static func fire(pixel: Pixel.Event, error: Error?, + includedParameters: [QueryParameters] = [.appVersion], withAdditionalParameters params: [String: String] = [:], onComplete: @escaping (Error?) -> Void = { _ in }) { var newParams = params if let error { newParams.appendErrorPixelParams(error: error) } - fire(pixel: pixel, withAdditionalParameters: newParams, includedParameters: [], onComplete: onComplete) + fire(pixel: pixel, withAdditionalParameters: newParams, includedParameters: includedParameters, onComplete: onComplete) } } diff --git a/Core/PixelEvent.swift b/Core/PixelEvent.swift index c29918a5f3..5d6a1e3494 100644 --- a/Core/PixelEvent.swift +++ b/Core/PixelEvent.swift @@ -74,6 +74,19 @@ extension Pixel { case browsingMenuFireproof case browsingMenuAutofill + case addressBarShare + case addressBarSettings + + case shareSheetResultSuccess + case shareSheetResultFail + case shareSheetActivityCopy + case shareSheetActivityAddBookmark + case shareSheetActivityAddFavorite + case shareSheetActivityFindInPage + case shareSheetActivityPrint + case shareSheetActivityAddToReadingList + case shareSheetActivityOther + case tabBarBackPressed case tabBarForwardPressed case bookmarksButtonPressed @@ -562,7 +575,6 @@ extension Pixel.Event { case .browsingMenuRemoveFromFavorites: return "mb_df" case .browsingMenuAddToFavoritesAddFavoriteFlow: return "mb_aff" case .browsingMenuToggleBrowsingMode: return "mb_dm" - case .browsingMenuShare: return "mb_sh" case .browsingMenuCopy: return "mb_cp" case .browsingMenuPrint: return "mb_pr" case .browsingMenuSettings: return "mb_st" @@ -572,7 +584,21 @@ extension Pixel.Event { case .browsingMenuReportBrokenSite: return "mb_rb" case .browsingMenuFireproof: return "mb_f" case .browsingMenuAutofill: return "m_nav_autofill_menu_item_pressed" - + + case .browsingMenuShare: return "m_browsingmenu_share" + + case .addressBarShare: return "m_addressbar_share" + case .addressBarSettings: return "m_addressbar_settings" + case .shareSheetResultSuccess: return "m_sharesheet_result_success" + case .shareSheetResultFail: return "m_sharesheet_result_fail" + case .shareSheetActivityCopy: return "m_sharesheet_activity_copy" + case .shareSheetActivityAddBookmark: return "m_sharesheet_activity_addbookmark" + case .shareSheetActivityAddFavorite: return "m_sharesheet_activity_addfavorite" + case .shareSheetActivityFindInPage: return "m_sharesheet_activity_findinpage" + case .shareSheetActivityPrint: return "m_sharesheet_activity_print" + case .shareSheetActivityAddToReadingList: return "m_sharesheet_activity_addtoreadinglist" + case .shareSheetActivityOther: return "m_sharesheet_activity_other" + case .tabBarBackPressed: return "mt_bk" case .tabBarForwardPressed: return "mt_fw" case .bookmarksButtonPressed: return "mt_bm" diff --git a/DuckDuckGo/MainViewController.swift b/DuckDuckGo/MainViewController.swift index f043f52def..fa2a0b7336 100644 --- a/DuckDuckGo/MainViewController.swift +++ b/DuckDuckGo/MainViewController.swift @@ -1463,7 +1463,7 @@ extension MainViewController: OmniBarDelegate { func onSharePressed() { hideSuggestionTray() guard let link = currentTab?.link else { return } - currentTab?.onShareAction(forLink: link, fromView: viewCoordinator.omniBar.shareButton, orginatedFromMenu: false) + currentTab?.onShareAction(forLink: link, fromView: viewCoordinator.omniBar.shareButton) } func onVoiceSearchPressed() { diff --git a/DuckDuckGo/OmniBar.swift b/DuckDuckGo/OmniBar.swift index bb8c6944ff..9498074044 100644 --- a/DuckDuckGo/OmniBar.swift +++ b/DuckDuckGo/OmniBar.swift @@ -446,6 +446,7 @@ class OmniBar: UIView { } @IBAction func onSettingsButtonPressed(_ sender: Any) { + Pixel.fire(pixel: .addressBarSettings) omniDelegate?.onSettingsPressed() } @@ -474,6 +475,7 @@ class OmniBar: UIView { } @IBAction func onSharePressed(_ sender: Any) { + Pixel.fire(pixel: .addressBarShare) omniDelegate?.onSharePressed() } diff --git a/DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift b/DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift index 835f9eb89d..b946236540 100644 --- a/DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift +++ b/DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift @@ -42,7 +42,8 @@ extension TabViewController { entries.append(BrowsingMenuEntry.regular(name: UserText.actionShare, image: UIImage(named: "Share-24")!, action: { [weak self] in guard let self = self else { return } guard let menu = self.chromeDelegate?.omniBar.menuButton else { return } - self.onShareAction(forLink: self.link!, fromView: menu, orginatedFromMenu: true) + Pixel.fire(pixel: .browsingMenuShare) + self.onShareAction(forLink: self.link!, fromView: menu) })) entries.append(BrowsingMenuEntry.regular(name: UserText.actionCopy, image: UIImage(named: "Copy-24")!, action: { [weak self] in @@ -302,10 +303,7 @@ extension TabViewController { } } - func onShareAction(forLink link: Link, fromView view: UIView, orginatedFromMenu: Bool) { - Pixel.fire(pixel: .browsingMenuShare, - withAdditionalParameters: [PixelParameters.originatedFromMenu: orginatedFromMenu ? "1" : "0"]) - + func onShareAction(forLink link: Link, fromView view: UIView) { shareLinkWithTemporaryDownload(temporaryDownloadForPreviewedFile, originalLink: link) { [weak self] link in guard let self = self else { return } var items: [Any] = [link, self.webView.viewPrintFormatter()] @@ -313,10 +311,40 @@ extension TabViewController { if let webView = self.webView { items.append(webView) } - self.presentShareSheet(withItems: items, fromView: view) + + self.presentShareSheet(withItems: items, fromView: view) { [weak self] activityType, result, _, error in + if result { + Pixel.fire(pixel: .shareSheetResultSuccess) + } else { + Pixel.fire(pixel: .shareSheetResultFail, error: error) + } + + if let activityType { + self?.firePixelForActivityType(activityType) + } + } } } + private func firePixelForActivityType(_ activityType: UIActivity.ActivityType) { + switch activityType { + case .copyToPasteboard: + Pixel.fire(pixel: .shareSheetActivityCopy) + case .saveBookmarkInDuckDuckGo: + Pixel.fire(pixel: .shareSheetActivityAddBookmark) + case .saveFavoriteInDuckDuckGo: + Pixel.fire(pixel: .shareSheetActivityAddFavorite) + case .findInPage: + Pixel.fire(pixel: .shareSheetActivityFindInPage) + case .print: + Pixel.fire(pixel: .shareSheetActivityPrint) + case .addToReadingList: + Pixel.fire(pixel: .shareSheetActivityAddToReadingList) + default: + Pixel.fire(pixel: .shareSheetActivityOther) + } + } + private func shareLinkWithTemporaryDownload(_ temporaryDownload: Download?, originalLink: Link, completion: @escaping(Link) -> Void) { From 7c44458a9e26bd331098b8766b4e142a096b6a80 Mon Sep 17 00:00:00 2001 From: Sabrina Tardio <44158575+SabrinaTardio@users.noreply.github.com> Date: Fri, 1 Dec 2023 13:07:36 +0100 Subject: [PATCH 03/22] Sabrina/sync setup update (#2198) Task/Issue URL: https://app.asana.com/0/0/1205948195318715/f Description: Update the sync UI flow according to https://www.figma.com/file/5wIXwQLKJ0dZVsP5XWcgbT/%F0%9F%8E%AF-Sync-9?type=design&node-id=8748-306047&mode=design&t=5IygRcQcvvNAJ7xg-0 --- Core/UIViewControllerExtension.swift | 8 +- DuckDuckGo/Base.lproj/Settings.storyboard | 42 +-- DuckDuckGo/SettingsViewController.swift | 4 +- .../Arrow-Circle-Right-12.svg | 11 + .../Contents.json | 15 + .../Sync-128.imageset/Contents.json | 21 ++ .../Sync-128.imageset/Sync-128.svg | 9 + .../Sync-Recover-128.imageset/Contents.json | 15 + .../Sync-Recover-128.svg | 20 ++ .../Sync-Server-128.imageset/Contents.json | 15 + .../Sync-Server-128.svg | 18 + ...cSettingsViewController+PDFRendering.swift | 12 +- ...cSettingsViewController+SyncDelegate.swift | 45 +-- DuckDuckGo/SyncSettingsViewController.swift | 47 +-- DuckDuckGo/UserText.swift | 2 +- ...000170c180>{number = 1, name = main}.plist | Bin 0 -> 106 bytes .../SyncManagementViewModelTests.swift | 49 ++- .../ViewModels/SaveRecoveryKeyViewModel.swift | 8 +- .../ViewModels/ScanOrPasteCodeViewModel.swift | 20 +- .../ViewModels/SyncSettingsViewModel.swift | 12 +- .../SyncUI/Views/DeviceConnectedView.swift | 108 +----- .../SyncUI/Views/Internal/CameraView.swift | 154 +++++++++ .../Views/Internal/ConnectModeView.swift | 38 --- .../Views/Internal/EditDeviceView.swift | 4 +- .../Views/Internal/QRCodeCopierView.swift | 100 ------ .../Views/Internal/QRCodeScannerView.swift | 5 +- .../SyncUI/Views/Internal/ShowCodeView.swift | 44 --- .../SyncUI/Views/Internal/UserText.swift | 227 +++++++------ .../Sources/SyncUI/Views/PasteCodeView.swift | 53 +-- .../SyncUI/Views/PreparingToSyncView.swift | 49 +++ .../SyncUI/Views/RecoverSyncedDataView.swift | 68 ++++ .../SyncUI/Views/SaveRecoveryKeyView.swift | 76 +++-- ...anOrEnterCodeToRecoverSyncedDataView.swift | 71 ++++ .../SyncUI/Views/ScanOrPasteCodeView.swift | 303 +++++------------ .../SyncUI/Views/SyncSettingsView.swift | 309 ++++++++---------- .../SyncUI/Views/SyncWithServerView.swift | 78 +++++ 36 files changed, 1137 insertions(+), 923 deletions(-) create mode 100644 DuckDuckGo/SyncAssets.xcassets/Arrow-Circle-Right-12.imageset/Arrow-Circle-Right-12.svg create mode 100644 DuckDuckGo/SyncAssets.xcassets/Arrow-Circle-Right-12.imageset/Contents.json create mode 100644 DuckDuckGo/SyncAssets.xcassets/Sync-128.imageset/Contents.json create mode 100644 DuckDuckGo/SyncAssets.xcassets/Sync-128.imageset/Sync-128.svg create mode 100644 DuckDuckGo/SyncAssets.xcassets/Sync-Recover-128.imageset/Contents.json create mode 100644 DuckDuckGo/SyncAssets.xcassets/Sync-Recover-128.imageset/Sync-Recover-128.svg create mode 100644 DuckDuckGo/SyncAssets.xcassets/Sync-Server-128.imageset/Contents.json create mode 100644 DuckDuckGo/SyncAssets.xcassets/Sync-Server-128.imageset/Sync-Server-128.svg create mode 100644 DuckDuckGoTests/NetworkProtectionVPNLocationViewModelTests.swift<_NSMainThread: 0x60000170c180>{number = 1, name = main}.plist create mode 100644 LocalPackages/SyncUI/Sources/SyncUI/Views/Internal/CameraView.swift delete mode 100644 LocalPackages/SyncUI/Sources/SyncUI/Views/Internal/ConnectModeView.swift delete mode 100644 LocalPackages/SyncUI/Sources/SyncUI/Views/Internal/QRCodeCopierView.swift delete mode 100644 LocalPackages/SyncUI/Sources/SyncUI/Views/Internal/ShowCodeView.swift create mode 100644 LocalPackages/SyncUI/Sources/SyncUI/Views/PreparingToSyncView.swift create mode 100644 LocalPackages/SyncUI/Sources/SyncUI/Views/RecoverSyncedDataView.swift create mode 100644 LocalPackages/SyncUI/Sources/SyncUI/Views/ScanOrEnterCodeToRecoverSyncedDataView.swift create mode 100644 LocalPackages/SyncUI/Sources/SyncUI/Views/SyncWithServerView.swift diff --git a/Core/UIViewControllerExtension.swift b/Core/UIViewControllerExtension.swift index f37bca411b..4e91074719 100644 --- a/Core/UIViewControllerExtension.swift +++ b/Core/UIViewControllerExtension.swift @@ -50,11 +50,15 @@ extension UIViewController { present(controller: shareController, fromButtonItem: buttonItem) } - public func presentShareSheet(withItems activityItems: [Any], fromView sourceView: UIView, atPoint point: Point? = nil, completion: UIActivityViewController.CompletionWithItemsHandler? = nil) { + public func presentShareSheet(withItems activityItems: [Any], fromView sourceView: UIView, atPoint point: Point? = nil, overrideInterfaceStyle: UIUserInterfaceStyle? = nil, completion: UIActivityViewController.CompletionWithItemsHandler? = nil) { let activities = buildActivities() let shareController = UIActivityViewController(activityItems: activityItems, applicationActivities: activities) shareController.completionWithItemsHandler = completion - shareController.overrideUserInterfaceStyle() + if let overrideInterfaceStyle { + shareController.overrideUserInterfaceStyle = overrideInterfaceStyle + } else { + shareController.overrideUserInterfaceStyle() + } shareController.excludedActivityTypes = [.markupAsPDF] present(controller: shareController, fromView: sourceView, atPoint: point) } diff --git a/DuckDuckGo/Base.lproj/Settings.storyboard b/DuckDuckGo/Base.lproj/Settings.storyboard index 1d4eb7fa61..63439e5402 100644 --- a/DuckDuckGo/Base.lproj/Settings.storyboard +++ b/DuckDuckGo/Base.lproj/Settings.storyboard @@ -104,7 +104,7 @@ -