Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into graeme/partial-form-save
Browse files Browse the repository at this point in the history
  • Loading branch information
graeme committed Dec 9, 2024
2 parents 2447e45 + dc12bff commit ed9c1a6
Show file tree
Hide file tree
Showing 85 changed files with 1,548 additions and 1,019 deletions.
310 changes: 98 additions & 212 deletions DuckDuckGo.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,16 @@
ReferencedContainer = "container:LocalPackages/AppKitExtensions">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "NewTabPageTests"
BuildableName = "NewTabPageTests"
BlueprintName = "NewTabPageTests"
ReferencedContainer = "container:LocalPackages/NewTabPage">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down Expand Up @@ -299,6 +309,10 @@
argument = "-NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints YES"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "-SUEnableAutomaticChecks NO"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "-com.apple.CoreData.ConcurrencyDebug 1"
isEnabled = "YES">
Expand Down
18 changes: 10 additions & 8 deletions DuckDuckGo/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import FeatureFlags
import History
import MetricKit
import Networking
import NewTabPage
import Persistence
import PixelKit
import PixelExperimentKit
Expand Down Expand Up @@ -97,12 +98,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
private(set) lazy var newTabPageActionsManager: NewTabPageActionsManaging = NewTabPageActionsManager(
appearancePreferences: .shared,
activeRemoteMessageModel: activeRemoteMessageModel,
privacyStats: privacyStats,
openURLHandler: { url in
Task { @MainActor in
WindowControllersManager.shared.showTab(with: .contentFromURL(url, source: .appOpenUrl))
}
}
privacyStats: privacyStats
)
let privacyStats: PrivacyStatsCollecting
let activeRemoteMessageModel: ActiveRemoteMessageModel
Expand Down Expand Up @@ -267,13 +263,19 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
privacyConfigurationManager: ContentBlocking.shared.privacyConfigurationManager
)
)
activeRemoteMessageModel = ActiveRemoteMessageModel(remoteMessagingClient: remoteMessagingClient)
activeRemoteMessageModel = ActiveRemoteMessageModel(remoteMessagingClient: remoteMessagingClient, openURLHandler: { url in
WindowControllersManager.shared.showTab(with: .contentFromURL(url, source: .appOpenUrl))
})
} else {
// As long as remoteMessagingClient is private to App Delegate and activeRemoteMessageModel
// is used only by HomePage RootView as environment object,
// it's safe to not initialize the client for unit tests to avoid side effects.
remoteMessagingClient = nil
activeRemoteMessageModel = ActiveRemoteMessageModel(remoteMessagingStore: nil, remoteMessagingAvailabilityProvider: nil)
activeRemoteMessageModel = ActiveRemoteMessageModel(
remoteMessagingStore: nil,
remoteMessagingAvailabilityProvider: nil,
openURLHandler: { _ in }
)
}

