parent
13e09d2163
commit
fd9583f2bb
@ -0,0 +1,19 @@ |
|||||||
|
// |
||||||
|
// URLs.swift |
||||||
|
// PadelClub |
||||||
|
// |
||||||
|
// Created by Laurent Morvillier on 22/04/2024. |
||||||
|
// |
||||||
|
|
||||||
|
import Foundation |
||||||
|
|
||||||
|
enum URLs: String, Identifiable { |
||||||
|
case subscriptions = "https://apple.co/2Th4vqI" |
||||||
|
|
||||||
|
var id: String { return self.rawValue } |
||||||
|
|
||||||
|
var url: URL { |
||||||
|
return URL(string: self.rawValue)! |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,115 @@ |
|||||||
|
// |
||||||
|
// PurchaseListView.swift |
||||||
|
// PadelClub |
||||||
|
// |
||||||
|
// Created by Laurent Morvillier on 22/04/2024. |
||||||
|
// |
||||||
|
|
||||||
|
import SwiftUI |
||||||
|
import StoreKit |
||||||
|
import LeStorage |
||||||
|
|
||||||
|
class PurchaseManager: ObservableObject { |
||||||
|
|
||||||
|
static let main: PurchaseManager = PurchaseManager() |
||||||
|
|
||||||
|
fileprivate var _products: [Product] = [] |
||||||
|
fileprivate var _purchases: [Purchase] = [] |
||||||
|
|
||||||
|
@Published var purchaseRows: [PurchaseRow] = [] |
||||||
|
|
||||||
|
init() { |
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(_purchasesChanged(notification:)), name: NSNotification.Name.CollectionDidChange, object: Guard.main.purchases) |
||||||
|
|
||||||
|
let identifiers: [String] = StoreItem.allCases.map { $0.rawValue } |
||||||
|
Task { |
||||||
|
do { |
||||||
|
self._products = try await Product.products(for: identifiers) |
||||||
|
self._buildRows() |
||||||
|
} catch { |
||||||
|
Logger.error(error) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@objc fileprivate func _purchasesChanged(notification: Notification) { |
||||||
|
guard let collection = notification.object as? StoredCollection<Purchase> else { |
||||||
|
return |
||||||
|
} |
||||||
|
self._purchases.removeAll() |
||||||
|
self._purchases.append(contentsOf: collection) |
||||||
|
self._buildRows() |
||||||
|
} |
||||||
|
|
||||||
|
fileprivate func _buildRows() { |
||||||
|
|
||||||
|
DispatchQueue.main.async { |
||||||
|
|
||||||
|
var rows: [PurchaseRow] = [] |
||||||
|
let userPurchases: [StoreKit.Transaction] = Guard.main.userFilteredPurchases() |
||||||
|
for userPurchase in userPurchases { |
||||||
|
|
||||||
|
if let item = StoreItem(rawValue: userPurchase.productID), |
||||||
|
let product = self._products.first(where: { $0.id == item.rawValue } ) { |
||||||
|
switch item { |
||||||
|
case .unit: |
||||||
|
let remainingTournaments = Guard.main.remainingTournaments |
||||||
|
if remainingTournaments > 0 { |
||||||
|
rows.append(PurchaseRow(name: product.displayName, item: item, quantity: remainingTournaments)) |
||||||
|
} |
||||||
|
default: |
||||||
|
rows.append(PurchaseRow(name: product.displayName, item: item)) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
self.purchaseRows = rows |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
struct PurchaseListView: View { |
||||||
|
|
||||||
|
@ObservedObject var manager = PurchaseManager() |
||||||
|
|
||||||
|
var body: some View { |
||||||
|
|
||||||
|
if self.manager.purchaseRows.count > 0 { |
||||||
|
|
||||||
|
Section { |
||||||
|
ForEach(self.manager.purchaseRows) { purchaseRow in |
||||||
|
|
||||||
|
Link(destination: URLs.subscriptions.url) { |
||||||
|
PurchaseView(purchaseRow: purchaseRow) |
||||||
|
} |
||||||
|
} |
||||||
|
} header: { |
||||||
|
Text("Vos achats") |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
struct PurchaseView: View { |
||||||
|
|
||||||
|
var purchaseRow: PurchaseRow |
||||||
|
|
||||||
|
var body: some View { |
||||||
|
HStack { |
||||||
|
Image(systemName: self.purchaseRow.item.systemImage) |
||||||
|
.foregroundColor(.accentColor) |
||||||
|
Text(self.purchaseRow.name) |
||||||
|
Spacer() |
||||||
|
if let quantity = purchaseRow.quantity { |
||||||
|
let remaining = Guard.main.remainingTournaments |
||||||
|
Text("\(remaining) / \(quantity.formatted())") |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#Preview { |
||||||
|
PurchaseListView() |
||||||
|
} |
||||||
Loading…
Reference in new issue