Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Customer Center] Improving customer center buttons #4165

Merged
merged 9 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//
// https://opensource.org/licenses/MIT
//
// ManageSubscriptionsButtonStyle.swift
// ButtonStyles.swift
//
//
// Created by Cesar de la Vega on 28/5/24.
Expand All @@ -25,7 +25,7 @@ import SwiftUI
@available(macOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
struct ManageSubscriptionsButtonStyle: PrimitiveButtonStyle {
struct ProminentButtonStyle: PrimitiveButtonStyle {

@Environment(\.appearance) private var appearance: CustomerCenterConfigData.Appearance
@Environment(\.colorScheme) private var colorScheme
Expand All @@ -37,8 +37,10 @@ struct ManageSubscriptionsButtonStyle: PrimitiveButtonStyle {
Button(action: { configuration.trigger() }, label: {
configuration.label.frame(maxWidth: .infinity)
})
.font(.body.weight(.medium))
.buttonStyle(.borderedProminent)
.controlSize(.large)
.buttonBorderShape(.roundedRectangle(radius: 16))
.applyIf(background != nil, apply: { $0.tint(background) })
.applyIf(textColor != nil, apply: { $0.foregroundColor(textColor) })
}
Expand All @@ -49,12 +51,47 @@ struct ManageSubscriptionsButtonStyle: PrimitiveButtonStyle {
@available(macOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
struct ManageSubscriptionsButtonStyle_Previews: PreviewProvider {
struct DismissCircleButton: View {
@Environment(\.localization) private var localization
codykerns marked this conversation as resolved.
Show resolved Hide resolved

var action: () -> Void

var body: some View {
Button {
action()
} label: {
Circle()
.fill(Color(uiColor: .secondarySystemFill))
.frame(width: 28, height: 28)
.overlay(
Image(systemName: "xmark")
.font(.system(size: 14, weight: .bold))
.foregroundStyle(.secondary)
.imageScale(.medium)
)
}
.buttonStyle(.plain)
.accessibilityLabel(Text(localization.commonLocalizedString(for: .dismiss)))
}
}

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
codykerns marked this conversation as resolved.
Show resolved Hide resolved
@available(macOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
struct ButtonStyles_Previews: PreviewProvider {

static var previews: some View {
Button("Didn't receive purchase") {}
.buttonStyle(ManageSubscriptionsButtonStyle())
VStack(spacing: 16.0) {
Button("Didn't receive purchase") {}
.buttonStyle(ProminentButtonStyle())

DismissCircleButton {

}
}.padding()
.environment(\.appearance, CustomerCenterConfigTestData.standardAppearance)
.environment(\.localization, CustomerCenterConfigTestData.customerCenterData.localization)
}

}
Expand Down
2 changes: 1 addition & 1 deletion RevenueCatUI/CustomerCenter/Views/FeedbackSurveyView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ struct FeedbackSurveyButtonsView: View {
Text(option.title)
}
})
.buttonStyle(ManageSubscriptionsButtonStyle())
.buttonStyle(ProminentButtonStyle())
.disabled(self.loadingState != nil)
}
}
Expand Down
18 changes: 11 additions & 7 deletions RevenueCatUI/CustomerCenter/Views/ManageSubscriptionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import SwiftUI
@available(watchOS, unavailable)
struct ManageSubscriptionsView: View {

@Environment(\.dismiss)
var dismiss

@Environment(\.appearance)
private var appearance: CustomerCenterConfigData.Appearance
@Environment(\.localization)
Expand Down Expand Up @@ -104,6 +107,13 @@ struct ManageSubscriptionsView: View {
.frame(maxWidth: 400)
}
}
.toolbar {
codykerns marked this conversation as resolved.
Show resolved Hide resolved
ToolbarItem(placement: .topBarTrailing) {
DismissCircleButton {
dismiss()
}
}
}
.task {
await loadInformationIfNeeded()
}
Expand Down Expand Up @@ -319,7 +329,7 @@ struct ManageSubscriptionButton: View {
Text(path.title)
}
})
.buttonStyle(ManageSubscriptionsButtonStyle())
.buttonStyle(ProminentButtonStyle())
.disabled(self.viewModel.loadingPath != nil)
.restorePurchasesAlert(isPresented: self.$viewModel.showRestoreAlert)
.sheet(item: self.$viewModel.promotionalOfferData,
Expand All @@ -337,13 +347,11 @@ struct ManageSubscriptionButton: View {
}

#if DEBUG

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
@available(macOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
struct ManageSubscriptionsView_Previews: PreviewProvider {

static var previews: some View {
let viewModelMonthlyRenewing = ManageSubscriptionsViewModel(
screen: CustomerCenterConfigTestData.customerCenterData.screens[.management]!,
Expand All @@ -354,12 +362,10 @@ struct ManageSubscriptionsView_Previews: PreviewProvider {
.previewDisplayName("Monthly renewing")
.environment(\.localization, CustomerCenterConfigTestData.customerCenterData.localization)
.environment(\.appearance, CustomerCenterConfigTestData.customerCenterData.appearance)

let viewModelYearlyExpiring = ManageSubscriptionsViewModel(
screen: CustomerCenterConfigTestData.customerCenterData.screens[.management]!,
subscriptionInformation: CustomerCenterConfigTestData.subscriptionInformationYearlyExpiring,
customerCenterActionHandler: nil)

ManageSubscriptionsView(viewModel: viewModelYearlyExpiring)
.previewDisplayName("Yearly expiring")
.environment(\.localization, CustomerCenterConfigTestData.customerCenterData.localization)
Expand All @@ -373,7 +379,6 @@ struct ManageSubscriptionsView_Previews: PreviewProvider {
@available(tvOS, unavailable)
@available(watchOS, unavailable)
struct SubscriptionDetailsView_Previews: PreviewProvider {

static var previews: some View {
SubscriptionDetailsView(
subscriptionInformation: CustomerCenterConfigTestData.subscriptionInformationMonthlyRenewing,
Expand All @@ -382,7 +387,6 @@ struct SubscriptionDetailsView_Previews: PreviewProvider {
)
.previewDisplayName("Subscription Details - Monthly")
.padding()

codykerns marked this conversation as resolved.
Show resolved Hide resolved
}
}
#endif
Expand Down
29 changes: 22 additions & 7 deletions RevenueCatUI/CustomerCenter/Views/NoSubscriptionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ struct NoSubscriptionsView: View {
self.configuration = configuration
}

var body: some View {
@ViewBuilder
var content: some View {
let background = Color.from(colorInformation: appearance.backgroundColor, for: colorScheme)
let textColor = Color.from(colorInformation: appearance.textColor, for: colorScheme)

Expand All @@ -70,17 +71,31 @@ struct NoSubscriptionsView: View {
showRestoreAlert = true
}
.restorePurchasesAlert(isPresented: $showRestoreAlert)
.buttonStyle(ManageSubscriptionsButtonStyle())

Button(localization.commonLocalizedString(for: .cancel)) {
dismiss()
}
.padding(.vertical)
.buttonStyle(ProminentButtonStyle())
}
.padding(.horizontal)
.applyIf(textColor != nil, apply: { $0.foregroundColor(textColor) })
}
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
DismissCircleButton {
dismiss()
}
}
}

}

var body: some View {
if #available(iOS 16.0, *) {
NavigationStack {
content
}
} else {
NavigationView {
content
}
}
}
Comment on lines +89 to 99
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This view will always be presented modally in some manner? If so this is fine, but if someone were to add this to an existing navigation stack, weird things could happen.

Additionally, I see we've used this pattern twice, if we use it a third time, should consider creating a component we can reuse for this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The modal question is one we'll need to answer, good call 👍

Agreed on the reusable component - will pull this out into a new component in a separate PR.


}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ struct PromoOfferButtonView: View {
.font(.subheadline)
}
})
.buttonStyle(ManageSubscriptionsButtonStyle())
.buttonStyle(ProminentButtonStyle())
.padding(.horizontal)
}
}
Expand Down
28 changes: 26 additions & 2 deletions RevenueCatUI/CustomerCenter/Views/WrongPlatformView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ struct WrongPlatformView: View {
@State
private var store: Store?

@Environment(\.dismiss)
var dismiss

@Environment(\.localization)
private var localization: CustomerCenterConfigData.Localization
@Environment(\.appearance)
private var appearance: CustomerCenterConfigData.Appearance
@Environment(\.colorScheme)
Expand All @@ -42,7 +47,7 @@ struct WrongPlatformView: View {
self._store = State(initialValue: store)
}

var body: some View {
@ViewBuilder var content: some View {
ZStack {
if let background = Color.from(colorInformation: appearance.backgroundColor, for: colorScheme) {
background.edgesIgnoringSafeArea(.all)
Expand All @@ -57,10 +62,17 @@ struct WrongPlatformView: View {
description: platformInstructions.1,
systemImage: "exclamationmark.triangle.fill"
)

}
.padding(.horizontal)
.applyIf(textColor != nil, apply: { $0.foregroundColor(textColor) })
}
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
DismissCircleButton {
dismiss()
}
}
}
.task {
if store == nil {
if let customerInfo = try? await Purchases.shared.customerInfo(),
Expand All @@ -71,6 +83,18 @@ struct WrongPlatformView: View {
}
}

var body: some View {
if #available(iOS 16.0, *) {
NavigationStack {
content
}
} else {
NavigationView {
content
}
}
}

private func humanReadablePlatformName(store: Store) -> String {
switch store {
case .appStore, .macAppStore:
Expand Down