Skip to content

Commit

Permalink
Merge branch 'main' into sam/remove-apptp
Browse files Browse the repository at this point in the history
# By Daniel Bernal (11) and others
# Via Mariusz Śpiewak (3) and others
* main: (63 commits)
  Release 7.115.1-1 (#2770)
  Fix iOS auto-clearing fails to remove cookies (#2769)
  Release 7.115.1-0 (#2768)
  Fix iOS auto-clearing fails to remove cookies (#2767)
  iOS: VPN screen improvements (#2721)
  Release 7.116.0-2 (#2763)
  Remove "Thank You" prompt (#2762)
  Test to ensure that page refresh doesn't affect url bar focus (#2749)
  Add support for uploading crash reports to Sentry (#2720)
  Replace SwiftLintPlugin with SwiftLintTool (#2710)
  Release 7.116.0-1 (#2761)
  Remove validator app (#2754)
  Fix crash when quickly adding/removing tabs in switcher (#2760)
  Fix settings navigation bar colors after reopening (#2758)
  Alpha ad-hoc lane (#2492)
  Keep a weak reference to UserScriptMessageBroker (#2755)
  Add refresh config cell to top of debug (#2735)
  VPN: Replace available interfaces in VPN metadata (#2750)
  Require device auth to be set in order to use Sync (#2722)
  Add new iOS pixels for measuring navigation  (#2730)
  ...

# Conflicts:
#	DuckDuckGo.xcodeproj/project.pbxproj
#	DuckDuckGo/AppDelegate.swift
#	DuckDuckGo/MainViewController.swift
  • Loading branch information
samsymons committed Apr 20, 2024
2 parents c854d06 + 8b16d76 commit f798eb2
Show file tree
Hide file tree
Showing 415 changed files with 23,112 additions and 4,616 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ jobs:
--form "file=@${asana_dsyms_path};type=application/zip"
fi
- name: Upload debug symbols to S3
if: always()
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }}
DSYM_S3_PATH: s3://${{ vars.DSYM_BUCKET_NAME }}/${{ vars.DSYM_BUCKET_PREFIX }}/
run: |
aws s3 cp "${{ github.workspace }}/DuckDuckGo-${{ env.app_version }}-dSYM.zip" ${{ env.DSYM_S3_PATH }}
- name: Send Mattermost message
if: ${{ success() || failure() }} # Don't execute when cancelled
env:
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/stale-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Close Stale Pull Requests

on:
schedule:
- cron: '0 0 * * *'

jobs:
close_stale_prs:
runs-on: ubuntu-latest
steps:
- name: Close stale pull requests
uses: actions/stale@v9
with:
stale-pr-message: 'This PR has been inactive for more than 7 days and will be automatically closed 7 days from now.'
days-before-pr-stale: 7
close-pr-message: 'This PR has been closed after 14 days of inactivity. Feel free to reopen it if you plan to continue working on it or have further discussions.'
days-before-pr-close: 7
stale-pr-label: stale
exempt-draft-pr: true
56 changes: 56 additions & 0 deletions .maestro/browser_features/search_bar.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# search_bar.yaml
appId: com.duckduckgo.mobile.ios
tags:
- release

---

# Set up
- clearState
- launchApp
- runFlow:
when:
visible:
text: "Let’s Do It!"
index: 0
file: ../shared/onboarding.yaml

# Load Site
- assertVisible:
id: "searchEntry"
- tapOn:
id: "searchEntry"
- inputText: "https://privacy-test-pages.site/features/auto-refresh.html"
- pressKey: Enter

# Manage onboarding
- runFlow:
when:
visible:
text: "Got It"
index: 0
file: ../shared/onboarding_browsing.yaml

- assertVisible: "Website that refreshes every 3 seconds."

# Start typing
- tapOn:
id: "searchEntry"
- inputText: "abcd"
- assertVisible: "abcd"

# Delay execution and let page refresh
- runFlow:
file: ../shared/delay.yaml

# More text to append
- inputText: "efgh"
- assertVisible: "abcdefgh"

# Delay execution and let page refresh
- runFlow:
file: ../shared/delay.yaml

- inputText: "ijkl"
- assertVisible: "abcdefghijkl"

4 changes: 4 additions & 0 deletions .maestro/data_clearing_tests/01_fire_proofing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ tags:
id: "searchEntry"
- inputText: "https://setcookie.net"
- pressKey: Enter
- runFlow:
file: ../shared/hide_daxdialogs.yaml

# Set a cookie
- assertVisible: "Cookie Test"
Expand All @@ -44,6 +46,8 @@ tags:
- tapOn: "Close Tabs and Clear Data"
- tapOn:
id: "alert.forget-data.confirm"
- assertVisible: "Cancel"
- tapOn: "Cancel"
- assertVisible:
id: "searchEntry"
- tapOn: "Close Tabs and Clear Data"
Expand Down
13 changes: 13 additions & 0 deletions .maestro/shared/delay.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# delay.yaml

appId: com.duckduckgo.mobile.ios
---

- runFlow:
when:
visible:
text: "This is just a text that will be never matched so this invocation will cause 5s delay"
index: 0
commands:
- stopApp

11 changes: 11 additions & 0 deletions .maestro/shared/hide_daxdialogs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
appId: com.duckduckgo.mobile.ios
---

- runFlow:
when:
visible:
id: "DaxIcon"
commands:
- tapOn: "Hide"
- tapOn: "Hide Tips Forever"

2 changes: 1 addition & 1 deletion .maestro/shared/onboarding.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ appId: com.duckduckgo.mobile.ios
index: 0
- assertVisible: "Make DuckDuckGo your default browser."
- tapOn:
id: "Skip"
text: "Skip"
2 changes: 1 addition & 1 deletion Configuration/Version.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1 @@
MARKETING_VERSION = 7.114.0
MARKETING_VERSION = 7.115.1
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// AccountManagerExtension.swift
// AccountManager+AppGroup.swift
// DuckDuckGo
//
// Copyright © 2024 DuckDuckGo. All rights reserved.
Expand All @@ -17,8 +17,6 @@
// limitations under the License.
//

#if SUBSCRIPTION

import Foundation
import Subscription

Expand All @@ -27,5 +25,3 @@ public extension AccountManager {
self.init(subscriptionAppGroup: Bundle.main.appGroup(bundle: .subs))
}
}

#endif
1 change: 1 addition & 0 deletions Core/AppDeepLinkSchemes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public enum AppDeepLinkSchemes: String, CaseIterable {
case addFavorite = "ddgAddFavorite"

case openVPN = "ddgOpenVPN"
case openPasswords = "ddgOpenPasswords"

public var url: URL {
URL(string: rawValue + "://")!
Expand Down
4 changes: 2 additions & 2 deletions Core/AppPrivacyConfigurationDataProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import BrowserServicesKit
final public class AppPrivacyConfigurationDataProvider: EmbeddedDataProvider {

public struct Constants {
public static let embeddedDataETag = "\"24f5176757f3bafd1ea7e457413fcff0\""
public static let embeddedDataSHA = "f318ef32f8069a458e8a4505eb8f53e3c25b60311d2daf763029c1e2606cea88"
public static let embeddedDataETag = "\"04caca2ca6549201eea931ca869c5e39\""
public static let embeddedDataSHA = "ddb923e2de2a0a27bc1050e32c89276834a3f3dd61b7c8672dac6f2d93047333"
}

public var embeddedDataEtag: String {
Expand Down
4 changes: 2 additions & 2 deletions Core/AppTrackerDataSetProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import BrowserServicesKit
final public class AppTrackerDataSetProvider: EmbeddedDataProvider {

public struct Constants {
public static let embeddedDataETag = "\"07bd7f610e3fa234856abcc2b56ab10e\""
public static let embeddedDataSHA = "1d7ef8f4c5a717a5d82f43383e33290021358d6255db12b6fdd0928e28d123ee"
public static let embeddedDataETag = "\"ef8ebcc98d8abccca793c7e04422b160\""
public static let embeddedDataSHA = "e2e8e5e191df54227222fbb0545a7eb8634b1156a69182323981bb6aed2c639d"
}

public var embeddedDataEtag: String {
Expand Down
9 changes: 9 additions & 0 deletions Core/AppURLs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import BrowserServicesKit
import Foundation

// swiftlint:disable line_length

public extension URL {

private static let base: String = ProcessInfo.processInfo.environment["BASE_URL", default: "https://duckduckgo.com"]
Expand All @@ -31,7 +33,12 @@ public extension URL {
static let emailProtection = URL(string: "\(base)/email")!
static let emailProtectionSignUp = URL(string: "\(base)/email/start-incontext")!
static let emailProtectionQuickLink = URL(string: AppDeepLinkSchemes.quickLink.appending("\(ddg.host!)/email"))!
static let emailProtectionAccountLink = URL(string: AppDeepLinkSchemes.quickLink.appending("\(ddg.host!)/email/settings/account"))!
static let emailProtectionSupportLink = URL(string: AppDeepLinkSchemes.quickLink.appending("\(ddg.host!)/email/settings/support"))!
static let emailProtectionHelpPageLink = URL(string: AppDeepLinkSchemes.quickLink.appending("\(ddg.host!)/duckduckgo-help-pages/email-protection/what-is-duckduckgo-email-protection/"))!
static let aboutLink = URL(string: AppDeepLinkSchemes.quickLink.appending("\(ddg.host!)/about"))!
static let apps = URL(string: AppDeepLinkSchemes.quickLink.appending("\(ddg.host!)/apps"))!
static let searchSettings = URL(string: AppDeepLinkSchemes.quickLink.appending("\(ddg.host!)/settings"))!

static let surrogates = URL(string: "\(staticBase)/surrogates.txt")!

Expand Down Expand Up @@ -262,3 +269,5 @@ public final class StatisticsDependentURLFactory {
}

}

// swiftlint:enable line_length
49 changes: 35 additions & 14 deletions Core/DailyPixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,28 @@ public final class DailyPixel {
private static let storage: UserDefaults = UserDefaults(suiteName: Constant.dailyPixelStorageIdentifier)!

/// Sends a given Pixel once per day.
/// This means a pixel will get sent twice the first time it is called per-day.
/// This is useful in situations where pixels receive spikes in volume, as the daily pixel can be used to determine how many users are actually affected.
/// Does not append any suffix unlike the alternative function below
public static func fire(pixel: Pixel.Event,
error: Swift.Error? = nil,
withAdditionalParameters params: [String: String] = [:],
includedParameters: [Pixel.QueryParameters] = [.atb, .appVersion],
onComplete: @escaping (Swift.Error?) -> Void = { _ in }) {
var key: String = pixel.name

if !pixel.hasBeenFiredToday(dailyPixelStorage: storage) {
if let error = error {
var errorParams: [String: String] = [:]
errorParams.appendErrorPixelParams(error: error)
key.append(":\(createSortedStringOfValues(from: errorParams))")
}

if !hasBeenFiredToday(forKey: key, dailyPixelStorage: storage) {
Pixel.fire(pixel: pixel,
withAdditionalParameters: params,
error: error,
includedParameters: includedParameters,
withAdditionalParameters: params,
onComplete: onComplete)
updatePixelLastFireDate(pixel: pixel)
updatePixelLastFireDate(forKey: key)
} else {
onComplete(Error.alreadyFired)
}
Expand All @@ -74,7 +82,9 @@ public final class DailyPixel {
includedParameters: [Pixel.QueryParameters] = [.atb, .appVersion],
onDailyComplete: @escaping (Swift.Error?) -> Void = { _ in },
onCountComplete: @escaping (Swift.Error?) -> Void = { _ in }) {
if !pixel.hasBeenFiredToday(dailyPixelStorage: storage) {
let key: String = pixel.name

if !hasBeenFiredToday(forKey: key, dailyPixelStorage: storage) {
Pixel.fire(
pixelNamed: pixel.name + "_d",
withAdditionalParameters: params,
Expand All @@ -84,7 +94,7 @@ public final class DailyPixel {
} else {
onDailyComplete(Error.alreadyFired)
}
updatePixelLastFireDate(pixel: pixel)
updatePixelLastFireDate(forKey: key)
var newParams = params
if let error {
newParams.appendErrorPixelParams(error: error)
Expand All @@ -97,19 +107,30 @@ public final class DailyPixel {
)
}

private static func updatePixelLastFireDate(pixel: Pixel.Event) {
storage.set(Date(), forKey: pixel.name)
private static func updatePixelLastFireDate(forKey key: String) {
storage.set(Date(), forKey: key)
}

}

private extension Pixel.Event {

func hasBeenFiredToday(dailyPixelStorage: UserDefaults) -> Bool {
if let lastFireDate = dailyPixelStorage.object(forKey: name) as? Date {
private static func hasBeenFiredToday(forKey key: String, dailyPixelStorage: UserDefaults) -> Bool {
if let lastFireDate = dailyPixelStorage.object(forKey: key) as? Date {
return Date().isSameDay(lastFireDate)
}
return false
}

private static func createSortedStringOfValues(from dict: [String: String], maxLength: Int = 50) -> String {
let sortedKeys = dict.keys.sorted()

let uniqueString = sortedKeys.compactMap { key -> String? in
guard let value = dict[key] else { return nil }
return value
}.joined(separator: ";")

if uniqueString.count > maxLength {
return String(uniqueString.prefix(maxLength))
}

return uniqueString
}

}
4 changes: 2 additions & 2 deletions Core/DefaultVariantManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ extension FeatureName {
// Define your feature e.g.:
// public static let experimentalFeature = FeatureName(rawValue: "experimentalFeature")

// Experiment coming soon
public static let history = FeatureName(rawValue: "history")
public static let newSuggestionLogic = FeatureName(rawValue: "newSuggestionLogic")
}

public struct VariantIOS: Variant {
Expand Down Expand Up @@ -63,7 +63,7 @@ public struct VariantIOS: Variant {
VariantIOS(name: "sd", weight: doNotAllocate, isIncluded: When.always, features: []),
VariantIOS(name: "se", weight: doNotAllocate, isIncluded: When.always, features: []),

VariantIOS(name: "mc", weight: 1, isIncluded: When.inEnglish, features: []),
VariantIOS(name: "mc", weight: 1, isIncluded: When.inEnglish, features: [.newSuggestionLogic]),
VariantIOS(name: "md", weight: 1, isIncluded: When.inEnglish, features: [.history]),

returningUser
Expand Down
4 changes: 4 additions & 0 deletions Core/Pixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,15 @@ public struct PixelParameters {
public static let function = "function"
public static let line = "line"
public static let reason = "reason"
public static let vpnCohort = "cohort"

// Return user
public static let returnUserErrorCode = "error_code"
public static let returnUserOldATB = "old_atb"
public static let returnUserNewATB = "new_atb"

// Pixel Experiment
public static let cohort = "cohort"
}

public struct PixelValues {
Expand Down
Loading

0 comments on commit f798eb2

Please sign in to comment.