fix search stuff

sync2
Raz 1 year ago
parent b2f38febc8
commit 6f929c44cf
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 23
      PadelClub/Data/PlayerRegistration.swift
  3. 1
      PadelClub/Data/TeamRegistration.swift
  4. 2
      PadelClub/Views/Player/Components/PlayerPopoverView.swift
  5. 2
      PadelClub/Views/Shared/SelectablePlayerListView.swift
  6. 17
      PadelClub/Views/Team/Components/TeamWeightView.swift
  7. 67
      PadelClub/Views/Tournament/Screen/AddTeamView.swift

@ -3295,7 +3295,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 9;
CURRENT_PROJECT_VERSION = 12;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
@ -3337,7 +3337,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 9;
CURRENT_PROJECT_VERSION = 12;
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6;

@ -73,6 +73,7 @@ final class PlayerRegistration: ModelObject, Storable {
self.ligueName = importedPlayer.ligueName
self.assimilation = importedPlayer.assimilation
self.source = .frenchFederation
self.birthdate = importedPlayer.birthYear
}
internal init?(federalData: [String], sex: Int, sexUnknown: Bool) {
@ -123,19 +124,17 @@ final class PlayerRegistration: ModelObject, Storable {
var computedAge: Int? {
if let birthdate {
let components = birthdate.components(separatedBy: "/")
if components.count == 3 {
if let age = components.last, let ageInt = Int(age) {
let year = Calendar.current.getSportAge()
if age.count == 2 { //si l'année est sur 2 chiffres dans le fichier
if ageInt < 23 {
return year - 2000 - ageInt
} else {
return year - 2000 + 100 - ageInt
}
} else { //si l'année est représenté sur 4 chiffres
return year - ageInt
if let age = components.last, let ageInt = Int(age) {
let year = Calendar.current.getSportAge()
if age.count == 2 { //si l'année est sur 2 chiffres dans le fichier
if ageInt < 23 {
return year - 2000 - ageInt
} else {
return year - 2000 + 100 - ageInt
}
} else { //si l'année est représenté sur 4 chiffres
return year - ageInt
}
}
}

@ -242,6 +242,7 @@ final class TeamRegistration: ModelObject, Storable {
let arrayOfIds : [String] = unsortedPlayers().compactMap({ $0.licenceId?.strippedLicense?.canonicalVersion })
let ids : Set<String> = Set<String>(arrayOfIds.sorted())
let searchedIds = Set<String>(playerLicenses.compactMap({ $0?.strippedLicense?.canonicalVersion }).sorted())
if ids.isEmpty || searchedIds.isEmpty { return false }
return ids.hashValue == searchedIds.hashValue
}

@ -31,7 +31,7 @@ struct PlayerPopoverView: View {
@State private var source: String?
init(source: String?, sex: Int, requiredField: [PlayerCreationField] = [], creationCompletionHandler: @escaping (PlayerRegistration) -> Void) {
init(source: String? = nil, sex: Int, requiredField: [PlayerCreationField] = [], creationCompletionHandler: @escaping (PlayerRegistration) -> Void) {
if let source {
let words = source.components(separatedBy: .whitespaces)
if words.isEmpty == false {

@ -1033,7 +1033,7 @@ struct MySearchView: View {
Text(searchViewModel.contentUnavailableMessage)
} actions: {
RowButtonView("Lancer une nouvelle recherche") {
RowButtonView("Nouvelle recherche") {
searchViewModel.debouncableText = ""
}
.padding()

@ -8,17 +8,16 @@
import SwiftUI
struct TeamWeightView: View {
var team: TeamRegistration
@EnvironmentObject var dataStore: DataStore
let team: TeamRegistration
var teamPosition: TeamPosition? = nil
var teamIndex: Int?
var displayWeight: Bool = true
init(team: TeamRegistration, teamPosition: TeamPosition? = nil) {
self.team = team
self.teamPosition = teamPosition
let tournament = team.tournamentObject()
self.teamIndex = tournament?.indexOf(team: team)
self.displayWeight = tournament?.hideWeight() == false
var teamIndex: Int? {
team.tournamentObject()?.indexOf(team: team)
}
var displayWeight: Bool {
team.tournamentObject()?.hideWeight() == false
}
var body: some View {

@ -7,16 +7,15 @@
import SwiftUI
import LeStorage
import CoreData
struct AddTeamView: View {
@EnvironmentObject var dataStore: DataStore
@Environment(\.dismiss) var dismiss
@FetchRequest(
sortDescriptors: [],
animation: .default)
private var fetchPlayers: FetchedResults<ImportedPlayer>
private var fetchRequest: FetchRequest<ImportedPlayer>
private var fetchPlayers: FetchedResults<ImportedPlayer> { fetchRequest.wrappedValue }
var tournament: Tournament
var cancelShouldDismiss: Bool = false
@ -69,14 +68,19 @@ struct AddTeamView: View {
_createdPlayerIds = .init(wrappedValue: createdPlayerIds)
}
let request: NSFetchRequest<ImportedPlayer> = ImportedPlayer.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(keyPath: \ImportedPlayer.rank, ascending: true)]
request.fetchLimit = 1000
if let pasteString {
_pasteString = .init(wrappedValue: pasteString)
_fetchPlayers = FetchRequest<ImportedPlayer>(sortDescriptors: [NSSortDescriptor(keyPath: \ImportedPlayer.rank, ascending: true)], predicate: SearchViewModel.pastePredicate(pasteField: pasteString, mostRecentDate: tournament.rankSourceDate, filterOption: tournament.tournamentCategory.playerFilterOption))
request.predicate = SearchViewModel.pastePredicate(pasteField: pasteString, mostRecentDate: tournament.rankSourceDate, filterOption: tournament.tournamentCategory.playerFilterOption)
_autoSelect = .init(wrappedValue: true)
_editableTextField = .init(wrappedValue: pasteString)
_textHeight = .init(wrappedValue: Self._calculateHeight(text: pasteString))
cancelShouldDismiss = true
}
fetchRequest = FetchRequest(fetchRequest: request, animation: .default)
}
var body: some View {
@ -138,12 +142,9 @@ struct AddTeamView: View {
} message: {
Text("Cette équipe existe déjà dans votre liste d'inscription.")
}
.sheet(isPresented: $presentPlayerSearch, onDismiss: {
selectionSearchField = nil
}) {
.sheet(isPresented: $presentPlayerSearch) {
NavigationStack {
SelectablePlayerListView(allowSelection: -1, searchField: searchField, filterOption: _filterOption(), showFemaleInMaleAssimilation: tournament.tournamentCategory.showFemaleInMaleAssimilation) { players in
selectionSearchField = nil
players.forEach { player in
let newPlayer = PlayerRegistration(importedPlayer: player)
newPlayer.setComputedRank(in: tournament)
@ -151,15 +152,24 @@ struct AddTeamView: View {
createdPlayerIds.insert(newPlayer.id)
}
} contentUnavailableAction: { searchViewModel in
selectionSearchField = searchViewModel.searchText
presentPlayerSearch = false
presentPlayerCreation = true
selectionSearchField = searchViewModel.searchText
}
}
.tint(.master)
}
.sheet(isPresented: $presentPlayerCreation) {
PlayerPopoverView(source: _searchSource(), sex: _addPlayerSex()) { p in
PlayerPopoverView(sex: _addPlayerSex()) { p in
p.setComputedRank(in: tournament)
createdPlayers.insert(p)
createdPlayerIds.insert(p.id)
}
.tint(.master)
}
.sheet(item: $selectionSearchField, onDismiss: {
selectionSearchField = nil
}) { selectionSearchField in
PlayerPopoverView(source: selectionSearchField, sex: _addPlayerSex()) { p in
p.setComputedRank(in: tournament)
createdPlayers.insert(p)
createdPlayerIds.insert(p.id)
@ -235,7 +245,11 @@ struct AddTeamView: View {
Section {
RowButtonView("Créer un non classé / non licencié") {
presentPlayerCreation = true
if let pasteString, pasteString.isEmpty == false {
selectionSearchField = pasteString
} else {
presentPlayerCreation = true
}
}
} footer: {
Text("Si le joueur n'a pas encore de licence ou n'a pas encore participé à une compétition, vous pouvez le créer vous-même.")
@ -258,10 +272,6 @@ struct AddTeamView: View {
return tournament.tournamentCategory.playerFilterOption
}
private func _searchSource() -> String? {
selectionSearchField ?? pasteString
}
private func _currentSelection() -> Set<PlayerRegistration> {
var currentSelection = Set<PlayerRegistration>()
createdPlayerIds.compactMap { id in
@ -437,9 +447,11 @@ struct AddTeamView: View {
VStack(alignment: .leading, spacing: 0) {
if let player = unsortedPlayers.first(where: { ($0.licenceId == p.licenceId && $0.licenceId != nil) }), editedTeam?.includes(player: player) == false {
Text("Déjà inscrit !").foregroundStyle(.logoRed).bold()
} else if tournament.isPlayerAgeInadequate(player: p) {
}
if tournament.isPlayerAgeInadequate(player: p) {
Text("Âge invalide !").foregroundStyle(.logoRed).bold()
} else if tournament.isPlayerRankInadequate(player: p) {
}
if tournament.isPlayerRankInadequate(player: p) {
Text("Trop bien classé !").foregroundStyle(.logoRed).bold()
}
PlayerView(player: p).tag(p.id)
@ -450,9 +462,11 @@ struct AddTeamView: View {
VStack(alignment: .leading, spacing: 0) {
if let pasteString, pasteString.isEmpty == false, unsortedPlayers.first(where: { $0.licenceId == p.license }) != nil {
Text("Déjà inscrit !").foregroundStyle(.logoRed).bold()
} else if tournament.isPlayerAgeInadequate(player: p) {
}
if tournament.isPlayerAgeInadequate(player: p) {
Text("Âge invalide !").foregroundStyle(.logoRed).bold()
} else if tournament.isPlayerRankInadequate(player: p) {
}
if tournament.isPlayerRankInadequate(player: p) {
Text("Trop bien classé !").foregroundStyle(.logoRed).bold()
}
ImportedPlayerView(player: p).tag(p.license!)
@ -515,7 +529,7 @@ struct AddTeamView: View {
Text("Aucun joueur classé n'a été trouvé dans ce message. Attention, si un joueur n'a pas joué de tournoi dans les 12 derniers, Padel Club ne pourra pas le trouver.")
} actions: {
RowButtonView("Créer un joueur non classé") {
presentPlayerCreation = true
selectionSearchField = pasteString
}
RowButtonView("Chercher dans la base") {
@ -584,16 +598,17 @@ struct AddTeamView: View {
@MainActor
private func handlePasteString(_ first: String) {
if first.isEmpty == false {
fetchPlayers.nsPredicate = SearchViewModel.pastePredicate(pasteField: first, mostRecentDate: SourceFileManager.shared.mostRecentDateAvailable, filterOption: _filterOption())
fetchPlayers.nsSortDescriptors = [NSSortDescriptor(keyPath: \ImportedPlayer.rank, ascending: true)]
autoSelect = true
DispatchQueue.main.async {
fetchPlayers.nsPredicate = SearchViewModel.pastePredicate(pasteField: first, mostRecentDate: SourceFileManager.shared.mostRecentDateAvailable, filterOption: _filterOption())
fetchPlayers.nsSortDescriptors = [NSSortDescriptor(keyPath: \ImportedPlayer.rank, ascending: true)]
autoSelect = true
}
}
pasteString = first
editableTextField = first
textHeight = Self._calculateHeight(text: first)
}
@ViewBuilder
private func _listOfPlayers(searchFilteredPlayers: [ImportedPlayer], pasteString: String) -> some View {
let sortedPlayers = _sortedPlayers(searchFilteredPlayers: searchFilteredPlayers, pasteString: pasteString)

Loading…
Cancel
Save