Skip to content
This repository was archived by the owner on Feb 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle
for try await event in SystemExtensionManager().activate() {
switch event {
case .waitingForUserApproval:
self.controllerErrorStore.lastErrorMessage = UserText.networkProtectionSystemSettings
onboardingStatusRawValue = OnboardingStatus.isOnboarding(step: .userNeedsToAllowExtension).rawValue
case .activated:
self.controllerErrorStore.lastErrorMessage = nil
activated = true
Expand Down Expand Up @@ -265,22 +265,37 @@ final class NetworkProtectionTunnelController: NetworkProtection.TunnelControlle
func start(enableLoginItems: Bool) async {
controllerErrorStore.lastErrorMessage = nil

if enableLoginItems {
loginItemsManager.enableLoginItems()
}

do {
#if NETP_SYSTEM_EXTENSION
guard try await ensureSystemExtensionIsActivated() else {
return
}

onboardingStatusRawValue = OnboardingStatus.isOnboarding(step: .userNeedsToAllowVPNConfiguration).rawValue
// We'll only update to completed if we were showing the onboarding step to
// allow the system extension. Otherwise we may override the allow-VPN
// onboarding step.
if onboardingStatusRawValue == OnboardingStatus.isOnboarding(step: .userNeedsToAllowExtension).rawValue {
onboardingStatusRawValue = OnboardingStatus.completed.rawValue
}
Comment on lines -278 to +279
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is based on design feedback.

Previous onboarding logic:

  • Show "Allow system extension"
  • Show "Allow vpn configuration"
  • Completed

Current onboarding logic:

  • Show "Allow system extension"
  • Dismiss onboarding view (ie: mark completed if the system-extension variant of it was shown)
  • Show "Allow VPN configuration" only if the user disallows it
  • Dismiss all onboarding views on successful completion.

#endif

let tunnelManager = try await loadOrMakeTunnelManager()
let tunnelManager: NETunnelProviderManager

do {
tunnelManager = try await loadOrMakeTunnelManager()
} catch {
if case NEVPNError.configurationReadWriteFailed = error {
onboardingStatusRawValue = OnboardingStatus.isOnboarding(step: .userNeedsToAllowVPNConfiguration).rawValue
}

throw error
}
onboardingStatusRawValue = OnboardingStatus.completed.rawValue

if enableLoginItems {
loginItemsManager.enableLoginItems()
}

switch tunnelManager.connection.status {
case .invalid:
throw StartError.connectionStatusInvalid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ final class UserText {
static let networkProtectionStatusViewFeatureOn = NSLocalizedString("network.protection.status.view.feature.on", value: "Network Protection is ON", comment: "Text shown in NetworkProtection's status view when NetP is ON.")
static let networkProtectionStatusViewTimerZero = "00:00:00"

// MARK: - Onboarding

static let networkProtectionOnboardingAllowExtensionTitle = NSLocalizedString("network.protection.onboarding.allow.extension.title", value: "Allow System Extension", comment: "Title for the onboarding allow-extension step")
static let networkProtectionOnboardingAllowExtensionDescPrefix = NSLocalizedString("network.protection.onboarding.allow.extension.desc.prefix", value: "Open System Settings to Privacy & Security. Scroll and select ", comment: "Non-bold prefix for the onboarding allow-extension description")
static let networkProtectionOnboardingAllowExtensionDescAllow = NSLocalizedString("network.protection.onboarding.allow.extension.desc.allow", value: "Allow", comment: "'Allow' word between the prefix and suffix for the onboarding allow-extension description")
static let networkProtectionOnboardingAllowExtensionDescSuffix = NSLocalizedString("network.protection.onboarding.allow.extension.desc.suffix", value: " for DuckDuckGo software.", comment: "Non-bold suffix for the onboarding allow-extension description")
static let networkProtectionOnboardingAllowExtensionAction = NSLocalizedString("network.protection.onboarding.allow.extension.action", value: "Open System Settings...", comment: "Action button title for the onboarding allow-extension view")

static let networkProtectionOnboardingAllowVPNTitle = NSLocalizedString("network.protection.onboarding.allow.vpn.title", value: "Add VPN Configuration", comment: "Title for the onboarding allow-VPN step")
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 networkProtectionOnboardingAllowVPNAction = NSLocalizedString("network.protection.onboarding.allow.vpn.action", value: "Add VPN Configuration...", comment: "Action button title for the onboarding allow-VPN view")

// MARK: - Connection Status

static let networkProtectionStatusDisconnected = NSLocalizedString("network.protection.status.disconnected", value: "Not connected", comment: "The label for the NetP VPN when disconnected")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import Foundation

public enum NetworkProtectionAsset: String {
public enum NetworkProtectionAsset: String, CaseIterable {
case ipAddressIcon = "IP-16"
case serverLocationIcon = "Server-Location-16"
case vpnDisabledImage = "VPN-Disabled-128"
Expand Down Expand Up @@ -47,4 +47,5 @@ public enum NetworkProtectionAsset: String {

// Images:
case allowSysexScreenshot = "allow-sysex-screenshot"
case allowSysexScreenshotBigSur = "allow-sysex-screenshot-bigsur"
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
{
"images" : [
{
"filename" : "image 40.pdf",
"idiom" : "universal"
"filename" : "exention-icon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "exention-icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "exention-icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
{
"images" : [
{
"filename" : "image 39.pdf",
"idiom" : "universal"
"filename" : "vpn-icon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "vpn-icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "vpn-icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"images" : [
{
"filename" : "theme=light, mac=big sur.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "theme=dark, mac=big sur.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "theme=light, mac=big sur@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "theme=dark, mac=big sur@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "theme=light, mac=big sur@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "theme=dark, mac=big sur@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,8 +1,52 @@
{
"images" : [
{
"filename" : "Mask group.pdf",
"idiom" : "universal"
"filename" : "theme=light, mac=ventura.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "theme=dark, mac=ventura.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "theme=light, mac=ventura@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "theme=dark, mac=ventura@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "theme=light, mac=ventura@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "theme=dark, mac=ventura@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ struct OnboardingStepView: View {
model.description.reduce(Text("")) { previous, fragment in
var newText = Text(fragment.text)

if fragment.isBold {
newText = newText.bold()
if fragment.isEmphasized {
newText = newText.fontWeight(.semibold)
}

return previous + newText
Expand All @@ -103,26 +103,25 @@ struct OnboardingStepView: View {

Button(model.actionTitle, action: model.action)
.applyStepButtonAttributes(colorScheme: colorScheme)
.padding(.top, 3)
}

Spacer()
}
}
.padding(.top, 16)
.padding(.bottom, model.actionScreenshot != nil ? 4 : 16)
.padding(.vertical, 16)
.padding(.horizontal, 10)

if let actionScreenshot = model.actionScreenshot {
Image(actionScreenshot)
.shadow(color: .black.opacity(0.18), radius: 5, x: 0, y: 0)
}
}
.cornerRadius(8)
.background(
RoundedRectangle(cornerRadius: 8, style: .circular)
RoundedRectangle(cornerRadius: 6, style: .circular)
.stroke(Color(.onboardingStepBorder))
.background(
RoundedRectangle(cornerRadius: 8, style: .circular)
RoundedRectangle(cornerRadius: 6, style: .circular)
.fill(Color(.onboardingStepBackground))
))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ extension OnboardingStepView {
final class Model: ObservableObject {
struct StyledTextFragment {
let text: String
let isBold: Bool
let isEmphasized: Bool

init(text: String, isBold: Bool = false) {
init(text: String, isEmphasized: Bool = false) {
self.text = text
self.isBold = isBold
self.isEmphasized = isEmphasized
}
}

Expand All @@ -54,46 +54,46 @@ extension OnboardingStepView {
var title: String {
switch step {
case .userNeedsToAllowExtension:
return "Step 1 of 2: Allow System Extension"
return UserText.networkProtectionOnboardingAllowExtensionTitle
case .userNeedsToAllowVPNConfiguration:
return "Step 2 of 2: Add VPN Configuration"
return UserText.networkProtectionOnboardingAllowVPNTitle
}
}

var description: [StyledTextFragment] {
switch step {
case .userNeedsToAllowExtension:
return [
.init(text: "Open "),
.init(text: "System Settings", isBold: true),
.init(text: " to "),
.init(text: "Privacy & Security", isBold: true),
.init(text: ". Scroll and select "),
.init(text: "Allow", isBold: true),
.init(text: " for DuckDuckGo software.")
.init(text: UserText.networkProtectionOnboardingAllowExtensionDescPrefix),
.init(text: UserText.networkProtectionOnboardingAllowExtensionDescAllow, isEmphasized: true),
.init(text: UserText.networkProtectionOnboardingAllowExtensionDescSuffix),
]
case .userNeedsToAllowVPNConfiguration:
return [
.init(text: "Select "),
.init(text: "Allow", isBold: true),
.init(text: " when prompted to finish setting up Network Protection.")
.init(text: UserText.networkProtectionOnboardingAllowVPNDescPrefix),
.init(text: UserText.networkProtectionOnboardingAllowVPNDescAllow, isEmphasized: true),
.init(text: UserText.networkProtectionOnboardingAllowVPNDescSuffix),
]
}
}

var actionTitle: String {
switch step {
case .userNeedsToAllowExtension:
return "Open System Settings..."
return UserText.networkProtectionOnboardingAllowExtensionAction
case .userNeedsToAllowVPNConfiguration:
return "Add VPN Configuration..."
return UserText.networkProtectionOnboardingAllowVPNAction
}
}

var actionScreenshot: NetworkProtectionAsset? {
switch step {
case .userNeedsToAllowExtension:
return .allowSysexScreenshot
if #available(macOS 12, *) {
return .allowSysexScreenshot
} else {
return .allowSysexScreenshotBigSur
}
case .userNeedsToAllowVPNConfiguration:
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public struct NetworkProtectionStatusView: View {
Spacer()

TunnelControllerView(model: model.tunnelControllerViewModel)
.disabled(model.tunnelControllerViewDisabled)

bottomMenuView()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ extension NetworkProtectionStatusView {
@Published
private(set) var onboardingStatus: OnboardingStatus = .completed

var mainPanelDisabled: Bool {
var tunnelControllerViewDisabled: Bool {
onboardingStatus != .completed
}

Expand Down
Loading