mirror of
https://github.com/passepartoutvpn/passepartout-apple.git
synced 2025-02-18 22:02:11 +00:00
Show the list of features included in each product (#1157)
List product features inline in the paywall. Inside the list, highlight the required features that originated the paywall.
This commit is contained in:
parent
954475e117
commit
914520009a
@ -55,6 +55,7 @@ struct InstalledProfileView: View, Routable {
|
||||
toggleButton
|
||||
}
|
||||
.modifier(HeaderModifier(layout: layout))
|
||||
.unanimated()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -786,20 +786,20 @@ public enum Strings {
|
||||
}
|
||||
}
|
||||
}
|
||||
public enum Product {
|
||||
/// Included features
|
||||
public static let includedFeatures = Strings.tr("Localizable", "views.paywall.product.included_features", fallback: "Included features")
|
||||
}
|
||||
public enum Rows {
|
||||
/// Restore purchases
|
||||
public static let restorePurchases = Strings.tr("Localizable", "views.paywall.rows.restore_purchases", fallback: "Restore purchases")
|
||||
}
|
||||
public enum Sections {
|
||||
public enum IncludedFeatures {
|
||||
/// Also includes
|
||||
public static let header = Strings.tr("Localizable", "views.paywall.sections.included_features.header", fallback: "Also includes")
|
||||
}
|
||||
public enum Products {
|
||||
/// All purchases support Family Sharing.
|
||||
public static let footer = Strings.tr("Localizable", "views.paywall.sections.products.footer", fallback: "All purchases support Family Sharing.")
|
||||
/// Available products
|
||||
public static let header = Strings.tr("Localizable", "views.paywall.sections.products.header", fallback: "Available products")
|
||||
/// Suggested products
|
||||
public static let header = Strings.tr("Localizable", "views.paywall.sections.products.header", fallback: "Suggested products")
|
||||
}
|
||||
public enum RequiredFeatures {
|
||||
/// Required features
|
||||
|
@ -260,12 +260,13 @@
|
||||
"views.paywall.alerts.verification.connect.1" = "Ihre Käufe werden überprüft.";
|
||||
"views.paywall.alerts.verification.connect.2" = "Falls die Überprüfung nicht abgeschlossen werden kann, wird die Verbindung in %d Minuten beendet.";
|
||||
"views.paywall.alerts.verification.edit" = "Bitte warten Sie, während Ihre Käufe überprüft werden.";
|
||||
"views.paywall.product.included_features" = "Enthaltene Funktionen";
|
||||
"views.paywall.rows.restore_purchases" = "Käufe wiederherstellen";
|
||||
"views.paywall.sections.all_features.header" = "Die Vollversion enthält";
|
||||
"views.paywall.sections.full_products.header" = "Vollversion";
|
||||
"views.paywall.sections.included_features.header" = "Enthält außerdem";
|
||||
"views.paywall.sections.products.footer" = "Alle Käufe unterstützen die Familienfreigabe.";
|
||||
"views.paywall.sections.products.header" = "Verfügbare Produkte";
|
||||
"views.paywall.sections.products.header" = "Empfohlene Produkte";
|
||||
"views.paywall.sections.required_features.header" = "Erforderliche Funktionen";
|
||||
"views.paywall.sections.restore.footer" = "Wenn du diese App oder Funktion in der Vergangenheit gekauft hast, kannst du deine Käufe wiederherstellen.";
|
||||
"views.paywall.sections.restore.header" = "Wiederherstellen";
|
||||
|
@ -260,12 +260,13 @@
|
||||
"views.paywall.alerts.verification.connect.1" = "Οι αγορές σας επαληθεύονται.";
|
||||
"views.paywall.alerts.verification.connect.2" = "Αν η επαλήθευση δεν ολοκληρωθεί, η σύνδεση θα τερματιστεί σε %d λεπτά.";
|
||||
"views.paywall.alerts.verification.edit" = "Παρακαλώ περιμένετε όσο επαληθεύονται οι αγορές σας.";
|
||||
"views.paywall.product.included_features" = "Περιλαμβανόμενες λειτουργίες";
|
||||
"views.paywall.rows.restore_purchases" = "Επαναφορά αγορών";
|
||||
"views.paywall.sections.all_features.header" = "Η πλήρης έκδοση περιλαμβάνει";
|
||||
"views.paywall.sections.full_products.header" = "Πλήρης έκδοση";
|
||||
"views.paywall.sections.included_features.header" = "Περιλαμβάνει επίσης";
|
||||
"views.paywall.sections.products.footer" = "Όλες οι αγορές υποστηρίζουν την Οικογενειακή Κοινή Χρήση.";
|
||||
"views.paywall.sections.products.header" = "Διαθέσιμα προϊόντα";
|
||||
"views.paywall.sections.products.header" = "Προτεινόμενα προϊόντα";
|
||||
"views.paywall.sections.required_features.header" = "Απαιτούμενες λειτουργίες";
|
||||
"views.paywall.sections.restore.footer" = "Εάν αγοράσατε αυτήν την εφαρμογή ή λειτουργία στο παρελθόν, μπορείτε να επαναφέρετε τις αγορές σας.";
|
||||
"views.paywall.sections.restore.header" = "Επαναφορά";
|
||||
|
@ -78,12 +78,12 @@
|
||||
"views.migration.alerts.delete.message" = "Do you want to discard these profiles? You will not be able to recover them later.\n\n%@";
|
||||
|
||||
"views.paywall.sections.required_features.header" = "Required features";
|
||||
"views.paywall.sections.included_features.header" = "Also includes";
|
||||
"views.paywall.sections.products.header" = "Available products";
|
||||
"views.paywall.sections.products.header" = "Suggested products";
|
||||
"views.paywall.sections.products.footer" = "All purchases support Family Sharing.";
|
||||
"views.paywall.sections.restore.header" = "Restore";
|
||||
"views.paywall.sections.restore.footer" = "If you bought this app or feature in the past, you can restore your purchases.";
|
||||
"views.paywall.rows.restore_purchases" = "Restore purchases";
|
||||
"views.paywall.product.included_features" = "Included features";
|
||||
"views.paywall.alerts.confirmation.title" = "Purchase required";
|
||||
"views.paywall.alerts.confirmation.message" = "This profile requires paid features to work.";
|
||||
"views.paywall.alerts.confirmation.message.connect" = "You may test the connection for %d minutes.";
|
||||
|
@ -260,12 +260,13 @@
|
||||
"views.paywall.alerts.verification.connect.1" = "Tus compras están siendo verificadas.";
|
||||
"views.paywall.alerts.verification.connect.2" = "Si la verificación no se completa, la conexión finalizará en %d minutos.";
|
||||
"views.paywall.alerts.verification.edit" = "Por favor, espera mientras verificamos tus compras.";
|
||||
"views.paywall.product.included_features" = "Funciones incluidas";
|
||||
"views.paywall.rows.restore_purchases" = "Restaurar compras";
|
||||
"views.paywall.sections.all_features.header" = "La versión completa incluye";
|
||||
"views.paywall.sections.full_products.header" = "Versión completa";
|
||||
"views.paywall.sections.included_features.header" = "También incluye";
|
||||
"views.paywall.sections.products.footer" = "Todas las compras admiten En Familia.";
|
||||
"views.paywall.sections.products.header" = "Productos disponibles";
|
||||
"views.paywall.sections.products.header" = "Productos sugeridos";
|
||||
"views.paywall.sections.required_features.header" = "Características requeridas";
|
||||
"views.paywall.sections.restore.footer" = "Si compraste esta app o característica en el pasado, puedes restaurar tus compras.";
|
||||
"views.paywall.sections.restore.header" = "Restaurar";
|
||||
|
@ -260,12 +260,13 @@
|
||||
"views.paywall.alerts.verification.connect.1" = "Vos achats sont en cours de vérification.";
|
||||
"views.paywall.alerts.verification.connect.2" = "Si la vérification ne peut être complétée, la connexion s’arrêtera dans %d minutes.";
|
||||
"views.paywall.alerts.verification.edit" = "Veuillez patienter pendant la vérification de vos achats.";
|
||||
"views.paywall.product.included_features" = "Fonctionnalités incluses";
|
||||
"views.paywall.rows.restore_purchases" = "Restaurer les achats";
|
||||
"views.paywall.sections.all_features.header" = "La version complète inclut";
|
||||
"views.paywall.sections.full_products.header" = "Version complète";
|
||||
"views.paywall.sections.included_features.header" = "Comprend également";
|
||||
"views.paywall.sections.products.footer" = "Tous les achats prennent en charge le Partage familial.";
|
||||
"views.paywall.sections.products.header" = "Produits disponibles";
|
||||
"views.paywall.sections.products.header" = "Produits suggérés";
|
||||
"views.paywall.sections.required_features.header" = "Fonctionnalités requises";
|
||||
"views.paywall.sections.restore.footer" = "Si vous avez acheté cette application ou cette fonctionnalité dans le passé, vous pouvez restaurer vos achats.";
|
||||
"views.paywall.sections.restore.header" = "Restaurer";
|
||||
|
@ -260,12 +260,13 @@
|
||||
"views.paywall.alerts.verification.connect.1" = "I tuoi acquisti sono in fase di verifica.";
|
||||
"views.paywall.alerts.verification.connect.2" = "Se la verifica non può essere completata, la connessione terminerà tra %d minuti.";
|
||||
"views.paywall.alerts.verification.edit" = "Attendere mentre i tuoi acquisti vengono verificati.";
|
||||
"views.paywall.product.included_features" = "Funzionalità incluse";
|
||||
"views.paywall.rows.restore_purchases" = "Ripristina acquisti";
|
||||
"views.paywall.sections.all_features.header" = "La versione completa include";
|
||||
"views.paywall.sections.full_products.header" = "Versione completa";
|
||||
"views.paywall.sections.included_features.header" = "Include anche";
|
||||
"views.paywall.sections.products.footer" = "Tutti gli acquisti supportano “In famiglia”.";
|
||||
"views.paywall.sections.products.header" = "Prodotti disponibili";
|
||||
"views.paywall.sections.products.header" = "Prodotti suggeriti";
|
||||
"views.paywall.sections.required_features.header" = "Funzionalità richieste";
|
||||
"views.paywall.sections.restore.footer" = "Se hai acquistato questa app o funzionalità in passato, puoi ripristinare i tuoi acquisti.";
|
||||
"views.paywall.sections.restore.header" = "Ripristina";
|
||||
|
@ -260,12 +260,13 @@
|
||||
"views.paywall.alerts.verification.connect.1" = "Je aankopen worden geverifieerd.";
|
||||
"views.paywall.alerts.verification.connect.2" = "Als de verificatie niet kan worden voltooid, wordt de verbinding over %d minuten beëindigd.";
|
||||
"views.paywall.alerts.verification.edit" = "Even geduld terwijl we je aankopen verifiëren.";
|
||||
"views.paywall.product.included_features" = "Inbegrepen functies";
|
||||
"views.paywall.rows.restore_purchases" = "Aankopen herstellen";
|
||||
"views.paywall.sections.all_features.header" = "De volledige versie bevat";
|
||||
"views.paywall.sections.full_products.header" = "Volledige versie";
|
||||
"views.paywall.sections.included_features.header" = "Bevat ook";
|
||||
"views.paywall.sections.products.footer" = "Alle aankopen ondersteunen Delen met gezin.";
|
||||
"views.paywall.sections.products.header" = "Beschikbare producten";
|
||||
"views.paywall.sections.products.header" = "Voorgestelde producten";
|
||||
"views.paywall.sections.required_features.header" = "Vereiste functies";
|
||||
"views.paywall.sections.restore.footer" = "Als je deze app of functie eerder hebt gekocht, kun je je aankopen herstellen.";
|
||||
"views.paywall.sections.restore.header" = "Herstellen";
|
||||
|
@ -260,12 +260,13 @@
|
||||
"views.paywall.alerts.verification.connect.1" = "Twoje zakupy są weryfikowane.";
|
||||
"views.paywall.alerts.verification.connect.2" = "Jeśli weryfikacja nie zostanie zakończona, połączenie zostanie zakończone za %d minut.";
|
||||
"views.paywall.alerts.verification.edit" = "Proszę czekać, trwa weryfikacja zakupów.";
|
||||
"views.paywall.product.included_features" = "Uwzględnione funkcje";
|
||||
"views.paywall.rows.restore_purchases" = "Przywróć zakupy";
|
||||
"views.paywall.sections.all_features.header" = "Pełna wersja zawiera";
|
||||
"views.paywall.sections.full_products.header" = "Pełna wersja";
|
||||
"views.paywall.sections.included_features.header" = "Zawiera także";
|
||||
"views.paywall.sections.products.footer" = "Wszystkie zakupy obsługują Chmurę rodzinną.";
|
||||
"views.paywall.sections.products.header" = "Dostępne produkty";
|
||||
"views.paywall.sections.products.header" = "Sugerowane produkty";
|
||||
"views.paywall.sections.required_features.header" = "Wymagane funkcje";
|
||||
"views.paywall.sections.restore.footer" = "Jeśli wcześniej kupiłeś tę aplikację lub funkcję, możesz przywrócić swoje zakupy.";
|
||||
"views.paywall.sections.restore.header" = "Przywróć";
|
||||
|
@ -260,12 +260,13 @@
|
||||
"views.paywall.alerts.verification.connect.1" = "Suas compras estão sendo verificadas.";
|
||||
"views.paywall.alerts.verification.connect.2" = "Se a verificação não for concluída, a conexão será encerrada em %d minutos.";
|
||||
"views.paywall.alerts.verification.edit" = "Aguarde enquanto suas compras estão sendo verificadas.";
|
||||
"views.paywall.product.included_features" = "Recursos incluídos";
|
||||
"views.paywall.rows.restore_purchases" = "Restaurar compras";
|
||||
"views.paywall.sections.all_features.header" = "A versão completa inclui";
|
||||
"views.paywall.sections.full_products.header" = "Versão completa";
|
||||
"views.paywall.sections.included_features.header" = "Também inclui";
|
||||
"views.paywall.sections.products.footer" = "Todas as compras são compatíveis com Compartilhamento Familiar.";
|
||||
"views.paywall.sections.products.header" = "Produtos disponíveis";
|
||||
"views.paywall.sections.products.header" = "Produtos sugeridos";
|
||||
"views.paywall.sections.required_features.header" = "Recursos necessários";
|
||||
"views.paywall.sections.restore.footer" = "Se você comprou este app ou recurso no passado, pode restaurar suas compras.";
|
||||
"views.paywall.sections.restore.header" = "Restaurar";
|
||||
|
@ -260,12 +260,13 @@
|
||||
"views.paywall.alerts.verification.connect.1" = "Ваши покупки проверяются.";
|
||||
"views.paywall.alerts.verification.connect.2" = "Если проверка не будет завершена, соединение завершится через %d минут.";
|
||||
"views.paywall.alerts.verification.edit" = "Пожалуйста, подождите, пока ваши покупки проверяются.";
|
||||
"views.paywall.product.included_features" = "Включенные функции";
|
||||
"views.paywall.rows.restore_purchases" = "Восстановить покупки";
|
||||
"views.paywall.sections.all_features.header" = "Полная версия включает";
|
||||
"views.paywall.sections.full_products.header" = "Полная версия";
|
||||
"views.paywall.sections.included_features.header" = "Также включает";
|
||||
"views.paywall.sections.products.footer" = "Все покупки поддерживают Семейный доступ.";
|
||||
"views.paywall.sections.products.header" = "Доступные продукты";
|
||||
"views.paywall.sections.products.header" = "Рекомендуемые продукты";
|
||||
"views.paywall.sections.required_features.header" = "Необходимые функции";
|
||||
"views.paywall.sections.restore.footer" = "Если вы уже купили это приложение или функцию в прошлом, вы можете восстановить свои покупки.";
|
||||
"views.paywall.sections.restore.header" = "Восстановить";
|
||||
|
@ -260,12 +260,13 @@
|
||||
"views.paywall.alerts.verification.connect.1" = "Dina köp verifieras.";
|
||||
"views.paywall.alerts.verification.connect.2" = "Om verifieringen inte kan slutföras kommer anslutningen att avslutas om %d minuter.";
|
||||
"views.paywall.alerts.verification.edit" = "Vänligen vänta medan dina köp verifieras.";
|
||||
"views.paywall.product.included_features" = "Inkluderade funktioner";
|
||||
"views.paywall.rows.restore_purchases" = "Återställ köp";
|
||||
"views.paywall.sections.all_features.header" = "Den fullständiga versionen innehåller";
|
||||
"views.paywall.sections.full_products.header" = "Fullständig version";
|
||||
"views.paywall.sections.included_features.header" = "Inkluderar även";
|
||||
"views.paywall.sections.products.footer" = "Alla köp stöder Familjedelning.";
|
||||
"views.paywall.sections.products.header" = "Tillgängliga produkter";
|
||||
"views.paywall.sections.products.header" = "Föreslagna produkter";
|
||||
"views.paywall.sections.required_features.header" = "Krävda funktioner";
|
||||
"views.paywall.sections.restore.footer" = "Om du har köpt denna app eller funktion tidigare kan du återställa dina köp.";
|
||||
"views.paywall.sections.restore.header" = "Återställ";
|
||||
|
@ -260,12 +260,13 @@
|
||||
"views.paywall.alerts.verification.connect.1" = "Ваші покупки перевіряються.";
|
||||
"views.paywall.alerts.verification.connect.2" = "Якщо перевірку не вдасться завершити, підключення завершиться через %d хвилин.";
|
||||
"views.paywall.alerts.verification.edit" = "Будь ласка, зачекайте, поки ваші покупки перевіряються.";
|
||||
"views.paywall.product.included_features" = "Включені функції";
|
||||
"views.paywall.rows.restore_purchases" = "Відновити покупки";
|
||||
"views.paywall.sections.all_features.header" = "Повна версія включає";
|
||||
"views.paywall.sections.full_products.header" = "Повна версія";
|
||||
"views.paywall.sections.included_features.header" = "Також включає";
|
||||
"views.paywall.sections.products.footer" = "Усі покупки підтримують “Сімейний доступ”.";
|
||||
"views.paywall.sections.products.header" = "Доступні продукти";
|
||||
"views.paywall.sections.products.header" = "Рекомендовані продукти";
|
||||
"views.paywall.sections.required_features.header" = "Необхідні функції";
|
||||
"views.paywall.sections.restore.footer" = "Якщо ви раніше купували цей додаток або функцію, ви можете відновити свої покупки.";
|
||||
"views.paywall.sections.restore.header" = "Відновлення";
|
||||
|
@ -260,12 +260,13 @@
|
||||
"views.paywall.alerts.verification.connect.1" = "您的购买正在验证中。";
|
||||
"views.paywall.alerts.verification.connect.2" = "如果无法完成验证,连接将在 %d 分钟后断开。";
|
||||
"views.paywall.alerts.verification.edit" = "请稍候,您的购买正在验证中。";
|
||||
"views.paywall.product.included_features" = "包含的功能";
|
||||
"views.paywall.rows.restore_purchases" = "恢复购买";
|
||||
"views.paywall.sections.all_features.header" = "完整版本包括";
|
||||
"views.paywall.sections.full_products.header" = "完整版本";
|
||||
"views.paywall.sections.included_features.header" = "还包括";
|
||||
"views.paywall.sections.products.footer" = "所有购买均支持“家人共享”。";
|
||||
"views.paywall.sections.products.header" = "可用产品";
|
||||
"views.paywall.sections.products.header" = "推荐产品";
|
||||
"views.paywall.sections.required_features.header" = "必需功能";
|
||||
"views.paywall.sections.restore.footer" = "如果您过去购买过此应用或功能,可以恢复您的购买记录。";
|
||||
"views.paywall.sections.restore.header" = "恢复";
|
||||
|
@ -74,6 +74,7 @@ extension Theme {
|
||||
case tunnelUninstall
|
||||
case tvOff
|
||||
case tvOn
|
||||
case undisclose
|
||||
case upgrade
|
||||
case warning
|
||||
}
|
||||
@ -135,6 +136,7 @@ extension Theme.ImageName {
|
||||
return "tv"
|
||||
}
|
||||
case .tvOn: return "tv"
|
||||
case .undisclose: return "chevron.up"
|
||||
case .upgrade: return "arrow.up.circle"
|
||||
case .warning: return "exclamationmark.triangle"
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ enum FeatureListViewStyle {
|
||||
struct FeatureListView<Content>: View where Content: View {
|
||||
let style: FeatureListViewStyle
|
||||
|
||||
let header: String
|
||||
var header: String?
|
||||
|
||||
let features: [AppFeature]
|
||||
|
||||
@ -50,12 +50,7 @@ struct FeatureListView<Content>: View where Content: View {
|
||||
|
||||
#if !os(tvOS)
|
||||
case .table:
|
||||
// XXX: work around Table artifact when 1 row and no headers
|
||||
if features.count > 1 {
|
||||
tableView
|
||||
} else {
|
||||
listView
|
||||
}
|
||||
tableView
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -70,10 +65,8 @@ private extension FeatureListView {
|
||||
#if !os(tvOS)
|
||||
var tableView: some View {
|
||||
Table(features.sorted()) {
|
||||
TableColumn("", content: content)
|
||||
TableColumn(header ?? "", content: content)
|
||||
}
|
||||
.withoutColumnHeaders()
|
||||
.themeSection(header: header)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ public struct PaywallProductView: View {
|
||||
|
||||
private let product: InAppProduct
|
||||
|
||||
private let highlightedFeatures: Set<AppFeature>
|
||||
|
||||
@Binding
|
||||
private var purchasingIdentifier: String?
|
||||
|
||||
@ -43,10 +45,14 @@ public struct PaywallProductView: View {
|
||||
|
||||
private let onError: (Error) -> Void
|
||||
|
||||
@State
|
||||
private var isPresentingFeatures = false
|
||||
|
||||
public init(
|
||||
iapManager: IAPManager,
|
||||
style: PaywallProductViewStyle,
|
||||
product: InAppProduct,
|
||||
highlightedFeatures: Set<AppFeature> = [],
|
||||
purchasingIdentifier: Binding<String?>,
|
||||
onComplete: @escaping (String, InAppPurchaseResult) -> Void,
|
||||
onError: @escaping (Error) -> Void
|
||||
@ -54,12 +60,30 @@ public struct PaywallProductView: View {
|
||||
self.iapManager = iapManager
|
||||
self.style = style
|
||||
self.product = product
|
||||
self.highlightedFeatures = highlightedFeatures
|
||||
_purchasingIdentifier = purchasingIdentifier
|
||||
self.onComplete = onComplete
|
||||
self.onError = onError
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
productView
|
||||
Group {
|
||||
includedFeaturesButton
|
||||
.padding(.top, 8)
|
||||
includedFeaturesList
|
||||
.if(isPresentingFeatures)
|
||||
}
|
||||
.font(.subheadline)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension PaywallProductView {
|
||||
|
||||
@ViewBuilder
|
||||
var productView: some View {
|
||||
if #available(iOS 17, macOS 14, tvOS 17, *) {
|
||||
StoreKitProductView(
|
||||
style: style,
|
||||
@ -79,4 +103,60 @@ public struct PaywallProductView: View {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var includedFeaturesButton: some View {
|
||||
Button {
|
||||
isPresentingFeatures.toggle()
|
||||
} label: {
|
||||
HStack {
|
||||
Text(Strings.Views.Paywall.Product.includedFeatures)
|
||||
ThemeImage(isPresentingFeatures ? .undisclose : .disclose)
|
||||
}
|
||||
.contentShape(.rect)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.cursor(.hand)
|
||||
}
|
||||
|
||||
var includedFeaturesList: some View {
|
||||
AppProduct(rawValue: product.productIdentifier)
|
||||
.map { product in
|
||||
FeatureListView(
|
||||
style: .list,
|
||||
features: product.features,
|
||||
content: featureView
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func featureView(for feature: AppFeature) -> some View {
|
||||
HStack {
|
||||
ThemeImage(.marked)
|
||||
.opaque(highlightedFeatures.contains(feature))
|
||||
|
||||
Text(feature.localizedDescription)
|
||||
.fontWeight(highlightedFeatures.contains(feature) ? .bold : .regular)
|
||||
.scrollableOnTV()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
List {
|
||||
PaywallProductView(
|
||||
iapManager: .forPreviews,
|
||||
style: .paywall,
|
||||
product: InAppProduct(
|
||||
productIdentifier: AppProduct.Features.appleTV.rawValue,
|
||||
localizedTitle: "Foo",
|
||||
localizedPrice: "$10",
|
||||
native: nil
|
||||
),
|
||||
highlightedFeatures: [.appleTV],
|
||||
purchasingIdentifier: .constant(nil),
|
||||
onComplete: { _, _ in },
|
||||
onError: { _ in }
|
||||
)
|
||||
}
|
||||
.withMockEnvironment()
|
||||
}
|
||||
|
@ -88,9 +88,6 @@ private extension PaywallView {
|
||||
Form {
|
||||
requiredFeaturesView
|
||||
productsView
|
||||
if suggestedProducts == nil {
|
||||
alsoIncludedEssentialsView
|
||||
}
|
||||
restoreView
|
||||
linksView
|
||||
}
|
||||
@ -123,6 +120,7 @@ private extension PaywallView {
|
||||
iapManager: iapManager,
|
||||
style: .paywall,
|
||||
product: $0,
|
||||
highlightedFeatures: requiredFeatures,
|
||||
purchasingIdentifier: $purchasingIdentifier,
|
||||
onComplete: onComplete,
|
||||
onError: onError
|
||||
@ -136,22 +134,6 @@ private extension PaywallView {
|
||||
}
|
||||
}
|
||||
|
||||
var alsoIncludedEssentialsView: some View {
|
||||
essentialFeatures
|
||||
.filter {
|
||||
!requiredFeatures.contains($0)
|
||||
}
|
||||
.nilIfEmpty
|
||||
.map {
|
||||
FeatureListView(
|
||||
style: featuresStyle,
|
||||
header: Strings.Views.Paywall.Sections.IncludedFeatures.header,
|
||||
features: $0,
|
||||
content: featureView(for:)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var linksView: some View {
|
||||
Section {
|
||||
Link(Strings.Unlocalized.eula, destination: Constants.shared.websites.eula)
|
||||
@ -159,14 +141,6 @@ private extension PaywallView {
|
||||
}
|
||||
}
|
||||
|
||||
var featuresStyle: FeatureListViewStyle {
|
||||
#if os(iOS)
|
||||
.list
|
||||
#else
|
||||
.table
|
||||
#endif
|
||||
}
|
||||
|
||||
func featureView(for feature: AppFeature) -> some View {
|
||||
Text(feature.localizedDescription)
|
||||
.scrollableOnTV()
|
||||
|
Loading…
Reference in New Issue
Block a user