|
|
|
|
@ -38,7 +38,6 @@ class SubscriptionModel: ObservableObject, StoreDelegate { |
|
|
|
|
@Published var error: Error? = nil |
|
|
|
|
|
|
|
|
|
@Published var isLoading: Bool = false |
|
|
|
|
@Published var isPurchasing: Bool = false |
|
|
|
|
@Published var selectedProduct: Product? = nil { |
|
|
|
|
didSet { |
|
|
|
|
self._computePrice() |
|
|
|
|
@ -52,7 +51,6 @@ class SubscriptionModel: ObservableObject, StoreDelegate { |
|
|
|
|
} |
|
|
|
|
@Published var products: [Product] = [] |
|
|
|
|
@Published var totalPrice: String = "" |
|
|
|
|
@State var showSuccessfulPurchaseView: Bool = false |
|
|
|
|
|
|
|
|
|
func load() { |
|
|
|
|
self.isLoading = true |
|
|
|
|
@ -72,30 +70,22 @@ class SubscriptionModel: ObservableObject, StoreDelegate { |
|
|
|
|
self.error = error |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func purchase() { |
|
|
|
|
func purchase() async throws -> Bool { |
|
|
|
|
Logger.log("start purchase...") |
|
|
|
|
guard let product: Product = self.selectedProduct, let storeManager = self.storeManager else { |
|
|
|
|
Logger.w("missing product or store manager") |
|
|
|
|
return |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
self.isPurchasing = true |
|
|
|
|
|
|
|
|
|
Task { |
|
|
|
|
do { |
|
|
|
|
if product.item.isConsumable { |
|
|
|
|
if let _ = try await storeManager.purchase(product, quantity: self.quantity) { |
|
|
|
|
self.isPurchasing = false |
|
|
|
|
self.showSuccessfulPurchaseView = true |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
let _ = try await storeManager.purchase(product) |
|
|
|
|
self.isPurchasing = false |
|
|
|
|
if product.item.isConsumable { |
|
|
|
|
if let _ = try await storeManager.purchase(product, quantity: self.quantity) { |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
} catch { |
|
|
|
|
Logger.error(error) |
|
|
|
|
self.isPurchasing = false |
|
|
|
|
} else { |
|
|
|
|
let _ = try await storeManager.purchase(product) |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _computePrice() { |
|
|
|
|
@ -118,10 +108,14 @@ struct SubscriptionView: View { |
|
|
|
|
|
|
|
|
|
@ObservedObject var model: SubscriptionModel = SubscriptionModel() |
|
|
|
|
|
|
|
|
|
@Binding var isPresented: Bool |
|
|
|
|
|
|
|
|
|
var showLackOfPlanMessage: Bool = false |
|
|
|
|
@State var isRestoring: Bool = false |
|
|
|
|
@State var showLoginView: Bool = false |
|
|
|
|
|
|
|
|
|
@State var isPurchasing: Bool = false |
|
|
|
|
@State var showSuccessfulPurchaseView: Bool = false |
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
|
|
|
|
|
|
Group { |
|
|
|
|
@ -147,21 +141,21 @@ struct SubscriptionView: View { |
|
|
|
|
|
|
|
|
|
Section { |
|
|
|
|
|
|
|
|
|
ForEach(self.model.products) { product in |
|
|
|
|
let isSelected = self.model.selectedProduct == product |
|
|
|
|
ProductView(product: product, |
|
|
|
|
quantity: self.$model.quantity, |
|
|
|
|
selected: isSelected) |
|
|
|
|
.foregroundStyle(.white) |
|
|
|
|
.frame(maxWidth: .infinity) |
|
|
|
|
.buttonStyle(.borderedProminent) |
|
|
|
|
.tint(Color.master) |
|
|
|
|
.listRowBackground(Color.clear) |
|
|
|
|
|
|
|
|
|
.onTapGesture { |
|
|
|
|
self.model.selectedProduct = product |
|
|
|
|
} |
|
|
|
|
ForEach(self.model.products) { product in |
|
|
|
|
let isSelected = self.model.selectedProduct == product |
|
|
|
|
ProductView(product: product, |
|
|
|
|
quantity: self.$model.quantity, |
|
|
|
|
selected: isSelected) |
|
|
|
|
.foregroundStyle(.white) |
|
|
|
|
.frame(maxWidth: .infinity) |
|
|
|
|
.buttonStyle(.borderedProminent) |
|
|
|
|
.tint(Color.master) |
|
|
|
|
.listRowBackground(Color.clear) |
|
|
|
|
|
|
|
|
|
.onTapGesture { |
|
|
|
|
self.model.selectedProduct = product |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} header: { |
|
|
|
|
Text("Sélectionnez une offre") |
|
|
|
|
} |
|
|
|
|
@ -178,7 +172,7 @@ struct SubscriptionView: View { |
|
|
|
|
} |
|
|
|
|
} label: { |
|
|
|
|
HStack { |
|
|
|
|
if self.model.isPurchasing { |
|
|
|
|
if self.isPurchasing { |
|
|
|
|
Spacer() |
|
|
|
|
ProgressView().tint(.white) |
|
|
|
|
Spacer() |
|
|
|
|
@ -230,7 +224,26 @@ struct SubscriptionView: View { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _purchase() { |
|
|
|
|
self.model.purchase() |
|
|
|
|
|
|
|
|
|
self.isPurchasing = true |
|
|
|
|
|
|
|
|
|
Task { |
|
|
|
|
do { |
|
|
|
|
let success = try await self.model.purchase() |
|
|
|
|
DispatchQueue.main.async { |
|
|
|
|
self.isPurchasing = false |
|
|
|
|
self.showSuccessfulPurchaseView = true |
|
|
|
|
if success { |
|
|
|
|
self.isPresented = false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} catch { |
|
|
|
|
Logger.error(error) |
|
|
|
|
DispatchQueue.main.async { |
|
|
|
|
self.isPurchasing = false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _load() { |
|
|
|
|
@ -337,6 +350,6 @@ struct SubscriptionFooterView: View { |
|
|
|
|
|
|
|
|
|
#Preview { |
|
|
|
|
NavigationStack { |
|
|
|
|
SubscriptionView(showLackOfPlanMessage: false) |
|
|
|
|
SubscriptionView(isPresented: .constant(true), showLackOfPlanMessage: false) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|