Merge branch 'main'

sync_v2
Raz 8 months ago
commit acb0be6ec3
  1. 16
      PadelClub.xcodeproj/project.pbxproj
  2. 2
      PadelClub/Data/DataStore.swift
  3. 2
      PadelClub/Data/README.md
  4. 30
      PadelClub/Data/Tournament.swift
  5. 53
      PadelClub/PadelClubApp.swift
  6. 40
      PadelClub/Utils/Patcher.swift
  7. 16
      PadelClub/Views/Navigation/Umpire/UmpireView.swift
  8. 14
      PadelClub/Views/Player/PlayerDetailView.swift

@ -3632,7 +3632,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
@ -3658,7 +3658,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.2;
MARKETING_VERSION = 1.2.1;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -3678,7 +3678,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6;
@ -3703,7 +3703,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.2;
MARKETING_VERSION = 1.2.1;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -3795,7 +3795,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
@ -3821,7 +3821,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1.1;
MARKETING_VERSION = 1.2.1;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -3841,7 +3841,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6;
@ -3866,7 +3866,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1.1;
MARKETING_VERSION = 1.2.1;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

@ -134,7 +134,7 @@ class DataStore: ObservableObject {
}
if Store.main.fileCollectionsAllLoaded() {
Patcher.applyAllWhenApplicable()
AutomaticPatcher.applyAllWhenApplicable()
}
}

@ -3,6 +3,7 @@ Dans Swift:
- Dans Data > Gen > créer un nouveau fichier json pour la classe
- Le paramètre "foreignKey" permet de générer une méthode qui récupère l'objet parent. Ajouter une étoile permet d'indiquer que l'on cherche l'objet dans le Store de l'objet et non le Store.main.
- Pour générer les fichiers, on se place dans le répertoire de generator.py et on lance la commande : python generator.py -i . -o .
- il faut avoir inflect: pip install inflect
Dans Django:
- Les modèles de base doivent étendre BaseModel
@ -29,5 +30,6 @@ Dans Django:
- L'ajouter aussi dans admin.py si nécéssaire
- Faire le *makemigrations* + *migrate*
Note: Les nouvelles classes de model doivent étendre BaseModel ou SideStoreModel
Enfin, revenir dans Xcode, ouvrir ServerDataTests et lancer le test mis à jour

