Skip to content

Commit

Permalink
Use ManageSubscriptionsView for users without active subscriptions (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
vegaro authored Dec 3, 2024
1 parent 6d4cdf9 commit 2386682
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 74 deletions.
4 changes: 4 additions & 0 deletions RevenueCat.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@
35272E2226D0048D00F22C3B /* HTTPClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E353CBE9CF2572A72A347F /* HTTPClientTests.swift */; };
352B7D7927BD919B002A47DD /* DangerousSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 352B7D7827BD919B002A47DD /* DangerousSettings.swift */; };
35316DAA2BD14BFD00E4A970 /* MockDiagnosticsSynchronizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35316DA82BD14BFD00E4A970 /* MockDiagnosticsSynchronizer.swift */; };
3531DF882CFE138D00D454BF /* ManageSubscriptionsButtonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3531DF872CFE138800D454BF /* ManageSubscriptionsButtonsView.swift */; };
353756522C382BC700A1B8D6 /* PreferredLocalesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 353756512C382BC700A1B8D6 /* PreferredLocalesProvider.swift */; };
353756652C382C2800A1B8D6 /* CustomerCenterConfigTestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 353756532C382C2800A1B8D6 /* CustomerCenterConfigTestData.swift */; };
353756662C382C2800A1B8D6 /* CustomerCenterError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 353756542C382C2800A1B8D6 /* CustomerCenterError.swift */; };
Expand Down Expand Up @@ -1511,6 +1512,7 @@
352B7D7827BD919B002A47DD /* DangerousSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DangerousSettings.swift; sourceTree = "<group>"; };
3530C18822653E8F00D6DF52 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; };
35316DA82BD14BFD00E4A970 /* MockDiagnosticsSynchronizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockDiagnosticsSynchronizer.swift; sourceTree = "<group>"; };
3531DF872CFE138800D454BF /* ManageSubscriptionsButtonsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManageSubscriptionsButtonsView.swift; sourceTree = "<group>"; };
353756512C382BC700A1B8D6 /* PreferredLocalesProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferredLocalesProvider.swift; sourceTree = "<group>"; };
353756532C382C2800A1B8D6 /* CustomerCenterConfigTestData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomerCenterConfigTestData.swift; sourceTree = "<group>"; };
353756542C382C2800A1B8D6 /* CustomerCenterError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomerCenterError.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3528,6 +3530,7 @@
353756602C382C2800A1B8D6 /* Views */ = {
isa = PBXGroup;
children = (
3531DF872CFE138800D454BF /* ManageSubscriptionsButtonsView.swift */,
2D2AFE8E2C6A9D8700D1B0B4 /* CompatibilityContentUnavailableView.swift */,
2C4C36122C6FBA8B00AE959B /* CompatibilityTopBarTrailing.swift */,
3537565B2C382C2800A1B8D6 /* CustomerCenterView.swift */,
Expand Down Expand Up @@ -6564,6 +6567,7 @@
77BA1AB32CCBB6EE009BF0EA /* RootView.swift in Sources */,
887A606C2C1D037000E1A461 /* Constants.swift in Sources */,
887A60BF2C1D037000E1A461 /* PaywallViewController.swift in Sources */,
3531DF882CFE138D00D454BF /* ManageSubscriptionsButtonsView.swift in Sources */,
2CC791552CC0452100FBE120 /* PurchaseButtonComponentViewModel.swift in Sources */,
2CC791562CC0452100FBE120 /* PackageComponentView.swift in Sources */,
2CC791592CC0452100FBE120 /* PurchaseButtonComponentView.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import SwiftUI
class ManageSubscriptionsViewModel: ObservableObject {

let screen: CustomerCenterConfigData.Screen
let paths: [CustomerCenterConfigData.HelpPath]

@Published
var showRestoreAlert: Bool = false
Expand Down Expand Up @@ -66,6 +67,7 @@ class ManageSubscriptionsViewModel: ObservableObject {
purchasesProvider: ManageSubscriptionsPurchaseType = ManageSubscriptionPurchases(),
loadPromotionalOfferUseCase: LoadPromotionalOfferUseCaseType? = nil) {
self.screen = screen
self.paths = screen.filteredPaths
self.purchasesProvider = purchasesProvider
self.customerCenterActionHandler = customerCenterActionHandler
self.loadPromotionalOfferUseCase = loadPromotionalOfferUseCase ?? LoadPromotionalOfferUseCase()
Expand All @@ -77,6 +79,7 @@ class ManageSubscriptionsViewModel: ObservableObject {
customerCenterActionHandler: CustomerCenterActionHandler?,
refundRequestStatus: RefundRequestStatus? = nil) {
self.screen = screen
self.paths = screen.filteredPaths
self.purchaseInformation = purchaseInformation
self.purchasesProvider = ManageSubscriptionPurchases()
self.refundRequestStatus = refundRequestStatus
Expand Down Expand Up @@ -261,4 +264,18 @@ private final class ManageSubscriptionPurchases: ManageSubscriptionsPurchaseType

}

private extension CustomerCenterConfigData.Screen {

var filteredPaths: [CustomerCenterConfigData.HelpPath] {
return self.paths.filter { path in
#if targetEnvironment(macCatalyst)
return path.type == .refundRequest
#else
return path.type != .unknown
#endif
}
}

}

#endif
8 changes: 7 additions & 1 deletion RevenueCatUI/CustomerCenter/Views/CustomerCenterView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,13 @@ private extension CustomerCenterView {
WrongPlatformView()
}
} else {
NoSubscriptionsView(configuration: configuration)
if let screen = configuration.screens[.noActive] {
ManageSubscriptionsView(screen: screen,
customerCenterActionHandler: viewModel.customerCenterActionHandler)
} else {
// Fallback with a restore button
NoSubscriptionsView(configuration: configuration)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// 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
//
// ManageSubscriptionsButtonsView.swift
//
// Created by Cesar de la Vega on 2/12/24.

import Foundation
import RevenueCat
import SwiftUI

#if os(iOS)

@available(iOS 15.0, *)
@available(macOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
struct ManageSubscriptionsButtonsView: View {

@ObservedObject
var viewModel: ManageSubscriptionsViewModel
@Binding
var loadingPath: CustomerCenterConfigData.HelpPath?
@Environment(\.openURL)
var openURL

@Environment(\.localization)
private var localization: CustomerCenterConfigData.Localization

var body: some View {
ForEach(self.viewModel.paths, id: \.id) { path in
ManageSubscriptionButton(path: path, viewModel: self.viewModel)
}
}

}

@available(iOS 15.0, *)
@available(macOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
struct ManageSubscriptionButton: View {

let path: CustomerCenterConfigData.HelpPath
@ObservedObject var viewModel: ManageSubscriptionsViewModel

@Environment(\.appearance) private var appearance: CustomerCenterConfigData.Appearance

var body: some View {
AsyncButton(action: {
await self.viewModel.determineFlow(for: path)
}, label: {
if self.viewModel.loadingPath?.id == path.id {
TintedProgressView()
} else {
Text(path.title)
}
})
.disabled(self.viewModel.loadingPath != nil)
}

}

#endif
94 changes: 27 additions & 67 deletions RevenueCatUI/CustomerCenter/Views/ManageSubscriptionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,32 @@ struct ManageSubscriptionsView: View {
purchaseInformation: purchaseInformation,
refundRequestStatus: self.viewModel.refundRequestStatus)
}
}
Section {
ManageSubscriptionsButtonsView(viewModel: self.viewModel,
loadingPath: self.$viewModel.loadingPath)
} header: {
if let subtitle = self.viewModel.screen.subtitle {
Text(subtitle)
.textCase(nil)
}
}
} else {
let fallbackDescription = localization.commonLocalizedString(for: .tryCheckRestore)

Section {
ManageSubscriptionsButtonsView(viewModel: self.viewModel,
loadingPath: self.$viewModel.loadingPath)
} header: {
if let subtitle = self.viewModel.screen.subtitle {
Text(subtitle)
.textCase(nil)
Section {
CompatibilityContentUnavailableView(
self.viewModel.screen.title,
systemImage: "exclamationmark.triangle.fill",
description: Text(self.viewModel.screen.subtitle ?? fallbackDescription)
)
}

Section {
ManageSubscriptionsButtonsView(viewModel: self.viewModel,
loadingPath: self.$viewModel.loadingPath)
}
}

}
} else {
TintedProgressView()
Expand Down Expand Up @@ -132,8 +147,10 @@ struct ManageSubscriptionsView: View {
}, content: { inAppBrowserURL in
SafariView(url: inAppBrowserURL.url)
})
.navigationTitle(self.viewModel.screen.title)
.navigationBarTitleDisplayMode(.inline)
.applyIf(self.viewModel.screen.type == .management, apply: {
$0.navigationTitle(self.viewModel.screen.title).navigationBarTitleDisplayMode(.inline)
})

}

}
Expand All @@ -152,63 +169,6 @@ private extension ManageSubscriptionsView {

}

@available(iOS 15.0, *)
@available(macOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
struct ManageSubscriptionsButtonsView: View {

@ObservedObject
var viewModel: ManageSubscriptionsViewModel
@Binding
var loadingPath: CustomerCenterConfigData.HelpPath?
@Environment(\.openURL)
var openURL

@Environment(\.localization)
private var localization: CustomerCenterConfigData.Localization

var body: some View {
let filteredPaths = self.viewModel.screen.paths.filter { path in
#if targetEnvironment(macCatalyst)
return path.type == .refundRequest
#else
return path.type != .unknown
#endif
}
ForEach(filteredPaths, id: \.id) { path in
ManageSubscriptionButton(path: path, viewModel: self.viewModel)
}
}

}

@available(iOS 15.0, *)
@available(macOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
struct ManageSubscriptionButton: View {

let path: CustomerCenterConfigData.HelpPath
@ObservedObject var viewModel: ManageSubscriptionsViewModel

@Environment(\.appearance) private var appearance: CustomerCenterConfigData.Appearance

var body: some View {
AsyncButton(action: {
await self.viewModel.determineFlow(for: path)
}, label: {
if self.viewModel.loadingPath?.id == path.id {
TintedProgressView()
} else {
Text(path.title)
}
})
.disabled(self.viewModel.loadingPath != nil)
}

}

#if DEBUG
@available(iOS 15.0, *)
@available(macOS, unavailable)
Expand Down
9 changes: 3 additions & 6 deletions RevenueCatUI/CustomerCenter/Views/NoSubscriptionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ struct NoSubscriptionsView: View {
}

var body: some View {
let fallbackDescription = "We can try checking your Apple account for any previous purchases"
let fallbackDescription = localization.commonLocalizedString(for: .tryCheckRestore)
let fallbackTitle = localization.commonLocalizedString(for: .noSubscriptionsFound)

List {
Section {
CompatibilityContentUnavailableView(
self.configuration.screens[.noActive]?.title ?? "No subscriptions found",
self.configuration.screens[.noActive]?.title ?? fallbackTitle,
systemImage: "exclamationmark.triangle.fill",
description:
Text(self.configuration.screens[.noActive]?.subtitle ?? fallbackDescription)
Expand All @@ -57,10 +58,6 @@ struct NoSubscriptionsView: View {
showRestoreAlert = true
}
.restorePurchasesAlert(isPresented: $showRestoreAlert)
} header: {
let subtitle = localization.commonLocalizedString(for: .tryCheckRestore)
Text(subtitle)
.textCase(nil)
}

}
Expand Down

0 comments on commit 2386682

Please sign in to comment.