mirror of
https://github.com/RevenueCat/purchases-ios
synced 2026-11-11 22:55:55 +05:45
221 lines
9.0 KiB
Swift
221 lines
9.0 KiB
Swift
//
|
|
// Copyright RevenueCat Inc. All Rights Reserved.
|
|
//
|
|
// Licensed under the MIT License (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://opensource.org/licenses/MIT
|
|
//
|
|
// ManageSubscriptionsView.swift
|
|
//
|
|
//
|
|
// Created by Andrés Boedo on 5/3/24.
|
|
//
|
|
|
|
import RevenueCat
|
|
import SwiftUI
|
|
|
|
#if os(iOS)
|
|
|
|
@available(iOS 15.0, *)
|
|
@available(macOS, unavailable)
|
|
@available(tvOS, unavailable)
|
|
@available(watchOS, unavailable)
|
|
struct ManageSubscriptionsView: View {
|
|
|
|
@Environment(\.appearance)
|
|
private var appearance: CustomerCenterConfigData.Appearance
|
|
|
|
@Environment(\.colorScheme)
|
|
private var colorScheme
|
|
|
|
@Environment(\.supportInformation)
|
|
private var support
|
|
|
|
@Environment(\.localization)
|
|
private var localization: CustomerCenterConfigData.Localization
|
|
|
|
@Environment(\.navigationOptions)
|
|
var navigationOptions
|
|
|
|
@StateObject
|
|
private var viewModel: ManageSubscriptionsViewModel
|
|
|
|
private let customerCenterActionHandler: CustomerCenterActionHandler?
|
|
|
|
init(screen: CustomerCenterConfigData.Screen,
|
|
purchaseInformation: PurchaseInformation?,
|
|
customerCenterActionHandler: CustomerCenterActionHandler?) {
|
|
let viewModel = ManageSubscriptionsViewModel(
|
|
screen: screen,
|
|
customerCenterActionHandler: customerCenterActionHandler,
|
|
purchaseInformation: purchaseInformation)
|
|
self.init(viewModel: viewModel, customerCenterActionHandler: customerCenterActionHandler)
|
|
}
|
|
|
|
fileprivate init(viewModel: ManageSubscriptionsViewModel,
|
|
customerCenterActionHandler: CustomerCenterActionHandler?) {
|
|
self._viewModel = .init(wrappedValue: viewModel)
|
|
self.customerCenterActionHandler = customerCenterActionHandler
|
|
}
|
|
|
|
var body: some View {
|
|
content
|
|
.compatibleNavigation(
|
|
item: $viewModel.feedbackSurveyData,
|
|
usesNavigationStack: navigationOptions.usesNavigationStack
|
|
) { feedbackSurveyData in
|
|
FeedbackSurveyView(
|
|
feedbackSurveyData: feedbackSurveyData,
|
|
customerCenterActionHandler: self.customerCenterActionHandler,
|
|
isPresented: .isNotNil(self.$viewModel.feedbackSurveyData))
|
|
.environment(\.appearance, appearance)
|
|
.environment(\.localization, localization)
|
|
.environment(\.navigationOptions, navigationOptions)
|
|
}
|
|
.compatibleNavigation(
|
|
isPresented: $viewModel.showPurchases,
|
|
usesNavigationStack: navigationOptions.usesNavigationStack
|
|
) {
|
|
PurchaseHistoryView(viewModel: PurchaseHistoryViewModel())
|
|
.environment(\.appearance, appearance)
|
|
.environment(\.localization, localization)
|
|
.environment(\.navigationOptions, navigationOptions)
|
|
}
|
|
.sheet(item: self.$viewModel.promotionalOfferData) { promotionalOfferData in
|
|
PromotionalOfferView(
|
|
promotionalOffer: promotionalOfferData.promotionalOffer,
|
|
product: promotionalOfferData.product,
|
|
promoOfferDetails: promotionalOfferData.promoOfferDetails,
|
|
onDismissPromotionalOfferView: { userAction in
|
|
Task(priority: .userInitiated) {
|
|
await self.viewModel.handleDismissPromotionalOfferView(userAction)
|
|
}
|
|
}
|
|
)
|
|
.environment(\.appearance, appearance)
|
|
.environment(\.localization, localization)
|
|
.interactiveDismissDisabled()
|
|
}
|
|
.sheet(item: self.$viewModel.inAppBrowserURL,
|
|
onDismiss: {
|
|
self.viewModel.onDismissInAppBrowser()
|
|
}, content: { inAppBrowserURL in
|
|
SafariView(url: inAppBrowserURL.url)
|
|
})
|
|
}
|
|
|
|
@ViewBuilder
|
|
var content: some View {
|
|
List {
|
|
if let purchaseInformation = self.viewModel.purchaseInformation {
|
|
SubscriptionDetailsView(
|
|
purchaseInformation: purchaseInformation,
|
|
refundRequestStatus: self.viewModel.refundRequestStatus
|
|
)
|
|
|
|
if support?.displayPurchaseHistoryLink == true {
|
|
Button {
|
|
viewModel.showPurchases = true
|
|
} label: {
|
|
Text(localization[.seeAllPurchases])
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
|
|
.contentShape(Rectangle())
|
|
}
|
|
}
|
|
|
|
Section {
|
|
ManageSubscriptionsButtonsView(
|
|
viewModel: self.viewModel
|
|
)
|
|
} header: {
|
|
if let subtitle = self.viewModel.screen.subtitle {
|
|
Text(subtitle)
|
|
.textCase(nil)
|
|
}
|
|
}
|
|
} else {
|
|
let fallbackDescription = localization[.tryCheckRestore]
|
|
|
|
Section {
|
|
CompatibilityContentUnavailableView(
|
|
self.viewModel.screen.title,
|
|
systemImage: "exclamationmark.triangle.fill",
|
|
description: Text(self.viewModel.screen.subtitle ?? fallbackDescription)
|
|
)
|
|
}
|
|
|
|
Section {
|
|
ManageSubscriptionsButtonsView(viewModel: self.viewModel)
|
|
}
|
|
}
|
|
}
|
|
.dismissCircleButtonToolbarIfNeeded()
|
|
.restorePurchasesAlert(isPresented: self.$viewModel.showRestoreAlert)
|
|
.applyIf(self.viewModel.screen.type == .management, apply: {
|
|
$0.navigationTitle(self.viewModel.screen.title)
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
#if DEBUG
|
|
@available(iOS 15.0, *)
|
|
@available(macOS, unavailable)
|
|
@available(tvOS, unavailable)
|
|
@available(watchOS, unavailable)
|
|
struct ManageSubscriptionsView_Previews: PreviewProvider {
|
|
|
|
// swiftlint:disable force_unwrapping
|
|
static var previews: some View {
|
|
ForEach(ColorScheme.allCases, id: \.self) { colorScheme in
|
|
CompatibilityNavigationStack {
|
|
let viewModelMonthlyRenewing = ManageSubscriptionsViewModel(
|
|
screen: CustomerCenterConfigTestData.customerCenterData.screens[.management]!,
|
|
customerCenterActionHandler: nil,
|
|
purchaseInformation: CustomerCenterConfigTestData.subscriptionInformationMonthlyRenewing,
|
|
refundRequestStatus: .success)
|
|
ManageSubscriptionsView(viewModel: viewModelMonthlyRenewing,
|
|
customerCenterActionHandler: nil)
|
|
.environment(\.localization, CustomerCenterConfigTestData.customerCenterData.localization)
|
|
.environment(\.appearance, CustomerCenterConfigTestData.customerCenterData.appearance)
|
|
}
|
|
.preferredColorScheme(colorScheme)
|
|
.previewDisplayName("Monthly renewing - \(colorScheme)")
|
|
|
|
CompatibilityNavigationStack {
|
|
let viewModelYearlyExpiring = ManageSubscriptionsViewModel(
|
|
screen: CustomerCenterConfigTestData.customerCenterData.screens[.management]!,
|
|
customerCenterActionHandler: nil,
|
|
purchaseInformation: CustomerCenterConfigTestData.subscriptionInformationYearlyExpiring)
|
|
ManageSubscriptionsView(viewModel: viewModelYearlyExpiring,
|
|
customerCenterActionHandler: nil)
|
|
.environment(\.localization, CustomerCenterConfigTestData.customerCenterData.localization)
|
|
.environment(\.appearance, CustomerCenterConfigTestData.customerCenterData.appearance)
|
|
}
|
|
.preferredColorScheme(colorScheme)
|
|
.previewDisplayName("Yearly expiring - \(colorScheme)")
|
|
|
|
CompatibilityNavigationStack {
|
|
let viewModelYearlyExpiring = ManageSubscriptionsViewModel(
|
|
screen: CustomerCenterConfigTestData.customerCenterData.screens[.management]!,
|
|
customerCenterActionHandler: nil,
|
|
purchaseInformation: CustomerCenterConfigTestData.subscriptionInformationFree)
|
|
ManageSubscriptionsView(viewModel: viewModelYearlyExpiring,
|
|
customerCenterActionHandler: nil)
|
|
.environment(\.localization, CustomerCenterConfigTestData.customerCenterData.localization)
|
|
.environment(\.appearance, CustomerCenterConfigTestData.customerCenterData.appearance)
|
|
}
|
|
.preferredColorScheme(colorScheme)
|
|
.previewDisplayName("Free subscription - \(colorScheme)")
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|