featureFlagger = DefaultFeatureFlagger(
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/Autoconsent/autoconsent-bundle.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions DuckDuckGo/BookmarksBar/View/BookmarksBarMenuPopover.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@ extension BookmarksBarMenuPopover: BookmarksBarMenuViewControllerDelegate {
}

func popover(shouldPreventClosure: Bool) {
var popover: BookmarksBarMenuPopover! = self
while popover != nil {
var window = contentViewController?.view.window
while let popover = window?.contentViewController?.nextResponder as? Self {
popover.behavior = shouldPreventClosure ? .applicationDefined : .transient
popover = mainWindow?.contentViewController?.nextResponder as? BookmarksBarMenuPopover
window = window?.parent
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
//

import AppKit
import Utilities

typealias NSAttributedStringBuilder = ArrayBuilder<NSAttributedString>
extension NSAttributedString {
Expand Down
86 changes: 0 additions & 86 deletions DuckDuckGo/Common/Extensions/NSMenuItemExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,6 @@ extension NSMenuItem {
return item
}

convenience init(title string: String, action selector: Selector? = nil, target: AnyObject? = nil, keyEquivalent: NSEvent.KeyEquivalent = [], representedObject: Any? = nil, state: NSControl.StateValue = .off, items: [NSMenuItem]? = nil) {
self.init(title: string, action: selector, keyEquivalent: keyEquivalent.charCode)
if !keyEquivalent.modifierMask.isEmpty {
self.keyEquivalentModifierMask = keyEquivalent.modifierMask
}
self.target = target
self.representedObject = representedObject
self.state = state

if let items {
self.submenu = NSMenu(title: title, items: items)
}
}

convenience init(title string: String, action selector: Selector? = nil, target: AnyObject? = nil, keyEquivalent: NSEvent.KeyEquivalent = [], representedObject: Any? = nil, state: NSControl.StateValue = .off, @MenuBuilder items: () -> [NSMenuItem]) {
self.init(title: string, action: selector, target: target, keyEquivalent: keyEquivalent, representedObject: representedObject, state: state, items: items())
}

convenience init(action selector: Selector?) {
self.init()
self.action = selector
}

convenience init(bookmarkViewModel: BookmarkViewModel) {
self.init()

Expand All @@ -65,67 +42,4 @@ extension NSMenuItem {
representedObject = bookmarkViewModels
action = #selector(MainViewController.openAllInTabs(_:))
}

convenience init(title: String) {
self.init(title: title, action: nil, keyEquivalent: "")
}

var topMenu: NSMenu? {
var menuItem = self
while let parent = menuItem.parent {
menuItem = parent
}

return menuItem.menu
}

func removeFromParent() {
parent?.submenu?.removeItem(self)
}

@discardableResult
func alternate() -> NSMenuItem {
self.isAlternate = true
return self
}

@discardableResult
func hidden() -> NSMenuItem {
self.isHidden = true
if !keyEquivalent.isEmpty {
self.allowsKeyEquivalentWhenHidden = true
}
return self
}

@discardableResult
func submenu(_ submenu: NSMenu) -> NSMenuItem {
self.submenu = submenu
return self
}

@discardableResult
func withImage(_ image: NSImage?) -> NSMenuItem {
self.image = image
return self
}

@discardableResult
func targetting(_ target: AnyObject) -> NSMenuItem {
self.target = target
return self
}

@discardableResult
func withSubmenu(_ submenu: NSMenu) -> NSMenuItem {
self.submenu = submenu
return self
}

@discardableResult
func withModifierMask(_ mask: NSEvent.ModifierFlags) -> NSMenuItem {
self.keyEquivalentModifierMask = mask
return self
}

}
5 changes: 0 additions & 5 deletions DuckDuckGo/Common/Extensions/URLExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,6 @@ extension URL {
// base url for Error Page Alternate HTML loaded into Web View
static let error = URL(string: "duck://error")!

static func duckFavicon(for faviconURL: URL) -> URL? {
let encodedURL = faviconURL.absoluteString.percentEncoded(withAllowedCharacters: .urlPathAllowed)
return URL(string: "duck://favicon/\(encodedURL)")
}

static let dataBrokerProtection = URL(string: "duck://personal-information-removal")!

#if !SANDBOX_TEST_TOOL
Expand Down
1 change: 1 addition & 0 deletions DuckDuckGo/Common/View/SwiftUI/NSPopUpButtonView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import AppKit
import SwiftUI
import Utilities

struct PopupButtonItem<SelectionValue: Equatable>: Equatable {

Expand Down
19 changes: 19 additions & 0 deletions DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ extension HomePage.Models {
// HTML NTP doesn't refresh on appear so we have to connect to the appear signal
// (the notification in this case) to trigger a refresh.
NotificationCenter.default.addObserver(self, selector: #selector(refreshFeaturesForHTMLNewTabPage(_:)), name: .newTabPageWebViewDidAppear, object: nil)

// This is just temporarily here to run an A/A test to check the new experiment framework works as expected
_ = Application.appDelegate.featureFlagger.getCohortIfEnabled(for: CredentialsSavingFlag())
}

@MainActor func performAction(for featureType: FeatureType) {
Expand Down Expand Up @@ -445,3 +448,19 @@ extension AppVersion {
return "\(components[0]).\(components[1])"
}
}

// This is just temporarily here to run an A/A test to check the new experiment framework works as expected
public struct CredentialsSavingFlag: FeatureFlagExperimentDescribing {
public init() {}

public typealias CohortType = Cohort

public var rawValue = "credentialSaving"

public var source: FeatureFlagSource = .remoteReleasable(.subfeature(ExperimentTestSubfeatures.experimentTestAA))

public enum Cohort: String, FlagCohort {
case control
case blue
}
}
67 changes: 67 additions & 0 deletions DuckDuckGo/NewTabPage/ActiveRemoteMessageModel+NewTabPage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//
// ActiveRemoteMessageModel+NewTabPage.swift
//
// 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 Combine
import NewTabPage
import RemoteMessaging

extension ActiveRemoteMessageModel: NewTabPageActiveRemoteMessageProviding {
var remoteMessagePublisher: AnyPublisher<RemoteMessageModel?, Never> {
$remoteMessage.dropFirst().eraseToAnyPublisher()
}

func isMessageSupported(_ message: RemoteMessageModel) -> Bool {
return message.content?.isSupported == true
}

func handleAction(_ action: RemoteAction?, andDismissUsing button: RemoteMessageButton) async {
if let action {
await handleAction(action)
}
await dismissRemoteMessage(with: .init(button))
}

private func handleAction(_ remoteAction: RemoteAction) async {
switch remoteAction {
case .url(let value), .share(let value, _), .survey(let value):
if let url = URL.makeURL(from: value) {
await openURLHandler(url)
}
case .appStore:
await openURLHandler(.appStore)
default:
break
}
}
}

extension RemoteMessageViewModel.ButtonAction {

init(_ button: RemoteMessageButton) {
switch button {
case .close:
self = .close
case .action:
self = .action
case .primaryAction:
self = .primaryAction
case .secondaryAction:
self = .secondaryAction
}
}
}
48 changes: 48 additions & 0 deletions DuckDuckGo/NewTabPage/AppearancePreferences+NewTabPage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// AppearancePreferences+NewTabPage.swift
//
// 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 Combine
import NewTabPage

extension AppearancePreferences: NewTabPageSectionsVisibilityProviding {
var isFavoritesVisible: Bool {
get {
isFavoriteVisible
}
set {
isFavoriteVisible = newValue
}
}

var isPrivacyStatsVisible: Bool {
get {
isRecentActivityVisible
}
set {
isRecentActivityVisible = newValue
}
}

var isFavoritesVisiblePublisher: AnyPublisher<Bool, Never> {
$isFavoriteVisible.dropFirst().removeDuplicates().eraseToAnyPublisher()
}

var isPrivacyStatsVisiblePublisher: AnyPublisher<Bool, Never> {
$isRecentActivityVisible.dropFirst().removeDuplicates().eraseToAnyPublisher()
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// NewTabPageNextStepsCardsProviding.swift
// ContinueSetUpModel+NewTabPage.swift
//
// Copyright © 2024 DuckDuckGo. All rights reserved.
//
Expand All @@ -18,24 +18,9 @@

import Common
import Combine
import UserScript
import NewTabPage
import PixelKit

protocol NewTabPageNextStepsCardsProviding: AnyObject {
var isViewExpanded: Bool { get set }
var isViewExpandedPublisher: AnyPublisher<Bool, Never> { get }

var cards: [NewTabPageNextStepsCardsClient.CardID] { get }
var cardsPublisher: AnyPublisher<[NewTabPageNextStepsCardsClient.CardID], Never> { get }

@MainActor
func handleAction(for card: NewTabPageNextStepsCardsClient.CardID)

@MainActor
func dismiss(_ card: NewTabPageNextStepsCardsClient.CardID)

func willDisplayCards(_ cards: [NewTabPageNextStepsCardsClient.CardID])
}
import UserScript

extension HomePage.Models.ContinueSetUpModel: NewTabPageNextStepsCardsProviding {
var isViewExpanded: Bool {
Expand Down
Loading

0 comments on commit ed9c1a6

Please sign in to comment.