parent
55b69bc9b4
commit
992d7fb744
@ -0,0 +1,99 @@ |
||||
// |
||||
// MatchDescriptor.swift |
||||
// PadelClub |
||||
// |
||||
// Created by Razmig Sarkissian on 02/04/2024. |
||||
// |
||||
|
||||
import Foundation |
||||
|
||||
class MatchDescriptor: ObservableObject { |
||||
@Published var matchFormat: MatchFormat |
||||
@Published var setDescriptors: [SetDescriptor] |
||||
var court: Int = 1 |
||||
var title: String = "Titre du match" |
||||
var teamLabelOne: String = "" |
||||
var teamLabelTwo: String = "" |
||||
var startDate: Date = Date() |
||||
var match: Match? |
||||
|
||||
init(match: Match? = nil) { |
||||
self.match = match |
||||
if let groupStage = match?.groupStageObject { |
||||
self.matchFormat = groupStage.matchFormat |
||||
self.setDescriptors = [SetDescriptor(setFormat: groupStage.matchFormat.setFormat)] |
||||
} else { |
||||
let format = match?.matchFormat ?? match?.currentTournament()?.matchFormat ?? .defaultFormatForMatchType(.groupStage) |
||||
self.matchFormat = format |
||||
self.setDescriptors = [SetDescriptor(setFormat: format.setFormat)] |
||||
} |
||||
self.teamLabelOne = match?.team(.one)?.teamLabel() ?? "" |
||||
self.teamLabelTwo = match?.team(.two)?.teamLabel() ?? "" |
||||
|
||||
if let match, let scoresTeamOne = match.teamScore(.one)?.score, let scoresTeamTwo = match.teamScore(.two)?.score { |
||||
|
||||
self.setDescriptors = combineArraysIntoTuples(scoresTeamOne.components(separatedBy: ","), scoresTeamTwo.components(separatedBy: ",")).map({ (a:String?, b:String?) in |
||||
SetDescriptor(valueTeamOne: a != nil ? Int(a!) : nil, valueTeamTwo: b != nil ? Int(b!) : nil, setFormat: match.matchFormat.setFormat) |
||||
}) |
||||
} |
||||
} |
||||
|
||||
var teamOneScores: [String] { |
||||
setDescriptors.compactMap { $0.valueTeamOne }.map { "\($0)" } |
||||
} |
||||
|
||||
var teamTwoScores: [String] { |
||||
setDescriptors.compactMap { $0.valueTeamTwo }.map { "\($0)" } |
||||
} |
||||
|
||||
var scoreTeamOne: Int { setDescriptors.compactMap { $0.winner }.filter { $0 == .one }.count } |
||||
var scoreTeamTwo: Int { setDescriptors.compactMap { $0.winner }.filter { $0 == .two }.count } |
||||
|
||||
var hasEnded: Bool { |
||||
return matchFormat.hasEnded(scoreTeamOne: scoreTeamOne, scoreTeamTwo: scoreTeamTwo) |
||||
} |
||||
|
||||
func addNewSet() { |
||||
if hasEnded == false { |
||||
setDescriptors.append(SetDescriptor(setFormat: matchFormat.newSetFormat(setCount: setDescriptors.count))) |
||||
} |
||||
} |
||||
|
||||
var winner: TeamData { |
||||
matchFormat.winner(scoreTeamOne: scoreTeamOne, scoreTeamTwo: scoreTeamTwo) |
||||
} |
||||
|
||||
var winnerLabel: String { |
||||
if winner == .one { |
||||
return teamLabelOne |
||||
} else { |
||||
return teamLabelTwo |
||||
} |
||||
} |
||||
} |
||||
|
||||
fileprivate func combineArraysIntoTuples(_ array1: [String], _ array2: [String]) -> [(String?, String?)] { |
||||
// Zip the two arrays together and map them to tuples of optional strings |
||||
let combined = zip(array1, array2).map { (element1, element2) in |
||||
return (element1, element2) |
||||
} |
||||
|
||||
// If one array is longer than the other, append the remaining elements |
||||
let remainingElements: [(String?, String?)] |
||||
if array1.count > array2.count { |
||||
let remaining = Array(array1[array2.count...]).map { (element) in |
||||
return (element, nil as String?) |
||||
} |
||||
remainingElements = remaining |
||||
} else if array2.count > array1.count { |
||||
let remaining = Array(array2[array1.count...]).map { (element) in |
||||
return (nil as String?, element) |
||||
} |
||||
remainingElements = remaining |
||||
} else { |
||||
remainingElements = [] |
||||
} |
||||
|
||||
// Concatenate the two arrays |
||||
return combined + remainingElements |
||||
} |
||||
@ -0,0 +1,33 @@ |
||||
// |
||||
// SetDescriptor.swift |
||||
// PadelClub |
||||
// |
||||
// Created by Razmig Sarkissian on 02/04/2024. |
||||
// |
||||
|
||||
import Foundation |
||||
|
||||
struct SetDescriptor: Identifiable, Equatable { |
||||
let id: UUID = UUID() |
||||
var valueTeamOne: Int? |
||||
var valueTeamTwo: Int? |
||||
var tieBreakValueTeamOne: Int? |
||||
var tieBreakValueTeamTwo: Int? |
||||
var setFormat: SetFormat |
||||
|
||||
var hasEnded: Bool { |
||||
if let valueTeamTwo, let valueTeamOne { |
||||
return setFormat.hasEnded(teamOne: valueTeamOne, teamTwo: valueTeamTwo) |
||||
} else { |
||||
return false |
||||
} |
||||
} |
||||
|
||||
var winner: TeamData? { |
||||
if let valueTeamTwo, let valueTeamOne { |
||||
return setFormat.winner(teamOne: valueTeamOne, teamTwo: valueTeamTwo) |
||||
} else { |
||||
return nil |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,45 @@ |
||||
// |
||||
// MatchListView.swift |
||||
// PadelClub |
||||
// |
||||
// Created by Razmig Sarkissian on 03/04/2024. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct MatchListView: View { |
||||
@EnvironmentObject var dataStore: DataStore |
||||
let section: String |
||||
let matches: [Match] |
||||
var matchViewStyle: MatchViewStyle = .sectionedStandardStyle |
||||
|
||||
@State private var isExpanded: Bool = true |
||||
|
||||
@ViewBuilder |
||||
var body: some View { |
||||
if matches.isEmpty == false { |
||||
Section { |
||||
if isExpanded { |
||||
ForEach(matches) { match in |
||||
MatchRowView(match: match, matchViewStyle: matchViewStyle) |
||||
} |
||||
} |
||||
} header: { |
||||
Button { |
||||
isExpanded.toggle() |
||||
} label: { |
||||
HStack { |
||||
Text(section.capitalized) |
||||
Spacer() |
||||
Text(matches.count.formatted()) |
||||
Image(systemName: isExpanded ? "chevron.down.circle" : "chevron.right.circle") |
||||
} |
||||
.contentShape(Rectangle()) |
||||
} |
||||
.buttonStyle(.plain) |
||||
.frame(maxWidth: .infinity) |
||||
} |
||||
.headerProminence(.increased) |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,107 @@ |
||||
// |
||||
// GroupStageTeamView.swift |
||||
// PadelClub |
||||
// |
||||
// Created by Razmig Sarkissian on 03/04/2024. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct GroupStageTeamView: View { |
||||
@EnvironmentObject var dataStore: DataStore |
||||
@Environment(\.dismiss) private var dismiss |
||||
let groupStage: GroupStage |
||||
var team: TeamRegistration |
||||
|
||||
var body: some View { |
||||
List { |
||||
ForEach(team.players()) { player in |
||||
Section { |
||||
ImportedPlayerView(player: player) |
||||
} footer: { |
||||
HStack { |
||||
Button("contacter") { |
||||
} |
||||
Spacer() |
||||
Button { |
||||
player.hasArrived.toggle() |
||||
try? dataStore.playerRegistrations.addOrUpdate(instance: player) |
||||
} label: { |
||||
Label("présent", systemImage: player.hasArrived ? "checkmark.circle" : "circle") |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
if groupStage.tournamentObject()?.hasEnded() == false { |
||||
Section { |
||||
if team.qualified == false { |
||||
RowButtonView("Qualifier l'équipe") { |
||||
team.qualified = true |
||||
team.bracketPosition = nil |
||||
_save() |
||||
} |
||||
} |
||||
} |
||||
Section { |
||||
if team.qualified { |
||||
RowButtonView("Annuler la qualification", role: .destructive) { |
||||
team.qualified = false |
||||
team.bracketPosition = nil |
||||
_save() |
||||
} |
||||
} |
||||
} |
||||
|
||||
Section { |
||||
// if let deltaLabel = bracket.tournament?.deltaLabel(index, bracketIndex: bracket.index.intValue) { |
||||
// Section { |
||||
// Button(role: .destructive) { |
||||
// entrant.resetBracketPosition() |
||||
// save() |
||||
// } label: { |
||||
// Text(deltaLabel) |
||||
// } |
||||
// Divider() |
||||
// } header: { |
||||
// Text("Toute l'équipe, poids: " + entrant.updatedRank.formatted()) |
||||
// } |
||||
// } |
||||
// |
||||
// ForEach(entrant.orderedPlayers) { player in |
||||
// if let deltaLabel = bracket.tournament?.playerDeltaLabel(rank: entrant.otherPlayer(player)?.currentRank, positionInBracket: index, bracketIndex: bracket.index.intValue) { |
||||
// Section { |
||||
// Button(role: .destructive) { |
||||
// entrant.team?.removeFromPlayers(player) |
||||
// save() |
||||
// } label: { |
||||
// Text(deltaLabel) |
||||
// } |
||||
// Divider() |
||||
// } header: { |
||||
// Text(player.longLabel + ", rang: " + player.formattedRank) |
||||
// } |
||||
// } |
||||
// } |
||||
} header: { |
||||
Text("Remplacement") |
||||
} |
||||
|
||||
Section { |
||||
RowButtonView("Retirer de la poule") { |
||||
team.groupStagePosition = nil |
||||
team.groupStage = nil |
||||
_save() |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.toolbarBackground(.visible, for: .navigationBar) |
||||
.navigationTitle("Détail de l'équipe") |
||||
} |
||||
|
||||
private func _save() { |
||||
try? dataStore.teamRegistrations.addOrUpdate(instance: team) |
||||
dismiss() |
||||
} |
||||
} |
||||
@ -0,0 +1,104 @@ |
||||
// |
||||
// EditScoreView.swift |
||||
// Padel Tournament |
||||
// |
||||
// Created by Razmig Sarkissian on 27/02/2023. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct EditScoreView: View { |
||||
@EnvironmentObject var dataStore: DataStore |
||||
@ObservedObject var matchDescriptor: MatchDescriptor |
||||
@Environment(\.dismiss) private var dismiss |
||||
|
||||
func walkout(_ team: TeamData) { |
||||
matchDescriptor.match?.setWalkOut(team) |
||||
save() |
||||
dismiss() |
||||
} |
||||
|
||||
var body: some View { |
||||
Form { |
||||
Section { |
||||
Text(matchDescriptor.teamLabelOne) |
||||
Text(matchDescriptor.teamLabelTwo) |
||||
} footer: { |
||||
HStack { |
||||
Menu { |
||||
Button { |
||||
walkout(.one) |
||||
} label: { |
||||
Text(matchDescriptor.teamLabelOne) |
||||
} |
||||
Button { |
||||
walkout(.two) |
||||
} label: { |
||||
Text(matchDescriptor.teamLabelTwo) |
||||
} |
||||
} label: { |
||||
Text("Forfait") |
||||
} |
||||
Spacer() |
||||
|
||||
MatchTypeSmallSelectionView(selectedFormat: $matchDescriptor.matchFormat, format: "Format") |
||||
.onChange(of: matchDescriptor.matchFormat) { newValue in |
||||
matchDescriptor.setDescriptors.removeAll() |
||||
matchDescriptor.addNewSet() |
||||
} |
||||
} |
||||
} |
||||
ForEach($matchDescriptor.setDescriptors) { $setDescriptor in |
||||
SetInputView(setDescriptor: $setDescriptor) |
||||
.onChange(of: setDescriptor.hasEnded) { hasEnded in |
||||
if hasEnded { |
||||
if matchDescriptor.hasEnded == false { |
||||
matchDescriptor.addNewSet() |
||||
} |
||||
} else { |
||||
let index = matchDescriptor.setDescriptors.firstIndex(where: { $0 == setDescriptor }) ?? 0 |
||||
matchDescriptor.setDescriptors = Array(matchDescriptor.setDescriptors[0...index]) |
||||
} |
||||
} |
||||
} |
||||
|
||||
if matchDescriptor.hasEnded { |
||||
Section { |
||||
HStack { |
||||
Spacer() |
||||
VStack { |
||||
Text(matchDescriptor.winnerLabel) |
||||
} |
||||
.multilineTextAlignment(.center) |
||||
Spacer() |
||||
} |
||||
RowButtonView("Victoire") { |
||||
matchDescriptor.match?.setScore(fromMatchDescriptor: matchDescriptor) |
||||
save() |
||||
dismiss() |
||||
} |
||||
} footer: { |
||||
Text("Termine la rencontre sur ce score") |
||||
} |
||||
} |
||||
|
||||
if matchDescriptor.match?.hasEnded() == false { |
||||
Section { |
||||
RowButtonView("Mise à jour") { |
||||
matchDescriptor.match?.updateScore(fromMatchDescriptor: matchDescriptor) |
||||
save() |
||||
dismiss() |
||||
} |
||||
} footer: { |
||||
Text("Met à jour le score pour la diffusion, ne termine pas la rencontre") |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
func save() { |
||||
if let match = matchDescriptor.match { |
||||
try? dataStore.matches.addOrUpdate(instance: match) |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,50 @@ |
||||
// |
||||
// PointSelectionView.swift |
||||
// Padel Tournament |
||||
// |
||||
// Created by Razmig Sarkissian on 27/02/2023. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct PointSelectionView: View { |
||||
@Binding var valueSelected: Int? |
||||
var values: [Int] |
||||
var possibleValues: [Int] |
||||
var disableValues: [Int] = [] |
||||
var deleteAction: () -> () |
||||
let gridItems: [GridItem] = [GridItem(.adaptive(minimum: 65), spacing: 20)] |
||||
|
||||
|
||||
init(valueSelected: Binding<Int?>, values: [Int], possibleValues: [Int], disableValues: [Int], deleteAction: @escaping () -> Void) { |
||||
_valueSelected = valueSelected |
||||
self.values = values |
||||
self.possibleValues = Set(values + possibleValues).sorted().reversed() |
||||
self.disableValues = disableValues |
||||
self.deleteAction = deleteAction |
||||
} |
||||
|
||||
var body: some View { |
||||
|
||||
LazyVGrid(columns: gridItems, alignment: .center, spacing: 20) { |
||||
ForEach(possibleValues, id: \.self) { value in |
||||
Button { |
||||
valueSelected = value |
||||
} label: { |
||||
PointView(value: "\(value).circle.fill") |
||||
} |
||||
.buttonStyle(.borderedProminent) |
||||
.controlSize(.large) |
||||
.disabled(disableValues.contains(value) || values.contains(value) == false ) |
||||
} |
||||
Button { |
||||
deleteAction() |
||||
} label: { |
||||
PointView(value: "delete.left.fill") |
||||
} |
||||
.buttonStyle(.borderedProminent) |
||||
.controlSize(.large) |
||||
} |
||||
.padding() |
||||
} |
||||
} |
||||
@ -0,0 +1,26 @@ |
||||
// |
||||
// PointView.swift |
||||
// Padel Tournament |
||||
// |
||||
// Created by Razmig Sarkissian on 27/02/2023. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct PointView: View { |
||||
let value: String |
||||
|
||||
var body: some View { |
||||
Image(systemName: value) |
||||
.resizable() |
||||
.aspectRatio(contentMode: .fit) |
||||
.font(.largeTitle) |
||||
.frame(height: 40) |
||||
} |
||||
} |
||||
|
||||
struct PointView_Previews: PreviewProvider { |
||||
static var previews: some View { |
||||
PointView(value:"delete.left.fill") |
||||
} |
||||
} |
||||
@ -0,0 +1,215 @@ |
||||
// |
||||
// SetInputView.swift |
||||
// PadelClub |
||||
// |
||||
// Created by Razmig Sarkissian on 02/04/2024. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct SetInputView: View { |
||||
@Binding var setDescriptor: SetDescriptor |
||||
@State private var showSetInputView: Bool = true |
||||
@State private var showTieBreakInputView: Bool = false |
||||
|
||||
var setFormat: SetFormat { setDescriptor.setFormat } |
||||
|
||||
private var showTieBreakView: Bool { |
||||
setFormat.shouldTiebreak(scoreTeamOne: setDescriptor.valueTeamOne ?? 0, scoreTeamTwo: setDescriptor.valueTeamTwo ?? 0) |
||||
} |
||||
|
||||
private var isMainViewTieBreakView: Bool { |
||||
setFormat == .superTieBreak || setFormat == .megaTieBreak |
||||
} |
||||
|
||||
private var currentValue: Binding<Int?> { |
||||
Binding { |
||||
if setDescriptor.valueTeamOne != nil { |
||||
return setDescriptor.valueTeamTwo |
||||
} else { |
||||
return setDescriptor.valueTeamOne |
||||
} |
||||
} set: { newValue, _ in |
||||
if setDescriptor.valueTeamOne != nil { |
||||
setDescriptor.valueTeamTwo = newValue |
||||
} else { |
||||
setDescriptor.valueTeamOne = newValue |
||||
} |
||||
} |
||||
} |
||||
|
||||
private var currentTiebreakValue: Binding<Int?> { |
||||
Binding { |
||||
if setDescriptor.tieBreakValueTeamOne != nil { |
||||
return setDescriptor.tieBreakValueTeamTwo |
||||
} else { |
||||
return setDescriptor.tieBreakValueTeamOne |
||||
} |
||||
} set: { newValue, _ in |
||||
|
||||
if let tieBreakValueTeamOne = setDescriptor.tieBreakValueTeamOne, let tieBreakValueTeamTwo = setDescriptor.tieBreakValueTeamTwo { |
||||
if tieBreakValueTeamOne < tieBreakValueTeamTwo && tieBreakValueTeamTwo > 6 { |
||||
setDescriptor.tieBreakValueTeamOne = newValue |
||||
} |
||||
else if tieBreakValueTeamOne > tieBreakValueTeamTwo && tieBreakValueTeamOne > 6 { |
||||
setDescriptor.tieBreakValueTeamTwo = newValue |
||||
} |
||||
} |
||||
else if setDescriptor.tieBreakValueTeamOne != nil { |
||||
setDescriptor.tieBreakValueTeamTwo = newValue |
||||
} else { |
||||
setDescriptor.tieBreakValueTeamOne = newValue |
||||
} |
||||
} |
||||
} |
||||
|
||||
private var disableValues: [Int] { |
||||
if let valueTeamOne = setDescriptor.valueTeamOne { |
||||
return setFormat.disableValuesForTeamTwo(with: valueTeamOne) |
||||
} |
||||
return [] |
||||
} |
||||
|
||||
private var disableTieBreakValues: [Int] { |
||||
if let tieBreakValueTeamOne = setDescriptor.tieBreakValueTeamOne { |
||||
if tieBreakValueTeamOne == 7 { |
||||
return [7,6] |
||||
} |
||||
} |
||||
return [] |
||||
} |
||||
|
||||
func deleteLastValue() { |
||||
setDescriptor.valueTeamOne = nil |
||||
setDescriptor.valueTeamTwo = nil |
||||
} |
||||
|
||||
func deleteLastTiebreakValue() { |
||||
setDescriptor.tieBreakValueTeamOne = nil |
||||
setDescriptor.tieBreakValueTeamTwo = nil |
||||
} |
||||
|
||||
func possibleValues() -> [Int] { |
||||
if let valueTeamOne = setDescriptor.valueTeamOne { |
||||
if valueTeamOne == 7 && setFormat == .six { |
||||
return [6,5] |
||||
} |
||||
if valueTeamOne == 5 && setFormat == .four { |
||||
return [3,2] |
||||
} |
||||
} |
||||
return setFormat.possibleValues |
||||
} |
||||
|
||||
func tieBreakPossibleValues() -> [Int] { |
||||
if let tieBreakValueTeamOne = setDescriptor.tieBreakValueTeamOne, let tieBreakValueTeamTwo = setDescriptor.tieBreakValueTeamTwo { |
||||
if tieBreakValueTeamOne == 6 && tieBreakValueTeamTwo == 8 { |
||||
return [] |
||||
} |
||||
if tieBreakValueTeamOne < 7 && tieBreakValueTeamTwo == 7 { |
||||
return [9, 5, 4, 3, 2, 1, 0] |
||||
} |
||||
if tieBreakValueTeamOne == 7 && tieBreakValueTeamTwo < 7 { |
||||
return [9, 5, 4, 3, 2, 1, 0] |
||||
} |
||||
return Array(((max(tieBreakValueTeamOne, tieBreakValueTeamTwo)+2)..<max(tieBreakValueTeamOne, tieBreakValueTeamTwo)+8)).reversed() |
||||
} |
||||
if setDescriptor.tieBreakValueTeamOne != nil { |
||||
return [9, 5, 4, 3, 2, 1, 0] |
||||
} |
||||
return SetFormat.six.possibleValues |
||||
} |
||||
|
||||
var body: some View { |
||||
Section { |
||||
DisclosureGroup(isExpanded: $showSetInputView) { |
||||
PointSelectionView(valueSelected: currentValue, values: possibleValues(), possibleValues: setFormat.possibleValues, disableValues: disableValues, deleteAction: deleteLastValue) |
||||
} label: { |
||||
SetLabelView(initialValueLeft: $setDescriptor.valueTeamOne, initialValueRight: $setDescriptor.valueTeamTwo, shouldDisplaySteppers: isMainViewTieBreakView) |
||||
} |
||||
if showTieBreakView { |
||||
DisclosureGroup(isExpanded: $showTieBreakInputView) { |
||||
PointSelectionView(valueSelected: currentTiebreakValue, values: tieBreakPossibleValues(), possibleValues: SetFormat.six.possibleValues, disableValues: disableTieBreakValues, deleteAction: deleteLastTiebreakValue) |
||||
} label: { |
||||
SetLabelView(initialValueLeft: $setDescriptor.tieBreakValueTeamOne, initialValueRight: $setDescriptor.tieBreakValueTeamTwo, shouldDisplaySteppers: showTieBreakInputView, isTieBreak: true) |
||||
} |
||||
} |
||||
} |
||||
.onChange(of: setDescriptor.valueTeamOne, perform: { newValue in |
||||
if let newValue { |
||||
if newValue == setFormat.scoreToWin - 1 && setFormat.tieBreak == 8 { |
||||
setDescriptor.valueTeamTwo = setFormat.scoreToWin |
||||
} else if newValue == setFormat.scoreToWin - 2 && setFormat.tieBreak == 8 { |
||||
setDescriptor.valueTeamTwo = setFormat.scoreToWin |
||||
} else if newValue == setFormat.scoreToWin - 1 { |
||||
setDescriptor.valueTeamTwo = setFormat.scoreToWin + 1 |
||||
} else if newValue <= setFormat.scoreToWin - 2 { |
||||
setDescriptor.valueTeamTwo = setFormat.scoreToWin |
||||
} else if newValue > 10 && setFormat == .superTieBreak { |
||||
setDescriptor.valueTeamTwo = newValue - 2 |
||||
} else if newValue > 15 && setFormat == .megaTieBreak { |
||||
setDescriptor.valueTeamTwo = newValue - 2 |
||||
} |
||||
|
||||
} |
||||
}) |
||||
.onChange(of: setDescriptor.valueTeamTwo, perform: { newValue in |
||||
if setDescriptor.valueTeamOne != nil && setDescriptor.valueTeamTwo != nil { |
||||
showSetInputView = false |
||||
} |
||||
}) |
||||
.onChange(of: setDescriptor.tieBreakValueTeamOne, perform: { newValue in |
||||
if let newValue, setDescriptor.tieBreakValueTeamTwo == nil { |
||||
if newValue > 7 { |
||||
setDescriptor.tieBreakValueTeamTwo = newValue - 2 |
||||
} |
||||
if newValue == 6 { |
||||
setDescriptor.tieBreakValueTeamTwo = newValue + 2 |
||||
} |
||||
if newValue <= 5 { |
||||
setDescriptor.tieBreakValueTeamTwo = 7 |
||||
} |
||||
} |
||||
else if let newValue, let tieBreakValueTeamTwo = setDescriptor.tieBreakValueTeamTwo { |
||||
if newValue > 6 && tieBreakValueTeamTwo < newValue { |
||||
setDescriptor.tieBreakValueTeamTwo = newValue - 2 |
||||
} |
||||
if newValue > 6 && tieBreakValueTeamTwo > newValue { |
||||
setDescriptor.tieBreakValueTeamTwo = newValue + 2 |
||||
} |
||||
if newValue == 6 { |
||||
setDescriptor.tieBreakValueTeamTwo = newValue + 2 |
||||
} |
||||
if newValue <= 5 { |
||||
setDescriptor.tieBreakValueTeamTwo = 7 |
||||
showTieBreakInputView = false |
||||
} |
||||
} |
||||
}) |
||||
.onChange(of: setDescriptor.tieBreakValueTeamTwo, perform: { newValue in |
||||
if let tieBreakValueTeamOne = setDescriptor.tieBreakValueTeamOne, tieBreakValueTeamOne <= 5 { |
||||
showTieBreakInputView = false |
||||
} else { |
||||
if let tieBreakValueTeamTwo = setDescriptor.tieBreakValueTeamTwo { |
||||
if let newValue { |
||||
if newValue > 6 && tieBreakValueTeamTwo > setDescriptor.tieBreakValueTeamOne ?? 0 { |
||||
setDescriptor.tieBreakValueTeamOne = newValue - 2 |
||||
} |
||||
if newValue > 4 && tieBreakValueTeamTwo < setDescriptor.tieBreakValueTeamOne ?? 0 { |
||||
setDescriptor.tieBreakValueTeamOne = newValue + 2 |
||||
} |
||||
} |
||||
} |
||||
|
||||
if let newValue, let tieBreakValueTeamOne = setDescriptor.tieBreakValueTeamOne { |
||||
if newValue < 6 && tieBreakValueTeamOne == 7 { |
||||
showTieBreakInputView = false |
||||
} |
||||
} |
||||
|
||||
} |
||||
}) |
||||
|
||||
.listRowSeparator(.hidden) |
||||
} |
||||
} |
||||
@ -0,0 +1,57 @@ |
||||
// |
||||
// SetLabelView.swift |
||||
// PadelClub |
||||
// |
||||
// Created by Razmig Sarkissian on 02/04/2024. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct SetLabelView: View { |
||||
@Binding var initialValueLeft: Int? |
||||
@Binding var initialValueRight: Int? |
||||
@State private var valueLeft: Int = 0 |
||||
@State private var valueRight: Int = 0 |
||||
var shouldDisplaySteppers: Bool = false |
||||
var isTieBreak: Bool = false |
||||
|
||||
var body: some View { |
||||
HStack(spacing: 0) { |
||||
if shouldDisplaySteppers { |
||||
Stepper(value: $valueLeft, in: 0...Int.max) { |
||||
|
||||
} onEditingChanged: { didChange in |
||||
initialValueLeft = valueLeft |
||||
} |
||||
.fixedSize() |
||||
.scaleEffect(0.7) |
||||
} |
||||
Spacer() |
||||
Text("\(valueLeft) / \(valueRight)") |
||||
.font(isTieBreak ? .headline : .largeTitle).monospacedDigit() |
||||
.scaledToFit() |
||||
.minimumScaleFactor(0.5) |
||||
.lineLimit(1) |
||||
Spacer() |
||||
if shouldDisplaySteppers { |
||||
Stepper(value: $valueRight, in: 0...Int.max) { |
||||
} onEditingChanged: { didChange in |
||||
initialValueRight = valueRight |
||||
} |
||||
.fixedSize() |
||||
.scaleEffect(0.7) |
||||
} |
||||
} |
||||
.onChange(of: initialValueLeft) { newValue in |
||||
valueLeft = initialValueLeft ?? 0 |
||||
} |
||||
.onChange(of: initialValueRight) { newValue in |
||||
valueRight = initialValueRight ?? 0 |
||||
} |
||||
.onAppear { |
||||
valueLeft = initialValueLeft ?? 0 |
||||
valueRight = initialValueRight ?? 0 |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,23 @@ |
||||
// |
||||
// MatchTypeSmallSelectionView.swift |
||||
// PadelClub |
||||
// |
||||
// Created by Razmig Sarkissian on 02/04/2024. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct MatchTypeSmallSelectionView: View { |
||||
@Binding var selectedFormat: MatchFormat |
||||
let format: String |
||||
|
||||
var body: some View { |
||||
Picker(selection: $selectedFormat) { |
||||
ForEach(MatchFormat.allCases, id: \.rawValue) { matchFormat in |
||||
Text(format + " " + matchFormat.format) |
||||
.tag(matchFormat) |
||||
} |
||||
} label: { |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,26 @@ |
||||
// |
||||
// TabItemModifier.swift |
||||
// PadelClub |
||||
// |
||||
// Created by Razmig Sarkissian on 02/04/2024. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct TabItemModifier: ViewModifier { |
||||
let tabDestination: TabDestination |
||||
|
||||
func body(content: Content) -> some View { |
||||
content |
||||
.tabItem { |
||||
Label(tabDestination.title, systemImage: tabDestination.image) |
||||
} |
||||
.tag(tabDestination as TabDestination?) |
||||
} |
||||
} |
||||
|
||||
extension View { |
||||
func tabItem(for tabDestination: TabDestination) -> some View { |
||||
modifier(TabItemModifier(tabDestination: tabDestination)) |
||||
} |
||||
} |
||||
Loading…
Reference in new issue