Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
diegoreymendez committed Oct 22, 2024
1 parent e6ccb08 commit 607feb0
Show file tree
Hide file tree
Showing 18 changed files with 124 additions and 89 deletions.
2 changes: 2 additions & 0 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3827,6 +3827,7 @@
7B1E819C27C8874900FF0E60 /* ContentOverlay.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ContentOverlay.storyboard; sourceTree = "<group>"; };
7B1E819D27C8874900FF0E60 /* ContentOverlayViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentOverlayViewController.swift; sourceTree = "<group>"; };
7B25FE322AD12C990012AFAB /* NetworkProtectionMac */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = NetworkProtectionMac; sourceTree = "<group>"; };
7B26AEE52CC674C900D66678 /* BrowserServicesKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = BrowserServicesKit; path = ../BrowserServicesKit; sourceTree = SOURCE_ROOT; };
7B2DDCF72A93A8BB0039D884 /* NetworkProtectionAppEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionAppEvents.swift; sourceTree = "<group>"; };
7B2E52242A5FEC09000C6D39 /* NetworkProtectionAgentNotificationsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionAgentNotificationsPresenter.swift; sourceTree = "<group>"; };
7B3618C12ADE75C8000D6154 /* NetworkProtectionNavBarPopoverManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionNavBarPopoverManager.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -5519,6 +5520,7 @@
378E279C2970217400FCADA2 /* LocalPackages */ = {
isa = PBXGroup;
children = (
7B26AEE52CC674C900D66678 /* BrowserServicesKit */,
9D9DE5712C63A96400D20B15 /* AppKitExtensions */,
7B9167A82C09E88800322310 /* AppLauncher */,
378E279D2970217400FCADA2 /* BuildToolPlugins */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,6 @@
"version" : "3.0.0"
}
},
{
"identity" : "browserserviceskit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/BrowserServicesKit",
"state" : {
"revision" : "c05ef03b3320ccecdace3b1d53d945313585c170"
}
},
{
"identity" : "content-scope-scripts",
"kind" : "remoteSourceControl",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
buildConfiguration = "CI"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/InfoPlist.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "DuckDuckGo App Store"
"value" : "DuckDuckGo"
}
},
"es" : {
Expand Down
10 changes: 5 additions & 5 deletions DuckDuckGo/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -30600,7 +30600,7 @@
},
"letsmove.alert.message" : {
"comment" : "Message of the alert shown if the app is launched not from the /Applications folder – suggesting to move it there",
"extractionState" : "stale",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
Expand Down Expand Up @@ -30660,7 +30660,7 @@
},
"letsmove.alert.title" : {
"comment" : "Title of the alert shown if the app is launched not from the /Applications folder – suggesting to move it there",
"extractionState" : "stale",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
Expand Down Expand Up @@ -30720,7 +30720,7 @@
},
"letsmove.could.not.move" : {
"comment" : "Error message when moving the app to the /Applications folder failed",
"extractionState" : "stale",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
Expand Down Expand Up @@ -30780,7 +30780,7 @@
},
"letsmove.dont.move.button" : {
"comment" : "Do Not Move to the /Applications folder button title",
"extractionState" : "stale",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
Expand Down Expand Up @@ -30840,7 +30840,7 @@
},
"letsmove.move.button" : {
"comment" : "Move the /Applications folder button title",
"extractionState" : "stale",
"extractionState" : "extracted_with_value",
"localizations" : {
"de" : {
"stringUnit" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ import Foundation
import LoginItems
import NetworkProtection
import NetworkProtectionIPC
import NetworkProtectionProxy
import NetworkProtectionUI
import os.log
import Subscription
import VPNAppLauncher
import SwiftUI
import NetworkProtectionProxy
import VPNAppLauncher

protocol NetworkProtectionIPCClient {
var ipcStatusObserver: ConnectionStatusObserver { get }
Expand Down Expand Up @@ -167,7 +168,8 @@ final class NetworkProtectionNavBarPopoverManager: NetPPopoverManager {
statusObserver: statusReporter.statusObserver,
activeSitePublisher: activeSitePublisher,
forMenuApp: false,
vpnSettings: vpnSettings)
vpnSettings: vpnSettings,
logger: Logger(subsystem: "DuckDuckGo", category: "TipKit"))

let popover = NetworkProtectionPopover(
statusViewModel: statusViewModel,
Expand Down
7 changes: 5 additions & 2 deletions DuckDuckGo/TipKit/TipKitAppEventHandling.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,17 @@ struct TipKitAppEventHandler: TipKitAppEventHandling {

let appConfigurationGroupIdentifier = Bundle.main.appGroup(bundle: .appConfiguration)

/*
guard let dataStoreLocation = try? DataStoreLocation.groupContainer(identifier: appConfigurationGroupIdentifier) else {
fatalError()
}
*/
let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appConfigurationGroupIdentifier)!

controller.configureTipKit([
.displayFrequency(.immediate),
.datastoreLocation(dataStoreLocation)
.displayFrequency(.immediate) //,
//.datastoreLocation(.url(url))
])
} else {
logger.log("TipKit initialization skipped: iOS 17.0 or later is required.")
Expand Down
1 change: 1 addition & 0 deletions DuckDuckGoVPN/DuckDuckGoVPNDebug.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<string>$(NETP_APP_GROUP)</string>
<string>$(IPC_APP_GROUP)</string>
<string>$(SUBSCRIPTION_APP_GROUP)</string>
<string>$(APP_CONFIGURATION_APP_GROUP)</string>
</array>
<key>keychain-access-groups</key>
<array>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ import AppKit
import Foundation
import Combine
import Common
import SwiftUI
import NetworkProtection
import LoginItems
import NetworkProtection
import os.log
import SwiftUI
import TipKitUtils

/// Abstraction of the the VPN status bar menu with a simple interface.
Expand Down Expand Up @@ -150,7 +151,8 @@ public final class StatusBarMenu: NSObject {
statusObserver: statusReporter.statusObserver,
activeSitePublisher: activeSitePublisher,
forMenuApp: true,
vpnSettings: VPNSettings(defaults: userDefaults))
vpnSettings: VPNSettings(defaults: userDefaults),
logger: Logger.init(subsystem: "DuckDuckGo", category: "TipKit"))

let debugInformationViewModel = DebugInformationViewModel(showDebugInformation: isOptionKeyPressed)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,8 @@ import TipKit

/// A tip to suggest to the user to use the autoconnect option for the VPN.
///
struct VPNAutoconnectTip {}

/// Necessary split to support older iOS versions.
///
@available(macOS 14.0, *)
extension VPNAutoconnectTip: Tip {
struct VPNAutoconnectTip: Tip {

enum ActionIdentifiers: String {
case enable = "com.duckduckgo.vpn.tip.autoconnect.action.enable"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,8 @@ import TipKit

/// A tip to suggest using domain exclusions when a site doesn't work.
///
struct VPNDomainExclusionsTip {}

/// Necessary split to support older iOS versions.
///
@available(macOS 14.0, *)
extension VPNDomainExclusionsTip: Tip {
struct VPNDomainExclusionsTip: Tip {

@Parameter(.transient)
static var vpnEnabled: Bool = false
Expand All @@ -39,7 +35,7 @@ extension VPNDomainExclusionsTip: Tip {
/// This condition may be indicative that the user is struggling, so they might want
/// to exclude a site.
///
static let viewOpenedWhehVPNAlreadyConnectedEvent = Tips.Event(id: "com.duckduckgo.vpn.tip.domainExclusions.popoverOpenedWhileAlreadyConnected")
static let viewOpenedWhenVPNAlreadyConnectedEvent = Tips.Event(id: "com.duckduckgo.vpn.tip.domainExclusions.popoverOpenedWhileAlreadyConnected")

var id: String {
"com.duckduckgo.vpn.tip.domainExclusions"
Expand All @@ -57,15 +53,15 @@ extension VPNDomainExclusionsTip: Tip {
Image(.domainExclusionsTip)
}

var rules: [Rule] {
var rules: [Self.Rule] {
#Rule(Self.$hasActiveSite) {
$0 == true
$0
}
#Rule(Self.$vpnEnabled) {
$0 == true
$0
}
#Rule(Self.viewOpenedWhehVPNAlreadyConnectedEvent) {
$0.donations.count > 1
#Rule(Self.viewOpenedWhenVPNAlreadyConnectedEvent) {
$0.donations.count > 0
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ import TipKit

/// A tip to suggest to the user to change their location using geo-switching
///
struct VPNGeoswitchingTip {}

@available(macOS 14.0, *)
extension VPNGeoswitchingTip: Tip {
struct VPNGeoswitchingTip: Tip {

static let vpnConnectedEvent = Tips.Event(id: "com.duckduckgo.vpn.tip.geoswitching.vpnConnectedEvent")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ import AppKit
import Combine
import Common
import NetworkProtection
import os.log
import TipKit
import TipKitUtils

@MainActor
public final class VPNTipsModel: ObservableObject {

@Published
private(set) var activeSiteInfo: ActiveSiteInfo? {
didSet {
willSet {
guard #available(macOS 14.0, *) else {
return
}
Expand All @@ -38,13 +40,20 @@ public final class VPNTipsModel: ObservableObject {

@Published
private(set) var connectionStatus: ConnectionStatus {
didSet {
willSet {
guard #available(macOS 14.0, *) else {
return
}

switch connectionStatus {
switch newValue {
case .connected:
if case connectionStatus = .connecting {
Task {
print("🧉💎 Geoswitching tip donated")
await VPNGeoswitchingTip.vpnConnectedEvent.donate()
}
}

VPNAutoconnectTip.vpnEnabled = true
VPNDomainExclusionsTip.vpnEnabled = true
default:
Expand All @@ -56,57 +65,74 @@ public final class VPNTipsModel: ObservableObject {

@Published
private(set) var featureFlag: Bool
let tips: TipGrouping

@Published
private var tips: TipGrouping

private let vpnSettings: VPNSettings
private let logger: Logger
private var cancellables = Set<AnyCancellable>()

static func makeTips(forMenuApp isMenuApp: Bool) -> TipGrouping {
static func makeTips(forMenuApp isMenuApp: Bool, logger: Logger) -> TipGrouping {

logger.debug("🧉🤌 makeTips")

guard #available(macOS 14.0, *) else {
return EmptyTipGroup()
}

let domainExclusionsTip = VPNDomainExclusionsTip()
let geoswitchingTip = VPNGeoswitchingTip()

Task {
for await statusUpdate in geoswitchingTip.statusUpdates {
logger.debug("🧉 VPNGeoswitchingTip status updated: \(String(describing: statusUpdate), privacy: .public)")
logger.debug("🪙 VPNGeoswitchingTip summary:\nL shouldDisplay: \(String(describing: geoswitchingTip.shouldDisplay), privacy: .public)")
}
}

Task {
for await statusUpdate in domainExclusionsTip.statusUpdates {
logger.debug("🧉 VPNDomainExclusionsTip status updated: \(String(describing: statusUpdate), privacy: .public)")
logger.debug("🪙 VPNDomainExclusionsTip summary:\nL shouldDisplay: \(String(describing: domainExclusionsTip.shouldDisplay), privacy: .public)\nL hasActiveSite: \(String(describing: VPNDomainExclusionsTip.hasActiveSite), privacy: .public)\nL vpnEnabled: \(String(describing: VPNDomainExclusionsTip.vpnEnabled), privacy: .public)")
}
}

// This is temporarily disabled until Xcode 16 is available.
// Ref: https://app.asana.com/0/414235014887631/1208528787265444/f
//
// if #available(macOS 15.0, *) {
// if isMenuApp {
// return TipGroup(.ordered) {
// VPNGeoswitchingTip()
// VPNAutoconnectTip()
// }
// } else {
// return TipGroup(.ordered) {
// VPNGeoswitchingTip()
// VPNDomainExclusionsTip()
// VPNAutoconnectTip()
// }
// return TipGroup(.ordered) {
// tips
// }
// }
if #available(macOS 14, *) {
if isMenuApp {
return LegacyTipGroup(.ordered) {
VPNGeoswitchingTip()
VPNAutoconnectTip()
}
} else {
return LegacyTipGroup(.ordered) {
VPNGeoswitchingTip()
VPNDomainExclusionsTip()
VPNAutoconnectTip()
}
// } else { ... what's below
if isMenuApp {
return LegacyTipGroup(.ordered) {
VPNGeoswitchingTip()
VPNAutoconnectTip()
}
} else {
return EmptyTipGroup()
return LegacyTipGroup(.ordered) {
VPNGeoswitchingTip()
VPNDomainExclusionsTip()
VPNAutoconnectTip()
}
}
}

public init(featureFlagPublisher: CurrentValuePublisher<Bool, Never>,
statusObserver: ConnectionStatusObserver,
activeSitePublisher: CurrentValuePublisher<ActiveSiteInfo?, Never>,
forMenuApp isMenuApp: Bool,
vpnSettings: VPNSettings) {
vpnSettings: VPNSettings,
logger: Logger) {

print("🧉🟢 New model instance")
self.activeSiteInfo = activeSitePublisher.value
self.connectionStatus = statusObserver.recentValue
self.featureFlag = featureFlagPublisher.value
self.tips = Self.makeTips(forMenuApp: isMenuApp)
self.logger = logger
self.tips = Self.makeTips(forMenuApp: isMenuApp, logger: logger)
self.vpnSettings = vpnSettings

if #available(macOS 14.0, *) {
Expand Down Expand Up @@ -152,4 +178,9 @@ public final class VPNTipsModel: ObservableObject {
vpnSettings.connectOnLogin = true
}
}

@available(macOS 14.0, *)
var currentTip: (any Tip)? {
tips.currentTip
}
}
Loading

0 comments on commit 607feb0

Please sign in to comment.