Reuse PurchaseButtonModifier in restricted areas (#815)

Fixes #687
This commit is contained in:
Davide 2024-11-05 13:27:05 +01:00 committed by GitHub
parent 833d717f06
commit 346aaec441
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 133 additions and 53 deletions

View File

@ -60,6 +60,12 @@ struct OnDemandView: View, ModuleDraftEditing {
Group {
enabledSection
restrictedArea
.modifier(PurchaseButtonModifier(
Strings.Modules.OnDemand.purchase,
feature: .onDemand,
showsIfRestricted: false,
paywallReason: $paywallReason
))
}
.moduleView(editor: editor, draft: draft.wrappedValue)
.modifier(PaywallModifier(reason: $paywallReason))
@ -81,22 +87,11 @@ private extension OnDemandView {
@ViewBuilder
var restrictedArea: some View {
switch iapManager.paywallReason(forFeature: .onDemand) {
case .purchase(let feature):
Button(Strings.Modules.OnDemand.purchase) {
paywallReason = .purchase(feature)
}
case .restricted:
EmptyView()
default:
if draft.wrappedValue.isEnabled {
policySection
if draft.wrappedValue.policy != .any {
networkSection
wifiSection
}
if draft.wrappedValue.isEnabled {
policySection
if draft.wrappedValue.policy != .any {
networkSection
wifiSection
}
}
}

View File

@ -234,7 +234,6 @@ private extension OpenVPNView {
.navigationTitle(Strings.Modules.Openvpn.credentials)
.themeForm()
.themeAnimation(on: draft.wrappedValue.isInteractive, category: .modules)
.modifier(PaywallModifier(reason: $paywallReason))
}
}
}

View File

@ -53,17 +53,14 @@ private extension AppleTVSection {
Toggle(Strings.Modules.General.Rows.appleTv(Strings.Unlocalized.appleTV), isOn: $profileEditor.isAvailableForTV)
}
@ViewBuilder
var purchaseButton: some View {
switch iapManager.paywallReason(forFeature: .appleTV) {
case .purchase(let feature):
Button(Strings.Modules.General.Rows.AppleTv.purchase) {
paywallReason = .purchase(feature)
}
default:
EmptyView()
}
EmptyView()
.modifier(PurchaseButtonModifier(
Strings.Modules.General.Rows.AppleTv.purchase,
feature: .appleTV,
showsIfRestricted: true,
paywallReason: $paywallReason
))
}
var footer: String {

View File

@ -132,17 +132,14 @@ private extension ProviderContentModifier {
)
}
@ViewBuilder
var purchaseButton: some View {
switch iapManager.paywallReason(forFeature: .providers) {
case .purchase(let feature):
Button(Strings.Providers.Picker.purchase) {
paywallReason = .purchase(feature)
}
default:
EmptyView()
}
EmptyView()
.modifier(PurchaseButtonModifier(
Strings.Providers.Picker.purchase,
feature: .providers,
showsIfRestricted: true,
paywallReason: $paywallReason
))
}
func refreshButton<Label>(label: () -> Label) -> some View where Label: View {

View File

@ -74,9 +74,17 @@ public struct OpenVPNCredentialsView: View {
public var body: some View {
Group {
restrictedArea
.modifier(PurchaseButtonModifier(
Strings.Modules.Openvpn.Credentials.Interactive.purchase,
feature: .interactiveLogin,
showsIfRestricted: false,
paywallReason: $paywallReason
))
inputSection
}
.themeManualInput()
.modifier(PaywallModifier(reason: $paywallReason))
.onLoad {
builder = credentials?.builder() ?? OpenVPN.Credentials.Builder()
builder.otp = nil
@ -114,19 +122,8 @@ private extension OpenVPNCredentialsView {
@ViewBuilder
var restrictedArea: some View {
switch iapManager.paywallReason(forFeature: .interactiveLogin) {
case .purchase(let feature):
Button(Strings.Modules.Openvpn.Credentials.Interactive.purchase) {
paywallReason = .purchase(feature)
}
case .restricted:
EmptyView()
default:
if !isAuthenticating {
interactiveSection
}
if !isAuthenticating {
interactiveSection
}
}

View File

@ -26,10 +26,10 @@
import CommonLibrary
import SwiftUI
struct PaywallModifier: ViewModifier {
public struct PaywallModifier: ViewModifier {
@Binding
var reason: PaywallReason?
private var reason: PaywallReason?
@State
private var isPresentingRestricted = false
@ -37,7 +37,11 @@ struct PaywallModifier: ViewModifier {
@State
private var paywallFeature: AppFeature?
func body(content: Content) -> some View {
public init(reason: Binding<PaywallReason?>) {
_reason = reason
}
public func body(content: Content) -> some View {
content
.alert(
Strings.Alerts.Iap.Restricted.title,

View File

@ -0,0 +1,91 @@
//
// PurchaseButtonModifier.swift
// Passepartout
//
// Created by Davide De Rosa on 11/5/24.
// Copyright (c) 2024 Davide De Rosa. All rights reserved.
//
// https://github.com/passepartoutvpn
//
// This file is part of Passepartout.
//
// Passepartout is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Passepartout is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
//
import CommonLibrary
import SwiftUI
public struct PurchaseButtonModifier: ViewModifier {
@EnvironmentObject
private var iapManager: IAPManager
private let title: String
private let label: String?
private let feature: AppFeature
private let showsIfRestricted: Bool
@Binding
private var paywallReason: PaywallReason?
public init(
_ title: String,
label: String? = nil,
feature: AppFeature,
showsIfRestricted: Bool,
paywallReason: Binding<PaywallReason?>
) {
self.title = title
self.label = label
self.feature = feature
self.showsIfRestricted = showsIfRestricted
_paywallReason = paywallReason
}
public func body(content: Content) -> some View {
switch iapManager.paywallReason(forFeature: feature) {
case .purchase:
purchaseView
case .restricted:
if showsIfRestricted {
content
}
default:
content
}
}
}
private extension PurchaseButtonModifier {
var purchaseView: some View {
HStack {
if let label {
Text(label)
Spacer()
}
purchaseButton
}
}
var purchaseButton: some View {
Button(title) {
paywallReason = .purchase(feature)
}
}
}