fix more stuff
multistore
Razmig Sarkissian 1 year ago
parent 3bdefc2511
commit d5adf5d83b
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 11
      PadelClub/Data/GroupStage.swift
  3. 40
      PadelClub/Data/Match.swift
  4. 12
      PadelClub/Data/Round.swift
  5. 28
      PadelClub/Data/Tournament.swift
  6. 8
      PadelClub/ViewModel/AgendaDestination.swift
  7. 4
      PadelClub/Views/Calling/CallSettingsView.swift
  8. 6
      PadelClub/Views/Cashier/Event/EventView.swift
  9. 2
      PadelClub/Views/Club/ClubSearchView.swift
  10. 13
      PadelClub/Views/Components/GenericDestinationPickerView.swift
  11. 11
      PadelClub/Views/Components/MatchListView.swift
  12. 6
      PadelClub/Views/GroupStage/GroupStageView.swift
  13. 15
      PadelClub/Views/GroupStage/GroupStagesView.swift
  14. 2
      PadelClub/Views/Match/MatchDetailView.swift
  15. 7
      PadelClub/Views/Round/LoserRoundsView.swift
  16. 2
      PadelClub/Views/Subscription/Guard.swift
  17. 2
      PadelClub/Views/Team/TeamPickerView.swift
  18. 7
      PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift
  19. 8
      PadelClub/Views/Tournament/Screen/TournamentCallView.swift
  20. 7
      PadelClub/Views/Tournament/Screen/TournamentCashierView.swift
  21. 6
      PadelClub/Views/Tournament/Screen/TournamentScheduleView.swift
  22. 6
      PadelClub/Views/Tournament/Screen/TournamentSettingsView.swift
  23. 14
      PadelClub/Views/ViewModifiers/ListRowViewModifier.swift

@ -1935,7 +1935,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 31; CURRENT_PROJECT_VERSION = 32;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6; DEVELOPMENT_TEAM = BQ3Y44M3Q6;
@ -1973,7 +1973,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 31; CURRENT_PROJECT_VERSION = 32;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6; DEVELOPMENT_TEAM = BQ3Y44M3Q6;

@ -179,48 +179,58 @@ class GroupStage: ModelObject, Storable {
} }
func availableToStart(playedMatches: [Match], in runningMatches: [Match]) async -> [Match] { func availableToStart(playedMatches: [Match], in runningMatches: [Match]) async -> [Match] {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func group stage availableToStart", id, duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func group stage availableToStart", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
return playedMatches.filter({ $0.canBeStarted(inMatches: runningMatches) && $0.isRunning() == false }) return playedMatches.filter({ $0.canBeStarted(inMatches: runningMatches) && $0.isRunning() == false })
} }
func runningMatches(playedMatches: [Match]) -> [Match] { func runningMatches(playedMatches: [Match]) -> [Match] {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func group stage runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func group stage runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
return playedMatches.filter({ $0.isRunning() }).sorted(by: \.computedStartDateForSorting) return playedMatches.filter({ $0.isRunning() }).sorted(by: \.computedStartDateForSorting)
} }
func asyncRunningMatches(playedMatches: [Match]) async -> [Match] { func asyncRunningMatches(playedMatches: [Match]) async -> [Match] {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func group stage runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func group stage runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
return playedMatches.filter({ $0.isRunning() }).sorted(by: \.computedStartDateForSorting) return playedMatches.filter({ $0.isRunning() }).sorted(by: \.computedStartDateForSorting)
} }
func readyMatches(playedMatches: [Match]) async -> [Match] { func readyMatches(playedMatches: [Match]) async -> [Match] {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func group stage readyMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func group stage readyMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
return playedMatches.filter({ $0.isReady() && $0.isRunning() == false && $0.hasEnded() == false }) return playedMatches.filter({ $0.isReady() && $0.isRunning() == false && $0.hasEnded() == false })
} }
func finishedMatches(playedMatches: [Match]) -> [Match] { func finishedMatches(playedMatches: [Match]) -> [Match] {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func group stage finishedMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func group stage finishedMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
return playedMatches.filter({ $0.hasEnded() }).sorted(by: \.computedEndDateForSorting).reversed() return playedMatches.filter({ $0.hasEnded() }).sorted(by: \.computedEndDateForSorting).reversed()
} }
@ -406,7 +416,6 @@ extension GroupStage: Selectable {
} }
func badgeValue() -> Int? { func badgeValue() -> Int? {
if teams().count < size { return nil }
return runningMatches(playedMatches: _matches()).count return runningMatches(playedMatches: _matches()).count
} }

