Skip to content

Commit

Permalink
Paywalls: .card and .condensedCard modes (#2995)
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoSoto committed Aug 17, 2023
1 parent a67368e commit 8f5be1c
Show file tree
Hide file tree
Showing 34 changed files with 658 additions and 465 deletions.
7 changes: 5 additions & 2 deletions RevenueCatUI/Data/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ import SwiftUI
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
enum Constants {

static let defaultAnimation: Animation = .easeIn(duration: 0.2)
static let fastAnimation: Animation = .easeIn(duration: 0.1)
static let defaultAnimation: Animation = .easeInOut(duration: 0.2)
static let fastAnimation: Animation = .easeInOut(duration: 0.1)
static let displayAllPlansAnimation: Animation = .easeInOut(duration: 0.2)

static let defaultCornerRadius: CGFloat = 20

/// For UI elements that wouldn't make sense to keep scaling up forever
static let maximumDynamicTypeSize: DynamicTypeSize = .accessibility3
Expand Down
49 changes: 49 additions & 0 deletions RevenueCatUI/Data/PaywallViewMode+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// PaywallViewMode+Extensions.swift
//
//
// Created by Nacho Soto on 8/9/23.
//

import RevenueCat

extension PaywallViewMode {

var displayAllPlansByDefault: Bool {
switch self {
case .fullScreen: return true
case .card: return true
case .condensedCard: return false
}
}

var displayAllPlansButton: Bool {
switch self {
case .fullScreen: return false
case .card: return false
case .condensedCard: return true
}
}

var shouldDisplayIcon: Bool {
switch self {
case .fullScreen: return true
case .card, .condensedCard: return false
}
}

var shouldDisplayText: Bool {
switch self {
case .fullScreen: return true
case .card, .condensedCard: return false
}
}

var shouldDisplayFeatures: Bool {
switch self {
case .fullScreen: return true
case .card, .condensedCard: return false
}
}

}
18 changes: 0 additions & 18 deletions RevenueCatUI/Data/TemplateViewConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,24 +91,6 @@ extension TemplateViewConfiguration.PackageConfiguration {

}

// MARK: - Helpers

@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
extension TemplateViewConfiguration.PackageConfiguration {

/// - Returns: a dictionary for all localizations keyed by each package.
func localizationPerPackage() -> [Package: ProcessedLocalizedConfiguration] {
return .init(
self.all
.lazy
.map { ($0.content, $0.localization) },
// Ignore duplicates
uniquingKeysWith: { first, _ in first }
)
}

}

// MARK: - Creation

@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
Expand Down
3 changes: 1 addition & 2 deletions RevenueCatUI/Data/TestData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ internal enum TestData {
)
),
blurredBackgroundImage: true,
termsOfServiceURL: URL(string: "https://revenuecat.com/tos")!,
privacyURL: URL(string: "https://revenuecat.com/tos")!
),
localization: Self.localization2,
Expand Down Expand Up @@ -253,7 +252,7 @@ internal enum TestData {
callToAction: "Start",
callToActionWithIntroOffer: "Start your {{ sub_offer_duration }} free",
offerDetails: "Only {{ price }} per {{ sub_period }}",
offerDetailsWithIntroOffer: "First {{ sub_offer_duration }} free,\n" +
offerDetailsWithIntroOffer: "First {{ sub_offer_duration }} free, " +
"then {{ total_price_and_per_month }}",
features: [
.init(title: "Today",
Expand Down
18 changes: 17 additions & 1 deletion RevenueCatUI/Helpers/PreviewHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ struct PreviewableTemplate<T: TemplateViewType>: View {

init(
offering: Offering,
mode: PaywallViewMode = .default,
presentInSheet: Bool = false,
creator: @escaping Creator
) {
self.configuration = offering.paywall!.configuration(
for: offering,
mode: .fullScreen,
mode: mode,
fonts: DefaultPaywallFontProvider(),
locale: .current
)
Expand Down Expand Up @@ -90,6 +91,8 @@ struct PreviewableTemplate<T: TemplateViewType>: View {
for: configuration.packages
)
}
.previewDisplayName("\(configuration.mode)")
.previewLayout(configuration.mode.layout)

case let .failure(error):
DebugErrorView("Invalid configuration: \(error)",
Expand All @@ -99,4 +102,17 @@ struct PreviewableTemplate<T: TemplateViewType>: View {

}

@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
private extension PaywallViewMode {

var layout: PreviewLayout {
switch self {
case .fullScreen: return .device
case .card: return .fixed(width: 400, height: 280)
case .condensedCard: return .fixed(width: 400, height: 150)
}
}

}

#endif
36 changes: 36 additions & 0 deletions RevenueCatUI/Modifiers/CardHidingModifier.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// CardHidingModifier.swift
//
//
// Created by Nacho Soto on 8/9/23.
//

import RevenueCat
import SwiftUI

@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
extension View {

func hideCardContent(_ hide: Bool, _ offset: CGFloat) -> some View {
return self.modifier(CardHidingModifier(hide: hide, offset: offset))
}

}

@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
private struct CardHidingModifier: ViewModifier {

var hide: Bool
var offset: CGFloat

func body(content: Content) -> some View {
content
.opacity(self.hide ? 0 : 1)
.offset(y: self.hide ? self.offset : 0)
.frame(height: self.hide ? 0 : nil)
.blur(radius: self.hide ? Self.blurRadius : 0)
}

private static let blurRadius: CGFloat = 20

}
35 changes: 6 additions & 29 deletions RevenueCatUI/PaywallView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public struct PaywallView: View {
purchaseHandler: purchaseHandler)
.transition(Self.transition)
} else {
LoadingPaywallView()
LoadingPaywallView(mode: self.mode)
.transition(Self.transition)
.task {
do {
Expand Down Expand Up @@ -202,38 +202,15 @@ struct LoadedOfferingPaywallView: View {
.environmentObject(self.purchaseHandler)
.preference(key: PurchasedCustomerInfoPreferenceKey.self,
value: self.purchaseHandler.purchasedCustomerInfo)
.hidden(if: self.shouldHidePaywall)
.disabled(self.purchaseHandler.actionInProgress)

if let aspectRatio = self.mode.aspectRatio {
view.aspectRatio(aspectRatio, contentMode: .fit)
} else {
view
}
}

private var shouldHidePaywall: Bool {
switch self.mode {
case .fullScreen:
return false

case .card, .banner:
return self.purchaseHandler.purchased
}
}

}

// MARK: - Extensions

@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
private extension PaywallViewMode {
view

var aspectRatio: CGFloat? {
switch self {
case .fullScreen: return nil
case .card: return 1
case .banner: return 8
case .card, .condensedCard:
view
.fixedSize(horizontal: false, vertical: true)
}
}

Expand Down Expand Up @@ -288,7 +265,7 @@ private extension PaywallViewMode {
var layout: PreviewLayout {
switch self {
case .fullScreen: return .device
case .card, .banner: return .sizeThatFits
case .card, .condensedCard: return .sizeThatFits
}
}

Expand Down
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"OK" = "OK";
"All plans" = "All plans";
"Privacy" = "Privacy";
"Privacy policy" = "Privacy policy";
"Purchases restored successfully!" = "Purchases restored successfully!";
Expand Down
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"OK" = "OK";
"All plans" = "Planes";
"Privacy" = "Privacidad";
"Privacy policy" = "Política de privacidad";
"Purchases restored successfully!" = "Compras restauradas!";
Expand Down
Loading

0 comments on commit 8f5be1c

Please sign in to comment.