Make system to manage a local User before having a logged one

multistore
Laurent 2 years ago
parent 95d0ceac0b
commit d19b679656
  1. 2
      PadelClub/Data/AppSettings.swift
  2. 50
      PadelClub/Data/DataStore.swift
  3. 14
      PadelClub/Data/User.swift
  4. 2
      PadelClub/Info.plist
  5. 6
      PadelClub/Views/Calling/CallMessageCustomizationView.swift
  6. 8
      PadelClub/Views/Club/ClubDetailView.swift
  7. 2
      PadelClub/Views/Club/ClubSearchView.swift
  8. 6
      PadelClub/Views/Club/CreateClubView.swift
  9. 6
      PadelClub/Views/Navigation/Toolbox/GlobalSettingsView.swift
  10. 6
      PadelClub/Views/Navigation/Toolbox/MatchFormatStorageView.swift
  11. 8
      PadelClub/Views/Navigation/Umpire/UmpireView.swift
  12. 3
      PadelClub/Views/Subscription/Guard.swift
  13. 4
      PadelClub/Views/Subscription/PurchaseListView.swift
  14. 1
      PadelClub/Views/Subscription/StoreManager.swift
  15. 11
      PadelClub/Views/Subscription/SubscriptionView.swift
  16. 1
      PadelClub/Views/User/UserCreationView.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

@ -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<DateInterval>
fileprivate(set) var matchSchedulers: StoredCollection<MatchScheduler>
fileprivate(set) var userStorage: StoredSingleton<User>
fileprivate var userStorage: StoredSingleton<User>
// fileprivate var _userStorage: OptionalStorage<User> = OptionalStorage<User>(fileName: "user.json")
fileprivate(set) var appSettingsStorage: MicroStorage<AppSettings> = MicroStorage()
fileprivate var _temporaryLocalUser: OptionalStorage<User> = OptionalStorage(fileName: "tmp_local_user.json")
fileprivate(set) var appSettingsStorage: MicroStorage<AppSettings> = MicroStorage(fileName: "appsettings.json")
var appSettings: AppSettings {
appSettingsStorage.item
@ -58,6 +60,8 @@ class DataStore: ObservableObject {
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") {
store.synchronizationApiURL = 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<User> = notification.object as? StoredSingleton<User> {
Logger.log("StoredObject<User> loaded with user = \(String(describing: object.item()))")
if let userSingleton: StoredSingleton<User> = notification.object as? StoredSingleton<User> {
Logger.log("StoredObject<User> 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

@ -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 {

@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIFileSharingEnabled</key>
<true/>
<key>CFBundleDocumentTypes</key>
<array>
<dict>

@ -116,11 +116,7 @@ struct CallMessageCustomizationView: View {
}
private func _save() {
do {
try dataStore.userStorage.update()
} catch {
Logger.error(error)
}
self.dataStore.saveUser()
}
@ViewBuilder

@ -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)
}
self.dataStore.saveUser()
}
.tint(isFavorite ? .green : .logoRed)
}

@ -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)

@ -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)
self.dataStore.saveUser()
}
dismiss()
}

@ -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)

@ -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()
}
}
}

@ -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)
}

@ -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 {

@ -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))
}
}

@ -23,7 +23,6 @@ extension Notification.Name {
static let StoreEventHappened = Notification.Name("storePurchaseSucceeded")
}
@available(iOS 15, *)
class StoreManager {
@Published private(set) var purchasedTransactions = Set<StoreKit.Transaction>()

@ -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 {
do {
if product.item.isConsumable {
if let _ = try await self.storeManager?.purchase(product, quantity: self.quantity) {
if let _ = try await storeManager.purchase(product, quantity: self.quantity) {
self.showSuccessfulPurchaseView = true
}
} else {
let _ = try await self.storeManager?.purchase(product)
let _ = try await storeManager.purchase(product)
}
} catch {
Logger.error(error)
}
}
}

@ -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,

Loading…
Cancel
Save