diff --git a/PadelClub.xcodeproj/project.pbxproj b/PadelClub.xcodeproj/project.pbxproj index 91e2516..89222c8 100644 --- a/PadelClub.xcodeproj/project.pbxproj +++ b/PadelClub.xcodeproj/project.pbxproj @@ -3434,6 +3434,7 @@ INFOPLIST_KEY_CFBundleDisplayName = "Padel Club (ProdTest)"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.sports"; INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES; + INFOPLIST_KEY_NSCalendarsUsageDescription = "Padel Club a besoin d'avoir accès à votre calendrier pour pouvoir y inscrire ce tournoi"; INFOPLIST_KEY_NSCameraUsageDescription = "En autorisant l'application à utiliser la caméra, vous pourrez prendre des photos des rencontres"; INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Padel Club a besoin de votre position pour rechercher les clubs autour de vous."; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; @@ -3477,6 +3478,7 @@ INFOPLIST_KEY_CFBundleDisplayName = "Padel Club (ProdTest)"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.sports"; INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES; + INFOPLIST_KEY_NSCalendarsUsageDescription = "Padel Club a besoin d'avoir accès à votre calendrier pour pouvoir y inscrire ce tournoi"; INFOPLIST_KEY_NSCameraUsageDescription = "En autorisant l'application à utiliser la caméra, vous pourrez prendre des photos des rencontres"; INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Padel Club a besoin de votre position pour rechercher les clubs autour de vous."; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; @@ -3521,6 +3523,7 @@ INFOPLIST_KEY_CFBundleDisplayName = "Padel Club (Beta)"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.sports"; INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES; + INFOPLIST_KEY_NSCalendarsUsageDescription = "Padel Club a besoin d'avoir accès à votre calendrier pour pouvoir y inscrire ce tournoi"; INFOPLIST_KEY_NSCameraUsageDescription = "En autorisant l'application à utiliser la caméra, vous pourrez prendre des photos des rencontres"; INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Padel Club a besoin de votre position pour rechercher les clubs autour de vous."; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; @@ -3562,6 +3565,7 @@ INFOPLIST_KEY_CFBundleDisplayName = "Padel Club (Beta)"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.sports"; INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES; + INFOPLIST_KEY_NSCalendarsUsageDescription = "Padel Club a besoin d'avoir accès à votre calendrier pour pouvoir y inscrire ce tournoi"; INFOPLIST_KEY_NSCameraUsageDescription = "En autorisant l'application à utiliser la caméra, vous pourrez prendre des photos des rencontres"; INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Padel Club a besoin de votre position pour rechercher les clubs autour de vous."; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; diff --git a/PadelClub/Data/Federal/FederalTournament.swift b/PadelClub/Data/Federal/FederalTournament.swift index e61f36c..003218e 100644 --- a/PadelClub/Data/Federal/FederalTournament.swift +++ b/PadelClub/Data/Federal/FederalTournament.swift @@ -239,7 +239,7 @@ struct CategorieAge: Codable { return FederalTournamentAge(rawValue: id) } if let libelle { - return FederalTournamentAge.allCases.first(where: { $0.localizedLabel().localizedCaseInsensitiveContains(libelle) }) + return FederalTournamentAge.allCases.first(where: { $0.localizedFederalAgeLabel().localizedCaseInsensitiveContains(libelle) }) } return nil } diff --git a/PadelClub/Data/Tournament.swift b/PadelClub/Data/Tournament.swift index 132db89..b55e575 100644 --- a/PadelClub/Data/Tournament.swift +++ b/PadelClub/Data/Tournament.swift @@ -1494,7 +1494,7 @@ defer { return tournamentLevel.localizedLevelLabel(.title) } } - let title: String = [tournamentLevel.localizedLevelLabel(displayStyle), tournamentCategory.localizedLabel(displayStyle), federalTournamentAge.localizedLabel(displayStyle)].filter({ $0.isEmpty == false }).joined(separator: " ") + let title: String = [tournamentLevel.localizedLevelLabel(displayStyle), tournamentCategory.localizedLabel(displayStyle), federalTournamentAge.localizedFederalAgeLabel(displayStyle)].filter({ $0.isEmpty == false }).joined(separator: " ") if displayStyle == .wide, let name { return [title, name].joined(separator: " - ") } else { @@ -2537,7 +2537,7 @@ extension Tournament: FederalTournamentHolder { func subtitleLabel(forBuild build: any TournamentBuildHolder) -> String { if isAnimation() { if displayAgeAndCategory(forBuild: build) == false { - return [build.category.localizedLabel(), build.age.localizedLabel()].filter({ $0.isEmpty == false }).joined(separator: " ") + return [build.category.localizedLabel(), build.age.localizedFederalAgeLabel()].filter({ $0.isEmpty == false }).joined(separator: " ") } else if name != nil { return build.level.localizedLevelLabel(.title) } else { diff --git a/PadelClub/Info.plist b/PadelClub/Info.plist index 40756ec..7b68d4a 100644 --- a/PadelClub/Info.plist +++ b/PadelClub/Info.plist @@ -33,7 +33,5 @@ ITSAppUsesNonExemptEncryption - UIFileSharingEnabled - diff --git a/PadelClub/Utils/PadelRule.swift b/PadelClub/Utils/PadelRule.swift index 9a4e040..4b21a3d 100644 --- a/PadelClub/Utils/PadelRule.swift +++ b/PadelClub/Utils/PadelRule.swift @@ -48,7 +48,7 @@ struct TournamentBuild: TournamentBuildHolder, Hashable, Codable, Identifiable { } var identifier: String { - level.localizedLevelLabel()+":"+category.localizedLabel()+":"+age.localizedLabel() + level.localizedLevelLabel()+":"+category.localizedLabel()+":"+age.localizedFederalAgeLabel() } func computedLabel(_ displayStyle: DisplayStyle = .wide) -> String { @@ -65,7 +65,7 @@ struct TournamentBuild: TournamentBuildHolder, Hashable, Codable, Identifiable { } func localizedAge(_ displayStyle: DisplayStyle = .wide) -> String { - age.localizedLabel(displayStyle) + age.localizedFederalAgeLabel(displayStyle) } } @@ -252,7 +252,7 @@ enum FederalTournamentAge: Int, Hashable, Codable, CaseIterable, Identifiable { } } - func localizedLabel(_ displayStyle: DisplayStyle = .wide) -> String { + func localizedFederalAgeLabel(_ displayStyle: DisplayStyle = .wide) -> String { switch self { case .unlisted: return displayStyle == .title ? "Aucune" : "" @@ -265,7 +265,7 @@ enum FederalTournamentAge: Int, Hashable, Codable, CaseIterable, Identifiable { case .a17_18: return "17/18 ans" case .senior: - return "Senior" + return displayStyle == .short ? "" : "Senior" case .a45: return "+45 ans" case .a55: @@ -274,7 +274,7 @@ enum FederalTournamentAge: Int, Hashable, Codable, CaseIterable, Identifiable { } var tournamentDescriptionLabel: String { - return localizedLabel() + return localizedFederalAgeLabel() } func isAgeValid(age: Int?) -> Bool { diff --git a/PadelClub/Utils/URLs.swift b/PadelClub/Utils/URLs.swift index 16e0fba..20e1013 100644 --- a/PadelClub/Utils/URLs.swift +++ b/PadelClub/Utils/URLs.swift @@ -50,6 +50,7 @@ enum URLs: String, Identifiable { } enum PageLink: String, Identifiable, CaseIterable { + case info = "Informations" case teams = "Équipes" case summons = "Convocations" case groupStages = "Poules" @@ -68,6 +69,8 @@ enum PageLink: String, Identifiable, CaseIterable { switch self { case .matches: return "" + case .info: + return "info" case .teams: return "teams" case .summons: diff --git a/PadelClub/ViewModel/FederalDataViewModel.swift b/PadelClub/ViewModel/FederalDataViewModel.swift index a5579b7..2ca3b2f 100644 --- a/PadelClub/ViewModel/FederalDataViewModel.swift +++ b/PadelClub/ViewModel/FederalDataViewModel.swift @@ -28,7 +28,7 @@ class FederalDataViewModel { var labels: [String] = [] labels.append(contentsOf: levels.map { $0.localizedLevelLabel() }.formatList()) labels.append(contentsOf: categories.map { $0.localizedLabel() }.formatList()) - labels.append(contentsOf: ageCategories.map { $0.localizedLabel() }.formatList()) + labels.append(contentsOf: ageCategories.map { $0.localizedFederalAgeLabel() }.formatList()) let clubNames = selectedClubs.compactMap { codeClub in let club: Club? = DataStore.shared.clubs.first(where: { $0.code == codeClub }) return club?.clubTitle(.short) diff --git a/PadelClub/Views/Cashier/Event/TournamentConfiguratorView.swift b/PadelClub/Views/Cashier/Event/TournamentConfiguratorView.swift index 9333ee9..30ec0f6 100644 --- a/PadelClub/Views/Cashier/Event/TournamentConfiguratorView.swift +++ b/PadelClub/Views/Cashier/Event/TournamentConfiguratorView.swift @@ -46,7 +46,7 @@ struct TournamentConfigurationView: View { } Picker(selection: $tournament.federalAgeCategory, label: Text("Limite d'âge")) { ForEach(FederalTournamentAge.allCases) { type in - Text(type.localizedLabel(.title)).tag(type) + Text(type.localizedFederalAgeLabel(.title)).tag(type) } } LabeledContent { diff --git a/PadelClub/Views/GroupStage/GroupStagesSettingsView.swift b/PadelClub/Views/GroupStage/GroupStagesSettingsView.swift index 3bf6939..6961bae 100644 --- a/PadelClub/Views/GroupStage/GroupStagesSettingsView.swift +++ b/PadelClub/Views/GroupStage/GroupStagesSettingsView.swift @@ -262,11 +262,15 @@ struct GroupStagesSettingsView: View { } .toolbar { ToolbarItem(placement: .topBarTrailing) { - ShareLink(item: tournament.groupStages().compactMap { $0.pasteData() }.joined(separator: "\n\n")) + ShareLink(item: groupStagesPaste(), preview: .init("Données des poules")) } } } + func groupStagesPaste() -> TournamentGroupStageShareContent { + TournamentGroupStageShareContent(tournament: tournament) + } + var menuBuildAllGroupStages: some View { RowButtonView("Refaire les poules", role: .destructive) { diff --git a/PadelClub/Views/Navigation/Agenda/TournamentLookUpView.swift b/PadelClub/Views/Navigation/Agenda/TournamentLookUpView.swift index 93e9aa6..783359c 100644 --- a/PadelClub/Views/Navigation/Agenda/TournamentLookUpView.swift +++ b/PadelClub/Views/Navigation/Agenda/TournamentLookUpView.swift @@ -369,7 +369,7 @@ struct TournamentLookUpView: View { NavigationLink { List([FederalTournamentAge.senior, FederalTournamentAge.a45, FederalTournamentAge.a55, FederalTournamentAge.a17_18, FederalTournamentAge.a15_16, FederalTournamentAge.a13_14, FederalTournamentAge.a11_12], selection: $appSettings.tournamentAges) { type in - Text(type.localizedLabel()) + Text(type.localizedFederalAgeLabel()) } .navigationTitle("Limites d'âge") .environment(\.editMode, Binding.constant(EditMode.active)) @@ -381,7 +381,7 @@ struct TournamentLookUpView: View { Text("Tous les âges") .foregroundStyle(.secondary) } else { - Text(ages.map({ $0.localizedLabel()}).joined(separator: ", ")) + Text(ages.map({ $0.localizedFederalAgeLabel()}).joined(separator: ", ")) .foregroundStyle(.secondary) } } diff --git a/PadelClub/Views/Navigation/Toolbox/ToolboxView.swift b/PadelClub/Views/Navigation/Toolbox/ToolboxView.swift index 114112d..487f80c 100644 --- a/PadelClub/Views/Navigation/Toolbox/ToolboxView.swift +++ b/PadelClub/Views/Navigation/Toolbox/ToolboxView.swift @@ -228,10 +228,9 @@ struct ToolboxView: View { ShareLink(item: URLs.appStore.url) { Label("Lien AppStore", systemImage: "link") } - if let zip = _getZip() { - ShareLink(item: zip) { - Label("Mes données", systemImage: "server.rack") - } + + ShareLink(item: ZipLog(), preview: .init("Mon archive")) { + Label("Mes données", systemImage: "server.rack") } } label: { Label("Partagez", systemImage: "square.and.arrow.up").labelStyle(.iconOnly) @@ -240,7 +239,14 @@ struct ToolboxView: View { } } } - +} + +//#Preview { +// ToolboxView() +//} + + +struct ZipLog: Transferable { private func _getZip() -> URL? { do { let filePath = try Club.storageDirectoryPath() @@ -250,8 +256,19 @@ struct ToolboxView: View { return nil } } -} -//#Preview { -// ToolboxView() -//} + func shareFile() -> URL? { + print("Generating URL...") + return _getZip() + } + + static var transferRepresentation: some TransferRepresentation { + FileRepresentation(exportedContentType: .zip) { transferable in + return SentTransferredFile(transferable.shareFile()!) + }.exportingCondition { $0.shareFile() != nil } + + ProxyRepresentation { transferable in + return transferable.shareFile()! + }.exportingCondition { $0.shareFile() != nil } + } +} diff --git a/PadelClub/Views/Round/RoundSettingsView.swift b/PadelClub/Views/Round/RoundSettingsView.swift index 42a45b4..2928a49 100644 --- a/PadelClub/Views/Round/RoundSettingsView.swift +++ b/PadelClub/Views/Round/RoundSettingsView.swift @@ -147,11 +147,16 @@ struct RoundSettingsView: View { } .toolbar { ToolbarItem(placement: .topBarTrailing) { - ShareLink(item: tournament.rounds().compactMap { $0.pasteData() }.joined(separator: "\n\n")) + ShareLink(item: roundsPaste(), preview: .init("Données du tableau")) } } } + func roundsPaste() -> TournamentRoundShareContent { + TournamentRoundShareContent(tournament: tournament) + } + + private func _removeAllSeeds() async { await tournament.removeAllSeeds() self.isEditingTournamentSeed.wrappedValue = true diff --git a/PadelClub/Views/Shared/SelectablePlayerListView.swift b/PadelClub/Views/Shared/SelectablePlayerListView.swift index 00a4836..352251d 100644 --- a/PadelClub/Views/Shared/SelectablePlayerListView.swift +++ b/PadelClub/Views/Shared/SelectablePlayerListView.swift @@ -109,7 +109,7 @@ struct SelectablePlayerListView: View { Section { Picker(selection: $searchViewModel.selectedAgeCategory) { ForEach(FederalTournamentAge.allCases) { ageCategory in - Text(ageCategory.localizedLabel(.title)).tag(ageCategory) + Text(ageCategory.localizedFederalAgeLabel(.title)).tag(ageCategory) } } label: { Text("Catégorie d'âge") @@ -142,7 +142,7 @@ struct SelectablePlayerListView: View { VStack(alignment: .trailing) { Label(searchViewModel.sortOption.localizedLabel(), systemImage: searchViewModel.ascending ? "chevron.up" : "chevron.down") if searchViewModel.selectedAgeCategory != .unlisted { - Text(searchViewModel.selectedAgeCategory.localizedLabel()).font(.caption) + Text(searchViewModel.selectedAgeCategory.localizedFederalAgeLabel()).font(.caption) } } } diff --git a/PadelClub/Views/Shared/TournamentFilterView.swift b/PadelClub/Views/Shared/TournamentFilterView.swift index 6af4d7c..3686aff 100644 --- a/PadelClub/Views/Shared/TournamentFilterView.swift +++ b/PadelClub/Views/Shared/TournamentFilterView.swift @@ -107,7 +107,7 @@ struct TournamentFilterView: View { } } } label: { - Text(category.localizedLabel(.title)) + Text(category.localizedFederalAgeLabel(.title)) } } } header: { diff --git a/PadelClub/Views/Tournament/Screen/Components/TournamentLevelPickerView.swift b/PadelClub/Views/Tournament/Screen/Components/TournamentLevelPickerView.swift index bc81b41..524a65a 100644 --- a/PadelClub/Views/Tournament/Screen/Components/TournamentLevelPickerView.swift +++ b/PadelClub/Views/Tournament/Screen/Components/TournamentLevelPickerView.swift @@ -42,7 +42,7 @@ struct TournamentLevelPickerView: View { Picker(selection: $tournament.federalTournamentAge, label: Text("Limite d'âge")) { ForEach(FederalTournamentAge.allCases) { type in - Text(type.localizedLabel(.title)).tag(type) + Text(type.localizedFederalAgeLabel(.title)).tag(type) } } Picker(selection: $tournament.groupStageOrderingMode, label: Text("Répartition en poule")) { diff --git a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift index fc7c297..be075c8 100644 --- a/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift +++ b/PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift @@ -426,15 +426,11 @@ struct InscriptionManagerView: View { private func _sharingTeamsMenuView() -> some View { Menu { - if let teamPaste = teamPaste() { - ShareLink(item: teamPaste) { - Text("En texte") - } + ShareLink(item: teamPaste(), preview: .init("Inscriptions")) { + Text("En texte") } - if let teamPaste = teamPaste(.csv) { - ShareLink(item: teamPaste) { - Text("En csv") - } + ShareLink(item: teamPaste(.csv), preview: .init("Inscriptions")) { + Text("En csv") } } label: { Label("Exporter les paires", systemImage: "square.and.arrow.up") @@ -449,8 +445,8 @@ struct InscriptionManagerView: View { tournament.unsortedTeamsWithoutWO() } - func teamPaste(_ exportFormat: ExportFormat = .rawText) -> URL? { - tournament.pasteDataForImporting(exportFormat).createFile(self.tournament.tournamentTitle(.short), exportFormat) + func teamPaste(_ exportFormat: ExportFormat = .rawText) -> TournamentShareFile { + TournamentShareFile(tournament: tournament, exportFormat: exportFormat) } var unsortedPlayers: [PlayerRegistration] { @@ -1015,3 +1011,55 @@ struct InscriptionManagerView: View { // .environment(Tournament.mock()) // } //} + +struct TournamentRoundShareContent: Transferable { + let tournament: Tournament + + func shareContent() -> String { + print("Generating URL...") + let content = tournament.rounds().compactMap { $0.pasteData() }.joined(separator: "\n\n") + return content + } + + static var transferRepresentation: some TransferRepresentation { + ProxyRepresentation { transferable in + return transferable.shareContent() + } + } +} + +struct TournamentGroupStageShareContent: Transferable { + let tournament: Tournament + + func shareContent() -> String { + print("Generating URL...") + let content = tournament.groupStages().compactMap { $0.pasteData() }.joined(separator: "\n\n") + return content + } + + static var transferRepresentation: some TransferRepresentation { + ProxyRepresentation { transferable in + return transferable.shareContent() + } + } +} + +struct TournamentShareFile: Transferable { + let tournament: Tournament + let exportFormat: ExportFormat + + func shareFile() -> URL { + print("Generating URL...") + return tournament.pasteDataForImporting(exportFormat).createFile(self.tournament.tournamentTitle()+"-inscriptions", exportFormat) + } + + static var transferRepresentation: some TransferRepresentation { + FileRepresentation(exportedContentType: .utf8PlainText) { transferable in + return SentTransferredFile(transferable.shareFile()) + } + + ProxyRepresentation { transferable in + return transferable.shareFile() + } + } +} diff --git a/PadelClub/Views/Tournament/Shared/TournamentCellView.swift b/PadelClub/Views/Tournament/Shared/TournamentCellView.swift index c4426d7..e3b862d 100644 --- a/PadelClub/Views/Tournament/Shared/TournamentCellView.swift +++ b/PadelClub/Views/Tournament/Shared/TournamentCellView.swift @@ -107,7 +107,7 @@ struct TournamentCellView: View { if displayStyle == .wide, tournament.displayAgeAndCategory(forBuild: build) { VStack(alignment: .leading, spacing: 0) { Text(build.category.localizedLabel()) - Text(build.age.localizedLabel()) + Text(build.age.localizedFederalAgeLabel()) } .font(.caption) } @@ -155,7 +155,7 @@ struct TournamentCellView: View { } } else { Text(build.category.localizedLabel()) - Text(build.age.localizedLabel()) + Text(build.age.localizedFederalAgeLabel()) } } }