Skip to content

Commit

Permalink
Update onboarding copy to comply with App Store (#2240)
Browse files Browse the repository at this point in the history
Task/Issue URL: https://app.asana.com/0/1199230911884351/1206662058767730/f
Tech Design URL:
CC:

Description:

This PR updates the onboarding copy to specify that beginning the onboarding flow will cause a login item to get added to the system.
  • Loading branch information
samsymons authored Feb 22, 2024
1 parent 5f13100 commit c1f2a21
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ final class NetworkProtectionNavBarPopoverManager {
]
}
},
agentLoginItem: LoginItem.vpnMenu
agentLoginItem: LoginItem.vpnMenu,
isMenuBarStatusView: false
)
popover.delegate = delegate

Expand Down
3 changes: 2 additions & 1 deletion DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ final class DuckDuckGoVPNAppDelegate: NSObject, NSApplicationDelegate {
})
]
},
agentLoginItem: nil)
agentLoginItem: nil,
isMenuBarStatusView: true)
}

@MainActor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ final class UserText {
static let networkProtectionOnboardingAllowVPNDescPrefix = NSLocalizedString("network.protection.onboarding.allow.vpn.desc.prefix", value: "Select ", comment: "Non-bold prefix for the onboarding allow-VPN description")
static let networkProtectionOnboardingAllowVPNDescAllow = NSLocalizedString("network.protection.onboarding.allow.vpn.desc.allow", value: "Allow", comment: "'Allow' word between the prefix and suffix for the onboarding allow-VPN description")
static let networkProtectionOnboardingAllowVPNDescSuffix = NSLocalizedString("network.protection.onboarding.allow.vpn.desc.suffix", value: " when prompted to finish setting up Network Protection.", comment: "Non-bold suffix for the onboarding allow-VPN description")
static let networkProtectionOnboardingAllowVPNDescExpandedSuffix = NSLocalizedString("network.protection.onboarding.allow.vpn.desc.expanded.suffix", value: " when prompted to finish setting up Network Protection.\n\nThis adds a shortcut in the menu bar so you can still access the VPN if the browser isn't running.", comment: "Non-bold suffix for the onboarding allow-VPN description")
static let networkProtectionOnboardingAllowVPNAction = NSLocalizedString("network.protection.onboarding.allow.vpn.action", value: "Add VPN Configuration...", comment: "Action button title for the onboarding allow-VPN view")

static let networkProtectionOnboardingMoveToApplicationsTitle = NSLocalizedString("network.protection.onboarding.move.to.applications.title", value: "Move DuckDuckGo App", comment: "Title for the onboarding move-app-to-applications step")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ public final class StatusBarMenu: NSObject {
iconProvider: IconProvider,
appLauncher: AppLaunching,
menuItems: @escaping () -> [MenuItem],
agentLoginItem: LoginItem?) {
agentLoginItem: LoginItem?,
isMenuBarStatusView: Bool) {

self.model = model
let statusItem = statusItem ?? NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
Expand All @@ -67,7 +68,8 @@ public final class StatusBarMenu: NSObject {
statusReporter: statusReporter,
appLauncher: appLauncher,
menuItems: menuItems,
agentLoginItem: agentLoginItem)
agentLoginItem: agentLoginItem,
isMenuBarStatusView: isMenuBarStatusView)
popover.behavior = .transient

super.init()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,18 @@ public final class NetworkProtectionPopover: NSPopover {
statusReporter: NetworkProtectionStatusReporter,
appLauncher: AppLaunching,
menuItems: @escaping () -> [MenuItem],
agentLoginItem: LoginItem?) {
agentLoginItem: LoginItem?,
isMenuBarStatusView: Bool) {

self.statusReporter = statusReporter
self.model = NetworkProtectionStatusView.Model(controller: controller,
onboardingStatusPublisher: onboardingStatusPublisher,
statusReporter: statusReporter,
debugInformationPublisher: debugInformationPublisher.eraseToAnyPublisher(),
appLauncher: appLauncher,
menuItems: menuItems,
agentLoginItem: agentLoginItem)
onboardingStatusPublisher: onboardingStatusPublisher,
statusReporter: statusReporter,
debugInformationPublisher: debugInformationPublisher.eraseToAnyPublisher(),
appLauncher: appLauncher,
menuItems: menuItems,
agentLoginItem: agentLoginItem,
isMenuBarStatusView: isMenuBarStatusView)

super.init()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,47 @@ extension PromptActionView {
///
final class Model: ObservableObject {

private let presentationData: PromptPresentable
private(set) var icon: NetworkProtectionAsset
private(set) var title: String
private(set) var description: [StyledTextFragment]
private(set) var actionTitle: String
private(set) var actionScreenshot: NetworkProtectionAsset?
let action: () -> Void

init(presentationData: PromptPresentable, action: @escaping () -> Void) {
self.presentationData = presentationData
self.action = action
}

var icon: NetworkProtectionAsset {
presentationData.icon
}

var title: String {
presentationData.title
}

var description: [StyledTextFragment] {
presentationData.description
convenience init(onboardingStep: OnboardingStep, isMenuBar: Bool, action: @escaping () -> Void) {
self.init(
icon: onboardingStep.icon,
title: onboardingStep.title,
description: onboardingStep.description(isMenuBar: isMenuBar),
actionTitle: onboardingStep.actionTitle,
actionScreenshot: onboardingStep.actionScreenshot,
action: action
)
}

var actionTitle: String {
presentationData.actionTitle
convenience init(presentationData data: PromptPresentable, action: @escaping () -> Void) {
self.init(
icon: data.icon,
title: data.title,
description: data.description,
actionTitle: data.actionTitle,
actionScreenshot: data.actionScreenshot,
action: action
)
}

var actionScreenshot: NetworkProtectionAsset? {
presentationData.actionScreenshot
init(icon: NetworkProtectionAsset,
title: String,
description: [StyledTextFragment],
actionTitle: String,
actionScreenshot: NetworkProtectionAsset? = nil,
action: @escaping () -> Void) {
self.icon = icon
self.title = title
self.description = description
self.actionTitle = actionTitle
self.actionScreenshot = actionScreenshot
self.action = action
}
}
}
Expand All @@ -77,7 +92,7 @@ struct StyledTextFragment {
}
}

extension OnboardingStep: PromptPresentable {
extension OnboardingStep {
var icon: NetworkProtectionAsset {
switch self {
case .userNeedsToAllowExtension:
Expand All @@ -96,7 +111,7 @@ extension OnboardingStep: PromptPresentable {
}
}

var description: [StyledTextFragment] {
func description(isMenuBar: Bool) -> [StyledTextFragment] {
switch self {
case .userNeedsToAllowExtension:
return [
Expand All @@ -105,11 +120,19 @@ extension OnboardingStep: PromptPresentable {
.init(text: UserText.networkProtectionOnboardingAllowExtensionDescSuffix),
]
case .userNeedsToAllowVPNConfiguration:
return [
.init(text: UserText.networkProtectionOnboardingAllowVPNDescPrefix),
.init(text: UserText.networkProtectionOnboardingAllowVPNDescAllow, isEmphasized: true),
.init(text: UserText.networkProtectionOnboardingAllowVPNDescSuffix),
]
if isMenuBar {
return [
.init(text: UserText.networkProtectionOnboardingAllowVPNDescPrefix),
.init(text: UserText.networkProtectionOnboardingAllowVPNDescAllow, isEmphasized: true),
.init(text: UserText.networkProtectionOnboardingAllowVPNDescSuffix)
]
} else {
return [
.init(text: UserText.networkProtectionOnboardingAllowVPNDescPrefix),
.init(text: UserText.networkProtectionOnboardingAllowVPNDescAllow, isEmphasized: true),
.init(text: UserText.networkProtectionOnboardingAllowVPNDescExpandedSuffix)
]
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ extension NetworkProtectionStatusView {
var showDebugInformation: Bool

public let agentLoginItem: LoginItem?
private let isMenuBarStatusView: Bool

// MARK: - Extra Menu Items

Expand Down Expand Up @@ -111,6 +112,7 @@ extension NetworkProtectionStatusView {
appLauncher: AppLaunching,
menuItems: @escaping () -> [MenuItem],
agentLoginItem: LoginItem?,
isMenuBarStatusView: Bool,
runLoopMode: RunLoop.Mode? = nil) {

self.tunnelController = controller
Expand All @@ -119,6 +121,7 @@ extension NetworkProtectionStatusView {
self.debugInformationPublisher = debugInformationPublisher
self.menuItems = menuItems
self.agentLoginItem = agentLoginItem
self.isMenuBarStatusView = isMenuBarStatusView
self.runLoopMode = runLoopMode

tunnelControllerViewModel = TunnelControllerViewModel(controller: tunnelController,
Expand Down Expand Up @@ -303,7 +306,7 @@ extension NetworkProtectionStatusView {
switch step {

case .userNeedsToAllowExtension, .userNeedsToAllowVPNConfiguration:
return PromptActionView.Model(presentationData: step) { [weak self] in
return PromptActionView.Model(onboardingStep: step, isMenuBar: self.isMenuBarStatusView) { [weak self] in
self?.tunnelControllerViewModel.startNetworkProtection()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ final class StatusBarMenuTests: XCTestCase {
iconProvider: MenuIconProvider(),
appLauncher: MockAppLauncher(),
menuItems: { [] },
agentLoginItem: nil)
agentLoginItem: nil,
isMenuBarStatusView: false)

menu.show()

Expand All @@ -77,7 +78,8 @@ final class StatusBarMenuTests: XCTestCase {
iconProvider: MenuIconProvider(),
appLauncher: MockAppLauncher(),
menuItems: { [] },
agentLoginItem: nil)
agentLoginItem: nil,
isMenuBarStatusView: false)

menu.hide()

Expand Down

0 comments on commit c1f2a21

Please sign in to comment.