club_update
Raz 1 year ago
parent 3c57358fdc
commit b815b210b7
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 16
      PadelClub/Data/GroupStage.swift
  3. 10
      PadelClub/Data/TeamRegistration.swift
  4. 56
      PadelClub/Views/GroupStage/GroupStageView.swift
  5. 4
      PadelClub/Views/Navigation/Agenda/ActivityView.swift
  6. 41
      PadelClub/Views/Round/RoundView.swift
  7. 11
      PadelClub/Views/ViewModifiers/ListRowViewModifier.swift

@ -1909,6 +1909,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 92;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
@ -1939,6 +1940,7 @@
OTHER_SWIFT_FLAGS = "-Onone";
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
@ -1953,6 +1955,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 92;
DEFINES_MODULE = YES;
@ -1981,6 +1984,7 @@
OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-function-bodies=5 -Xfrontend -warn-long-expression-type-checking=20 -Xfrontend -warn-long-function-bodies=50";
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;

@ -200,7 +200,7 @@ final class GroupStage: ModelObject, Storable {
return _matches().first(where: { matchIndexes.contains($0.index) })
}
func availableToStart(playedMatches: [Match], in runningMatches: [Match]) async -> [Match] {
func availableToStart(playedMatches: [Match], in runningMatches: [Match]) -> [Match] {
#if DEBUG_TIME //DEBUGING TIME
let start = Date()
defer {
@ -222,19 +222,7 @@ final class GroupStage: ModelObject, Storable {
return playedMatches.filter({ $0.isRunning() }).sorted(by: \.computedStartDateForSorting)
}
func asyncRunningMatches(playedMatches: [Match]) async -> [Match] {
#if DEBUG_TIME //DEBUGING TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func group stage runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
return playedMatches.filter({ $0.isRunning() }).sorted(by: \.computedStartDateForSorting)
}
func readyMatches(playedMatches: [Match]) async -> [Match] {
func readyMatches(playedMatches: [Match]) -> [Match] {
#if DEBUG_TIME //DEBUGING TIME
let start = Date()
defer {

@ -76,9 +76,9 @@ final class TeamRegistration: ModelObject, Storable {
self.tournamentStore.teamScores.deleteDependencies(self.teamScores())
}
func hasArrived() {
func hasArrived(isHere: Bool = false) {
let unsortedPlayers = unsortedPlayers()
unsortedPlayers.forEach({ $0.hasArrived = true })
unsortedPlayers.forEach({ $0.hasArrived = !isHere })
do {
try self.tournamentStore.playerRegistrations.addOrUpdate(contentOfs: unsortedPlayers)
} catch {
@ -86,6 +86,12 @@ final class TeamRegistration: ModelObject, Storable {
}
}
func isHere() -> Bool {
let unsortedPlayers = unsortedPlayers()
return unsortedPlayers.allSatisfy({ $0.hasArrived })
}
func isSeedable() -> Bool {
bracketPosition == nil && groupStage == nil
}

@ -20,10 +20,6 @@ struct GroupStageView: View {
@State private var confirmResetMatch: Bool = false
let playedMatches: [Match]
@State private var runningMatches: [Match]?
@State private var readyMatches: [Match]?
@State private var availableToStart: [Match]?
init(groupStage: GroupStage) {
self.groupStage = groupStage
self.playedMatches = groupStage.playedMatches()
@ -55,16 +51,14 @@ struct GroupStageView: View {
}
.headerProminence(.increased)
MatchListView(section: "en cours", matches: runningMatches, hideWhenEmpty: true)
let runningMatches = groupStage.runningMatches(playedMatches: playedMatches)
MatchListView(section: "en cours", matches: groupStage.runningMatches(playedMatches: playedMatches), hideWhenEmpty: true)
let availableToStart = groupStage.availableToStart(playedMatches: playedMatches, in: runningMatches)
MatchListView(section: "prêt à démarrer", matches: availableToStart, hideWhenEmpty: true)
MatchListView(section: "à lancer", matches: self.readyMatches, hideWhenEmpty: true)
.listRowView(isActive: availableToStart.isEmpty == false, color: .green, hideColorVariation: true)
MatchListView(section: "à lancer", matches: groupStage.readyMatches(playedMatches: playedMatches), hideWhenEmpty: true)
MatchListView(section: "terminés", matches: groupStage.finishedMatches(playedMatches: playedMatches), isExpanded: false)
}
.task {
self.runningMatches = await groupStage.asyncRunningMatches(playedMatches: playedMatches)
self.readyMatches = await groupStage.readyMatches(playedMatches: playedMatches)
self.availableToStart = await groupStage.availableToStart(playedMatches: playedMatches, in: runningMatches ?? [])
}
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
_groupStageMenuView()
@ -148,6 +142,11 @@ struct GroupStageView: View {
}
ForEach(team.players()) { player in
Text(player.playerLabel()).lineLimit(1)
.overlay {
if player.hasArrived && team.isHere() == false {
Color.logoYellow.opacity(0.6)
}
}
}
}
Spacer()
@ -175,12 +174,43 @@ struct GroupStageView: View {
}
}
.contextMenu {
Button("équipe présente") {
team.hasArrived()
let teamHasArrived = team.isHere()
Button {
team.hasArrived(isHere: teamHasArrived)
} label: {
if teamHasArrived {
Label("équipe présente", systemImage: "checkmark").foregroundStyle(.green)
} else {
Text("équipe présente")
}
}
Divider()
Section {
ForEach(team.players()) { player in
Button {
player.hasArrived.toggle()
do {
try self.tournamentStore.playerRegistrations.addOrUpdate(instance: player)
} catch {
Logger.error(error)
}
} label: {
if player.hasArrived {
Label("\(player.playerLabel())", systemImage: "checkmark")
} else {
Text("\(player.playerLabel())")
}
}
}
} header: {
Text("Joueur présent")
}
}
}
.listRowView(isActive: team.qualified, color: .master)
.listRowView(isActive: team.isHere(), color: .green, hideColorVariation: true)
} else {
VStack(alignment: .leading, spacing: 0) {
Text("#\(index + 1)")

@ -110,12 +110,14 @@ struct ActivityView: View {
self.error = nil
}
}
.padding()
} else if isGatheringFederalTournaments {
ProgressView()
} else {
if tournaments.isEmpty && viewStyle == .list {
if searchText.isEmpty == false {
ContentUnavailableView.search(text: searchText)
.padding()
} else if federalDataViewModel.areFiltersEnabled() {
ContentUnavailableView {
Text("Aucun résultat")
@ -126,8 +128,10 @@ struct ActivityView: View {
federalDataViewModel.removeFilters()
}
}
.padding()
} else {
_dataEmptyView()
.padding()
}
}
}

@ -157,15 +157,22 @@ struct RoundView: View {
}
if availableQualifiedTeams.isEmpty == false {
if spaceLeft.isEmpty == false {
let qualifiedOnSeedSpot = (spaceLeft.isEmpty || tournament.seeds().isEmpty) ? true : false
let availableSeedSpot : [any SpinDrawable] = qualifiedOnSeedSpot ? (seedSpaceLeft + spaceLeft).flatMap({ $0.matchSpots() }).filter({ $0.match.team( $0.teamPosition) == nil }) : spaceLeft
if availableSeedSpot.isEmpty == false {
Section {
DisclosureGroup {
ForEach(availableQualifiedTeams) { team in
NavigationLink {
SpinDrawView(drawees: [team], segments: spaceLeft) { results in
SpinDrawView(drawees: [team], segments: availableSeedSpot) { results in
Task {
results.forEach { drawResult in
team.setSeedPosition(inSpot: spaceLeft[drawResult.drawIndex], slot: nil, opposingSeeding: true)
if let matchSpot : MatchSpot = availableSeedSpot[drawResult.drawIndex] as? MatchSpot {
team.setSeedPosition(inSpot: matchSpot.match, slot: matchSpot.teamPosition, opposingSeeding: false)
} else if let matchSpot : Match = availableSeedSpot[drawResult.drawIndex] as? Match {
team.setSeedPosition(inSpot: matchSpot, slot: nil, opposingSeeding: true)
}
}
_save()
if tournament.availableSeeds().isEmpty && tournament.availableQualifiedTeams().isEmpty {
@ -357,3 +364,31 @@ struct RoundView: View {
// RoundView(round: Round.mock())
// .environment(Tournament.mock())
//}
struct MatchSpot: SpinDrawable {
let match: Match
let teamPosition: TeamPosition
func segmentLabel(_ displayStyle: DisplayStyle) -> [String] {
[match.roundTitle(), matchTitle(displayStyle: displayStyle)].compactMap { $0 }
}
func matchTitle(displayStyle: DisplayStyle) -> String {
[match.matchTitle(displayStyle), teamPositionLabel()].joined(separator: " - ")
}
func teamPositionLabel() -> String {
switch teamPosition {
case .one:
return "haut"
case .two:
return "bas"
}
}
}
extension Match {
func matchSpots() -> [MatchSpot] {
[MatchSpot(match: self, teamPosition: .one), MatchSpot(match: self, teamPosition: .two)]
}
}

@ -10,12 +10,17 @@ import SwiftUI
struct ListRowViewModifier: ViewModifier {
let isActive: Bool
let color: Color
var hideColorVariation: Bool = false
func colorVariation() -> Color {
hideColorVariation ? Color(uiColor: .systemBackground) : color.variation()
}
func body(content: Content) -> some View {
if isActive {
content
.listRowBackground(
color.variation()
colorVariation()
.overlay(alignment: .leading, content: {
color.frame(width: 8)
})
@ -27,7 +32,7 @@ struct ListRowViewModifier: ViewModifier {
}
extension View {
func listRowView(isActive: Bool = false, color: Color) -> some View {
modifier(ListRowViewModifier(isActive: isActive, color: color))
func listRowView(isActive: Bool = false, color: Color, hideColorVariation: Bool = false) -> some View {
modifier(ListRowViewModifier(isActive: isActive, color: color, hideColorVariation: hideColorVariation))
}
}

Loading…
Cancel
Save