Skip to content

Commit

Permalink
Implements pixels for our VPN tips
Browse files Browse the repository at this point in the history
  • Loading branch information
diegoreymendez committed Nov 26, 2024
1 parent 5a77984 commit 5cd2212
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import Common
import NetworkProtection
import os.log
import TipKit
import PixelKit
import VPNPixels

@MainActor
public final class VPNTipsModel: ObservableObject {
Expand Down Expand Up @@ -183,14 +185,33 @@ public final class VPNTipsModel: ObservableObject {

// MARK: - UI Events

@available(macOS 14.0, *)
func handleAutoconnectTipInvalidated(_ reason: Tip.InvalidationReason) {
switch reason {
case .actionPerformed:
PixelKit.fire(VPNTipPixel.autoconnectTip(step: .actioned))
default:
PixelKit.fire(VPNTipPixel.autoconnectTip(step: .dismissed))
}
}

@available(macOS 14.0, *)
func handleDomainExclusionTipInvalidated(_ reason: Tip.InvalidationReason) {
switch reason {
case .actionPerformed:
PixelKit.fire(VPNTipPixel.domainExclusionsTip(step: .actioned))
default:
PixelKit.fire(VPNTipPixel.domainExclusionsTip(step: .dismissed))
}
}

@available(macOS 14.0, *)
func handleGeoswitchingTipInvalidated(_ reason: Tip.InvalidationReason) {
switch reason {
case .actionPerformed:
Logger.networkProtection.log("🧉 Geo-switching tip actioned")
break
PixelKit.fire(VPNTipPixel.geoswitchingTip(step: .actioned))
default:
Logger.networkProtection.log("🧉 Geo-switching tip dismissed")
PixelKit.fire(VPNTipPixel.geoswitchingTip(step: .dismissed))
}
}

Expand All @@ -207,9 +228,47 @@ public final class VPNTipsModel: ObservableObject {
}

@available(macOS 14.0, *)
func handleTunnelControllerShown() {
func handleTunnelControllerAppear() {
guard !isMenuApp else { return }

handleTipDistanceConditionsCheckpoint()
}

@available(macOS 14.0, *)
func handleTunnelControllerDisappear() {
guard !isMenuApp else { return }

if case .available = autoconnectTip.status {
PixelKit.fire(VPNTipPixel.autoconnectTip(step: .ignored))
}

if case .available = domainExclusionsTip.status {
PixelKit.fire(VPNTipPixel.domainExclusionsTip(step: .ignored))
}

if case .available = geoswitchingTip.status {
PixelKit.fire(VPNTipPixel.geoswitchingTip(step: .ignored))
}
}

@available(macOS 14.0, *)
func handleAutoconnectionTipShown() {
guard !isMenuApp else { return }

PixelKit.fire(VPNTipPixel.autoconnectTip(step: .shown))
}

@available(macOS 14.0, *)
func handleDomainExclusionsTipShown() {
guard !isMenuApp else { return }

PixelKit.fire(VPNTipPixel.domainExclusionsTip(step: .shown))
}

@available(macOS 14.0, *)
func handleGeoswitchingTipShown() {
guard !isMenuApp else { return }

PixelKit.fire(VPNTipPixel.geoswitchingTip(step: .shown))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,22 @@ public struct TunnelControllerView: View {
.tipBackground(Color(.tipBackground))
.padding(.horizontal, 9)
.padding(.vertical, 6)
.onAppear {
tipsModel.handleAutoconnectionTipShown()
}
.task {
var previousStatus = tipsModel.autoconnectTip.status

for await status in tipsModel.autoconnectTip.statusUpdates {
if case .invalidated(let reason) = status {
if case .available = previousStatus {
tipsModel.handleAutoconnectTipInvalidated(reason)
}
}

previousStatus = status
}
}
}

SiteTroubleshootingView()
Expand All @@ -78,17 +94,20 @@ public struct TunnelControllerView: View {
.tipBackground(Color(.tipBackground))
.padding(.horizontal, 9)
.padding(.vertical, 6)
.onAppear {
tipsModel.handleDomainExclusionsTipShown()
}
.task {
var previousStatus = tipsModel.domainExclusionsTip.status

for await status in tipsModel.domainExclusionsTip.statusUpdates {
if case .invalidated = status {
if case .invalidated(let reason) = status {
if case .available = previousStatus {
Logger.networkProtection.log("🧉 Domain exclusions tip dismissed")
tipsModel.handleDomainExclusionTipInvalidated(reason)
}

previousStatus = status
}

previousStatus = status
}
}
}
Expand All @@ -105,7 +124,12 @@ public struct TunnelControllerView: View {
}
.onAppear {
if #available(macOS 14.0, *) {
tipsModel.handleTunnelControllerShown()
tipsModel.handleTunnelControllerAppear()
}
}
.onDisappear {
if #available(macOS 14.0, *) {
tipsModel.handleTunnelControllerDisappear()
}
}
}
Expand Down Expand Up @@ -226,6 +250,9 @@ public struct TunnelControllerView: View {
.tipBackground(Color(.tipBackground))
.padding(.horizontal, 9)
.padding(.vertical, 6)
.onAppear {
tipsModel.handleGeoswitchingTipShown()
}
.task {
var previousStatus = tipsModel.geoswitchingTip.status

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// VPNTipPixel.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 Foundation
import PixelKit

public enum VPNTipStep: String {
case shown
case ignored
case actioned
case dismissed
}

public enum VPNTipPixel: VPNPixel {
case autoconnectTip(step: VPNTipStep)
case domainExclusionsTip(step: VPNTipStep)
case geoswitchingTip(step: VPNTipStep)

public var unscopedPixelName: String {
switch self {
case .autoconnectTip(let step):
return "tip_autoconnect_\(step)"
case .domainExclusionsTip(let step):
return "tip_site-exclusion_\(step)"
case .geoswitchingTip(let step):
return "tip_geoswitching_\(step)"
}
}

public var error: (any Error)? {
nil
}

public var parameters: [String: String]? {
nil
}
}

0 comments on commit 5cd2212

Please sign in to comment.