Skip to content

Commit

Permalink
Merge branch 'release/7.139.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
alessandroboron committed Sep 26, 2024
2 parents 63a18b7 + 059bc1a commit 6ef5460
Show file tree
Hide file tree
Showing 60 changed files with 2,410 additions and 243 deletions.
10 changes: 10 additions & 0 deletions .maestro/shared/onboarding.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,13 @@ appId: com.duckduckgo.mobile.ios
# - assertVisible: "Make DuckDuckGo your default browser."
- tapOn:
text: "Skip"

- runFlow:
when:
visible: "Which color looks best on me?"
commands:
- assertVisible: "Next"
- tapOn: "Next"
- assertVisible: "Where should I put your address bar?"
- assertVisible: "Next"
- tapOn: "Next"
66 changes: 66 additions & 0 deletions Core/Debouncer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// Debouncer.swift
// DuckDuckGo
//
// Copyright © 2024 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation

/// A class that provides a debouncing mechanism.
public final class Debouncer {
private let runLoop: RunLoop
private let mode: RunLoop.Mode
private var timer: Timer?

/// Initializes a new instance of `Debouncer`.
///
/// - Parameters:
/// - runLoop: The `RunLoop` on which the debounced actions will be scheduled. Defaults to the current run loop.
///
/// - mode: The `RunLoop.Mode` in which the debounced actions will be scheduled. Defaults to `.default`.
///
/// Use `RunLoop.main` for UI-related actions to ensure they run on the main thread.
public init(runLoop: RunLoop = .current, mode: RunLoop.Mode = .default) {
self.runLoop = runLoop
self.mode = mode
}

/// Debounces the provided block of code, executing it after a specified time interval elapses.
/// - Parameters:
/// - dueTime: The time interval (in seconds) to wait before executing the block.
/// - block: The closure to execute after the due time has passed.
///
/// If `dueTime` is less than or equal to zero, the block is executed immediately.
public func debounce(for dueTime: TimeInterval, block: @escaping () -> Void) {
timer?.invalidate()

guard dueTime > 0 else { return block() }

let timer = Timer(timeInterval: dueTime, repeats: false, block: { timer in
guard timer.isValid else { return }
block()
})

runLoop.add(timer, forMode: mode)
self.timer = timer
}

/// Cancels any pending execution of the debounced block.
public func cancel() {
timer?.invalidate()
timer = nil
}
}
7 changes: 5 additions & 2 deletions Core/DefaultVariantManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ extension FeatureName {
// public static let experimentalFeature = FeatureName(rawValue: "experimentalFeature")

public static let newOnboardingIntro = FeatureName(rawValue: "newOnboardingIntro")
public static let newOnboardingIntroHighlights = FeatureName(rawValue: "newOnboardingIntroHighlights")
public static let contextualDaxDialogs = FeatureName(rawValue: "contextualDaxDialogs")
}

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

VariantIOS(name: "ma", weight: 1, isIncluded: When.always, features: []),
VariantIOS(name: "mb", weight: 1, isIncluded: When.always, features: [.newOnboardingIntro]),
VariantIOS(name: "ms", weight: 1, isIncluded: When.always, features: [.newOnboardingIntro]),
VariantIOS(name: "mu", weight: 1, isIncluded: When.always, features: [.newOnboardingIntro, .contextualDaxDialogs]),
VariantIOS(name: "mx", weight: 1, isIncluded: When.always, features: [.newOnboardingIntroHighlights, .contextualDaxDialogs]),

returningUser
]
Expand Down
28 changes: 20 additions & 8 deletions Core/NSAttributedStringExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,26 @@ extension NSAttributedString {
}
}

// MARK: - AttributedString Helper Extensions

public extension String {

var attributed: NSAttributedString {
NSAttributedString(string: self)
}

var nsRange: NSRange {
NSRange(startIndex..., in: self)
}

func range(of string: String) -> NSRange {
(self as NSString).range(of: string)
}

}

// MARK: Helper Operators

/// Concatenates two `NSAttributedString` instances, returning a new `NSAttributedString`.
///
/// - Parameters:
Expand Down Expand Up @@ -115,11 +135,3 @@ public func + (lhs: NSAttributedString, rhs: String) -> NSAttributedString {
public func + (lhs: String, rhs: NSAttributedString) -> NSAttributedString {
NSAttributedString(string: lhs) + rhs
}

private extension String {

var nsRange: NSRange {
NSRange(startIndex..., in: self)
}

}
Loading

0 comments on commit 6ef5460

Please sign in to comment.