fix seed interval stuff for loser bracket

disable account check
multistore
Razmig Sarkissian 1 year ago
parent 87c4b10d97
commit 8508bedcca
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 16
      PadelClub/Data/Round.swift
  3. 31
      PadelClub/Data/Tournament.swift
  4. 27
      PadelClub/ViewModel/SeedInterval.swift
  5. 11
      PadelClub/Views/Calling/CallView.swift
  6. 11
      PadelClub/Views/Calling/Components/MenuWarningView.swift
  7. 11
      PadelClub/Views/Calling/SendToAllView.swift
  8. 16
      PadelClub/Views/Match/Components/MatchDateView.swift
  9. 11
      PadelClub/Views/Match/MatchDetailView.swift
  10. 62
      PadelClub/Views/Round/LoserRoundView.swift

@ -1912,7 +1912,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 67; CURRENT_PROJECT_VERSION = 68;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
@ -1953,7 +1953,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 67; CURRENT_PROJECT_VERSION = 68;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6; DEVELOPMENT_TEAM = BQ3Y44M3Q6;

@ -363,7 +363,7 @@ class Round: ModelObject, Storable {
} }
func hasNextRound() -> Bool { func hasNextRound() -> Bool {
return nextRound()?.isDisabled() == false return nextRound()?.isRankDisabled() == false
} }
func seedInterval() -> SeedInterval? { func seedInterval() -> SeedInterval? {
@ -396,6 +396,20 @@ class Round: ModelObject, Storable {
return RoundRule.roundName(fromRoundIndex: index, displayStyle: displayStyle) return RoundRule.roundName(fromRoundIndex: index, displayStyle: displayStyle)
} }
func roundTitleAndPointsRange(_ displayStyle: DisplayStyle = .wide, expanded: Bool = false, inTournament: Tournament) -> (String?, String?) {
let seedInterval = seedInterval()?.withLast(enabledMatches().count * 2 - 1)
var roundTitle : String? = nil
if parent != nil {
roundTitle = seedInterval?.localizedLabel(displayStyle) ?? "Round pas trouvé"
} else {
roundTitle = RoundRule.roundName(fromRoundIndex: index, displayStyle: displayStyle)
}
let tournamentTeamCount = inTournament.teamCount
let pointsEarned: String? = seedInterval?.pointsRange(tournamentLevel: inTournament.tournamentLevel, teamsCount: tournamentTeamCount)
return (roundTitle, pointsEarned)
}
func updateTournamentState() { func updateTournamentState() {
if let tournamentObject = tournamentObject(), index == 0, isUpperBracket(), hasEnded() { if let tournamentObject = tournamentObject(), index == 0, isUpperBracket(), hasEnded() {
tournamentObject.endDate = Date() tournamentObject.endDate = Date()

@ -1094,22 +1094,45 @@ class Tournament : ModelObject, Storable {
} }
let others: [Round] = rounds.flatMap { round in let others: [Round] = rounds.flatMap { round in
round.loserRoundsAndChildren().filter { $0.isRankDisabled() == false && $0.hasNextRound() == false } print("round", round.roundTitle())
let rounds = round.loserRoundsAndChildren().filter { $0.isRankDisabled() == false && $0.hasNextRound() == false }
print(rounds.count, rounds.map { $0.roundTitle() })
return rounds
}.compactMap({ $0 }) }.compactMap({ $0 })
others.forEach { round in others.forEach { round in
print("round", round.roundTitle())
if let interval = round.seedInterval() { if let interval = round.seedInterval() {
print("interval", interval.localizedLabel())
let playedMatches = round.playedMatches().filter { $0.disabled == false || $0.isReady() } let playedMatches = round.playedMatches().filter { $0.disabled == false || $0.isReady() }
print("playedMatches", playedMatches.count)
let winners = playedMatches.compactMap({ $0.winningTeamId }).filter({ ids.contains($0) == false }) let winners = playedMatches.compactMap({ $0.winningTeamId }).filter({ ids.contains($0) == false })
print("winners", winners.count)
let losers = playedMatches.compactMap({ $0.losingTeamId }).filter({ ids.contains($0) == false }) let losers = playedMatches.compactMap({ $0.losingTeamId }).filter({ ids.contains($0) == false })
print("losers", losers.count)
if winners.isEmpty { if winners.isEmpty {
let disabledIds = playedMatches.flatMap({ $0.teamScores.compactMap({ $0.teamRegistration }) }).filter({ ids.contains($0) == false }) let disabledIds = playedMatches.flatMap({ $0.teamScores.compactMap({ $0.teamRegistration }) }).filter({ ids.contains($0) == false })
teams[interval.last] = disabledIds teams[interval.computedLast] = disabledIds
let teamNames : [String] = disabledIds.compactMap {
let t : TeamRegistration? = Store.main.findById($0)
return t
}.map { $0.canonicalName }
print("winners.isEmpty", "\(interval.computedLast) : ", teamNames)
disabledIds.forEach { ids.insert($0) } disabledIds.forEach { ids.insert($0) }
} else { } else {
teams[interval.first + winners.count - 1] = winners teams[interval.computedFirst + winners.count - 1] = winners
let teamNames : [String] = winners.compactMap {
let t: TeamRegistration? = Store.main.findById($0)
return t
}.map { $0.canonicalName }
print("winners", "\(interval.computedFirst + winners.count - 1) : ", teamNames)
winners.forEach { ids.insert($0) } winners.forEach { ids.insert($0) }
teams[interval.last] = losers teams[interval.computedLast] = losers
let loserTeamNames : [String] = losers.compactMap {
let t: TeamRegistration? = Store.main.findById($0)
return t
}.map { $0.canonicalName }
print("losers", "\(interval.computedLast) : ", loserTeamNames)
losers.forEach { ids.insert($0) } losers.forEach { ids.insert($0) }
} }
} }

@ -26,6 +26,14 @@ struct SeedInterval: Hashable, Comparable {
first == 1 && last == 2 first == 1 && last == 2
} }
func reducedBy(_ count: Int, firstAlso: Bool = false) -> SeedInterval {
return SeedInterval(first: first - (firstAlso ? count : 0), last: last - count, reduce: reduce)
}
func withLast(_ lastValue: Int) -> SeedInterval {
return SeedInterval(first: first, last: first + lastValue, reduce: reduce)
}
var count: Int { var count: Int {
dimension dimension
} }
@ -45,6 +53,25 @@ struct SeedInterval: Hashable, Comparable {
} }
} }
func chunksOrSelf() -> [SeedInterval] {
if dimension > 3 {
let split = dimension / 2
let firstHalf = SeedInterval(first: first, last: first + split - 1, reduce: reduce)
let secondHalf = SeedInterval(first: first + split, last: last, reduce: reduce)
return [firstHalf, secondHalf]
} else {
return [self]
}
}
var computedLast: Int {
last - reduce
}
var computedFirst: Int {
first - reduce
}
func localizedLabel(_ displayStyle: DisplayStyle = .wide) -> String { func localizedLabel(_ displayStyle: DisplayStyle = .wide) -> String {
if dimension < 2 { if dimension < 2 {
return "#\(first - reduce) / #\(last - reduce)" return "#\(first - reduce) / #\(last - reduce)"

@ -229,11 +229,12 @@ struct CallView: View {
} }
fileprivate func _verifyUser(_ handler: () -> ()) { fileprivate func _verifyUser(_ handler: () -> ()) {
if Store.main.userId != nil { handler()
handler() // if Store.main.userId != nil {
} else { // handler()
self.showUserCreationView = true // } else {
} // self.showUserCreationView = true
// }
} }
fileprivate func _payTournamentAndExecute(_ handler: () -> ()) { fileprivate func _payTournamentAndExecute(_ handler: () -> ()) {

@ -142,11 +142,12 @@ struct MenuWarningView: View {
} }
fileprivate func _verifyUser(_ handler: () -> ()) { fileprivate func _verifyUser(_ handler: () -> ()) {
if Store.main.userId != nil { handler()
handler() // if Store.main.userId != nil {
} else { // handler()
self.showUserCreationView = true // } else {
} // self.showUserCreationView = true
// }
} }
fileprivate func _payTournamentAndExecute(_ handler: () -> ()) { fileprivate func _payTournamentAndExecute(_ handler: () -> ()) {

@ -229,11 +229,12 @@ struct SendToAllView: View {
} }
fileprivate func _verifyUser(_ handler: () -> ()) { fileprivate func _verifyUser(_ handler: () -> ()) {
if Store.main.userId != nil { handler()
handler() // if Store.main.userId != nil {
} else { // handler()
self.showUserCreationView = true // } else {
} // self.showUserCreationView = true
// }
} }
fileprivate func _payTournamentAndExecute(_ handler: () -> ()) { fileprivate func _payTournamentAndExecute(_ handler: () -> ()) {

@ -26,6 +26,22 @@ struct MatchDateView: View {
var body: some View { var body: some View {
Menu { Menu {
Button("Ne pas jouer ce match") {
match._toggleMatchDisableState(true)
}
Button("Jouer ce match") {
match._toggleMatchDisableState(false)
}
Button("Créer les scores") {
let teamsScores = match.getOrCreateTeamScores()
do {
try dataStore.teamScores.addOrUpdate(contentOfs: teamsScores)
} catch {
Logger.error(error)
}
}
let estimatedDuration = match.getDuration() let estimatedDuration = match.getDuration()
if match.startDate == nil && isReady { if match.startDate == nil && isReady {
Button("Démarrer") { Button("Démarrer") {

@ -442,11 +442,12 @@ struct MatchDetailView: View {
} }
fileprivate func _verifyUser(_ handler: () -> ()) { fileprivate func _verifyUser(_ handler: () -> ()) {
if Store.main.userId != nil { handler()
handler() // if Store.main.userId != nil {
} else { // handler()
self.showUserCreationView = true // } else {
} // self.showUserCreationView = true
// }
} }
fileprivate func _payTournamentAndExecute(_ handler: () -> ()) { fileprivate func _payTournamentAndExecute(_ handler: () -> ()) {

@ -23,35 +23,53 @@ struct LoserRoundView: View {
if isEditingTournamentSeed == true { if isEditingTournamentSeed == true {
_editingView() _editingView()
} }
let shouldDisplayLoserRounds = loserRounds.filter({
let matches = $0.playedMatches().filter { isEditingTournamentSeed == true || (isEditingTournamentSeed == false && $0.disabled == false) }
return matches.isEmpty == false
}).isEmpty == false
ForEach(loserRounds) { loserRound in if shouldDisplayLoserRounds {
if true { ForEach(loserRounds) { loserRound in
Section { let matches = loserRound.playedMatches().filter { isEditingTournamentSeed == true || (isEditingTournamentSeed == false && $0.disabled == false) }.sorted(by: \.index)
let matches = loserRound.playedMatches().sorted(by: \.index) if matches.isEmpty == false {
ForEach(matches) { match in Section {
MatchRowView(match: match, matchViewStyle: .sectionedStandardStyle) ForEach(matches) { match in
.overlay { MatchRowView(match: match, matchViewStyle: .sectionedStandardStyle)
if match.disabled /*&& isEditingTournamentSeed*/ { .overlay {
Image(systemName: "xmark") if match.disabled && isEditingTournamentSeed {
.resizable() Image(systemName: "xmark")
.scaledToFit() .resizable()
.opacity(0.8) .scaledToFit()
.opacity(0.8)
}
}
.disabled(match.disabled)
if isEditingTournamentSeed {
RowButtonView(match.disabled ? "Jouer ce match" : "Ne pas jouer ce match", role: .destructive) {
match._toggleMatchDisableState(!match.disabled)
} }
} }
.disabled(match.disabled) }
} } header: {
} header: { HStack {
HStack { let labels = loserRound.roundTitleAndPointsRange(.wide, expanded: isEditingTournamentSeed, inTournament: tournament)
Text(loserRound.roundTitle(.wide)) if let seedIntervalLocalizedLabel = labels.0 {
let tournamentTeamCount = tournament.teamCount Text(seedIntervalLocalizedLabel)
if let seedIntervalPointRange = loserRound.seedInterval()?.pointsRange(tournamentLevel: tournament.tournamentLevel, teamsCount: tournamentTeamCount) { }
Spacer() if let seedIntervalPointRange = labels.1 {
Text(seedIntervalPointRange) Spacer()
.font(.caption) Text(seedIntervalPointRange)
.font(.caption)
}
} }
} }
} }
} }
} else {
Section {
ContentUnavailableView("Aucun match joué", systemImage: "tennisball", description: Text("Il n'y aucun match à jouer dans ce tour de match de classement."))
}
} }
} }
.headerProminence(.increased) .headerProminence(.increased)

Loading…
Cancel
Save