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

@ -363,7 +363,7 @@ class Round: ModelObject, Storable {
}
func hasNextRound() -> Bool {
return nextRound()?.isDisabled() == false
return nextRound()?.isRankDisabled() == false
}
func seedInterval() -> SeedInterval? {
@ -395,6 +395,20 @@ class Round: ModelObject, Storable {
}
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() {
if let tournamentObject = tournamentObject(), index == 0, isUpperBracket(), hasEnded() {

@ -1094,22 +1094,45 @@ class Tournament : ModelObject, Storable {
}
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 })
others.forEach { round in
print("round", round.roundTitle())
if let interval = round.seedInterval() {
print("interval", interval.localizedLabel())
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 })
print("winners", winners.count)
let losers = playedMatches.compactMap({ $0.losingTeamId }).filter({ ids.contains($0) == false })
print("losers", losers.count)
if winners.isEmpty {
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) }
} 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) }
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) }
}
}

@ -26,6 +26,14 @@ struct SeedInterval: Hashable, Comparable {
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 {
dimension
}
@ -44,7 +52,26 @@ struct SeedInterval: Hashable, Comparable {
return nil
}
}
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 {
if dimension < 2 {
return "#\(first - reduce) / #\(last - reduce)"

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

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

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

@ -26,6 +26,22 @@ struct MatchDateView: View {
var body: some View {
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()
if match.startDate == nil && isReady {
Button("Démarrer") {

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

@ -23,35 +23,53 @@ struct LoserRoundView: View {
if isEditingTournamentSeed == true {
_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 true {
Section {
let matches = loserRound.playedMatches().sorted(by: \.index)
ForEach(matches) { match in
MatchRowView(match: match, matchViewStyle: .sectionedStandardStyle)
.overlay {
if match.disabled /*&& isEditingTournamentSeed*/ {
Image(systemName: "xmark")
.resizable()
.scaledToFit()
.opacity(0.8)
if shouldDisplayLoserRounds {
ForEach(loserRounds) { loserRound in
let matches = loserRound.playedMatches().filter { isEditingTournamentSeed == true || (isEditingTournamentSeed == false && $0.disabled == false) }.sorted(by: \.index)
if matches.isEmpty == false {
Section {
ForEach(matches) { match in
MatchRowView(match: match, matchViewStyle: .sectionedStandardStyle)
.overlay {
if match.disabled && isEditingTournamentSeed {
Image(systemName: "xmark")
.resizable()
.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: {
HStack {
Text(loserRound.roundTitle(.wide))
let tournamentTeamCount = tournament.teamCount
if let seedIntervalPointRange = loserRound.seedInterval()?.pointsRange(tournamentLevel: tournament.tournamentLevel, teamsCount: tournamentTeamCount) {
Spacer()
Text(seedIntervalPointRange)
.font(.caption)
}
} header: {
HStack {
let labels = loserRound.roundTitleAndPointsRange(.wide, expanded: isEditingTournamentSeed, inTournament: tournament)
if let seedIntervalLocalizedLabel = labels.0 {
Text(seedIntervalLocalizedLabel)
}
if let seedIntervalPointRange = labels.1 {
Spacer()
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)

Loading…
Cancel
Save