From 889d1116526f1a144c8d04ce68fd13485af75b5f Mon Sep 17 00:00:00 2001 From: Daniel Bernal Date: Tue, 20 Feb 2024 17:40:04 +0100 Subject: [PATCH] Subscription Entitlement Checks (#2491) Task/Issue URL: https://app.asana.com/0/1204099484721401/1206427924871956/f Description: Adopts the final entitlements for subscriptions Updates to latest BSK Steps to test this PR: Get a subscription Confirm all three options are visible in settings --- .../xcshareddata/swiftpm/Package.resolved | 2 +- DuckDuckGo/SettingsSubscriptionView.swift | 44 +++++++------- DuckDuckGo/SettingsViewModel.swift | 57 ++++++++++++------- 3 files changed, 61 insertions(+), 42 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 8c6ed5092d..1b44f4907b 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -156,7 +156,7 @@ { "identity" : "trackerradarkit", "kind" : "remoteSourceControl", - "location" : "https://github.com/duckduckgo/TrackerRadarKit.git", + "location" : "https://github.com/duckduckgo/TrackerRadarKit", "state" : { "revision" : "a6b7ba151d9dc6684484f3785293875ec01cc1ff", "version" : "1.2.2" diff --git a/DuckDuckGo/SettingsSubscriptionView.swift b/DuckDuckGo/SettingsSubscriptionView.swift index 3d4f3253ad..d9e11e2acd 100644 --- a/DuckDuckGo/SettingsSubscriptionView.swift +++ b/DuckDuckGo/SettingsSubscriptionView.swift @@ -67,30 +67,36 @@ struct SettingsSubscriptionView: View { private var subscriptionDetailsView: some View { return Group { - SettingsCellView(label: UserText.settingsPProVPNTitle, - subtitle: viewModel.state.networkProtection.status != "" ? viewModel.state.networkProtection.status : nil, - action: { viewModel.presentLegacyView(.netP) }, - disclosureIndicator: true, - isButton: true) - + if viewModel.shouldShowNetP { + SettingsCellView(label: UserText.settingsPProVPNTitle, + subtitle: viewModel.state.networkProtection.status != "" ? viewModel.state.networkProtection.status : nil, + action: { viewModel.presentLegacyView(.netP) }, + disclosureIndicator: true, + isButton: true) + } - SettingsCellView(label: UserText.settingsPProDBPTitle, - subtitle: UserText.settingsPProDBPSubTitle, - action: { isShowingDBP.toggle() }, isButton: true) - .sheet(isPresented: $isShowingDBP) { - SubscriptionPIRView() + if viewModel.shouldShowDBP { + SettingsCellView(label: UserText.settingsPProDBPTitle, + subtitle: UserText.settingsPProDBPSubTitle, + action: { isShowingDBP.toggle() }, isButton: true) + .sheet(isPresented: $isShowingDBP) { + SubscriptionPIRView() + } } - SettingsCellView(label: UserText.settingsPProITRTitle, - subtitle: UserText.settingsPProITRSubTitle, - action: { isShowingITP.toggle() }, isButton: true) - .sheet(isPresented: $isShowingITP) { - SubscriptionITPView() + if viewModel.shouldShowITP { + SettingsCellView(label: UserText.settingsPProITRTitle, + subtitle: UserText.settingsPProITRSubTitle, + action: { isShowingITP.toggle() }, isButton: true) + .sheet(isPresented: $isShowingITP) { + SubscriptionITPView() + } } - - NavigationLink(destination: SubscriptionSettingsView()) { - SettingsCustomCell(content: { manageSubscriptionView }) + if viewModel.shouldShowDBP || viewModel.shouldShowITP || viewModel.shouldShowNetP { + NavigationLink(destination: SubscriptionSettingsView()) { + SettingsCustomCell(content: { manageSubscriptionView }) + } } } diff --git a/DuckDuckGo/SettingsViewModel.swift b/DuckDuckGo/SettingsViewModel.swift index 1b84d3a200..2064972949 100644 --- a/DuckDuckGo/SettingsViewModel.swift +++ b/DuckDuckGo/SettingsViewModel.swift @@ -74,6 +74,10 @@ final class SettingsViewModel: ObservableObject { // Add more views as needed here... @Published var shouldNavigateToDBP = false @Published var shouldNavigateToITP = false + + @Published var shouldShowNetP = false + @Published var shouldShowDBP = false + @Published var shouldShowITP = false // Our View State @Published private(set) var state: SettingsState @@ -327,32 +331,41 @@ extension SettingsViewModel { @available(iOS 15.0, *) @MainActor private func setupSubscriptionEnvironment() async { - // Active subscription check - if let token = accountManager.accessToken { + guard let token = accountManager.accessToken else { + setupSubscriptionPurchaseOptions() + return + } + + // Fetch available subscriptions from the backend (or sign out) + switch await SubscriptionService.getSubscriptionDetails(token: token) { + case .success(let response) where !response.isSubscriptionActive: + AccountManager().signOut() + setupSubscriptionPurchaseOptions() + case .success(let response): + // Cache Subscription state + Self.cachedHasActiveSubscription = self.state.subscription.hasActiveSubscription - // Fetch available subscriptions from the backend (or sign out) - if case .success(let response) = await SubscriptionService.getSubscriptionDetails(token: token) { - if !response.isSubscriptionActive { - AccountManager().signOut() - setupSubscriptionPurchaseOptions() - return - } - - // Check for valid entitlements - if case let .success(entitlements) = await AccountManager().fetchEntitlements() { - self.state.subscription.hasActiveSubscription = !entitlements.isEmpty - } - - // Cache Subscription state - Self.cachedHasActiveSubscription = self.state.subscription.hasActiveSubscription - - // Enable Subscription purchase if there's no active subscription - if self.state.subscription.hasActiveSubscription == false { - setupSubscriptionPurchaseOptions() + // Check entitlements and update UI accordingly + let entitlements: [AccountManager.Entitlement] = [.identityTheftRestoration, .dataBrokerProtection, .networkProtection] + for entitlement in entitlements { + if case .success = await AccountManager().hasEntitlement(for: entitlement) { + switch entitlement { + case .identityTheftRestoration: + self.shouldShowITP = true + case .dataBrokerProtection: + self.shouldShowDBP = true + case .networkProtection: + self.shouldShowNetP = true + } } } - } else { + + // Enable Subscription purchase if there's no active subscription + if !self.state.subscription.hasActiveSubscription { + setupSubscriptionPurchaseOptions() + } + default: setupSubscriptionPurchaseOptions() } }