diff --git a/PadelClub/Data/AppSettings.swift b/PadelClub/Data/AppSettings.swift index 9991be5..60828c1 100644 --- a/PadelClub/Data/AppSettings.swift +++ b/PadelClub/Data/AppSettings.swift @@ -12,8 +12,6 @@ import SwiftUI @Observable class AppSettings: MicroStorable { - static var fileName: String { "appsettings.json" } - var lastDataSource: String? = nil var callMessageBody : String? = nil diff --git a/PadelClub/Data/DataStore.swift b/PadelClub/Data/DataStore.swift index fba2e0d..0e69fbb 100644 --- a/PadelClub/Data/DataStore.swift +++ b/PadelClub/Data/DataStore.swift @@ -16,16 +16,18 @@ class DataStore: ObservableObject { @Published var user: User = User.placeHolder() { didSet { - Store.main.collectionsCanSynchronize = (user.username.count > 0) - do { + let loggedUser = (user.username.count > 0) + Store.main.collectionsCanSynchronize = loggedUser + + if loggedUser { if self.user.id != self.userStorage.item()?.id { - try self.userStorage.setItemNoSync(self.user) + self.userStorage.setItemNoSync(self.user) if Store.main.collectionsCanSynchronize { Store.main.loadCollectionFromServer() } } - } catch { - Logger.error(error) + } else { + self._temporaryLocalUser.item = self.user } } } @@ -44,10 +46,10 @@ class DataStore: ObservableObject { fileprivate(set) var dateIntervals: StoredCollection fileprivate(set) var matchSchedulers: StoredCollection - fileprivate(set) var userStorage: StoredSingleton + fileprivate var userStorage: StoredSingleton -// fileprivate var _userStorage: OptionalStorage = OptionalStorage(fileName: "user.json") - fileprivate(set) var appSettingsStorage: MicroStorage = MicroStorage() + fileprivate var _temporaryLocalUser: OptionalStorage = OptionalStorage(fileName: "tmp_local_user.json") + fileprivate(set) var appSettingsStorage: MicroStorage = MicroStorage(fileName: "appsettings.json") var appSettings: AppSettings { appSettingsStorage.item @@ -57,6 +59,8 @@ class DataStore: ObservableObject { let store = Store.main store.synchronizationApiURL = "https://xlr.alwaysdata.net/api/" var synchronized : Bool = true + + self.user = User.placeHolder() // force the didSet #if DEBUG if let server = PListReader.readString(plist: "local", key: "server") { @@ -91,14 +95,32 @@ class DataStore: ObservableObject { } + func saveUser() { + + do { + if user.username.count > 0 { + try self.userStorage.update() + } else { + self._temporaryLocalUser.item = self.user + } + } catch { + Logger.error(error) + } + + + } + @objc func collectionDidLoad(notification: Notification) { self.objectWillChange.send() - if let object: StoredSingleton = notification.object as? StoredSingleton { - Logger.log("StoredObject loaded with user = \(String(describing: object.item()))") + if let userSingleton: StoredSingleton = notification.object as? StoredSingleton { + Logger.log("StoredObject loaded with user = \(String(describing: userSingleton.item()))") - if let user = object.item() { - self.user = user - } + self.user = userSingleton.item() ?? User.placeHolder() +// if let user = object.item() { +// self.user = user +// } else { +// self. +// } } } @@ -112,6 +134,8 @@ class DataStore: ObservableObject { // todo qu'est ce qu'on fait des API Call ? } + self.user = self._temporaryLocalUser.item ?? User.placeHolder() + Store.main.disconnect() Store.main.collectionsCanSynchronize = false diff --git a/PadelClub/Data/User.swift b/PadelClub/Data/User.swift index c83f2cd..cf79f18 100644 --- a/PadelClub/Data/User.swift +++ b/PadelClub/Data/User.swift @@ -130,9 +130,21 @@ class User: ModelObject, UserBase, Storable { class UserCreationForm: User, UserPasswordBase { - init(username: String, password: String, firstName: String, lastName: String, email: String, phone: String?, country: String?) { + init(user: User, username: String, password: String, firstName: String, lastName: String, email: String, phone: String?, country: String?) { self.password = password super.init(username: username, email: email, firstName: firstName, lastName: lastName, phone: phone, country: country) + + self.summonsMessageBody = user.summonsMessageBody + self.summonsMessageSignature = user.summonsMessageSignature + self.summonsAvailablePaymentMethods = user.summonsAvailablePaymentMethods + self.summonsDisplayFormat = user.summonsDisplayFormat + self.summonsDisplayEntryFee = user.summonsDisplayEntryFee + self.summonsUseFullCustomMessage = user.summonsUseFullCustomMessage + self.matchFormatsDefaultDuration = user.matchFormatsDefaultDuration + self.bracketMatchFormatPreference = user.bracketMatchFormatPreference + self.groupStageMatchFormatPreference = user.groupStageMatchFormatPreference + self.loserBracketMatchFormatPreference = user.loserBracketMatchFormatPreference + } required init(from decoder: Decoder) throws { diff --git a/PadelClub/Info.plist b/PadelClub/Info.plist index f3a644a..17dc2c2 100644 --- a/PadelClub/Info.plist +++ b/PadelClub/Info.plist @@ -2,6 +2,8 @@ + UIFileSharingEnabled + CFBundleDocumentTypes diff --git a/PadelClub/Views/Calling/CallMessageCustomizationView.swift b/PadelClub/Views/Calling/CallMessageCustomizationView.swift index acaeb17..0c30e7f 100644 --- a/PadelClub/Views/Calling/CallMessageCustomizationView.swift +++ b/PadelClub/Views/Calling/CallMessageCustomizationView.swift @@ -116,11 +116,7 @@ struct CallMessageCustomizationView: View { } private func _save() { - do { - try dataStore.userStorage.update() - } catch { - Logger.error(error) - } + self.dataStore.saveUser() } @ViewBuilder diff --git a/PadelClub/Views/Club/ClubDetailView.swift b/PadelClub/Views/Club/ClubDetailView.swift index c9ce608..a98034b 100644 --- a/PadelClub/Views/Club/ClubDetailView.swift +++ b/PadelClub/Views/Club/ClubDetailView.swift @@ -154,7 +154,7 @@ struct ClubDetailView: View { do { try dataStore.clubs.deleteById(club.id) dataStore.user.clubs.removeAll(where: { $0 == club.id }) - try dataStore.userStorage.update() + self.dataStore.saveUser() } catch { Logger.error(error) } @@ -174,16 +174,12 @@ struct ClubDetailView: View { let isFavorite = club.isFavorite() ToolbarItem(placement: .topBarTrailing) { BarButtonView("Favori", icon: isFavorite ? "star.fill" : "star") { - do { - if isFavorite { - dataStore.user.clubs.removeAll(where: { $0 == club.id }) - } else { - dataStore.user.clubs.append(club.id) - } - try dataStore.userStorage.update() - } catch { - Logger.error(error) + if isFavorite { + dataStore.user.clubs.removeAll(where: { $0 == club.id }) + } else { + dataStore.user.clubs.append(club.id) } + self.dataStore.saveUser() } .tint(isFavorite ? .green : .logoRed) } diff --git a/PadelClub/Views/Club/ClubSearchView.swift b/PadelClub/Views/Club/ClubSearchView.swift index 81786ad..bb7aef9 100644 --- a/PadelClub/Views/Club/ClubSearchView.swift +++ b/PadelClub/Views/Club/ClubSearchView.swift @@ -100,7 +100,7 @@ struct ClubSearchView: View { try dataStore.clubs.addOrUpdate(instance: clubToEdit) if dataStore.user.clubs.contains(where: { $0 == clubToEdit.id }) == false { dataStore.user.clubs.append(clubToEdit.id) - try dataStore.userStorage.update() + self.dataStore.saveUser() } } catch { Logger.error(error) diff --git a/PadelClub/Views/Club/CreateClubView.swift b/PadelClub/Views/Club/CreateClubView.swift index 09c3f33..91e2794 100644 --- a/PadelClub/Views/Club/CreateClubView.swift +++ b/PadelClub/Views/Club/CreateClubView.swift @@ -43,13 +43,9 @@ struct CreateClubView: View { } //save into user - do { - if dataStore.user.clubs.contains(where: { $0 == existingOrCreatedClub.id }) == false { - dataStore.user.clubs.append(existingOrCreatedClub.id) - try dataStore.userStorage.update() - } - } catch { - Logger.error(error) + if dataStore.user.clubs.contains(where: { $0 == existingOrCreatedClub.id }) == false { + dataStore.user.clubs.append(existingOrCreatedClub.id) + self.dataStore.saveUser() } dismiss() } diff --git a/PadelClub/Views/Navigation/Toolbox/GlobalSettingsView.swift b/PadelClub/Views/Navigation/Toolbox/GlobalSettingsView.swift index 7731072..d39811d 100644 --- a/PadelClub/Views/Navigation/Toolbox/GlobalSettingsView.swift +++ b/PadelClub/Views/Navigation/Toolbox/GlobalSettingsView.swift @@ -59,11 +59,7 @@ struct GlobalSettingsView: View { user.groupStageMatchFormatPreference, user.loserBracketMatchFormatPreference ]) { - do { - try dataStore.userStorage.update() - } catch { - Logger.error(error) - } + self.dataStore.saveUser() } .navigationTitle("Formats par défaut") .navigationBarTitleDisplayMode(.inline) diff --git a/PadelClub/Views/Navigation/Toolbox/MatchFormatStorageView.swift b/PadelClub/Views/Navigation/Toolbox/MatchFormatStorageView.swift index a8f5b60..0e03920 100644 --- a/PadelClub/Views/Navigation/Toolbox/MatchFormatStorageView.swift +++ b/PadelClub/Views/Navigation/Toolbox/MatchFormatStorageView.swift @@ -44,11 +44,7 @@ struct MatchFormatStorageView: View { } .onChange(of: estimatedDuration) { dataStore.user.saveMatchFormatsDefaultDuration(matchFormat, estimatedDuration: estimatedDuration) - do { - try dataStore.userStorage.update() - } catch { - Logger.error(error) - } + self.dataStore.saveUser() } } } diff --git a/PadelClub/Views/Navigation/Umpire/UmpireView.swift b/PadelClub/Views/Navigation/Umpire/UmpireView.swift index 0e729d3..ec62254 100644 --- a/PadelClub/Views/Navigation/Umpire/UmpireView.swift +++ b/PadelClub/Views/Navigation/Umpire/UmpireView.swift @@ -73,11 +73,7 @@ struct UmpireView: View { } else { Button("supprimer", role: .destructive) { dataStore.user.licenceId = nil - do { - try dataStore.userStorage.update() - } catch { - Logger.error(error) - } + self.dataStore.saveUser() } } } @@ -168,7 +164,7 @@ struct UmpireView: View { do { try dataStore.clubs.addOrUpdate(instance: userClub) user.setUserClub(userClub) - try dataStore.userStorage.update() + self.dataStore.saveUser() } catch { Logger.error(error) } diff --git a/PadelClub/Views/Subscription/Guard.swift b/PadelClub/Views/Subscription/Guard.swift index 82c64b7..c340a3b 100644 --- a/PadelClub/Views/Subscription/Guard.swift +++ b/PadelClub/Views/Subscription/Guard.swift @@ -216,11 +216,10 @@ import LeStorage } struct PurchaseRow: Identifiable { + var id: UInt64 var name: String var item: StoreItem var quantity: Int? - - var id: String { self.item.rawValue } } fileprivate extension StoreKit.Transaction { diff --git a/PadelClub/Views/Subscription/PurchaseListView.swift b/PadelClub/Views/Subscription/PurchaseListView.swift index 82ffe94..0b95f14 100644 --- a/PadelClub/Views/Subscription/PurchaseListView.swift +++ b/PadelClub/Views/Subscription/PurchaseListView.swift @@ -61,7 +61,7 @@ class PurchaseManager: ObservableObject { let product = self._products.first(where: { $0.id == item.rawValue } ) { switch item { case .fivePerMonth, .monthlyUnlimited: - rows.append(PurchaseRow(name: product.displayName, item: item)) + rows.append(PurchaseRow(id: userPurchase.originalID, name: product.displayName, item: item)) case .unit: break } @@ -73,7 +73,7 @@ class PurchaseManager: ObservableObject { if remainingTournaments > 0 { let unitItem: StoreItem = StoreItem.unit if let product = self._products.first(where: { $0.id == unitItem.rawValue } ) { - rows.append(PurchaseRow(name: product.displayName, item: unitItem, quantity: remainingTournaments)) + rows.append(PurchaseRow(id: 0, name: product.displayName, item: unitItem, quantity: remainingTournaments)) } } diff --git a/PadelClub/Views/Subscription/StoreManager.swift b/PadelClub/Views/Subscription/StoreManager.swift index 1875a0a..1ae252c 100644 --- a/PadelClub/Views/Subscription/StoreManager.swift +++ b/PadelClub/Views/Subscription/StoreManager.swift @@ -23,7 +23,6 @@ extension Notification.Name { static let StoreEventHappened = Notification.Name("storePurchaseSucceeded") } -@available(iOS 15, *) class StoreManager { @Published private(set) var purchasedTransactions = Set() diff --git a/PadelClub/Views/Subscription/SubscriptionView.swift b/PadelClub/Views/Subscription/SubscriptionView.swift index d9b29f8..657bb49 100644 --- a/PadelClub/Views/Subscription/SubscriptionView.swift +++ b/PadelClub/Views/Subscription/SubscriptionView.swift @@ -74,16 +74,21 @@ class SubscriptionModel: ObservableObject, StoreDelegate { func purchase() { Logger.log("start purchase...") - guard let product: Product = self.selectedProduct else { + guard let product: Product = self.selectedProduct, let storeManager = self.storeManager else { + Logger.w("missing product or store manager") return } Task { - if product.item.isConsumable { - if let _ = try await self.storeManager?.purchase(product, quantity: self.quantity) { - self.showSuccessfulPurchaseView = true + do { + if product.item.isConsumable { + if let _ = try await storeManager.purchase(product, quantity: self.quantity) { + self.showSuccessfulPurchaseView = true + } + } else { + let _ = try await storeManager.purchase(product) } - } else { - let _ = try await self.storeManager?.purchase(product) + } catch { + Logger.error(error) } } } diff --git a/PadelClub/Views/User/UserCreationView.swift b/PadelClub/Views/User/UserCreationView.swift index e5b9008..22eec00 100644 --- a/PadelClub/Views/User/UserCreationView.swift +++ b/PadelClub/Views/User/UserCreationView.swift @@ -113,6 +113,7 @@ struct UserCreationFormView: View { Task { do { let userCreationForm = UserCreationForm( + user: DataStore.shared.user, // local user username: self.username, password: self.password1, firstName: self.firstName,