Merge branch 'main'

release
Raz 1 year ago
commit e318df1eb5
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 8
      PadelClub/Data/TeamRegistration.swift
  3. 2
      PadelClub/Data/Tournament.swift
  4. 45
      PadelClub/Utils/Patcher.swift
  5. 47
      PadelClub/Views/Calling/TeamsCallingView.swift
  6. 2
      PadelClub/Views/Navigation/Umpire/UmpireView.swift
  7. 5
      PadelClub/Views/Shared/ImportedPlayerView.swift
  8. 12
      PadelClub/Views/Shared/SelectablePlayerListView.swift
  9. 16
      PadelClub/Views/Team/EditingTeamView.swift
  10. 11
      PadelClub/Views/Tournament/Screen/BroadcastView.swift

@ -1985,7 +1985,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.5;
MARKETING_VERSION = 1.0.6;
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
OTHER_SWIFT_FLAGS = "-Onone";
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
@ -2033,7 +2033,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.5;
MARKETING_VERSION = 1.0.6;
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
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;

@ -498,6 +498,14 @@ final class TeamRegistration: ModelObject, Storable {
return self.tournamentStore.matches.first(where: { $0.round == initialRoundObject.id && $0.index == bracketPosition / 2 })
}
func toggleSummonConfirmation() {
if confirmationDate == nil { confirmationDate = Date() }
else { confirmationDate = nil }
}
func didConfirmSummon() -> Bool {
confirmationDate != nil
}
func tournamentObject() -> Tournament? {
return Store.main.findById(tournament)

@ -113,7 +113,7 @@ final class Tournament : ModelObject, Storable {
self.startDate = startDate
self.endDate = endDate
self.creationDate = creationDate
self.isPrivate = isPrivate
self.isPrivate = Guard.main.purchasedTransactions.isEmpty
self.groupStageFormat = groupStageFormat
self.roundFormat = roundFormat
self.loserRoundFormat = loserRoundFormat

@ -15,6 +15,7 @@ enum PatchError: Error {
enum Patch: String, CaseIterable {
case alexisLeDu
case importDataFromDevToProd
case fixMissingMatches
var id: String {
return "padelclub.app.patch.\(self.rawValue)"
@ -45,6 +46,7 @@ class Patcher {
switch patch {
case .alexisLeDu: self._patchAlexisLeDu()
case .importDataFromDevToProd: try self._importDataFromDev()
case .fixMissingMatches: self._patchMissingMatches()
}
}
@ -116,4 +118,47 @@ class Patcher {
}
fileprivate static func _patchMissingMatches() {
guard let url = StoreCenter.main.synchronizationApiURL else {
return
}
guard url == "https://padelclub.app/roads/" else {
return
}
let services = Services(url: url)
for tournament in DataStore.shared.tournaments {
let store = tournament.tournamentStore
let identifier = StoreIdentifier(value: tournament.id, parameterName: "tournament")
Task {
do {
// if nothing is online we upload the data
let matches: [Match] = try await services.get(identifier: identifier)
if matches.isEmpty {
store.matches.insertAllIntoCurrentService()
}
let playerRegistrations: [PlayerRegistration] = try await services.get(identifier: identifier)
if playerRegistrations.isEmpty {
store.playerRegistrations.insertAllIntoCurrentService()
}
let teamScores: [TeamScore] = try await services.get(identifier: identifier)
if teamScores.isEmpty {
store.teamScores.insertAllIntoCurrentService()
}
} catch {
Logger.error(error)
}
}
}
}
}

@ -6,6 +6,7 @@
//
import SwiftUI
import LeStorage
struct TeamsCallingView: View {
@Environment(Tournament.self) var tournament: Tournament
@ -15,7 +16,23 @@ struct TeamsCallingView: View {
let teams = tournament.selectedSortedTeams()
Section {
ForEach(teams) { team in
Menu {
_menuOptions(team: team)
} label: {
HStack {
TeamRowView(team: team, displayCallDate: true)
if team.called() {
Spacer()
Menu {
_menuOptions(team: team)
} label: {
LabelOptions().labelStyle(.iconOnly)
}
}
}
}
.buttonStyle(.plain)
.listRowView(isActive: team.didConfirmSummon(), color: .green, hideColorVariation: true)
}
}
}
@ -25,4 +42,34 @@ struct TeamsCallingView: View {
.toolbarBackground(.visible, for: .navigationBar)
}
@ViewBuilder
func _menuOptions(team: TeamRegistration) -> some View {
Button {
team.toggleSummonConfirmation()
do {
try self.tournament.tournamentStore.teamRegistrations.addOrUpdate(instance: team)
} catch {
Logger.error(error)
}
} label: {
if team.didConfirmSummon() {
Label("Confirmation reçue", systemImage: "checkmark.circle.fill").foregroundStyle(.green)
} else {
Label("Confirmation reçue", systemImage: "circle").foregroundStyle(.logoRed)
}
}
Divider()
Button(role: .destructive) {
team.callDate = nil
do {
try self.tournament.tournamentStore.teamRegistrations.addOrUpdate(instance: team)
} catch {
Logger.error(error)
}
} label: {
Text("Effacer la date de convocation")
}
}
}

@ -56,7 +56,7 @@ struct UmpireView: View {
Section {
if let currentPlayerData {
//todo palmares
ImportedPlayerView(player: currentPlayerData)
ImportedPlayerView(player: currentPlayerData, showProgression: true)
// NavigationLink {
//
// } label: {

@ -11,7 +11,7 @@ struct ImportedPlayerView: View {
let player: PlayerHolder
var index: Int? = nil
var showFemaleInMaleAssimilation: Bool = false
@State var showProgression: Bool = false
var showProgression: Bool = false
var body: some View {
VStack(alignment: .leading) {
@ -54,7 +54,7 @@ struct ImportedPlayerView: View {
}
}
if player.getProgression() != 0 {
if showProgression, player.getProgression() != 0 {
HStack(alignment: .top, spacing: 2) {
Text("(")
Text(player.getProgression().formatted(.number.sign(strategy: .always())))
@ -77,6 +77,7 @@ struct ImportedPlayerView: View {
}
}
}
.lineLimit(1)
if showFemaleInMaleAssimilation, let assimilatedAsMaleRank = player.getAssimilatedAsMaleRank() {
HStack(alignment: .top, spacing: 2) {

@ -364,7 +364,7 @@ struct MySearchView: View {
let array = Array(searchViewModel.selectedPlayers)
Section {
ForEach(array) { player in
ImportedPlayerView(player: player, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation)
ImportedPlayerView(player: player, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation, showProgression: true)
}
.onDelete { indexSet in
for index in indexSet {
@ -379,7 +379,7 @@ struct MySearchView: View {
} else {
Section {
ForEach(players, id: \.self) { player in
ImportedPlayerView(player: player, index: nil, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation)
ImportedPlayerView(player: player, index: nil, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation, showProgression: true)
}
} header: {
if players.isEmpty == false {
@ -398,7 +398,7 @@ struct MySearchView: View {
Button {
searchViewModel.selectedPlayers.insert(player)
} label: {
ImportedPlayerView(player: player, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation)
ImportedPlayerView(player: player, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation, showProgression: true)
}
.buttonStyle(.plain)
}
@ -412,7 +412,7 @@ struct MySearchView: View {
Section {
ForEach(players.indices, id: \.self) { index in
let player = players[index]
ImportedPlayerView(player: player, index: searchViewModel.showIndex() ? (index + 1) : nil, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation)
ImportedPlayerView(player: player, index: searchViewModel.showIndex() ? (index + 1) : nil, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation, showProgression: true)
}
} header: {
if players.isEmpty == false {
@ -429,13 +429,13 @@ struct MySearchView: View {
Button {
searchViewModel.selectedPlayers.insert(player)
} label: {
ImportedPlayerView(player: player, index: searchViewModel.showIndex() ? (index + 1) : nil, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation)
ImportedPlayerView(player: player, index: searchViewModel.showIndex() ? (index + 1) : nil, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation, showProgression: true)
.contentShape(Rectangle())
}
.frame(maxWidth: .infinity)
.buttonStyle(.plain)
} else {
ImportedPlayerView(player: player, index: searchViewModel.showIndex() ? (index + 1) : nil, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation)
ImportedPlayerView(player: player, index: searchViewModel.showIndex() ? (index + 1) : nil, showFemaleInMaleAssimilation: searchViewModel.showFemaleInMaleAssimilation, showProgression: true)
}
}
} header: {

@ -76,6 +76,22 @@ struct EditingTeamView: View {
} label: {
Text("Convocation")
}
Button {
team.toggleSummonConfirmation()
do {
try self.tournament.tournamentStore.teamRegistrations.addOrUpdate(instance: team)
} catch {
Logger.error(error)
}
} label: {
if team.didConfirmSummon() {
Label("Confirmation reçue", systemImage: "checkmark.circle.fill").foregroundStyle(.green)
} else {
Label("Confirmation reçue", systemImage: "circle").foregroundStyle(.logoRed)
}
}
} else {
Text("Cette équipe n'a pas été convoquée")
}

@ -108,9 +108,18 @@ struct BroadcastView: View {
Section {
Toggle(isOn: $tournament.isPrivate) {
Text("Tournoi privé")
if (tournament.isPrivate && Guard.main.purchasedTransactions.isEmpty) {
Text("Vous devez disposer d'une offre pour rendre publique ce tournoi.")
.foregroundStyle(.logoRed)
}
}
#if DEBUG
#else
.disabled((tournament.isPrivate && Guard.main.purchasedTransactions.isEmpty))
#endif
} footer: {
let footerString = "Le tournoi sera masqué sur le site [Padel Club](\(URLs.main.rawValue))"
let verb : String = tournament.isPrivate ? "est" : "sera"
let footerString = " Le tournoi \(verb) masqué sur le site [Padel Club](\(URLs.main.rawValue))"
Text(.init(footerString))
}

Loading…
Cancel
Save