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 6, 2024
1 parent 0445c24 commit b675ce3
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 65 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>
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 {
return switch appearance.mode {
case .system:
Color.accentColor
case .custom(color: let color):
color.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 @@ -60,8 +60,7 @@ class FeedbackSurveyViewModel: ObservableObject {
// @PublicForExternalTesting
init(feedbackSurveyData: FeedbackSurveyData,
promotionalOfferViewModel: PromotionalOfferViewModel,
customerInfoFetcher: @escaping CustomerInfoFetcher
) {
customerInfoFetcher: @escaping CustomerInfoFetcher) {
self.feedbackSurveyData = feedbackSurveyData
self.promotionalOfferViewModel = promotionalOfferViewModel
self.customerInfoFetcher = customerInfoFetcher
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
60 changes: 34 additions & 26 deletions RevenueCatUI/CustomerCenter/Views/ManageSubscriptionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,29 +43,31 @@ struct ManageSubscriptionsView: View {
var body: some View {
NavigationView {
VStack {
if viewModel.isLoaded {
HeaderView(viewModel: viewModel)
if self.viewModel.isLoaded {
HeaderView(viewModel: self.viewModel)

if let subscriptionInformation = self.viewModel.subscriptionInformation {
SubscriptionDetailsView(subscriptionInformation: subscriptionInformation,
refundRequestStatusMessage: viewModel.refundRequestStatusMessage)
refundRequestStatusMessage: self.viewModel.refundRequestStatusMessage)
}

Spacer()

ManageSubscriptionsButtonsView(viewModel: viewModel,
ManageSubscriptionsButtonsView(viewModel: self.viewModel,
loadingPath: self.$viewModel.loadingPath)

} else {
ProgressView()
.progressViewStyle(CircularProgressViewStyle())
}

if let feedbackSurveyData = viewModel.feedbackSurveyData {
if let feedbackSurveyData = self.viewModel.feedbackSurveyData,
let configuration = self.viewModel.configuration {
NavigationLink(
destination: FeedbackSurveyView(feedbackSurveyData: feedbackSurveyData)
destination: FeedbackSurveyView(feedbackSurveyData: feedbackSurveyData,
appearance: configuration.appearance)
.onDisappear {
viewModel.feedbackSurveyData = nil
self.viewModel.feedbackSurveyData = nil
},
isActive: .constant(true)
) {
Expand Down Expand Up @@ -193,27 +195,33 @@ struct ManageSubscriptionButton: View {
@ObservedObject var viewModel: ManageSubscriptionsViewModel

var body: some View {
AsyncButton(action: {
await viewModel.determineFlow(for: path)
}) {
if viewModel.loadingPath?.id == path.id {
ProgressView()
} else {
Text(path.title)
if let configuration = viewModel.configuration {
AsyncButton(action: {
await viewModel.determineFlow(for: path)
}) {
if self.viewModel.loadingPath?.id == path.id {
ProgressView()
} else {
Text(path.title)
}
}
.restorePurchasesAlert(isPresented: self.$viewModel.showRestoreAlert)
.sheet(isPresented: self.$viewModel.isShowingPromotionalOffer, onDismiss: {
self.viewModel.handleSheetDismiss()
}, content: {
if let promotionalOffer = self.viewModel.promotionalOffer,
let product = self.viewModel.product {
PromotionalOfferView(promotionalOffer: promotionalOffer,
product: product,
appearance: configuration.appearance)
}
})
.buttonStyle(ManageSubscriptionsButtonStyle(appearance: configuration.appearance))
.disabled(self.viewModel.loadingPath?.id == path.id)
} else {
EmptyView()
}
.restorePurchasesAlert(isPresented: $viewModel.showRestoreAlert)
.sheet(isPresented: $viewModel.isShowingPromotionalOffer, onDismiss: {
viewModel.handleSheetDismiss()
}, content: {
if let promotionalOffer = viewModel.promotionalOffer,
let product = viewModel.product {
PromotionalOfferView(promotionalOffer: promotionalOffer,
product: product)
}
})
.buttonStyle(ManageSubscriptionsButtonStyle())
.disabled(viewModel.loadingPath?.id == path.id)

}
}

Expand Down
15 changes: 8 additions & 7 deletions RevenueCatUI/CustomerCenter/Views/NoSubscriptionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,17 @@ struct NoSubscriptionsView: View {
// TODO: build screen using this configuration
let configuration: CustomerCenterConfigData

@Environment(\.dismiss)
var dismiss

@State
private var showRestoreAlert: Bool = false

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

var appearance: CustomerCenterConfigData.Appearance

@Environment(\.dismiss)
private var dismiss
@State
private var showRestoreAlert: Bool = false

var body: some View {
VStack {
Text("No Subscriptions found")
Expand All @@ -54,7 +55,7 @@ struct NoSubscriptionsView: View {
showRestoreAlert = true
}
.restorePurchasesAlert(isPresented: $showRestoreAlert)
.buttonStyle(ManageSubscriptionsButtonStyle())
.buttonStyle(ManageSubscriptionsButtonStyle(appearance: 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
24 changes: 8 additions & 16 deletions Sources/CustomerCenter/CustomerCenterConfigData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@

import Foundation

// swiftlint:disable missing_docs
public typealias RCColor = PaywallColor

// swiftlint:disable missing_docs
// swiftlint:disable nesting
public struct CustomerCenterConfigData {
Expand Down Expand Up @@ -153,22 +156,11 @@ public struct CustomerCenterConfigData {
}

}

public enum AppearanceMode: String {

case custom = "CUSTOM"
case system = "SYSTEM"

init(from rawValue: String) {
switch rawValue {
case "CUSTOM":
self = .custom
case "SYSTEM":
self = .system
default:
self = .system
}
}

public enum AppearanceMode {

case system
case custom(color: RCColor)

}

Expand Down
13 changes: 10 additions & 3 deletions Sources/Networking/Responses/CustomerCenterConfigResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,23 @@ struct CustomerCenterConfigResponse {

struct Appearance {

let mode: String
let mode: AppearanceMode
let light: AppearanceCustomColors
let dark: AppearanceCustomColors

struct AppearanceCustomColors {
enum AppearanceMode: String {

case system = "SYSTEM"
case custom = "CUSTOM"

}

struct AppearanceCustomColors {

let accentColor: String
let backgroundColor: String
let textColor: String

}

}
Expand Down

0 comments on commit b675ce3

Please sign in to comment.