From 10392a02c8c4f570a42dc7be598e0749f912b236 Mon Sep 17 00:00:00 2001 From: Josh Holtz Date: Thu, 19 Dec 2024 15:40:22 -0600 Subject: [PATCH] Fixing text, image, and footer render issues (#4607) * Fixes stuff but needs cleaning up * Fixes * Make it work with paywalls v1 again * Fixed some image dimensions * Fix lint * Add comment --- RevenueCatUI/Modifiers/FitToAspectRatio.swift | 15 +++++-- .../Components/Image/ImageComponentView.swift | 42 +++++++++++++++++-- .../Image/ImageComponentViewModel.swift | 8 ++++ .../V2/Components/Root/RootView.swift | 8 +++- .../Components/Text/TextComponentView.swift | 2 +- .../Template1Preview.swift | 2 + .../Template5Preview.swift | 2 + .../V2/ViewHelpers/BackgroundStyle.swift | 8 ++++ .../PaywallComponentPropertyTypes.swift | 6 ++- 9 files changed, 83 insertions(+), 10 deletions(-) diff --git a/RevenueCatUI/Modifiers/FitToAspectRatio.swift b/RevenueCatUI/Modifiers/FitToAspectRatio.swift index 6b1536fdd0..db5740ecb6 100644 --- a/RevenueCatUI/Modifiers/FitToAspectRatio.swift +++ b/RevenueCatUI/Modifiers/FitToAspectRatio.swift @@ -17,10 +17,14 @@ import SwiftUI @available(iOS 15.0, macOS 12.0, tvOS 15.0, *) extension Image { - func fitToAspect(_ aspectRatio: Double, contentMode: SwiftUI.ContentMode) -> some View { + func fitToAspect(_ aspectRatio: Double, + contentMode: SwiftUI.ContentMode, + containerContentMode: SwiftUI.ContentMode? = nil) -> some View { self.resizable() .scaledToFill() - .modifier(FitToAspectRatio(aspectRatio: aspectRatio, contentMode: contentMode)) + .modifier(FitToAspectRatio(aspectRatio: aspectRatio, + contentMode: contentMode, + containerContentMode: containerContentMode)) } } @@ -30,10 +34,15 @@ private struct FitToAspectRatio: ViewModifier { let aspectRatio: Double let contentMode: SwiftUI.ContentMode + let containerContentMode: SwiftUI.ContentMode? + + private let paywallsV1ContainerContentMode: SwiftUI.ContentMode = .fit func body(content: Content) -> some View { Color.clear - .aspectRatio(self.aspectRatio, contentMode: .fit) + .aspectRatio( + self.aspectRatio, + contentMode: self.containerContentMode ?? self.paywallsV1ContainerContentMode) .overlay( content.aspectRatio(nil, contentMode: self.contentMode) ) diff --git a/RevenueCatUI/Templates/V2/Components/Image/ImageComponentView.swift b/RevenueCatUI/Templates/V2/Components/Image/ImageComponentView.swift index 3b471a819d..4dbaef3472 100644 --- a/RevenueCatUI/Templates/V2/Components/Image/ImageComponentView.swift +++ b/RevenueCatUI/Templates/V2/Components/Image/ImageComponentView.swift @@ -32,6 +32,9 @@ struct ImageComponentView: View { @Environment(\.screenCondition) private var screenCondition + @Environment(\.colorScheme) + private var colorScheme + let viewModel: ImageComponentViewModel var body: some View { @@ -48,17 +51,40 @@ struct ImageComponentView: View { darkUrl: style.darkUrl, darkLowResUrl: style.darkLowResUrl ) { (image, size) in - renderImage(image, size, with: style) + self.renderImage(image, size, with: style) } .size(style.size) .clipped() } } + private func aspectRatio(style: ImageComponentStyle) -> Double { + let (width, height) = self.imageSize(style: style) + return Double(width) / Double(height) + } + + private func imageSize(style: ImageComponentStyle) -> (width: Int, height: Int) { + switch self.colorScheme { + case .light: + return (style.widthLight, style.heightLight) + case .dark: + return (style.widthDark ?? style.widthLight, style.heightDark ?? style.heightLight) + @unknown default: + return (style.widthLight, style.heightLight) + } + } + private func renderImage(_ image: Image, _ size: CGSize, with style: ImageComponentStyle) -> some View { image - .resizable() - .aspectRatio(contentMode: style.contentMode) + .fitToAspect( + self.aspectRatio(style: style), + contentMode: style.contentMode, + containerContentMode: style.contentMode + ) + .frame(maxWidth: .infinity) + // WIP: Fix this later when accessibility info is available + .accessibilityHidden(true) + // WIP: Need to replace this gradient with the better one .overlay( LinearGradient( gradient: Gradient(colors: style.gradientColors), @@ -66,6 +92,8 @@ struct ImageComponentView: View { endPoint: .bottom ) ) + // WIP: this needs more shapes and borders + // WIP: this might also need dropshadow .shape(border: nil, shape: style.shape) } @@ -92,6 +120,8 @@ struct ImageComponentView_Previews: PreviewProvider { component: .init( source: .init( light: .init( + width: 750, + height: 530, original: catUrl, heic: catUrl, heicLowRes: catUrl @@ -118,6 +148,8 @@ struct ImageComponentView_Previews: PreviewProvider { component: .init( source: .init( light: .init( + width: 750, + height: 530, original: catUrl, heic: catUrl, heicLowRes: catUrl @@ -144,6 +176,8 @@ struct ImageComponentView_Previews: PreviewProvider { component: .init( source: .init( light: .init( + width: 750, + height: 530, original: catUrl, heic: catUrl, heicLowRes: catUrl @@ -173,6 +207,8 @@ struct ImageComponentView_Previews: PreviewProvider { component: .init( source: .init( light: .init( + width: 750, + height: 530, original: catUrl, heic: catUrl, heicLowRes: catUrl diff --git a/RevenueCatUI/Templates/V2/Components/Image/ImageComponentViewModel.swift b/RevenueCatUI/Templates/V2/Components/Image/ImageComponentViewModel.swift index e2dfb5cee6..9e1708fd99 100644 --- a/RevenueCatUI/Templates/V2/Components/Image/ImageComponentViewModel.swift +++ b/RevenueCatUI/Templates/V2/Components/Image/ImageComponentViewModel.swift @@ -118,6 +118,10 @@ extension LocalizedImagePartial { struct ImageComponentStyle { let visible: Bool + let widthLight: Int + let heightLight: Int + let widthDark: Int? + let heightDark: Int? let url: URL let lowResUrl: URL? let darkUrl: URL? @@ -136,6 +140,10 @@ struct ImageComponentStyle { gradientColors: [PaywallComponent.ColorHex]? = nil ) { self.visible = visible + self.widthLight = source.light.width + self.heightLight = source.light.height + self.widthDark = source.dark?.width + self.heightDark = source.dark?.height self.url = source.light.heic self.lowResUrl = source.light.heicLowRes self.darkUrl = source.dark?.heic diff --git a/RevenueCatUI/Templates/V2/Components/Root/RootView.swift b/RevenueCatUI/Templates/V2/Components/Root/RootView.swift index 3db99b6343..c8e0a8cdd7 100644 --- a/RevenueCatUI/Templates/V2/Components/Root/RootView.swift +++ b/RevenueCatUI/Templates/V2/Components/Root/RootView.swift @@ -34,7 +34,8 @@ struct RootView: View { StackComponentView(viewModel: viewModel.stackViewModel, onDismiss: onDismiss) }.applyIfLet(viewModel.stickyFooterViewModel) { stackView, stickyFooterViewModel in stackView - .safeAreaInset(edge: .bottom) { + // Using overlay because safeAreaInsert with fixedSize + .overlay( StackComponentView( viewModel: stickyFooterViewModel.stackViewModel, onDismiss: onDismiss, @@ -45,7 +46,10 @@ struct RootView: View { trailing: 0 ) ) - } + .fixedSize(horizontal: false, vertical: true) + .edgesIgnoringSafeArea(.bottom), + alignment: .bottom + ) // First we ensure our footer draws in the bottom safe area. Then we add additional padding, so its // background shows in that same bottom safe area. .ignoresSafeArea(edges: .bottom) diff --git a/RevenueCatUI/Templates/V2/Components/Text/TextComponentView.swift b/RevenueCatUI/Templates/V2/Components/Text/TextComponentView.swift index 1470f47f64..6bf877b223 100644 --- a/RevenueCatUI/Templates/V2/Components/Text/TextComponentView.swift +++ b/RevenueCatUI/Templates/V2/Components/Text/TextComponentView.swift @@ -49,7 +49,7 @@ struct TextComponentView: View { ) { style in Group { if style.visible { - Text(style.text) + Text(.init(style.text)) .font(style.fontSize) .fontWeight(style.fontWeight) .fixedSize(horizontal: false, vertical: true) diff --git a/RevenueCatUI/Templates/V2/Previews/TemplateComponentsViewPreviews/Template1Preview.swift b/RevenueCatUI/Templates/V2/Previews/TemplateComponentsViewPreviews/Template1Preview.swift index 7d43df73b9..5cfe7ddbf6 100644 --- a/RevenueCatUI/Templates/V2/Previews/TemplateComponentsViewPreviews/Template1Preview.swift +++ b/RevenueCatUI/Templates/V2/Previews/TemplateComponentsViewPreviews/Template1Preview.swift @@ -26,6 +26,8 @@ private enum Template1Preview { static let catImage = PaywallComponent.ImageComponent( source: .init( light: .init( + width: 750, + height: 530, original: catUrl, heic: catUrl, heicLowRes: catUrl diff --git a/RevenueCatUI/Templates/V2/Previews/TemplateComponentsViewPreviews/Template5Preview.swift b/RevenueCatUI/Templates/V2/Previews/TemplateComponentsViewPreviews/Template5Preview.swift index e16a4e1b59..dc2fc2fd9b 100644 --- a/RevenueCatUI/Templates/V2/Previews/TemplateComponentsViewPreviews/Template5Preview.swift +++ b/RevenueCatUI/Templates/V2/Previews/TemplateComponentsViewPreviews/Template5Preview.swift @@ -32,6 +32,8 @@ private enum Template5Preview { static let catImage = PaywallComponent.ImageComponent( source: .init( light: .init( + width: 750, + height: 530, original: catUrl, heic: catUrl, heicLowRes: catUrl diff --git a/RevenueCatUI/Templates/V2/ViewHelpers/BackgroundStyle.swift b/RevenueCatUI/Templates/V2/ViewHelpers/BackgroundStyle.swift index c547dde9ec..bdfb0d32ac 100644 --- a/RevenueCatUI/Templates/V2/ViewHelpers/BackgroundStyle.swift +++ b/RevenueCatUI/Templates/V2/ViewHelpers/BackgroundStyle.swift @@ -170,11 +170,15 @@ struct BackgrounDStyle_Previews: PreviewProvider { testContent .backgroundStyle(.image(.init( light: .init( + width: 750, + height: 530, original: lightUrl, heic: lightUrl, heicLowRes: lightUrl ), dark: .init( + width: 1024, + height: 853, original: darkUrl, heic: darkUrl, heicLowRes: darkUrl @@ -187,11 +191,15 @@ struct BackgrounDStyle_Previews: PreviewProvider { testContent .backgroundStyle(.image(.init( light: .init( + width: 750, + height: 530, original: lightUrl, heic: lightUrl, heicLowRes: lightUrl ), dark: .init( + width: 1024, + height: 853, original: darkUrl, heic: darkUrl, heicLowRes: darkUrl diff --git a/Sources/Paywalls/Components/Common/PaywallComponentPropertyTypes.swift b/Sources/Paywalls/Components/Common/PaywallComponentPropertyTypes.swift index 785131c50f..9a43ab5f77 100644 --- a/Sources/Paywalls/Components/Common/PaywallComponentPropertyTypes.swift +++ b/Sources/Paywalls/Components/Common/PaywallComponentPropertyTypes.swift @@ -32,12 +32,16 @@ public extension PaywallComponent { struct ImageUrls: Codable, Sendable, Hashable, Equatable { - public init(original: URL, heic: URL, heicLowRes: URL) { + public init(width: Int, height: Int, original: URL, heic: URL, heicLowRes: URL) { + self.width = width + self.height = height self.original = original self.heic = heic self.heicLowRes = heicLowRes } + public let width: Int + public let height: Int public let original: URL public let heic: URL public let heicLowRes: URL