Skip to content

Commit

Permalink
Merge branch 'main' into dominik/xcode-16
Browse files Browse the repository at this point in the history
# By Dominik Kapusta (4) and others
# Via Dominik Kapusta (1) and others
* main:
  Remove VPN test rollout pixel (#3510)
  VPN clean-up (#3474)
  Update Ruby to 3.3.4 (#3519)
  Fix UI tests failing  (#3517)
  Add menu option to set as default browser (#3508)
  Bump version to 1.113.0 (300)
  Deprecate PixelKit daily pixel suffixes (#3509)
  Update permission usage description strings in Info.plist (#3518)
  Fix add to favorites and open in new tabs action not working on manager (#3467)
  Hiding of tab previews for pinned tabs fixed (#3513)
  Update C-S-S to 6.29.0 (#3515)
  Freemium PIR: Ship Review Changes - Updated New Tab Banner UI (#3501)
  Send pixel on sync secure storage read failure (#3497)
  Remove com.apple.security.device.usb entitlement (#3495)

# Conflicts:
#	DuckDuckGo.xcodeproj/project.pbxproj
#	DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
  • Loading branch information
samsymons committed Nov 7, 2024
2 parents 7eca015 + afed3b7 commit 781b009
Show file tree
Hide file tree
Showing 61 changed files with 494 additions and 323 deletions.
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.0.4
3.3.4
2 changes: 1 addition & 1 deletion Configuration/BuildNumber.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1 @@
CURRENT_PROJECT_VERSION = 298
CURRENT_PROJECT_VERSION = 300
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/content-scope-scripts",
"state" : {
"revision" : "48fee2508995d4ac02d18b3d55424adedcb4ce4f",
"version" : "6.28.0"
"revision" : "6cab7bdb584653a5dc007cc1ae827ec41c5a91bc",
"version" : "6.29.0"
}
},
{
Expand Down Expand Up @@ -75,7 +75,7 @@
{
"identity" : "lottie-spm",
"kind" : "remoteSourceControl",
"location" : "https://github.com/airbnb/lottie-spm.git",
"location" : "https://github.com/airbnb/lottie-spm",
"state" : {
"revision" : "1d29eccc24cc8b75bff9f6804155112c0ffc9605",
"version" : "4.4.3"
Expand Down
2 changes: 2 additions & 0 deletions DuckDuckGo/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate {

freemiumDBPScanResultPolling = DefaultFreemiumDBPScanResultPolling(dataManager: DataBrokerProtectionManager.shared.dataManager, freemiumDBPUserStateManager: freemiumDBPUserStateManager)
freemiumDBPScanResultPolling?.startPollingOrObserving()

PixelKit.fire(NonStandardEvent(GeneralPixel.launch(isDefault: DefaultBrowserPreferences().isDefault)))
}

private func fireFailedCompilationsPixelIfNeeded() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"images" : [
{
"filename" : "Set-as-Default-16D.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "Information-Remover-128.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
Binary file not shown.
7 changes: 7 additions & 0 deletions DuckDuckGo/Bookmarks/Extensions/Bookmarks+Tab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ extension Tab {
}
}

@MainActor
static func with(contentsOf bookmarks: [Bookmark], burnerMode: BurnerMode) -> [Tab] {
bookmarks.compactMap { bookmark -> Tab? in
guard let url = bookmark.urlObject else { return nil }
return Tab(content: .url(url, source: .bookmark), shouldLoadInBackground: true, burnerMode: burnerMode)
}
}
}

extension TabCollection {
Expand Down
30 changes: 19 additions & 11 deletions DuckDuckGo/Bookmarks/Services/BookmarksContextMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,17 @@ extension BookmarksContextMenu: BookmarkMenuItemSelectors {
}

@objc func toggleBookmarkAsFavorite(_ sender: NSMenuItem) {
guard let bookmark = sender.representedObject as? Bookmark else {
if let bookmark = sender.representedObject as? Bookmark{
bookmark.isFavorite.toggle()
bookmarkManager.update(bookmark: bookmark)
} else if let bookmarks = sender.representedObject as? [Bookmark] {
bookmarks.forEach { bookmark in
bookmark.isFavorite.toggle()
bookmarkManager.update(bookmark: bookmark)
}
} else {
assertionFailure("Failed to cast menu represented object to Bookmark")
return
}

bookmark.isFavorite.toggle()
bookmarkManager.update(bookmark: bookmark)
}

@MainActor
Expand Down Expand Up @@ -424,16 +428,20 @@ extension BookmarksContextMenu: FolderMenuItemSelectors {

@MainActor
@objc func openInNewTabs(_ sender: NSMenuItem) {
guard let tabCollection = windowControllersManager.lastKeyMainWindowController?.mainViewController.tabCollectionViewModel,
let folder = sender.representedObject as? BookmarkFolder
else {
guard let tabCollection = windowControllersManager.lastKeyMainWindowController?.mainViewController.tabCollectionViewModel else {
assertionFailure("Cannot open all in new tabs")
return
}

let tabs = Tab.withContentOfBookmark(folder: folder, burnerMode: tabCollection.burnerMode)
tabCollection.append(tabs: tabs)
PixelExperiment.fireOnboardingBookmarkUsed5to7Pixel()
if let folder = sender.representedObject as? BookmarkFolder {
let tabs = Tab.withContentOfBookmark(folder: folder, burnerMode: tabCollection.burnerMode)
tabCollection.append(tabs: tabs)
PixelExperiment.fireOnboardingBookmarkUsed5to7Pixel()
} else if let bookmarks = sender.representedObject as? [Bookmark] {
let tabs = Tab.with(contentsOf: bookmarks, burnerMode: tabCollection.burnerMode)
tabCollection.append(tabs: tabs)
PixelExperiment.fireOnboardingBookmarkUsed5to7Pixel()
}
}

@MainActor
Expand Down
39 changes: 24 additions & 15 deletions DuckDuckGo/Common/Localizables/UserText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ struct UserText {

static let aboutDuckDuckGo = NSLocalizedString("preferences.about.about-duckduckgo", value: "About DuckDuckGo", comment: "About screen")
static let duckduckgoTagline = NSLocalizedString("preferences.about.duckduckgo-tagline", value: "Your protection, our priority.", comment: "About screen")
static let setAsDefaultBrowser = NSLocalizedString("preferences.set-as-default", value: "Set DuckDuckGo As Default Browser", comment: "Menu option to set the browser as default")
static let aboutUnsupportedDeviceInfo1 = NSLocalizedString("preferences.about.unsupported-device-info1", value: "DuckDuckGo is no longer providing browser updates for your version of macOS.", comment: "This string represents a message informing the user that DuckDuckGo is no longer providing browser updates for their version of macOS")
static func aboutUnsupportedDeviceInfo2(version: String) -> String {
let localized = NSLocalizedString("preferences.about.unsupported-device-info2", value: "Please update to macOS %@ or later to use the most recent version of DuckDuckGo. You can also keep using your current version of the browser, but it will not receive further updates.", comment: "Copy in section that tells the user to update their macOS version since their current version is unsupported")
Expand Down Expand Up @@ -1382,41 +1383,49 @@ struct UserText {
// Comment: "Title for Freemium Personal Information Removal (Scan-Only) item in the options menu"
static let freemiumDBPOptionsMenuItem = "Free Personal Information Scan"

// Key: "home.page.promotion.freemium.dbp.text"
// Comment: "Text for the Freemium DBP Home Page Promotion"
static let homePagePromotionFreemiumDBPText = "Find your personal info on sites that sell it."
// Key: "home.page.promotion.freemium.dbp.title"
// Comment: "Title for the Freemium DBP Home Page Promotion"
static let homePagePromotionFreemiumDBPTitle = "Personal Information Removal"

// Key: "home.page.promotion.freemium.dbp.description.markdown"
// Comment: "Markdown Description for the Freemium DBP Home Page Promotion"
static let homePagePromotionFreemiumDBPDescriptionMarkdown = "Find out which sites are selling **your info.**"

// Key: "home.page.promotion.freemium.dbp.description"
// Comment: "Description for the Freemium DBP Home Page Promotion"
static let homePagePromotionFreemiumDBPDescription = "Find out which sites are selling your info."

// Key: "home.page.promotion.freemium.dbp.button.title"
// Comment: "Title for the Freemium DBP Home Page Promotion Button"
static let homePagePromotionFreemiumDBPButtonTitle = "Free Scan"

// Key: "home.page.promotion.freemium.dbp.post.scan.engagement.result.single.match.text"
// Comment: "Text for the Freemium DBP Home Page Post Scan Engagement Promotion When Only One Record is Found"
static let homePagePromotionFreemiumDBPPostScanEngagementResultSingleMatchText = "Your free personal info scan found 1 record about you on 1 site."
// Key: "home.page.promotion.freemium.dbp.post.scan.engagement.result.single.match.description"
// Comment: "Description for the Freemium DBP Home Page Post Scan Engagement Promotion When Only One Record is Found"
static let homePagePromotionFreemiumDBPPostScanEngagementResultSingleMatchDescription = "Your free personal info scan found 1 record about you on 1 site."

/// Generates Text for the Freemium DBP Home Page Post Scan Engagement Promotion when records are found on a single broker site.
/// Key: "home.page.promotion.freemium.dbp.post.scan.engagement.result.single.broker.text"
/// Generates Description for the Freemium DBP Home Page Post Scan Engagement Promotion when records are found on a single broker site.
/// Key: "home.page.promotion.freemium.dbp.post.scan.engagement.result.single.broker.description"
///
/// - Parameter resultCount: The number of records found.
/// - Returns: A formatted string indicating the number of records found on 1 site.
static func homePagePromotionFreemiumDBPPostScanEngagementResultSingleBrokerText(resultCount: Int) -> String {
static func homePagePromotionFreemiumDBPPostScanEngagementResultSingleBrokerDescription(resultCount: Int) -> String {
String(format: "Your free personal info scan found %d records about you on 1 site.", resultCount)
}

/// Generates Text for the Freemium DBP Home Page Post Scan Engagement Promotion when records are found on multiple broker sites.
/// Key: "home.page.promotion.freemium.dbp.post.scan.engagement.result.plural.text"
/// Generates Description for the Freemium DBP Home Page Post Scan Engagement Promotion when records are found on multiple broker sites.
/// Key: "home.page.promotion.freemium.dbp.post.scan.engagement.result.plural.description"
///
/// - Parameters:
/// - resultCount: The number of records found.
/// - brokerCount: The number of broker sites where records were found.
/// - Returns: A formatted string indicating the number of records found on multiple sites.
static func homePagePromotionFreemiumDBPPostScanEngagementResultPluralText(resultCount: Int, brokerCount: Int) -> String {
static func homePagePromotionFreemiumDBPPostScanEngagementResultPluralDescription(resultCount: Int, brokerCount: Int) -> String {
String(format: "Your free personal info scan found %d records about you on %d different sites.", resultCount, brokerCount)
}

// Key: "home.page.promotion.freemium.dbp.post.scan.engagement.no.results.text"
// Comment: "Text for the Freemium DBP Home Page Post Scan Engagement Promotion When There Are No Results"
static let homePagePromotionFreemiumDBPPostScanEngagementNoResultsText = "Good news, your free personal info scan didn't find any records about you. We'll keep checking periodically."
// Key: "home.page.promotion.freemium.dbp.post.scan.engagement.no.results.description"
// Comment: "Description for the Freemium DBP Home Page Post Scan Engagement Promotion When There Are No Results"
static let homePagePromotionFreemiumDBPPostScanEngagementNoResultsDescription = "Good news, your free personal info scan didn't find any records about you. We'll keep checking periodically."

// Key: "home.page.promotion.freemium.dbp.post.scan.engagement.button.title"
// Comment: "Title for the Freemium DBP Home Page Post Scan Engagement Promotion Button"
Expand Down
1 change: 1 addition & 0 deletions DuckDuckGo/Common/Logger+Multiple.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ extension Logger {
static var tabSnapshots = { Logger(subsystem: "Tab Snapshots", category: "") }()
static var tabLazyLoading = { Logger(subsystem: "Lazy Loading", category: "") }()
static var updates = { Logger(subsystem: "Updates", category: "") }()
static var tabPreview = { Logger(subsystem: "Tab Preview", category: "") }()
}
7 changes: 3 additions & 4 deletions DuckDuckGo/DBP/DataBrokerProtectionPixelsHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class DataBrokerProtectionPixelsHandler: EventMapping<DataBrokerProtectio
.ipcServerImmediateScansFinishedWithError(error: let error),
.ipcServerAppLaunchedXPCError(error: let error),
.ipcServerAppLaunchedScheduledScansFinishedWithError(error: let error):
PixelKit.fire(DebugEvent(event, error: error), frequency: .dailyAndCount, includeAppVersionParameter: true)
PixelKit.fire(DebugEvent(event, error: error), frequency: .legacyDailyAndCount, includeAppVersionParameter: true)
case .ipcServerProfileSavedCalledByApp,
.ipcServerProfileSavedReceivedByAgent,
.ipcServerImmediateScansInterrupted,
Expand All @@ -50,7 +50,7 @@ public class DataBrokerProtectionPixelsHandler: EventMapping<DataBrokerProtectio
.ipcServerAppLaunchedScheduledScansBlocked,
.ipcServerAppLaunchedScheduledScansInterrupted,
.ipcServerAppLaunchedScheduledScansFinishedWithoutError:
PixelKit.fire(event, frequency: .dailyAndCount, includeAppVersionParameter: true)
PixelKit.fire(event, frequency: .legacyDailyAndCount, includeAppVersionParameter: true)
case .parentChildMatches,
.optOutStart,
.optOutEmailGenerate,
Expand Down Expand Up @@ -106,7 +106,6 @@ public class DataBrokerProtectionPixelsHandler: EventMapping<DataBrokerProtectio
.dataBrokerMetricsWeeklyStats,
.dataBrokerMetricsMonthlyStats,
.invalidPayload,
.pixelTest,
.customDataBrokerStatsOptoutSubmit,
.customGlobalStatsOptoutSubmit,
.weeklyChildBrokerOrphanedOptOuts:
Expand All @@ -122,7 +121,7 @@ public class DataBrokerProtectionPixelsHandler: EventMapping<DataBrokerProtectio
.entitlementCheckValid,
.entitlementCheckInvalid,
.entitlementCheckError:
PixelKit.fire(event, frequency: .dailyAndCount)
PixelKit.fire(event, frequency: .legacyDailyAndCount)
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions DuckDuckGo/DuckDuckGoAppStore.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.usb</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
Expand Down
2 changes: 0 additions & 2 deletions DuckDuckGo/DuckDuckGoAppStoreCI.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.usb</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
Expand Down
2 changes: 0 additions & 2 deletions DuckDuckGo/DuckDuckGoAppStoreDebug.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.usb</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
Expand Down
31 changes: 19 additions & 12 deletions DuckDuckGo/Freemium/DBP/Extensions/PromotionView+FreemiumDBP.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,18 @@ extension PromotionViewModel {
static func freemiumDBPPromotion(proceedAction: @escaping () -> Void,
closeAction: @escaping () -> Void) -> PromotionViewModel {

let text = UserText.homePagePromotionFreemiumDBPText
let title = UserText.homePagePromotionFreemiumDBPTitle
var description = UserText.homePagePromotionFreemiumDBPDescription

if #available(macOS 12.0, *) {
description = UserText.homePagePromotionFreemiumDBPDescriptionMarkdown
}

let actionButtonText = UserText.homePagePromotionFreemiumDBPButtonTitle

return PromotionViewModel(image: .radarCheck,
text: text,
return PromotionViewModel(image: .informationRemover128,
title: title,
description: description,
proceedButtonText: actionButtonText,
proceedAction: proceedAction,
closeAction: closeAction)
Expand All @@ -37,22 +44,22 @@ extension PromotionViewModel {
proceedAction: @escaping () -> Void,
closeAction: @escaping () -> Void) -> PromotionViewModel {

var text = ""
var description = ""

switch (resultCount, brokerCount) {
case (1, _):
text = UserText.homePagePromotionFreemiumDBPPostScanEngagementResultSingleMatchText
description = UserText.homePagePromotionFreemiumDBPPostScanEngagementResultSingleMatchDescription
case (let resultCount, 1):
text = UserText.homePagePromotionFreemiumDBPPostScanEngagementResultSingleBrokerText(resultCount: resultCount)
description = UserText.homePagePromotionFreemiumDBPPostScanEngagementResultSingleBrokerDescription(resultCount: resultCount)
default:
text = UserText.homePagePromotionFreemiumDBPPostScanEngagementResultPluralText(resultCount: resultCount,
description = UserText.homePagePromotionFreemiumDBPPostScanEngagementResultPluralDescription(resultCount: resultCount,
brokerCount: brokerCount)
}

let actionButtonText = UserText.homePagePromotionFreemiumDBPPostScanEngagementButtonTitle

return PromotionViewModel(image: .radarCheck,
text: text,
return PromotionViewModel(image: .informationRemover128,
description: description,
proceedButtonText: actionButtonText,
proceedAction: proceedAction,
closeAction: closeAction)
Expand All @@ -61,11 +68,11 @@ extension PromotionViewModel {
static func freemiumDBPPromotionScanEngagementNoResults(proceedAction: @escaping () -> Void,
closeAction: @escaping () -> Void) -> PromotionViewModel {

let text = UserText.homePagePromotionFreemiumDBPPostScanEngagementNoResultsText
let description = UserText.homePagePromotionFreemiumDBPPostScanEngagementNoResultsDescription
let actionButtonText = UserText.homePagePromotionFreemiumDBPPostScanEngagementButtonTitle

return PromotionViewModel(image: .radarCheck,
text: text,
return PromotionViewModel(image: .informationRemover128,
description: description,
proceedButtonText: actionButtonText,
proceedAction: proceedAction,
closeAction: closeAction)
Expand Down
8 changes: 5 additions & 3 deletions DuckDuckGo/HomePage/Model/PromotionViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ extension HomePage.Models {
final class PromotionViewModel: ObservableObject {

let image: ImageResource
let text: String
let title: String?
let description: String
let proceedButtonText: String
let proceedAction: () -> Void
let closeAction: () -> Void

init(image: ImageResource, text: String, proceedButtonText: String, proceedAction: @escaping () -> Void, closeAction: @escaping () -> Void) {
init(image: ImageResource, title: String? = nil, description: String, proceedButtonText: String, proceedAction: @escaping () -> Void, closeAction: @escaping () -> Void) {
self.image = image
self.text = text
self.title = title
self.description = description
self.proceedButtonText = proceedButtonText
self.proceedAction = proceedAction
self.closeAction = closeAction
Expand Down
Loading

0 comments on commit 781b009

Please sign in to comment.