Skip to content

Commit

Permalink
[Paywalls V2] Add support for alias solid hex colors (not gradients) (#…
Browse files Browse the repository at this point in the history
…4632)

* Added alias colors

* Fixes from PR review
  • Loading branch information
joshdholtz authored Jan 7, 2025
1 parent 68bf247 commit 4672cbb
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ struct StackComponentView: View {
}
.padding(style.padding)
.padding(additionalPadding)
.backgroundStyle(style.backgroundStyle)
.backgroundStyle(style.backgroundStyle, uiConfigProvider: self.viewModel.uiConfigProvider)
.shape(border: style.border,
shape: style.shape)
.applyIfLet(style.shadow) { view, shadow in
Expand Down Expand Up @@ -456,7 +456,8 @@ fileprivate extension StackComponentViewModel {

try self.init(
component: component,
viewModels: viewModels
viewModels: viewModels,
uiConfigProvider: .init(uiConfig: PreviewUIConfig.make())
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,19 @@ private typealias PresentedStackPartial = PaywallComponent.PartialStackComponent
class StackComponentViewModel {

private let component: PaywallComponent.StackComponent
let uiConfigProvider: UIConfigProvider
private let presentedOverrides: PresentedOverrides<PresentedStackPartial>?

let viewModels: [PaywallComponentViewModel]

init(
component: PaywallComponent.StackComponent,
viewModels: [PaywallComponentViewModel]
viewModels: [PaywallComponentViewModel],
uiConfigProvider: UIConfigProvider
) throws {
self.component = component
self.viewModels = viewModels
self.uiConfigProvider = uiConfigProvider

self.presentedOverrides = try self.component.overrides?.toPresentedOverrides { $0 }
}
Expand All @@ -51,6 +54,7 @@ class StackComponentViewModel {
)

let style = StackComponentStyle(
uiConfigProvider: self.uiConfigProvider,
visible: partial?.visible ?? true,
dimension: partial?.dimension ?? self.component.dimension,
size: partial?.size ?? self.component.size,
Expand Down Expand Up @@ -107,6 +111,7 @@ struct StackComponentStyle {
let shadow: ShadowModifier.ShadowInfo?

init(
uiConfigProvider: UIConfigProvider,
visible: Bool,
dimension: PaywallComponent.Dimension,
size: PaywallComponent.Size,
Expand All @@ -126,8 +131,8 @@ struct StackComponentStyle {
self.padding = padding.edgeInsets
self.margin = margin.edgeInsets
self.shape = shape?.shape
self.border = border?.border
self.shadow = shadow?.shadow
self.border = border?.border(uiConfigProvider: uiConfigProvider)
self.shadow = shadow?.shadow(uiConfigProvider: uiConfigProvider)
}

var vstackStrategy: StackStrategy {
Expand Down Expand Up @@ -185,9 +190,9 @@ private extension PaywallComponent.Shape {
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
private extension PaywallComponent.Border {

var border: ShapeModifier.BorderInfo? {
ShapeModifier.BorderInfo(
color: self.color.toDynamicColor(),
func border(uiConfigProvider: UIConfigProvider) -> ShapeModifier.BorderInfo? {
return ShapeModifier.BorderInfo(
color: self.color.toDynamicColor(uiConfigProvider: uiConfigProvider),
width: self.width
)
}
Expand All @@ -197,9 +202,9 @@ private extension PaywallComponent.Border {
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
private extension PaywallComponent.Shadow {

var shadow: ShadowModifier.ShadowInfo? {
ShadowModifier.ShadowInfo(
color: self.color.toDynamicColor(),
func shadow(uiConfigProvider: UIConfigProvider) -> ShadowModifier.ShadowInfo? {
return ShadowModifier.ShadowInfo(
color: self.color.toDynamicColor(uiConfigProvider: uiConfigProvider),
radius: self.radius,
x: self.x,
y: self.y
Expand Down
60 changes: 58 additions & 2 deletions RevenueCatUI/Templates/V2/Components/Text/TextComponentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
//
// Created by Josh Holtz on 6/11/24.

// swiftlint:disable file_length

import Foundation
import RevenueCat
import SwiftUI
Expand Down Expand Up @@ -54,10 +56,10 @@ struct TextComponentView: View {
.fontWeight(style.fontWeight)
.fixedSize(horizontal: false, vertical: true)
.multilineTextAlignment(style.textAlignment)
.foregroundColorScheme(style.color)
.foregroundColorScheme(style.color, uiConfigProvider: self.viewModel.uiConfigProvider)
.padding(style.padding)
.size(style.size, alignment: style.horizontalAlignment)
.backgroundStyle(style.backgroundStyle)
.backgroundStyle(style.backgroundStyle, uiConfigProvider: self.viewModel.uiConfigProvider)
.padding(style.margin)
} else {
EmptyView()
Expand Down Expand Up @@ -189,6 +191,60 @@ struct TextComponentView_Previews: PreviewProvider {
.previewLayout(.sizeThatFits)
.previewDisplayName("Custom Font")

// Custom Color
VStack {
TextComponentView(
// swiftlint:disable:next force_try
viewModel: try! .init(
localizationProvider: .init(
locale: Locale.current,
localizedStrings: [
"id_1": .string("Red bg, yellow fg")
]
),
uiConfigProvider: .init(uiConfig: PreviewUIConfig.make(
colors: [
"primary": .hex("#ff0000"),
"secondary": .hex("#ffcc00")
]
)),
component: .init(
text: "id_1",
color: .init(light: .alias("secondary")),
backgroundColor: .init(light: .alias("primary")),
fontSize: .headingXXL
)
)
)

TextComponentView(
// swiftlint:disable:next force_try
viewModel: try! .init(
localizationProvider: .init(
locale: Locale.current,
localizedStrings: [
"id_1": .string("Clear bg and default fg")
]
),
uiConfigProvider: .init(uiConfig: PreviewUIConfig.make(
colors: [
"primary": .hex("#ff0000"),
"secondary": .hex("#ffcc00")
]
)),
component: .init(
text: "id_1",
color: .init(light: .alias("not a thing")),
backgroundColor: .init(light: .alias("also not a thing")),
fontSize: .headingXXL
)
)
)
}
.previewRequiredEnvironmentProperties()
.previewLayout(.sizeThatFits)
.previewDisplayName("Custom Color")

// Gradient
TextComponentView(
// swiftlint:disable:next force_try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import SwiftUI
class TextComponentViewModel {

private let localizationProvider: LocalizationProvider
private let uiConfigProvider: UIConfigProvider
let uiConfigProvider: UIConfigProvider
private let component: PaywallComponent.TextComponent

private let text: String
Expand Down
22 changes: 14 additions & 8 deletions RevenueCatUI/Templates/V2/PaywallsV2View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ struct PaywallsV2View: View {
private var paywallStateManager: PaywallStateManager

private let paywallComponentsData: PaywallComponentsData
private let uiConfig: UIConfig
private let uiConfigProvider: UIConfigProvider
private let offering: Offering
private let onDismiss: () -> Void

Expand All @@ -61,8 +61,10 @@ struct PaywallsV2View: View {
showZeroDecimalPlacePrices: Bool,
onDismiss: @escaping () -> Void
) {
let uiConfigProvider = UIConfigProvider(uiConfig: paywallComponents.uiConfig)

self.paywallComponentsData = paywallComponents.data
self.uiConfig = paywallComponents.uiConfig
self.uiConfigProvider = uiConfigProvider
self.offering = offering
self.onDismiss = onDismiss
self._introOfferEligibilityContext = .init(
Expand All @@ -80,7 +82,7 @@ struct PaywallsV2View: View {
componentsConfig: componentsConfig,
componentsLocalizations: paywallComponents.data.componentsLocalizations,
defaultLocale: paywallComponents.data.defaultLocale,
uiConfig: paywallComponents.uiConfig,
uiConfigProvider: uiConfigProvider,
offering: offering,
introEligibilityChecker: introEligibilityChecker,
showZeroDecimalPlacePrices: showZeroDecimalPlacePrices
Expand All @@ -93,6 +95,7 @@ struct PaywallsV2View: View {
case .success(let paywallState):
LoadedPaywallsV2View(
paywallState: paywallState,
uiConfigProvider: self.uiConfigProvider,
onDismiss: self.onDismiss
)
.environment(\.screenCondition, ScreenCondition.from(self.horizontalSizeClass))
Expand Down Expand Up @@ -135,13 +138,15 @@ struct PaywallsV2View: View {
private struct LoadedPaywallsV2View: View {

private let paywallState: PaywallState
private let uiConfigProvider: UIConfigProvider
private let onDismiss: () -> Void

@StateObject
private var selectedPackageContext: PackageContext

init(paywallState: PaywallState, onDismiss: @escaping () -> Void) {
init(paywallState: PaywallState, uiConfigProvider: UIConfigProvider, onDismiss: @escaping () -> Void) {
self.paywallState = paywallState
self.uiConfigProvider = uiConfigProvider
self.onDismiss = onDismiss

self._selectedPackageContext = .init(
Expand All @@ -164,7 +169,10 @@ private struct LoadedPaywallsV2View: View {
}
.environmentObject(self.selectedPackageContext)
.frame(maxHeight: .infinity, alignment: .topLeading)
.backgroundStyle(self.paywallState.componentsConfig.background.backgroundStyle)
.backgroundStyle(
self.paywallState.componentsConfig.background.backgroundStyle,
uiConfigProvider: self.uiConfigProvider
)
.edgesIgnoringSafeArea(.top)
}

Expand All @@ -178,7 +186,7 @@ fileprivate extension PaywallsV2View {
componentsConfig: PaywallComponentsData.PaywallComponentsConfig,
componentsLocalizations: [PaywallComponent.LocaleID: PaywallComponent.LocalizationDictionary],
defaultLocale: String,
uiConfig: UIConfig,
uiConfigProvider: UIConfigProvider,
offering: Offering,
introEligibilityChecker: TrialOrIntroEligibilityChecker,
showZeroDecimalPlacePrices: Bool
Expand All @@ -190,8 +198,6 @@ fileprivate extension PaywallsV2View {
)

do {
let uiConfigProvider = UIConfigProvider(uiConfig: uiConfig)

let factory = ViewModelFactory()
let root = try factory.toRootViewModel(
componentsConfig: componentsConfig,
Expand Down
37 changes: 23 additions & 14 deletions RevenueCatUI/Templates/V2/ViewHelpers/BackgroundStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ struct BackgroundStyleModifier: ViewModifier {
var colorScheme

var backgroundStyle: BackgroundStyle?
var uiConfigProvider: UIConfigProvider

func body(content: Content) -> some View {
if let backgroundStyle {
content
.apply(backgroundStyle: backgroundStyle, colorScheme: colorScheme)
.apply(backgroundStyle: backgroundStyle, colorScheme: colorScheme, uiConfigProvider: uiConfigProvider)
} else {
content
}
Expand All @@ -46,12 +47,16 @@ struct BackgroundStyleModifier: ViewModifier {
fileprivate extension View {

@ViewBuilder
func apply(backgroundStyle: BackgroundStyle, colorScheme: ColorScheme) -> some View {
func apply(
backgroundStyle: BackgroundStyle,
colorScheme: ColorScheme,
uiConfigProvider: UIConfigProvider
) -> some View {
switch backgroundStyle {
case .color(let color):
switch color.effectiveColor(for: colorScheme) {
case .hex, .alias:
self.background(color.toDynamicColor())
self.background(color.toDynamicColor(uiConfigProvider: uiConfigProvider))
case .linear(let degrees, _):
self.background {
GradientView(
Expand Down Expand Up @@ -91,8 +96,8 @@ fileprivate extension View {
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
extension View {

func backgroundStyle(_ backgroundStyle: BackgroundStyle?) -> some View {
self.modifier(BackgroundStyleModifier(backgroundStyle: backgroundStyle))
func backgroundStyle(_ backgroundStyle: BackgroundStyle?, uiConfigProvider: UIConfigProvider) -> some View {
self.modifier(BackgroundStyleModifier(backgroundStyle: backgroundStyle, uiConfigProvider: uiConfigProvider))
}

}
Expand Down Expand Up @@ -143,7 +148,7 @@ struct BackgrounDStyle_Previews: PreviewProvider {
.backgroundStyle(.color(.init(
light: .hex("#ff0000"),
dark: .hex("#ffcc00")
)))
)), uiConfigProvider: .init(uiConfig: PreviewUIConfig.make()))
.previewLayout(.sizeThatFits)
.previewDisplayName("Color - Light (should be red)")

Expand All @@ -152,7 +157,7 @@ struct BackgrounDStyle_Previews: PreviewProvider {
.backgroundStyle(.color(.init(
light: .hex("#ff0000"),
dark: .hex("#ffcc00")
)))
)), uiConfigProvider: .init(uiConfig: PreviewUIConfig.make()))
.preferredColorScheme(.dark)
.previewLayout(.sizeThatFits)
.previewDisplayName("Color - Dark (should be yellow)")
Expand All @@ -161,7 +166,7 @@ struct BackgrounDStyle_Previews: PreviewProvider {
testContent
.backgroundStyle(.color(.init(
light: .hex("#ff0000")
)))
)), uiConfigProvider: .init(uiConfig: PreviewUIConfig.make()))
.preferredColorScheme(.dark)
.previewLayout(.sizeThatFits)
.previewDisplayName("Color - Dark (should be red because fallback)")
Expand All @@ -183,7 +188,7 @@ struct BackgrounDStyle_Previews: PreviewProvider {
heic: darkUrl,
heicLowRes: darkUrl
)
)))
)), uiConfigProvider: .init(uiConfig: PreviewUIConfig.make()))
.previewLayout(.sizeThatFits)
.previewDisplayName("Image - Light (should be pink cat)")

Expand All @@ -204,7 +209,7 @@ struct BackgrounDStyle_Previews: PreviewProvider {
heic: darkUrl,
heicLowRes: darkUrl
)
)))
)), uiConfigProvider: .init(uiConfig: PreviewUIConfig.make()))
.preferredColorScheme(.dark)
.previewLayout(.sizeThatFits)
.previewDisplayName("Image - Dark (should be japan cats)")
Expand All @@ -222,7 +227,8 @@ struct BackgrounDStyle_Previews: PreviewProvider {
.init(color: "#E58984", percent: 100)
])
)
)
),
uiConfigProvider: .init(uiConfig: PreviewUIConfig.make())
)
.preferredColorScheme(.dark)
.previewLayout(.sizeThatFits)
Expand All @@ -241,7 +247,8 @@ struct BackgrounDStyle_Previews: PreviewProvider {
.init(color: "#9DEAD3", percent: 100)
])
)
)
),
uiConfigProvider: .init(uiConfig: PreviewUIConfig.make())
)
.previewLayout(.sizeThatFits)
.previewDisplayName("Linear Gradient - Light (should be green")
Expand All @@ -259,7 +266,8 @@ struct BackgrounDStyle_Previews: PreviewProvider {
.init(color: "#E58984", percent: 100)
])
)
)
),
uiConfigProvider: .init(uiConfig: PreviewUIConfig.make())
)
.preferredColorScheme(.dark)
.previewLayout(.sizeThatFits)
Expand All @@ -279,7 +287,8 @@ struct BackgrounDStyle_Previews: PreviewProvider {
.init(color: "#ffffff", percent: 100)
])
)
)
),
uiConfigProvider: .init(uiConfig: PreviewUIConfig.make())
)
.previewLayout(.sizeThatFits)
.previewDisplayName("Radial Gradient - Light (should be green")
Expand Down
Loading

0 comments on commit 4672cbb

Please sign in to comment.