Skip to content

Commit

Permalink
Add colors support
Browse files Browse the repository at this point in the history
  • Loading branch information
vegaro committed Jul 8, 2024
1 parent 3a391d1 commit 03a3906
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,12 @@ enum CustomerCenterConfigTestData {
)
],
appearance: .init(
mode: .custom,
light: .init(
accentColor: "#ffffff",
backgroundColor: "#000000",
textColor: "#000000"
),
dark: .init(
accentColor: "#000000",
backgroundColor: "#ffffff",
textColor: "#ffffff"
)
mode: .custom(accentColor: try! RCColor(light: RCColor(stringRepresentation: "#ffffff"),
dark: try! RCColor(stringRepresentation: "#000000")),
backgroundColor: try! RCColor(light: RCColor(stringRepresentation: "#000000"),
dark: try! RCColor(stringRepresentation: "#ffffff")),
textColor: try! RCColor(light: RCColor(stringRepresentation: "#000000"),
dark: try! RCColor(stringRepresentation: "#ffffff")))
),
localization: .init(
locale: "en_US",
Expand Down
31 changes: 27 additions & 4 deletions RevenueCatUI/CustomerCenter/ManageSubscriptionsButtonStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
//

import Foundation
import RevenueCat
import SwiftUI

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
Expand All @@ -22,12 +23,17 @@ import SwiftUI
@available(watchOS, unavailable)
struct ManageSubscriptionsButtonStyle: ButtonStyle {

func makeBody(configuration: Configuration) -> some View {
var appearance: CustomerCenterConfigData.Appearance

@Environment(\.colorScheme)
private var colorScheme

func makeBody(configuration: ButtonStyleConfiguration) -> some View {
configuration.label
.padding()
.frame(width: 300)
.background(Color.accentColor)
.foregroundColor(.white)
.background(color(from: appearance))
.foregroundColor(colorScheme == .dark ? Color.black : Color.white)
.cornerRadius(10)
.scaleEffect(configuration.isPressed ? 0.95 : 1.0)
.opacity(configuration.isPressed ? 0.8 : 1.0)
Expand All @@ -36,6 +42,23 @@ struct ManageSubscriptionsButtonStyle: ButtonStyle {

}

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
@available(macOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
private extension ManageSubscriptionsButtonStyle {

func color(from appearance: CustomerCenterConfigData.Appearance) -> Color {
switch appearance.mode {
case .system:
Color.accentColor
case .custom(accentColor: let accentColor, backgroundColor: let backgroundColor, textColor: let textColor):
accentColor.underlyingColor
}
}

}

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
@available(macOS, unavailable)
@available(tvOS, unavailable)
Expand All @@ -44,7 +67,7 @@ struct CustomButtonStylePreview_Previews: PreviewProvider {

static var previews: some View {
Button("Didn't receive purchase") {}
.buttonStyle(ManageSubscriptionsButtonStyle())
.buttonStyle(ManageSubscriptionsButtonStyle(appearance: CustomerCenterConfigData.Appearance(mode: .system)))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import RevenueCat
class ManageSubscriptionsViewModel: ObservableObject {

let screen: CustomerCenterConfigData.Screen
let appearance: CustomerCenterConfigData.Appearance

@Published
var showRestoreAlert: Bool = false
Expand Down Expand Up @@ -66,25 +67,31 @@ class ManageSubscriptionsViewModel: ObservableObject {

private var error: Error?

convenience init(screen: CustomerCenterConfigData.Screen) {
convenience init(screen: CustomerCenterConfigData.Screen,
appearance: CustomerCenterConfigData.Appearance) {
self.init(screen: screen,
appearance: appearance,
purchasesProvider: ManageSubscriptionPurchases(),
promotionalOfferViewModel: PromotionalOfferViewModel())
}

// @PublicForExternalTesting
init(screen: CustomerCenterConfigData.Screen,
appearance: CustomerCenterConfigData.Appearance,
purchasesProvider: ManageSubscriptionsPurchaseType,
promotionalOfferViewModel: PromotionalOfferViewModel) {
self.state = .notLoaded
self.screen = screen
self.appearance = appearance
self.purchasesProvider = purchasesProvider
self.promotionalOfferViewModel = promotionalOfferViewModel
}

init(screen: CustomerCenterConfigData.Screen,
appearance: CustomerCenterConfigData.Appearance,
subscriptionInformation: SubscriptionInformation) {
self.screen = screen
self.appearance = appearance
self.subscriptionInformation = subscriptionInformation
self.purchasesProvider = ManageSubscriptionPurchases()
self.promotionalOfferViewModel = PromotionalOfferViewModel()
Expand Down Expand Up @@ -125,22 +132,9 @@ class ManageSubscriptionsViewModel: ObservableObject {
)
}

#if os(iOS) || targetEnvironment(macCatalyst)
func determineFlow(for path: CustomerCenterConfigData.HelpPath) async {
if case let .feedbackSurvey(feedbackSurvey) = path.detail {
self.feedbackSurveyData = FeedbackSurveyData(configuration: feedbackSurvey) { [weak self] in
Task {
await self?.performAction(for: path)
}
}
} else {
await self.performAction(for: path)
}
}

func handleSheetDismiss() {
func handleSheetDismiss() async {
if let loadingPath = loadingPath {
performAction(for: loadingPath)
await self.performAction(for: loadingPath)
self.loadingPath = nil
}
}
Expand All @@ -150,14 +144,16 @@ class ManageSubscriptionsViewModel: ObservableObject {
switch path.detail {
case let .feedbackSurvey(feedbackSurvey):
self.feedbackSurveyData = FeedbackSurveyData(configuration: feedbackSurvey) { [weak self] in
await self?.performAction(for: path)
Task {
await self?.performAction(for: path)
}
}
case let .promotionalOffer(promotionalOffer):
self.loadingPath = path
await promotionalOfferViewModel.loadPromo(promotionalOfferId: promotionalOffer.iosOfferId)
self.isShowingPromotionalOffer = true
default:
performAction(for: path)
await self.performAction(for: path)
}
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion RevenueCatUI/CustomerCenter/Views/CustomerCenterView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private extension CustomerCenterView {
if viewModel.hasSubscriptions {
if viewModel.subscriptionsAreFromApple,
let screen = configuration[.management] {
ManageSubscriptionsView(screen: screen)
ManageSubscriptionsView(screen: screen, appearance: configuration.appearance)
} else {
WrongPlatformView()
}
Expand Down
14 changes: 10 additions & 4 deletions RevenueCatUI/CustomerCenter/Views/FeedbackSurveyView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ struct FeedbackSurveyView: View {

@StateObject
private var viewModel: FeedbackSurveyViewModel
private let appearance: CustomerCenterConfigData.Appearance

init(feedbackSurveyData: FeedbackSurveyData) {
init(feedbackSurveyData: FeedbackSurveyData,
appearance: CustomerCenterConfigData.Appearance) {
self._viewModel = StateObject(wrappedValue: FeedbackSurveyViewModel(feedbackSurveyData: feedbackSurveyData))
self.appearance = appearance
}

var body: some View {
Expand All @@ -42,6 +45,7 @@ struct FeedbackSurveyView: View {

FeedbackSurveyButtonsView(options: self.viewModel.feedbackSurveyData.configuration.options,
action: self.viewModel.handleAction(for:),
appearance: self.appearance,
loadingStates: self.$viewModel.loadingStates)
}
.sheet(
Expand All @@ -51,8 +55,8 @@ struct FeedbackSurveyView: View {
if let promotionalOffer = self.viewModel.promotionalOffer,
let product = self.viewModel.product {
PromotionalOfferView(promotionalOffer: promotionalOffer,
product: product
)
product: product,
appearance: self.appearance)
}
})
}
Expand All @@ -68,6 +72,8 @@ struct FeedbackSurveyButtonsView: View {

let options: [CustomerCenterConfigData.HelpPath.FeedbackSurvey.Option]
let action: (CustomerCenterConfigData.HelpPath.FeedbackSurvey.Option) async -> Void
let appearance: CustomerCenterConfigData.Appearance

@Binding
var loadingStates: [String: Bool]

Expand All @@ -85,7 +91,7 @@ struct FeedbackSurveyButtonsView: View {
Text(option.title)
}
}
.buttonStyle(ManageSubscriptionsButtonStyle())
.buttonStyle(ManageSubscriptionsButtonStyle(appearance: appearance))
.disabled(self.loadingStates[option.id] ?? false)
}
}
Expand Down
18 changes: 12 additions & 6 deletions RevenueCatUI/CustomerCenter/Views/ManageSubscriptionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ struct ManageSubscriptionsView: View {
@StateObject
private var viewModel: ManageSubscriptionsViewModel

init(screen: CustomerCenterConfigData.Screen) {
let viewModel = ManageSubscriptionsViewModel(screen: screen)
init(screen: CustomerCenterConfigData.Screen,
appearance: CustomerCenterConfigData.Appearance) {
let viewModel = ManageSubscriptionsViewModel(screen: screen, appearance: appearance)
self._viewModel = .init(wrappedValue: viewModel)
}

Expand Down Expand Up @@ -63,7 +64,8 @@ struct ManageSubscriptionsView: View {

if let feedbackSurveyData = self.viewModel.feedbackSurveyData {
NavigationLink(
destination: FeedbackSurveyView(feedbackSurveyData: feedbackSurveyData)
destination: FeedbackSurveyView(feedbackSurveyData: feedbackSurveyData,
appearance: self.viewModel.appearance)
.onDisappear {
self.viewModel.feedbackSurveyData = nil
},
Expand Down Expand Up @@ -204,15 +206,18 @@ struct ManageSubscriptionButton: View {
}
.restorePurchasesAlert(isPresented: self.$viewModel.showRestoreAlert)
.sheet(isPresented: self.$viewModel.isShowingPromotionalOffer, onDismiss: {
self.viewModel.handleSheetDismiss()
Task {
await self.viewModel.handleSheetDismiss()
}
}, content: {
if let promotionalOffer = self.viewModel.promotionalOffer,
let product = self.viewModel.product {
PromotionalOfferView(promotionalOffer: promotionalOffer,
product: product)
product: product,
appearance: self.viewModel.appearance)
}
})
.buttonStyle(ManageSubscriptionsButtonStyle())
.buttonStyle(ManageSubscriptionsButtonStyle(appearance: self.viewModel.appearance))
.disabled(self.viewModel.loadingPath?.id == path.id)
}
}
Expand All @@ -229,6 +234,7 @@ struct ManageSubscriptionsView_Previews: PreviewProvider {
static var previews: some View {
let viewModel = ManageSubscriptionsViewModel(
screen: CustomerCenterConfigTestData.customerCenterData[.management]!,
appearance: CustomerCenterConfigTestData.customerCenterData.appearance,
subscriptionInformation: CustomerCenterConfigTestData.subscriptionInformation)
ManageSubscriptionsView(viewModel: viewModel)
}
Expand Down
15 changes: 7 additions & 8 deletions RevenueCatUI/CustomerCenter/Views/NoSubscriptionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,20 @@ import SwiftUI
@available(watchOS, unavailable)
@available(visionOS, unavailable)
struct NoSubscriptionsView: View {

init(configuration: CustomerCenterConfigData) {
self.configuration = configuration
}

// swiftlint:disable:next todo
// TODO: build screen using this configuration
let configuration: CustomerCenterConfigData
private let configuration: CustomerCenterConfigData

@Environment(\.dismiss)
var dismiss

private var dismiss
@State
private var showRestoreAlert: Bool = false

init(configuration: CustomerCenterConfigData) {
self.configuration = configuration
}

var body: some View {
VStack {
Text("No Subscriptions found")
Expand All @@ -54,7 +53,7 @@ struct NoSubscriptionsView: View {
showRestoreAlert = true
}
.restorePurchasesAlert(isPresented: $showRestoreAlert)
.buttonStyle(ManageSubscriptionsButtonStyle())
.buttonStyle(ManageSubscriptionsButtonStyle(appearance: self.configuration.appearance))

Button("Cancel") {
dismiss()
Expand Down
13 changes: 10 additions & 3 deletions RevenueCatUI/CustomerCenter/Views/PromotionalOfferView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,30 @@ import SwiftUI
@available(visionOS, unavailable)
struct PromotionalOfferView: View {

private let appearance: CustomerCenterConfigData.Appearance

@StateObject
private var viewModel: PromotionalOfferViewModel
@Environment(\.dismiss)
private var dismiss
private var promotionalOfferId: String

init(promotionalOfferId: String) {
init(promotionalOfferId: String,
appearance: CustomerCenterConfigData.Appearance) {
let viewModel = PromotionalOfferViewModel()
self._viewModel = StateObject(wrappedValue: viewModel)
self.promotionalOfferId = promotionalOfferId
self.appearance = appearance
}

init(promotionalOffer: PromotionalOffer, product: StoreProduct) {
init(promotionalOffer: PromotionalOffer,
product: StoreProduct,
appearance: CustomerCenterConfigData.Appearance) {
let viewModel = PromotionalOfferViewModel(product: product, promotionalOffer: promotionalOffer)
self._viewModel = StateObject(wrappedValue: viewModel)
// force unwrap since it is only `nil` for SK1 products before iOS 12.2.
self.promotionalOfferId = promotionalOffer.discount.offerIdentifier!
self.appearance = appearance
}

var body: some View {
Expand Down Expand Up @@ -74,7 +81,7 @@ struct PromotionalOfferView: View {
.font(.subheadline)
}
})
.buttonStyle(ManageSubscriptionsButtonStyle())
.buttonStyle(ManageSubscriptionsButtonStyle(appearance: self.appearance))

Button("No thanks") {
dismiss()
Expand Down
Loading

0 comments on commit 03a3906

Please sign in to comment.