Skip to content

Commit

Permalink
Ref brave/brave-ios#4879: VPN Churn Improvements - Callout Logic and …
Browse files Browse the repository at this point in the history
…Settings Changes (brave/brave-ios#8040)
  • Loading branch information
soner-yuksel authored Sep 25, 2023
1 parent b913cda commit 36282c6
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import SwiftUI
import BraveVPN
import Onboarding
import SafariServices
import StoreKit

// MARK: - Callouts

Expand Down Expand Up @@ -255,12 +256,44 @@ extension BrowserViewController {

private func presentVPNUpdateBillingCallout(skipSafeGuards: Bool = false) {
if !skipSafeGuards {
// TODO: Condition
return
// Checking subscription receipt is in retry period
guard let receiptStatus = Preferences.VPN.vpnReceiptStatus.value else {
return
}

if receiptStatus != BraveVPN.ReceiptResponse.Status.retryPeriod.rawValue {
return
}
}


#if compiler(>=5.8)
if #available(iOS 16.4, *) {
Task { @MainActor in
for await message in StoreKit.Message.messages {
guard let windowScene = currentScene else {
return
}

try? message.display(in: windowScene)
}
}
} else {
presentVPNChurnBilling()
}
#else
presentVPNChurnBilling()
#endif

presentVPNChurnPromoCallout(for: .updateBillingExpired) {
// TODO: Action
func presentVPNChurnBilling() {
presentVPNChurnPromoCallout(for: .updateBillingExpired) {
// Opens Apple's 'manage subscription' screen
guard let url = URL.apple.manageSubscriptions else { return }

if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, options: [:])
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ extension BrowserViewController {
func featuresMenuSection(_ menuController: MenuViewController) -> some View {
VStack(alignment: .leading, spacing: 5) {
VPNMenuButton(
retryStateActive: Preferences.VPN.vpnReceiptStatus.value == BraveVPN.ReceiptResponse.Status.retryPeriod.rawValue,
vpnProductInfo: self.vpnProductInfo,
displayVPNDestination: { [unowned self] vc in
(self.presentedViewController as? MenuViewController)?
Expand Down Expand Up @@ -54,6 +55,7 @@ extension BrowserViewController {
.padding(.bottom, 5)

VPNMenuButton(
retryStateActive: Preferences.VPN.vpnReceiptStatus.value == BraveVPN.ReceiptResponse.Status.retryPeriod.rawValue,
vpnProductInfo: self.vpnProductInfo,
description: Strings.OptionsMenu.braveVPNItemDescription,
displayVPNDestination: { [unowned self] vc in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import BraveVPN

/// A menu button that provides a shortcut to toggling Brave VPN
struct VPNMenuButton: View {
/// The status indicating VPN is in retry state
var retryStateActive: Bool
/// The product info
var vpnProductInfo: VPNProductInfo
/// The description for product info
Expand Down Expand Up @@ -78,15 +80,12 @@ struct VPNMenuButton: View {

private var vpnToggle: some View {
Toggle("Brave VPN", isOn: isVPNEnabledBinding)
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
.toggleStyle(SwitchToggleStyle(tint: retryStateActive ? Color(.braveErrorBorder) : .accentColor))
}

var body: some View {
HStack {
MenuItemHeaderView(
icon: Image(braveSystemName: "leo.product.vpn"),
title: description == nil ? "Brave VPN" : Strings.OptionsMenu.braveVPNItemTitle,
subtitle: description)
headerView
Spacer()
if isVPNStatusChanging {
ActivityIndicatorView(isAnimating: true)
Expand Down Expand Up @@ -122,4 +121,30 @@ struct VPNMenuButton: View {
}
}
}

private var headerView: some View {
HStack(spacing: 14) {
Image(braveSystemName: retryStateActive ? "leo.warning.triangle-filled" : "leo.product.vpn")
.font(.body)
.frame(width: 32, height: 32)
.foregroundColor(retryStateActive ? Color(.braveErrorLabel) : Color(.braveLabel))
.background(
RoundedRectangle(cornerRadius: 8, style: .continuous)
.fill(Color(.secondaryBraveGroupedBackground))
.shadow(color: Color.black.opacity(0.1), radius: 1, x: 0, y: 1)
)
.padding(.vertical, 2)
VStack(alignment: .leading, spacing: 3) {
Text(verbatim: description == nil ? "Brave VPN" : Strings.OptionsMenu.braveVPNItemTitle)
.foregroundColor(Color(.bravePrimary))
if let subTitle = description {
Text(retryStateActive ? Strings.VPN.vpnUpdatePaymentMethodDescriptionText : subTitle)
.font(.subheadline)
.foregroundColor(retryStateActive ? Color(.braveErrorLabel) : Color(.secondaryBraveLabel))
}
}
.padding(.vertical, description != nil ? 5 : 0)
}
.foregroundColor(Color(.braveLabel))
}
}
12 changes: 11 additions & 1 deletion Sources/Brave/Frontend/Settings/SettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,10 @@ class SettingsViewController: TableViewController {
private func vpnSettingsRow() -> Row {

let (text, color) = { () -> (String, UIColor) in
if Preferences.VPN.vpnReceiptStatus.value == BraveVPN.ReceiptResponse.Status.retryPeriod.rawValue {
return (Strings.VPN.updateActionCellTitle, .braveErrorLabel)
}

switch BraveVPN.vpnState {
case .notPurchased:
return ("", UIColor.black)
Expand Down Expand Up @@ -596,7 +600,13 @@ class SettingsViewController: TableViewController {

guard let vcToShow = vc else { return }
self.navigationController?.pushViewController(vcToShow, animated: true)
}, image: UIImage(braveSystemNamed: "leo.product.vpn"), accessory: .disclosureIndicator,
},
image: Preferences.VPN.vpnReceiptStatus.value == BraveVPN.ReceiptResponse.Status.retryPeriod.rawValue
? UIImage(braveSystemNamed: "leo.warning.triangle-filled")?
.withRenderingMode(.alwaysOriginal)
.withTintColor(.braveErrorLabel)
: UIImage(braveSystemNamed: "leo.product.vpn"),
accessory: .disclosureIndicator,
cellClass: ColoredDetailCell.self, context: [ColoredDetailCell.colorKey: color], uuid: "vpnrow")
}

Expand Down
4 changes: 4 additions & 0 deletions Sources/BraveShared/BraveURLs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ extension URL {
public static let screenTimeHelp =
URL(string: "https://support.apple.com/guide/security/secd8831e732/web")!
}
public enum Apple {
public static let manageSubscriptions = URL(string: "https://apps.apple.com/account/subscriptions")
}
public static let brave = Brave.self
public static let apple = Apple.self
}

public struct AppURLScheme {
Expand Down
15 changes: 15 additions & 0 deletions Sources/BraveStrings/BraveStrings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3141,6 +3141,11 @@ extension Strings {
value: "Update Payment",
comment: "Action button title that updates method payment")

public static let updateActionCellTitle =
NSLocalizedString("vpn.updateActionCellTitle", tableName: "BraveShared", bundle: .module,
value: "Update",
comment: "Cell title indicates update payment method")

public static let subscribeVPNActionButtonTitle =
NSLocalizedString("vpn.subscribeVPNActionButtonTitle", tableName: "BraveShared", bundle: .module,
value: "Subscribe Now",
Expand Down Expand Up @@ -3175,6 +3180,16 @@ extension Strings {
NSLocalizedString("vpn.subscribeVPNPopOverSubDescription", tableName: "BraveShared", bundle: .module,
value: "Ready to safeguard every app on your phone? Come back to Brave VPN and get 20% off for the next 3 months.",
comment: "Pop up sub description the subscription for VPN can be used for all platforms")

public static let vpnUpdatePaymentMethodDescriptionText =
NSLocalizedString("vpn.vpnUpdatePaymentMethodDescriptionText", tableName: "BraveShared", bundle: .module,
value: "Please update your payment method",
comment: "Text description of VPN subscription needs a method of payment update")

public static let vpnActionUpdatePaymentMethodSettingsText =
NSLocalizedString("vpn.vpnActionUpdatePaymentMethodSettingsText", tableName: "BraveShared", bundle: .module,
value: "Update Payment Method",
comment: "Text for necesseray required action of VPN subscription needs a method of payment update")
}

}
Expand Down
Loading

0 comments on commit 36282c6

Please sign in to comment.