2024-09-23 13:02:26 +00:00
|
|
|
//
|
|
|
|
// PaywallModifier.swift
|
|
|
|
// Passepartout
|
|
|
|
//
|
|
|
|
// Created by Davide De Rosa on 9/11/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/>.
|
|
|
|
//
|
|
|
|
|
2024-11-03 12:16:13 +00:00
|
|
|
import CommonLibrary
|
2024-09-23 13:02:26 +00:00
|
|
|
import SwiftUI
|
|
|
|
|
2024-11-05 12:27:05 +00:00
|
|
|
public struct PaywallModifier: ViewModifier {
|
2024-09-23 13:02:26 +00:00
|
|
|
|
|
|
|
@Binding
|
2024-11-05 12:27:05 +00:00
|
|
|
private var reason: PaywallReason?
|
2024-09-23 13:02:26 +00:00
|
|
|
|
|
|
|
@State
|
|
|
|
private var isPresentingRestricted = false
|
|
|
|
|
|
|
|
@State
|
2024-11-05 17:55:57 +00:00
|
|
|
private var paywallArguments: PaywallArguments?
|
2024-09-23 13:02:26 +00:00
|
|
|
|
2024-11-05 12:27:05 +00:00
|
|
|
public init(reason: Binding<PaywallReason?>) {
|
|
|
|
_reason = reason
|
|
|
|
}
|
|
|
|
|
|
|
|
public func body(content: Content) -> some View {
|
2024-09-23 13:02:26 +00:00
|
|
|
content
|
|
|
|
.alert(
|
|
|
|
Strings.Alerts.Iap.Restricted.title,
|
|
|
|
isPresented: $isPresentingRestricted,
|
|
|
|
actions: {
|
|
|
|
Button(Strings.Global.ok) {
|
|
|
|
reason = nil
|
|
|
|
isPresentingRestricted = false
|
|
|
|
}
|
|
|
|
},
|
|
|
|
message: {
|
|
|
|
Text(Strings.Alerts.Iap.Restricted.message)
|
|
|
|
}
|
|
|
|
)
|
2024-11-05 17:55:57 +00:00
|
|
|
.themeModal(item: $paywallArguments) { args in
|
2024-10-28 19:08:13 +00:00
|
|
|
NavigationStack {
|
2024-11-05 17:55:57 +00:00
|
|
|
PaywallView(
|
|
|
|
isPresented: isPresentingPurchase,
|
|
|
|
feature: args.feature,
|
|
|
|
suggestedProduct: args.product
|
|
|
|
)
|
2024-10-28 19:08:13 +00:00
|
|
|
}
|
2024-11-07 17:27:36 +00:00
|
|
|
.frame(idealHeight: 400)
|
2024-09-23 13:02:26 +00:00
|
|
|
}
|
|
|
|
.onChange(of: reason) {
|
|
|
|
switch $0 {
|
|
|
|
case .restricted:
|
|
|
|
isPresentingRestricted = true
|
|
|
|
|
2024-11-05 17:55:57 +00:00
|
|
|
case .purchase(let feature, let product):
|
|
|
|
paywallArguments = PaywallArguments(feature: feature, product: product)
|
2024-09-23 13:02:26 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private extension PaywallModifier {
|
|
|
|
var isPresentingPurchase: Binding<Bool> {
|
|
|
|
Binding {
|
2024-11-05 17:55:57 +00:00
|
|
|
paywallArguments != nil
|
2024-09-23 13:02:26 +00:00
|
|
|
} set: {
|
|
|
|
if !$0 {
|
2024-11-05 17:55:57 +00:00
|
|
|
// make sure to reset this to allow paywall to appear again
|
|
|
|
reason = nil
|
|
|
|
paywallArguments = nil
|
2024-09-23 13:02:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-11-05 17:55:57 +00:00
|
|
|
|
|
|
|
private struct PaywallArguments: Identifiable {
|
|
|
|
let feature: AppFeature
|
|
|
|
|
|
|
|
let product: AppProduct?
|
|
|
|
|
|
|
|
var id: String {
|
|
|
|
feature.id
|
|
|
|
}
|
|
|
|
}
|