@ -184,16 +184,12 @@ class Match: ModelObject, Storable {
} }
func resetScores() { func resetScores() {
if hasEnded() == false {
teamScores.forEach({ $0.score = nil }) teamScores.forEach({ $0.score = nil })
do { do {
try DataStore.shared.teamScores.addOrUpdate(contentOfs: teamScores) try DataStore.shared.teamScores.addOrUpdate(contentOfs: teamScores)
} catch { } catch {
Logger.error(error) Logger.error(error)
} }
} else {
updateTeamScores()
}
} }
func teamWillBeWalkOut(_ team: TeamRegistration) { func teamWillBeWalkOut(_ team: TeamRegistration) {
@ -468,6 +464,9 @@ class Match: ModelObject, Storable {
if endDate == nil { if endDate == nil {
endDate = Date() endDate = Date()
} }
if startDate == nil {
startDate = endDate?.addingTimeInterval(Double(-getDuration()*60))
}
winningTeamId = team(matchDescriptor.winner)?.id winningTeamId = team(matchDescriptor.winner)?.id
losingTeamId = team(matchDescriptor.winner.otherTeam)?.id losingTeamId = team(matchDescriptor.winner.otherTeam)?.id
groupStageObject?.updateGroupStageState() groupStageObject?.updateGroupStageState()
@ -705,34 +704,13 @@ class Match: ModelObject, Storable {
} }
func team(_ team: TeamPosition) -> TeamRegistration? { func team(_ team: TeamPosition) -> TeamRegistration? {
// let start = Date() #if DEBUG_TIME
// defer { let start = Date()
// let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) defer {
// print("func match get team", id, duration.formatted(.units(allowed: [.seconds, .milliseconds]))) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
// } print("func match get team", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
if groupStage != nil {
switch team {
case .one:
return groupStageProjectedTeam(.one)
case .two:
return groupStageProjectedTeam(.two)
} }
} else { #endif
switch team {
case .one:
return roundProjectedTeam(.one)
case .two:
return roundProjectedTeam(.two)
}
}
}
func asyncTeam(_ team: TeamPosition) async -> TeamRegistration? {
// let start = Date()
// defer {
// let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
// print("func match get team", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
// }
if groupStage != nil { if groupStage != nil {
switch team { switch team {
case .one: case .one:

@ -221,11 +221,6 @@ class Round: ModelObject, Storable {
} }
func playedMatches() -> [Match] { func playedMatches() -> [Match] {
// let start = Date()
// defer {
// let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
// print("func round playedMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
// }
if parent == nil { if parent == nil {
return enabledMatches() return enabledMatches()
} else { } else {
@ -549,7 +544,12 @@ class Round: ModelObject, Storable {
} }
extension Round: Selectable { extension Round: Selectable, Equatable {
static func == (lhs: Round, rhs: Round) -> Bool {
lhs.id == rhs.id
}
func selectionLabel() -> String { func selectionLabel() -> String {
if let parentRound { if let parentRound {
return "Tour #\(parentRound.loserRounds().count - index)" return "Tour #\(parentRound.loserRounds().count - index)"

@ -727,12 +727,13 @@ class Tournament : ModelObject, Storable {
} }
func selectedSortedTeams() -> [TeamRegistration] { func selectedSortedTeams() -> [TeamRegistration] {
// let start = Date() #if DEBUG_TIME
// defer { let start = Date()
// let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) defer {
// print("func selectedSortedTeams", id, tournamentTitle(), duration.formatted(.units(allowed: [.seconds, .milliseconds]))) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
// } print("func selectedSortedTeams", id, tournamentTitle(), duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
var _sortedTeams : [TeamRegistration] = [] var _sortedTeams : [TeamRegistration] = []
let _teams = unsortedTeams().filter({ $0.walkOut == false }) let _teams = unsortedTeams().filter({ $0.walkOut == false })
@ -956,47 +957,57 @@ class Tournament : ModelObject, Storable {
} }
func availableToStart(_ allMatches: [Match], in runningMatches: [Match]) async -> [Match] { func availableToStart(_ allMatches: [Match], in runningMatches: [Match]) async -> [Match] {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func tournament availableToStart", id, duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func tournament availableToStart", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
return allMatches.filter({ $0.canBeStarted(inMatches: runningMatches) && $0.isRunning() == false }).sorted(by: \.computedStartDateForSorting) return allMatches.filter({ $0.canBeStarted(inMatches: runningMatches) && $0.isRunning() == false }).sorted(by: \.computedStartDateForSorting)
} }
func asyncRunningMatches(_ allMatches: [Match]) async -> [Match] { func asyncRunningMatches(_ allMatches: [Match]) async -> [Match] {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func tournament runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func tournament runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
return allMatches.filter({ $0.isRunning() && $0.isReady() }).sorted(by: \.computedStartDateForSorting) return allMatches.filter({ $0.isRunning() && $0.isReady() }).sorted(by: \.computedStartDateForSorting)
} }
func runningMatches(_ allMatches: [Match]) -> [Match] { func runningMatches(_ allMatches: [Match]) -> [Match] {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func tournament runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func tournament runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
return allMatches.filter({ $0.isRunning() && $0.isReady() }).sorted(by: \.computedStartDateForSorting) return allMatches.filter({ $0.isRunning() && $0.isReady() }).sorted(by: \.computedStartDateForSorting)
} }
func readyMatches(_ allMatches: [Match]) async -> [Match] { func readyMatches(_ allMatches: [Match]) async -> [Match] {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func tournament readyMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func tournament readyMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
return allMatches.filter({ $0.isReady() && $0.isRunning() == false && $0.hasEnded() == false }).sorted(by: \.computedStartDateForSorting) return allMatches.filter({ $0.isReady() && $0.isRunning() == false && $0.hasEnded() == false }).sorted(by: \.computedStartDateForSorting)
} }
func finishedMatches(_ allMatches: [Match], limit: Int? = nil) -> [Match] { func finishedMatches(_ allMatches: [Match], limit: Int? = nil) -> [Match] {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func tournament finishedMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func tournament finishedMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
let _limit = limit ?? courtCount let _limit = limit ?? courtCount
return Array(allMatches.filter({ $0.hasEnded() }).sorted(by: \.computedEndDateForSorting).reversed().prefix(_limit)) return Array(allMatches.filter({ $0.hasEnded() }).sorted(by: \.computedEndDateForSorting).reversed().prefix(_limit))
} }
@ -1653,7 +1664,10 @@ class Tournament : ModelObject, Storable {
func getGroupStageChunkValue() -> Int { func getGroupStageChunkValue() -> Int {
if teamsPerGroupStage >= 2 { if teamsPerGroupStage >= 2 {
return min(groupStageCount, courtCount / (teamsPerGroupStage / 2)) let result = courtCount / (teamsPerGroupStage / 2)
let remainder = courtCount % (teamsPerGroupStage / 2)
let value = remainder == 0 ? result : result + 1
return min(groupStageCount, value)
} else { } else {
return 1 return 1
} }

@ -8,8 +8,12 @@
import Foundation import Foundation
import SwiftUI import SwiftUI
enum AgendaDestination: CaseIterable, Identifiable, Selectable { enum AgendaDestination: Int, CaseIterable, Identifiable, Selectable, Equatable {
var id: Self { self } var id: Int { self.rawValue }
static func == (lhs: AgendaDestination, rhs: AgendaDestination) -> Bool {
return lhs.id == rhs.id
}
case activity case activity
case history case history

@ -51,7 +51,7 @@ struct CallSettingsView: View {
} }
} }
#if DEBUG // #if DEBUG
Section { Section {
RowButtonView("Annuler toutes les convocations", role: .destructive) { RowButtonView("Annuler toutes les convocations", role: .destructive) {
let teams = tournament.unsortedTeams() let teams = tournament.unsortedTeams()
@ -79,7 +79,7 @@ struct CallSettingsView: View {
} }
} }
} }
#endif //#endif
} }
.sheet(isPresented: $showSendToAllView) { .sheet(isPresented: $showSendToAllView) {
SendToAllView(addLink: false) SendToAllView(addLink: false)

@ -8,7 +8,11 @@
import SwiftUI import SwiftUI
import LeStorage import LeStorage
enum EventDestination: Identifiable, Selectable { enum EventDestination: Identifiable, Selectable, Equatable {
static func == (lhs: EventDestination, rhs: EventDestination) -> Bool {
return lhs.id == rhs.id
}
case links case links
case tournaments(Event) case tournaments(Event)
case cashier case cashier

@ -96,9 +96,9 @@ struct ClubSearchView: View {
_importClub(clubToEdit: clubToEdit, clubMarker: clubMark) _importClub(clubToEdit: clubToEdit, clubMarker: clubMark)
} label: { } label: {
clubView(clubMark) clubView(clubMark)
.frame(maxWidth: .infinity)
.contentShape(Rectangle()) .contentShape(Rectangle())
} }
.frame(maxWidth: .infinity)
.buttonStyle(.plain) .buttonStyle(.plain)
} }
} header: { } header: {

@ -7,13 +7,14 @@
import SwiftUI import SwiftUI
struct GenericDestinationPickerView<T: Identifiable & Selectable>: View { struct GenericDestinationPickerView<T: Identifiable & Selectable & Equatable >: View {
@EnvironmentObject var dataStore: DataStore @EnvironmentObject var dataStore: DataStore
@Binding var selectedDestination: T? @Binding var selectedDestination: T?
let destinations: [T] let destinations: [T]
let nilDestinationIsValid: Bool let nilDestinationIsValid: Bool
var body: some View { var body: some View {
ScrollViewReader { proxy in
ScrollView(.horizontal) { ScrollView(.horizontal) {
HStack { HStack {
if nilDestinationIsValid { if nilDestinationIsValid {
@ -29,6 +30,7 @@ struct GenericDestinationPickerView<T: Identifiable & Selectable>: View {
.fill(selectedDestination == nil ? .master : .beige) .fill(selectedDestination == nil ? .master : .beige)
} }
.buttonStyle(.plain) .buttonStyle(.plain)
.id("settings")
} }
ForEach(destinations) { destination in ForEach(destinations) { destination in
@ -43,6 +45,7 @@ struct GenericDestinationPickerView<T: Identifiable & Selectable>: View {
Capsule() Capsule()
.fill(selectedDestination?.id == destination.id ? .master : .beige) .fill(selectedDestination?.id == destination.id ? .master : .beige)
} }
.id(destination.id)
.buttonStyle(.plain) .buttonStyle(.plain)
.overlay(alignment: .bottomTrailing) { .overlay(alignment: .bottomTrailing) {
if let badge = destination.badgeImage() { if let badge = destination.badgeImage() {
@ -78,5 +81,13 @@ struct GenericDestinationPickerView<T: Identifiable & Selectable>: View {
Divider() Divider()
} }
} }
.onAppear {
if let selectedDestination {
proxy.scrollTo(selectedDestination.id)
} else {
proxy.scrollTo("settings")
}
}
}
} }
} }

@ -12,11 +12,21 @@ struct MatchListView: View {
let section: String let section: String
let matches: [Match]? let matches: [Match]?
var matchViewStyle: MatchViewStyle = .standardStyle var matchViewStyle: MatchViewStyle = .standardStyle
var hideWhenEmpty: Bool = false
@State var isExpanded: Bool = true @State var isExpanded: Bool = true
private func _shouldHide() -> Bool {
if matches != nil && matches!.isEmpty && hideWhenEmpty == true {
return true
} else {
return false
}
}
@ViewBuilder @ViewBuilder
var body: some View { var body: some View {
if _shouldHide() == false {
Section { Section {
DisclosureGroup(isExpanded: $isExpanded) { DisclosureGroup(isExpanded: $isExpanded) {
if let matches { if let matches {
@ -38,4 +48,5 @@ struct MatchListView: View {
} }
} }
} }
}
} }

@ -48,9 +48,9 @@ struct GroupStageView: View {
} }
.headerProminence(.increased) .headerProminence(.increased)
MatchListView(section: "en cours", matches: runningMatches) MatchListView(section: "en cours", matches: runningMatches, hideWhenEmpty: true)
MatchListView(section: "prêt à démarrer", matches: availableToStart) MatchListView(section: "prêt à démarrer", matches: availableToStart, hideWhenEmpty: true)
MatchListView(section: "à lancer", matches: self.readyMatches) MatchListView(section: "à lancer", matches: self.readyMatches, hideWhenEmpty: true)
MatchListView(section: "terminés", matches: groupStage.finishedMatches(playedMatches: playedMatches), isExpanded: false) MatchListView(section: "terminés", matches: groupStage.finishedMatches(playedMatches: playedMatches), isExpanded: false)
} }
.task { .task {

@ -11,7 +11,11 @@ struct GroupStagesView: View {
var tournament: Tournament var tournament: Tournament
@State private var selectedDestination: GroupStageDestination? @State private var selectedDestination: GroupStageDestination?
enum GroupStageDestination: Selectable, Identifiable { enum GroupStageDestination: Selectable, Identifiable, Equatable {
static func == (lhs: GroupStagesView.GroupStageDestination, rhs: GroupStagesView.GroupStageDestination) -> Bool {
lhs.id == rhs.id
}
case all case all
case groupStage(GroupStage) case groupStage(GroupStage)
@ -47,7 +51,12 @@ struct GroupStagesView: View {
} }
func badgeImage() -> Badge? { func badgeImage() -> Badge? {
nil switch self {
case .all:
return nil
case .groupStage(let groupStage):
return groupStage.badgeImage()
}
} }
} }
@ -105,7 +114,7 @@ struct GroupStagesView: View {
} }
.navigationTitle("Toutes les poules") .navigationTitle("Toutes les poules")
case .groupStage(let groupStage): case .groupStage(let groupStage):
GroupStageView(groupStage: groupStage) GroupStageView(groupStage: groupStage).id(groupStage.id)
case nil: case nil:
GroupStageSettingsView() GroupStageSettingsView()
.navigationTitle("Réglages") .navigationTitle("Réglages")

@ -308,6 +308,8 @@ struct MatchDetailView: View {
Button(role: .destructive) { Button(role: .destructive) {
match.resetScores() match.resetScores()
match.resetMatch()
match.confirmed = false
save() save()
} label: { } label: {
Text("Supprimer les scores") Text("Supprimer les scores")

@ -34,7 +34,12 @@ struct LoserRound: Identifiable, Selectable {
} }
extension LoserRound { extension LoserRound: Equatable {
static func == (lhs: LoserRound, rhs: LoserRound) -> Bool {
lhs.id == rhs.id
}
func selectionLabel() -> String { func selectionLabel() -> String {
return "Tour #\(turnIndex + 1)" return "Tour #\(turnIndex + 1)"
} }

@ -141,7 +141,7 @@ import LeStorage
var currentPlan: StoreItem? { var currentPlan: StoreItem? {
// #if DEBUG // #if DEBUG
// return .monthlyUnlimited return .monthlyUnlimited
// #else // #else
if let currentBestPlan = self.currentBestPlan, let plan = StoreItem(rawValue: currentBestPlan.productID) { if let currentBestPlan = self.currentBestPlan, let plan = StoreItem(rawValue: currentBestPlan.productID) {
return plan return plan

@ -80,7 +80,9 @@ struct TeamPickerView: View {
presentTeamPickerView = false presentTeamPickerView = false
} label: { } label: {
TeamRowView(team: team) TeamRowView(team: team)
.contentShape(Rectangle())
} }
.frame(maxWidth: .infinity)
.buttonStyle(.plain) .buttonStyle(.plain)
} }
} }

@ -138,12 +138,13 @@ struct InscriptionManagerView: View {
} }
private func _setHash() async { private func _setHash() async {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func _setHash", duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func _setHash", duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
let selectedSortedTeams = tournament.selectedSortedTeams() let selectedSortedTeams = tournament.selectedSortedTeams()
if self.teamsHash == nil, selectedSortedTeams.isEmpty == false { if self.teamsHash == nil, selectedSortedTeams.isEmpty == false {
self.teamsHash = _simpleHash(ids: selectedSortedTeams.map { $0.id }) self.teamsHash = _simpleHash(ids: selectedSortedTeams.map { $0.id })
@ -410,11 +411,13 @@ struct InscriptionManagerView: View {
} }
private func _prepareStats() async { private func _prepareStats() async {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func _prepareStats", duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func _prepareStats", duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
unsortedPlayers = tournament.unsortedPlayers() unsortedPlayers = tournament.unsortedPlayers()
walkoutTeams = tournament.walkoutTeams() walkoutTeams = tournament.walkoutTeams()
@ -448,11 +451,13 @@ struct InscriptionManagerView: View {
} }
private func _getIssues() async { private func _getIssues() async {
#if DEBUG_TIME
let start = Date() let start = Date()
defer { defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000) let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func _getIssues", duration.formatted(.units(allowed: [.seconds, .milliseconds]))) print("func _getIssues", duration.formatted(.units(allowed: [.seconds, .milliseconds])))
} }
#endif
await registrationIssues = tournament.registrationIssues() await registrationIssues = tournament.registrationIssues()
} }

@ -7,7 +7,13 @@
import SwiftUI import SwiftUI
enum CallDestination: Identifiable, Selectable { enum CallDestination: Identifiable, Selectable, Equatable {
static func == (lhs: CallDestination, rhs: CallDestination) -> Bool {
return lhs.id == rhs.id
}
case seeds(Tournament) case seeds(Tournament)
case groupStages(Tournament) case groupStages(Tournament)

@ -7,7 +7,12 @@
import SwiftUI import SwiftUI
enum CashierDestination: Identifiable, Selectable { enum CashierDestination: Identifiable, Selectable, Equatable {
static func == (lhs: CashierDestination, rhs: CashierDestination) -> Bool {
return lhs.id == rhs.id
}
case summary case summary
case groupStage(GroupStage) case groupStage(GroupStage)
case bracket(Round) case bracket(Round)

@ -20,7 +20,11 @@ extension Schedulable {
} }
} }
enum ScheduleDestination: String, Identifiable, Selectable { enum ScheduleDestination: String, Identifiable, Selectable, Equatable {
static func == (lhs: ScheduleDestination, rhs: ScheduleDestination) -> Bool {
return lhs.id == rhs.id
}
var id: String { self.rawValue } var id: String { self.rawValue }
case planning case planning

@ -7,7 +7,11 @@
import SwiftUI import SwiftUI
enum TournamentSettings: Identifiable, Selectable { enum TournamentSettings: Identifiable, Selectable, Equatable {
static func == (lhs: TournamentSettings, rhs: TournamentSettings) -> Bool {
return lhs.id == rhs.id
}
case status case status
case general case general
case club(Tournament) case club(Tournament)

@ -14,12 +14,12 @@ struct ListRowViewModifier: ViewModifier {
func body(content: Content) -> some View { func body(content: Content) -> some View {
if isActive { if isActive {
content content
// .listRowBackground( .listRowBackground(
// color.variation() color.variation()
// .overlay(alignment: .leading, content: { .overlay(alignment: .leading, content: {
// color.frame(width: 8) color.frame(width: 8)
// }) })
// ) )
} else { } else {
content content
} }
@ -27,7 +27,7 @@ struct ListRowViewModifier: ViewModifier {
} }
extension View { extension View {
func listRowView(isActive: Bool = true, color: Color) -> some View { func listRowView(isActive: Bool = false, color: Color) -> some View {
modifier(ListRowViewModifier(isActive: isActive, color: color)) modifier(ListRowViewModifier(isActive: isActive, color: color))
} }
} }

Loading…
Cancel
Save