Raz 8 months ago
parent fdfe9b92ee
commit 289056bcd0
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 24
      PadelClub/Data/GroupStage.swift
  3. 12
      PadelClub/Views/Calling/CallView.swift
  4. 81
      PadelClub/Views/GroupStage/GroupStagesView.swift
  5. 2
      PadelClub/Views/Tournament/Screen/TableStructureView.swift

@ -3318,7 +3318,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\"";
@ -3364,7 +3364,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;

@ -438,7 +438,7 @@ final class GroupStage: ModelObject, Storable {
unsortedTeams().flatMap({ $0.unsortedPlayers() })
}
fileprivate typealias TeamScoreAreInIncreasingOrder = (TeamGroupStageScore, TeamGroupStageScore) -> Bool
typealias TeamScoreAreInIncreasingOrder = (TeamGroupStageScore, TeamGroupStageScore) -> Bool
typealias TeamGroupStageScore = (team: TeamRegistration, wins: Int, loses: Int, setDifference: Int, gameDifference: Int)
@ -492,20 +492,24 @@ final class GroupStage: ModelObject, Storable {
var scoreCache: [Int: TeamGroupStageScore] = [:]
func computedScore(forTeam team: TeamRegistration, step: Int = 0) -> TeamGroupStageScore? {
if let cachedScore = scoreCache[team.groupStagePositionAtStep(step)!] {
return cachedScore
} else {
let score = _score(forGroupStagePosition: team.groupStagePositionAtStep(step)!)
if let score = score {
scoreCache[team.groupStagePositionAtStep(step)!] = score
}
return score
}
}
func teams(_ sortedByScore: Bool = false, scores: [TeamGroupStageScore]? = nil) -> [TeamRegistration] {
if sortedByScore {
return unsortedTeams().compactMap({ team in
// Check cache or use provided scores, otherwise calculate and store in cache
scores?.first(where: { $0.team.id == team.id }) ?? {
if let cachedScore = scoreCache[team.groupStagePositionAtStep(step)!] {
return cachedScore
} else {
let score = _score(forGroupStagePosition: team.groupStagePositionAtStep(step)!)
if let score = score {
scoreCache[team.groupStagePositionAtStep(step)!] = score
}
return score
}
return computedScore(forTeam: team, step: step)
}()
}).sorted { (lhs, rhs) in
let predicates: [TeamScoreAreInIncreasingOrder] = [

@ -199,14 +199,16 @@ struct CallView: View {
let uncalledTeams = teams.filter { $0.getPhoneNumbers().isEmpty }
if networkMonitor.connected == false {
if uncalledTeams.isEmpty == false {
if uncalledTeams.isEmpty == false, calledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
} else {
self.sentError = .messageNotSent
}
} else {
if uncalledTeams.isEmpty == false {
if uncalledTeams.isEmpty == false, calledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
} else if uncalledTeams.isEmpty == false, calledTeams.isEmpty {
self._called(uncalledTeams, true)
}
self._called(calledTeams, true)
}
@ -228,14 +230,16 @@ struct CallView: View {
if networkMonitor.connected == false {
self.contactType = nil
if uncalledTeams.isEmpty == false {
if uncalledTeams.isEmpty == false, calledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
} else {
self.sentError = .mailNotSent
}
} else {
if uncalledTeams.isEmpty == false {
if uncalledTeams.isEmpty == false, calledTeams.isEmpty == false {
self.sentError = .uncalledTeams(uncalledTeams)
} else if uncalledTeams.isEmpty == false, calledTeams.isEmpty {
self._called(uncalledTeams, true)
}
self._called(calledTeams, true)
}

@ -105,6 +105,80 @@ struct GroupStagesView: View {
allDestinations.append(contentsOf: groupStageDestinations)
return allDestinations
}
func sortedTeams(missingQualifiedFromGroupStages: [TeamRegistration]) -> [GroupStage.TeamGroupStageScore] {
let sortedTeams = missingQualifiedFromGroupStages.compactMap({ team in
team.groupStageObject()?.computedScore(forTeam: team)
}).sorted { (lhs, rhs) in
let predicates: [GroupStage.TeamScoreAreInIncreasingOrder] = [
{ $0.wins < $1.wins },
{ $0.setDifference < $1.setDifference },
{ $0.gameDifference < $1.gameDifference},
]
for predicate in predicates {
if !predicate(lhs, rhs) && !predicate(rhs, lhs) {
continue
}
return predicate(lhs, rhs)
}
return false
}
return sortedTeams
}
func _sortedAdditionnalTeams(missingQualifiedFromGroupStages: [TeamRegistration]) -> some View {
Section {
let teamGroupStageScores = self.sortedTeams(missingQualifiedFromGroupStages: missingQualifiedFromGroupStages).reversed()
ForEach(teamGroupStageScores, id: \.team.id) { teamGroupStageScore in
let team = teamGroupStageScore.team
let groupStage = team.groupStageObject()!
let groupStagePosition = team.groupStagePosition!
NavigationLink {
GroupStageTeamView(groupStage: groupStage, team: team)
.environment(self.tournament)
} label: {
HStack {
VStack(alignment: .leading) {
if let teamName = team.name, teamName.isEmpty == false {
Text(teamName).foregroundStyle(.secondary).font(.footnote)
}
ForEach(team.players()) { player in
Text(player.playerLabel()).lineLimit(1)
}
}
Spacer()
if let score = groupStage.scoreLabel(forGroupStagePosition: groupStagePosition, score: teamGroupStageScore) {
VStack(alignment: .trailing) {
HStack(spacing: 0.0) {
Text(score.wins)
Text("/")
Text(score.losses)
}.font(.headline).monospacedDigit()
if let setsDifference = score.setsDifference {
HStack(spacing: 4.0) {
Text(setsDifference)
}.font(.footnote)
}
if let gamesDifference = score.gamesDifference {
HStack(spacing: 4.0) {
Text(gamesDifference)
}.font(.footnote)
}
}
}
}
}
}
} header: {
let name = "\((tournament.qualifiedPerGroupStage + 1).ordinalFormatted())"
Text("Meilleurs \(name) de poule")
}
}
var body: some View {
VStack(spacing: 0) {
@ -116,9 +190,8 @@ struct GroupStagesView: View {
List {
if tournament.groupStageAdditionalQualified > 0 {
let missingQualifiedFromGroupStages = tournament.missingQualifiedFromGroupStages()
let name = "\((tournament.qualifiedPerGroupStage + 1).ordinalFormatted())"
Section {
let name = "\((tournament.qualifiedPerGroupStage + 1).ordinalFormatted())"
NavigationLink {
SpinDrawView(drawees: ["Qualification d'un \(name) de poule"], segments: missingQualifiedFromGroupStages) { results in
results.forEach { drawResult in
@ -134,6 +207,8 @@ struct GroupStagesView: View {
Text("Qualifier un \(name) de poule par tirage au sort")
}
.disabled(tournament.moreQualifiedToDraw() == 0 || missingQualifiedFromGroupStages.isEmpty)
} header: {
Text("Tirage au sort d'un \(name) de poule")
} footer: {
if tournament.moreQualifiedToDraw() == 0 {
Text("Aucune équipe supplémentaire à qualifier. Vous pouvez en rajouter en modifier le paramètre dans structure.")
@ -141,6 +216,8 @@ struct GroupStagesView: View {
Text("Aucune équipe supplémentaire à tirer au sort. Attendez la fin des poules.")
}
}
_sortedAdditionnalTeams(missingQualifiedFromGroupStages: missingQualifiedFromGroupStages)
}
let runningMatches = Tournament.runningMatches(allMatches)

@ -45,7 +45,7 @@ struct TableStructureView: View {
var moreQualifiedLabel: String {
if groupStageAdditionalQualified == 0 { return "Aucun" }
return (groupStageAdditionalQualified > 1 ? "les \(groupStageAdditionalQualified)" : "le") + " meilleur\(groupStageAdditionalQualified.pluralSuffix) " + (qualifiedPerGroupStage + 1).ordinalFormatted()
return (groupStageAdditionalQualified > 1 ? "les \(groupStageAdditionalQualified)" : "le") + " " + (qualifiedPerGroupStage + 1).ordinalFormatted()
}
var maxGroupStages: Int {

Loading…
Cancel
Save