fix lag when opening planning view with a lot of matchespaca_championship
parent
1d70070a68
commit
47198e9b88
@ -0,0 +1,152 @@ |
||||
// |
||||
// BracketCallingView.swift |
||||
// PadelClub |
||||
// |
||||
// Created by razmig on 15/10/2024. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct BracketCallingView: View { |
||||
@Environment(Tournament.self) var tournament: Tournament |
||||
@State private var displayByMatch: Bool = true |
||||
@State private var initialSeedRound: Int = 0 |
||||
@State private var initialSeedCount: Int = 0 |
||||
let tournamentRounds: [Round] |
||||
let teams: [TeamRegistration] |
||||
|
||||
init(tournament: Tournament) { |
||||
let rounds = tournament.rounds() |
||||
self.tournamentRounds = rounds |
||||
self.teams = tournament.availableSeeds() |
||||
let index = rounds.count - 1 |
||||
_initialSeedRound = .init(wrappedValue: index) |
||||
_initialSeedCount = .init(wrappedValue: RoundRule.numberOfMatches(forRoundIndex: index)) |
||||
} |
||||
|
||||
var initialRound: Round { |
||||
tournamentRounds.first(where: { $0.index == initialSeedRound })! |
||||
} |
||||
|
||||
func filteredRounds() -> [Round] { |
||||
tournamentRounds.filter({ $0.index >= initialSeedRound }).reversed() |
||||
} |
||||
|
||||
func seedCount(forRoundIndex roundIndex: Int) -> Int { |
||||
if roundIndex < initialSeedRound { return 0 } |
||||
if roundIndex == initialSeedRound { |
||||
return initialSeedCount |
||||
} |
||||
|
||||
let seedCount = RoundRule.numberOfMatches(forRoundIndex: roundIndex) |
||||
let previousSeedCount = self.seedCount(forRoundIndex: roundIndex - 1) |
||||
|
||||
let total = seedCount - previousSeedCount |
||||
if total < 0 { return 0 } |
||||
return total |
||||
} |
||||
|
||||
func seeds(forRoundIndex roundIndex: Int) -> [TeamRegistration] { |
||||
let previousSeeds: Int = (initialSeedRound..<roundIndex).map { seedCount(forRoundIndex: $0) }.reduce(0, +) |
||||
|
||||
|
||||
if roundIndex == tournamentRounds.count - 1 { |
||||
return Array(teams.dropFirst(previousSeeds)) |
||||
} else { |
||||
return Array(teams.dropFirst(previousSeeds).prefix(seedCount(forRoundIndex: roundIndex))) |
||||
} |
||||
} |
||||
|
||||
|
||||
var body: some View { |
||||
List { |
||||
NavigationLink { |
||||
TeamsCallingView(teams: teams.filter({ $0.callDate == nil })) |
||||
.environment(tournament) |
||||
} label: { |
||||
LabeledContent("Équipes non contactées", value: teams.filter({ $0.callDate == nil }).count.formatted()) |
||||
} |
||||
|
||||
PlayersWithoutContactView(players: teams.flatMap({ $0.unsortedPlayers() }).sorted(by: \.computedRank)) |
||||
|
||||
Section { |
||||
Picker(selection: $initialSeedRound) { |
||||
ForEach(tournamentRounds) { |
||||
Text($0.roundTitle()).tag($0.index) |
||||
} |
||||
} label: { |
||||
Text("Premier tour") |
||||
} |
||||
.onChange(of: initialSeedRound) { |
||||
initialSeedCount = RoundRule.numberOfMatches(forRoundIndex: initialSeedRound) |
||||
} |
||||
|
||||
LabeledContent { |
||||
StepperView(count: $initialSeedCount, minimum: 0, maximum: RoundRule.numberOfMatches(forRoundIndex: initialSeedRound)) |
||||
} label: { |
||||
Text("Têtes de série") |
||||
} |
||||
} |
||||
|
||||
ForEach(filteredRounds()) { round in |
||||
let seeds = seeds(forRoundIndex: round.index) |
||||
let callSeeds = seeds.filter({ tournament.isStartDateIsDifferentThanCallDate($0) == false }) |
||||
if seeds.isEmpty == false { |
||||
Section { |
||||
NavigationLink { |
||||
_roundView(round: round, seeds: seeds) |
||||
.environment(tournament) |
||||
} label: { |
||||
CallView.CallStatusView(count: callSeeds.count, total: seeds.count, startDate: round.playedMatches().first?.startDate) |
||||
} |
||||
} header: { |
||||
Text(round.roundTitle()) |
||||
} footer: { |
||||
if let startDate = round.startDate ?? round.playedMatches().first?.startDate { |
||||
CallView(teams: seeds, callDate: startDate, matchFormat: round.matchFormat, roundLabel: round.roundTitle()) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.headerProminence(.increased) |
||||
.navigationTitle("Prévision") |
||||
} |
||||
|
||||
@ViewBuilder |
||||
private func _roundView(round: Round, seeds: [TeamRegistration]) -> some View { |
||||
List { |
||||
NavigationLink("Équipes non contactées") { |
||||
TeamsCallingView(teams: seeds.filter({ $0.callDate == nil })) |
||||
} |
||||
Section { |
||||
ForEach(seeds) { team in |
||||
CallView.TeamView(team: team) |
||||
} |
||||
} header: { |
||||
Text(round.roundTitle()) |
||||
} |
||||
} |
||||
.overlay { |
||||
if seeds.isEmpty { |
||||
ContentUnavailableView { |
||||
Label("Aucune équipe dans ce tour", systemImage: "clock.badge.questionmark") |
||||
} description: { |
||||
Text("Padel Club n'a pas réussi à déterminer quelles équipes jouent ce tour.") |
||||
} actions: { |
||||
// RowButtonView("Horaire intelligent") { |
||||
// selectedScheduleDestination = nil |
||||
// } |
||||
} |
||||
} |
||||
} |
||||
.headerProminence(.increased) |
||||
.navigationTitle(round.roundTitle()) |
||||
.navigationBarTitleDisplayMode(.inline) |
||||
.toolbarBackground(.visible, for: .navigationBar) |
||||
} |
||||
} |
||||
|
||||
//#Preview { |
||||
// SeedsCallingView() |
||||
//} |
||||
Loading…
Reference in new issue