fix stuff for syncing

multistore
Razmig Sarkissian 2 years ago
parent 4a002de680
commit 41823ec896
  1. 6
      PadelClub/Data/DataStore.swift
  2. 12
      PadelClub/Data/User.swift
  3. 6
      PadelClub/Extensions/String+Extensions.swift
  4. 2
      PadelClub/Utils/Network/NetworkManager.swift
  5. 35
      PadelClub/Utils/SourceFileManager.swift
  6. 8
      PadelClub/Views/Club/ClubDetailView.swift
  7. 2
      PadelClub/Views/Club/ClubsView.swift
  8. 14
      PadelClub/Views/Navigation/Agenda/ActivityView.swift
  9. 2
      PadelClub/Views/Navigation/Agenda/EventListView.swift
  10. 22
      PadelClub/Views/Navigation/Umpire/UmpireView.swift

@ -77,7 +77,7 @@ class DataStore: ObservableObject {
// store.addMigration(Migration<TournamentV2, Tournament>(version: 3)) // store.addMigration(Migration<TournamentV2, Tournament>(version: 3))
let indexed : Bool = true let indexed : Bool = true
let synchronized : Bool = false let synchronized : Bool = true
self.clubs = store.registerCollection(synchronized: synchronized, indexed: indexed) self.clubs = store.registerCollection(synchronized: synchronized, indexed: indexed)
self.courts = store.registerCollection(synchronized: synchronized, indexed: indexed) self.courts = store.registerCollection(synchronized: synchronized, indexed: indexed)
self.tournaments = store.registerCollection(synchronized: synchronized, indexed: indexed) self.tournaments = store.registerCollection(synchronized: synchronized, indexed: indexed)
@ -88,10 +88,10 @@ class DataStore: ObservableObject {
self.playerRegistrations = store.registerCollection(synchronized: synchronized, indexed: indexed) self.playerRegistrations = store.registerCollection(synchronized: synchronized, indexed: indexed)
self.rounds = store.registerCollection(synchronized: synchronized, indexed: indexed) self.rounds = store.registerCollection(synchronized: synchronized, indexed: indexed)
self.matches = store.registerCollection(synchronized: synchronized, indexed: indexed) self.matches = store.registerCollection(synchronized: synchronized, indexed: indexed)
self.monthData = store.registerCollection(synchronized: synchronized, indexed: indexed) self.monthData = store.registerCollection(synchronized: false, indexed: indexed)
self.dateIntervals = store.registerCollection(synchronized: synchronized, indexed: indexed) self.dateIntervals = store.registerCollection(synchronized: synchronized, indexed: indexed)
self.userStorage = store.registerObject(synchronized: synchronized) self.userStorage = store.registerObject(synchronized: false)
NotificationCenter.default.addObserver(self, selector: #selector(collectionWasUpdated), name: NSNotification.Name.CollectionDidLoad, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(collectionWasUpdated), name: NSNotification.Name.CollectionDidLoad, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(collectionWasUpdated), name: NSNotification.Name.CollectionDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(collectionWasUpdated), name: NSNotification.Name.CollectionDidChange, object: nil)

@ -61,6 +61,18 @@ class User: UserBase, Storable {
clubs?.isEmpty == false clubs?.isEmpty == false
} }
func hasFavoriteClubsAndCreatedClubs() -> Bool {
clubsObjects(includeCreated: true).isEmpty == false
}
func setUserClub(_ userClub: Club) {
if clubs == nil {
clubs = [userClub.id]
} else {
clubs!.insert(userClub.id, at: 0)
}
}
func clubsObjects(includeCreated: Bool = false) -> [Club] { func clubsObjects(includeCreated: Bool = false) -> [Club] {
guard let clubs else { return [] } guard let clubs else { return [] }
return Store.main.filter(isIncluded: { (includeCreated && $0.creator == id) || clubs.contains($0.id) }) return Store.main.filter(isIncluded: { (includeCreated && $0.creator == id) || clubs.contains($0.id) })

@ -52,8 +52,10 @@ extension String {
// Extract the first character of each sentence // Extract the first character of each sentence
let firstLetters = sentences.compactMap { sentence -> Character? in let firstLetters = sentences.compactMap { sentence -> Character? in
let trimmedSentence = sentence.trimmingCharacters(in: .whitespacesAndNewlines) let trimmedSentence = sentence.trimmingCharacters(in: .whitespacesAndNewlines)
if let firstCharacter = trimmedSentence.first { if trimmedSentence.count > 2 {
return firstCharacter if let firstCharacter = trimmedSentence.first {
return firstCharacter
}
} }
return nil return nil
} }

@ -22,7 +22,7 @@ class NetworkManager {
let dateString = ["CLASSEMENT-PADEL", fileName, lastDateString].joined(separator: "-") + ".csv" let dateString = ["CLASSEMENT-PADEL", fileName, lastDateString].joined(separator: "-") + ".csv"
let documentsUrl:URL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL?)! let documentsUrl: URL = SourceFileManager.shared.rankingSourceDirectory
let destinationFileUrl = documentsUrl.appendingPathComponent("\(dateString)") let destinationFileUrl = documentsUrl.appendingPathComponent("\(dateString)")
let fileURL = URL(string: "https://padelclub.app/static/\(dateString)") let fileURL = URL(string: "https://padelclub.app/static/\(dateString)")

@ -9,7 +9,32 @@ import Foundation
class SourceFileManager { class SourceFileManager {
static let shared = SourceFileManager() static let shared = SourceFileManager()
init() {
createDirectoryIfNeeded()
}
let rankingSourceDirectory : URL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appending(path: "rankings")
func createDirectoryIfNeeded() {
let fileManager = FileManager.default
do {
let directoryURL = rankingSourceDirectory
// Check if the directory exists
if !fileManager.fileExists(atPath: directoryURL.path) {
// Directory does not exist, create it
try fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: true, attributes: nil)
print("Directory created at: \(directoryURL)")
} else {
print("Directory already exists at: \(directoryURL)")
}
} catch {
print("Error: \(error)")
}
}
var lastDataSource: String? { var lastDataSource: String? {
DataStore.shared.appSettings.lastDataSource DataStore.shared.appSettings.lastDataSource
} }
@ -117,16 +142,14 @@ class SourceFileManager {
} }
func removeAllFilesFromServer() { func removeAllFilesFromServer() {
let docDir = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) let allFiles = try! FileManager.default.contentsOfDirectory(at: rankingSourceDirectory, includingPropertiesForKeys: nil)
let allFiles = try! FileManager.default.contentsOfDirectory(at: docDir, includingPropertiesForKeys: nil)
allFiles.filter { $0.pathExtension == "csv" }.forEach { url in allFiles.filter { $0.pathExtension == "csv" }.forEach { url in
try? FileManager.default.removeItem(at: url) try? FileManager.default.removeItem(at: url)
} }
} }
var allFiles: [URL] { var allFiles: [URL] {
let docDir = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) let allFiles = try! FileManager.default.contentsOfDirectory(at: rankingSourceDirectory, includingPropertiesForKeys: nil).filter({ url in
let allFiles = try! FileManager.default.contentsOfDirectory(at: docDir, includingPropertiesForKeys: nil).filter({ url in
url.pathExtension == "csv" url.pathExtension == "csv"
}) })
@ -149,8 +172,8 @@ enum SourceFile: String, CaseIterable {
case messieurs = "MESSIEURS" case messieurs = "MESSIEURS"
var filesFromServer: [URL] { var filesFromServer: [URL] {
let docDir = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) let rankingSourceDirectory = SourceFileManager.shared.rankingSourceDirectory
let allFiles = try! FileManager.default.contentsOfDirectory(at: docDir, includingPropertiesForKeys: nil) let allFiles = try! FileManager.default.contentsOfDirectory(at: rankingSourceDirectory, includingPropertiesForKeys: nil)
return allFiles.filter{$0.pathExtension == "csv" && $0.path().contains(rawValue)} return allFiles.filter{$0.pathExtension == "csv" && $0.path().contains(rawValue)}
} }

@ -142,9 +142,6 @@ struct ClubDetailView: View {
LabeledContent("Ville") { LabeledContent("Ville") {
Text(club.city ?? "") Text(club.city ?? "")
} }
LabeledContent("Code Postal") {
Text(club.zipCode ?? "")
}
Link(destination: federalLink) { Link(destination: federalLink) {
Text("Fiche du club sur tenup") Text("Fiche du club sur tenup")
} }
@ -168,7 +165,7 @@ struct ClubDetailView: View {
.keyboardType(.alphabet) .keyboardType(.alphabet)
.autocorrectionDisabled() .autocorrectionDisabled()
.defaultFocus($focusedField, ._name, priority: .automatic) .defaultFocus($focusedField, ._name, priority: .automatic)
.navigationTitle(displayContext == .addition ? "Nouveau club" : club.name) .navigationTitle(displayContext == .addition ? "Nouveau club" : "Détail du club")
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.toolbar(.visible, for: .navigationBar) .toolbar(.visible, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar)
@ -176,7 +173,7 @@ struct ClubDetailView: View {
if displayContext == .edition || displayContext == .lockedForEditing { if displayContext == .edition || displayContext == .lockedForEditing {
let isFavorite = club.isFavorite() let isFavorite = club.isFavorite()
ToolbarItem(placement: .topBarTrailing) { ToolbarItem(placement: .topBarTrailing) {
BarButtonView("Favori", icon: isFavorite ? "start" : "star.fill") { BarButtonView("Favori", icon: isFavorite ? "star.fill" : "star") {
do { do {
if isFavorite { if isFavorite {
dataStore.user?.clubs?.removeAll(where: { $0 == club.id }) dataStore.user?.clubs?.removeAll(where: { $0 == club.id })
@ -188,6 +185,7 @@ struct ClubDetailView: View {
Logger.error(error) Logger.error(error)
} }
} }
.tint(isFavorite ? .green : .logoRed)
} }
} }
} }

@ -55,7 +55,7 @@ struct ClubsView: View {
} }
} }
.overlay { .overlay {
if dataStore.user == nil || dataStore.user?.hasClubs() == true { if dataStore.user?.hasFavoriteClubsAndCreatedClubs() == false {
ContentUnavailableView { ContentUnavailableView {
Label("Aucun club", systemImage: "house.and.flag.fill") Label("Aucun club", systemImage: "house.and.flag.fill")
} description: { } description: {

@ -122,14 +122,14 @@ struct ActivityView: View {
// } // }
.task { .task {
if navigation.agendaDestination == .tenup if navigation.agendaDestination == .tenup
&& dataStore.user?.hasClubs() == false && dataStore.user?.hasClubs() == true
&& federalDataViewModel.federalTournaments.isEmpty { && federalDataViewModel.federalTournaments.isEmpty {
_gatherFederalTournaments() _gatherFederalTournaments()
} }
} }
.onChange(of: navigation.agendaDestination) { .onChange(of: navigation.agendaDestination) {
if navigation.agendaDestination == .tenup if navigation.agendaDestination == .tenup
&& dataStore.user?.hasClubs() == false && dataStore.user?.hasClubs() == true
&& federalDataViewModel.federalTournaments.isEmpty { && federalDataViewModel.federalTournaments.isEmpty {
_gatherFederalTournaments() _gatherFederalTournaments()
} }
@ -202,7 +202,11 @@ struct ActivityView: View {
.environment(navigation) .environment(navigation)
.tint(.master) .tint(.master)
} }
.sheet(isPresented: $presentClubSearchView) { .sheet(isPresented: $presentClubSearchView, onDismiss: {
if dataStore.user?.hasClubs() == true {
navigation.agendaDestination = .tenup
}
}) {
ClubImportView() ClubImportView()
.tint(.master) .tint(.master)
} }
@ -253,7 +257,7 @@ struct ActivityView: View {
RowButtonView("Créer un nouvel événement") { RowButtonView("Créer un nouvel événement") {
newTournament = Tournament.newEmptyInstance() newTournament = Tournament.newEmptyInstance()
} }
if dataStore.user == nil || dataStore.user?.hasClubs() == true { if dataStore.user?.hasClubs() == false {
RowButtonView("Chercher l'un de vos clubs") { RowButtonView("Chercher l'un de vos clubs") {
presentClubSearchView = true presentClubSearchView = true
} }
@ -274,7 +278,7 @@ struct ActivityView: View {
} }
private func _tenupEmptyView() -> some View { private func _tenupEmptyView() -> some View {
if dataStore.user == nil || dataStore.user?.hasClubs() == true { if dataStore.user?.hasClubs() == false {
ContentUnavailableView { ContentUnavailableView {
Label("Aucun tournoi", systemImage: "shield.slash") Label("Aucun tournoi", systemImage: "shield.slash")
} description: { } description: {

@ -51,7 +51,7 @@ struct EventListView: View {
.headerProminence(.increased) .headerProminence(.increased)
.task { .task {
if navigation.agendaDestination == .tenup if navigation.agendaDestination == .tenup
&& dataStore.user?.hasClubs() == false && dataStore.user?.hasClubs() == true
&& _tournaments.isEmpty { && _tournaments.isEmpty {
_gatherFederalTournaments(startDate: section) _gatherFederalTournaments(startDate: section)
} }

@ -57,24 +57,22 @@ struct UmpireView: View {
} }
} else { } else {
NavigationLink { NavigationLink {
SelectablePlayerListView(allowSelection: 1, playerSelectionAction: { players in SelectablePlayerListView(allowSelection: 1, searchField: user.firstName + " " + user.lastName, playerSelectionAction: { players in
if let player = players.first { if let player = players.first {
user.licenceId = player.license user.licenceId = player.license
let userClub = Club.findOrCreate(name: player.clubName!, code: player.clubCode) if user.clubsObjects().contains(where: { $0.code == player.clubCode }) == false {
do { let userClub = Club.findOrCreate(name: player.clubName!, code: player.clubCode)
try dataStore.clubs.addOrUpdate(instance: userClub) do {
try dataStore.clubs.addOrUpdate(instance: userClub)
if user.clubs == nil { user.setUserClub(userClub)
user.clubs = [userClub.id] try dataStore.userStorage.update()
} else { } catch {
user.clubs!.insert(userClub.id, at: 0) Logger.error(error)
} }
try dataStore.userStorage.update()
} catch {
Logger.error(error)
} }
} }
}) })
.id(UUID())
} label: { } label: {
Label("Ma fiche joueur", systemImage: "person.bust.circle.fill") Label("Ma fiche joueur", systemImage: "person.bust.circle.fill")
} }

Loading…
Cancel
Save