@ -19,7 +19,7 @@ final class Tournament: BaseTournament {
func shouldRefreshTeams() -> Bool {
guard let lastTeamRefresh else { return true }
return lastTeamRefresh.timeIntervalSinceNow < -60
return lastTeamRefresh.timeIntervalSinceNow < -600
}
@ObservationIgnored
@ -494,9 +494,20 @@ defer {
}) {
return seedGroupAvailable(atRoundIndex: roundIndex, availableSeedGroup: chunk)
} else if fullLeftSeeds.count > 1, targetSpots > 1, fullLeftSeeds.count >= targetSpots {
let seeds = seeds()
if let firstIndex = seeds.firstIndex(where: { $0.isSeedable() }) {
return seedGroupAvailable(atRoundIndex: roundIndex, availableSeedGroup: SeedInterval(first: firstIndex + 1, last: firstIndex + targetSpots))
let currentSeeds = seeds()
if let firstIndex = currentSeeds.firstIndex(where: { $0.isSeedable() }) {
if firstIndex < seededTeamsCount {
return nil
} else {
let sg = SeedInterval(first: seededTeamsCount + 1, last: seededTeamsCount + targetSpots)
let futureAvailableSeeds = self.seeds(inSeedGroup: sg)
if futureAvailableSeeds.count == targetSpots {
return seedGroupAvailable(atRoundIndex: roundIndex, availableSeedGroup: sg)
} else {
return nil
}
}
}
}
}
@ -2325,6 +2336,10 @@ defer {
// MARK: - Status
func shouldTournamentBeOver() async -> Bool {
return false
if tournamentStore?.store.fileCollectionsAllLoaded() == false {
return false
}
#if _DEBUGING_TIME //DEBUGING TIME
let start = Date()
defer {
@ -2366,26 +2381,21 @@ defer {
func refreshTeamList() async {
guard StoreCenter.main.isAuthenticated else { return }
guard tournamentStore?.store.fileCollectionsAllLoaded() == true else { return }
guard shouldRefreshTeams(), refreshInProgress == false, enableOnlineRegistration, hasEnded() == false else { return }
await MainActor.run {
refreshInProgress = true
}
do {
try await self.tournamentStore?.playerRegistrations.loadDataFromServerIfAllowed(clear: true)
try await self.tournamentStore?.teamScores.loadDataFromServerIfAllowed(clear: true)
try await self.tournamentStore?.teamRegistrations.loadDataFromServerIfAllowed(clear: true)
await MainActor.run {
refreshInProgress = false
lastTeamRefresh = Date()
}
} catch {
Logger.error(error)
await MainActor.run {
refreshInProgress = false
lastTeamRefresh = Date()
}
}
}
// MARK: -

@ -17,9 +17,10 @@ struct PadelClubApp: App {
@StateObject var dataStore = DataStore.shared
@State private var registrationError: RegistrationError? = nil
@State private var importObserverViewModel = ImportObserver()
@State private var showDisconnectionAlert: Bool = false
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@State var blockApp = false
@State var requiredVersion: String? = nil
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@ -65,8 +66,8 @@ struct PadelClubApp: App {
var body: some Scene {
WindowGroup {
if self.blockApp {
DownloadNewVersionView()
if let requiredVersion {
DownloadNewVersionView(version: requiredVersion)
} else {
MainView()
.environment(\.horizontalSizeClass, .compact)
@ -91,6 +92,10 @@ struct PadelClubApp: App {
.accentColor(.master)
.onAppear {
self._checkVersion()
if ManualPatcher.patchIfPossible(.disconnect) == true {
self.showDisconnectionAlert = true
}
#if DEBUG
print("Running in Debug mode")
#elseif TESTFLIGHT
@ -104,6 +109,9 @@ struct PadelClubApp: App {
self._onAppear()
print(PersistenceController.getModelVersion())
}
.alert(isPresented: self.$showDisconnectionAlert, content: {
Alert(title: Text("Vous avez été déconnecté. Veuillez vous reconnecter pour récupérer vos données."))
})
.task {
// try? Tips.resetDatastore()
@ -125,7 +133,9 @@ struct PadelClubApp: App {
Logger.log(">>> REQUIRED VERSION = \(requiredVersion)")
if let currentVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
await MainActor.run {
self.blockApp = VersionComparator.compare(cleanedRequired, currentVersion) == 1
if VersionComparator.compare(cleanedRequired, currentVersion) == 1 {
self.requiredVersion = cleanedRequired
}
}
}
}
@ -211,22 +221,40 @@ struct PadelClubApp: App {
struct DownloadNewVersionView: View {
var version: String
var body: some View {
VStack {
// AngledStripesBackground()
Spacer()
VStack(spacing: 20.0) {
Text("Veuillez télécharger la nouvelle version de Padel Club pour continuer à vous servir de l'app !")
.padding(32.0)
.background(.logoYellow)
.fontWeight(.semibold)
.foregroundStyle(.white)
.padding()
.background(.logoRed)
.clipShape(.buttonBorder)
// .padding(32.0)
VStack(alignment: .center, spacing: 0.0
) {
Text("Version \(self.version)")
.fontWeight(.bold)
Image(systemName: "square.and.arrow.down").font(.title)
}.padding().background(.logoYellow)
.clipShape(.buttonBorder)
}.frame(maxWidth: .infinity)
.foregroundStyle(.logoBackground)
.fontWeight(.medium)
.multilineTextAlignment(.center)
.padding(.horizontal, 64.0)
.padding(.horizontal, 36.0)
Image("logo").padding(.vertical, 50.0)
Spacer()
}.background(.logoBackground)
}
.background(.logoBackground)
.onTapGesture {
UIApplication.shared.open(URLs.appStore.url)
}
@ -235,3 +263,12 @@ struct DownloadNewVersionView: View {
}
struct DisconnectionAlertView: View {
var body: some View {
Text("Vous avez été déconnecté. Veuillez vous reconnecter pour récupérer vos données.").multilineTextAlignment(.center).padding()
}
}
#Preview {
DownloadNewVersionView(version: "1.2")
}

@ -8,6 +8,44 @@
import Foundation
import LeStorage
enum ManualPatch: String {
case disconnect
var id: String {
return "padelclub.app.manual.patch.\(self.rawValue)"
}
}
class ManualPatcher {
static func patchIfPossible(_ patch: ManualPatch) -> Bool {
if UserDefaults.standard.value(forKey: patch.id) == nil {
do {
Logger.log(">>> Patches \(patch.rawValue)...")
let result = try self._applyPatch(patch)
UserDefaults.standard.setValue(true, forKey: patch.id)
return result
} catch {
Logger.error(error)
}
}
return false
}
fileprivate static func _applyPatch(_ patch: ManualPatch) throws -> Bool {
switch patch {
case .disconnect:
let rawToken = try? StoreCenter.main.rawTokenShouldNotBeUsed()
if StoreCenter.main.userName != nil || StoreCenter.main.userId != nil || rawToken != nil {
DataStore.shared.disconnect()
return true
} else {
return false
}
}
}
}
enum PatchError: Error {
case patchError(message: String)
}
@ -21,7 +59,7 @@ enum Patch: String, CaseIterable {
}
}
class Patcher {
class AutomaticPatcher {
static func applyAllWhenApplicable() {
for patch in Patch.allCases {

@ -121,14 +121,14 @@ struct UmpireView: View {
Text("Il s'agit des clubs qui sont utilisés pour récupérer les tournois tenup.")
}
Section {
NavigationLink {
UmpireStatisticView()
} label: {
Text("Statistiques de participations")
}
}
// Section {
// NavigationLink {
// UmpireStatisticView()
// } label: {
// Text("Statistiques de participations")
// }
// }
//
Section {
@Bindable var user = dataStore.user

@ -220,13 +220,13 @@ struct PlayerDetailView: View {
}
}
Section {
NavigationLink {
PlayerStatisticView(player: player)
} label: {
Text("Statistiques de participations")
}
}
// Section {
// NavigationLink {
// PlayerStatisticView(player: player)
// } label: {
// Text("Statistiques de participations")
// }
// }
}
.onChange(of: [player.hasArrived, player.captain, player.coach]) {
_save()

Loading…
Cancel
Save