diff --git a/PadelClub.xcodeproj/project.pbxproj b/PadelClub.xcodeproj/project.pbxproj index aa81921..28724fc 100644 --- a/PadelClub.xcodeproj/project.pbxproj +++ b/PadelClub.xcodeproj/project.pbxproj @@ -242,6 +242,8 @@ FFDB1C732BB2CFE900F1E467 /* MySortDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFDB1C722BB2CFE900F1E467 /* MySortDescriptor.swift */; }; FFDDD40C2B93B2BB00C91A49 /* DeferredViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFDDD40B2B93B2BB00C91A49 /* DeferredViewModifier.swift */; }; FFE103082C353B7600684FC9 /* EventClubSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE103072C353B7600684FC9 /* EventClubSettingsView.swift */; }; + FFE103102C366DCD00684FC9 /* EditSharingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE1030F2C366DCD00684FC9 /* EditSharingView.swift */; }; + FFE103122C366E5900684FC9 /* ImagePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE103112C366E5900684FC9 /* ImagePickerView.swift */; }; FFE2D2E22C231BEE00D0C7BE /* SupportButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE2D2E12C231BEE00D0C7BE /* SupportButtonView.swift */; }; FFEF7F4E2BDE69130033D0F0 /* MenuWarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFEF7F4D2BDE69130033D0F0 /* MenuWarningView.swift */; }; FFF0241E2BF48B15001F14B4 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = FFF0241D2BF48B15001F14B4 /* Localizable.strings */; }; @@ -574,6 +576,8 @@ FFDB1C722BB2CFE900F1E467 /* MySortDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MySortDescriptor.swift; sourceTree = ""; }; FFDDD40B2B93B2BB00C91A49 /* DeferredViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeferredViewModifier.swift; sourceTree = ""; }; FFE103072C353B7600684FC9 /* EventClubSettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EventClubSettingsView.swift; path = PadelClub/Views/Tournament/Screen/Components/EventClubSettingsView.swift; sourceTree = SOURCE_ROOT; }; + FFE1030F2C366DCD00684FC9 /* EditSharingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditSharingView.swift; sourceTree = ""; }; + FFE103112C366E5900684FC9 /* ImagePickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePickerView.swift; sourceTree = ""; }; FFE2D2E12C231BEE00D0C7BE /* SupportButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportButtonView.swift; sourceTree = ""; }; FFEF7F4D2BDE69130033D0F0 /* MenuWarningView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuWarningView.swift; sourceTree = ""; }; FFF0241C2BF48B15001F14B4 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; @@ -1076,6 +1080,7 @@ FFCFC0192BBC5A8500B82851 /* MatchTypeSmallSelectionView.swift */, FF663FBD2BE019EC0031AE83 /* TournamentFilterView.swift */, FFE2D2E12C231BEE00D0C7BE /* SupportButtonView.swift */, + FFE103112C366E5900684FC9 /* ImagePickerView.swift */, ); path = Shared; sourceTree = ""; @@ -1164,6 +1169,7 @@ FF967D052BAF3C4200A9A3BD /* MatchSetupView.swift */, FF967D002BAEF0B400A9A3BD /* MatchSummaryView.swift */, FF967D022BAEF0C000A9A3BD /* MatchDetailView.swift */, + FFE1030F2C366DCD00684FC9 /* EditSharingView.swift */, FF025AD92BD0C2BD00A86CF8 /* Components */, ); path = Match; @@ -1506,6 +1512,7 @@ FF8F26412BADFC8700650388 /* TournamentInitView.swift in Sources */, C4A47D8A2B7BBB6500ADC637 /* SubscriptionView.swift in Sources */, FF1DC5572BAB3AED00FD8220 /* ClubsView.swift in Sources */, + FFE103122C366E5900684FC9 /* ImagePickerView.swift in Sources */, FF8F264F2BAE0B9600650388 /* MatchTypeSelectionView.swift in Sources */, FF967D062BAF3C4200A9A3BD /* MatchSetupView.swift in Sources */, FF4AB6B52B9248200002987F /* NetworkManager.swift in Sources */, @@ -1520,6 +1527,7 @@ FF9268012BCE94920080F940 /* SeedsCallingView.swift in Sources */, FF9268092BCEDC2C0080F940 /* CallView.swift in Sources */, FF5D0D742BB41DF8005CB568 /* Color+Extensions.swift in Sources */, + FFE103102C366DCD00684FC9 /* EditSharingView.swift in Sources */, FF7091682B90F79F00AB08DA /* TournamentCellView.swift in Sources */, FF6EC9042B9479F500EA7F5A /* Sequence+Extensions.swift in Sources */, FF9267FA2BCE78EC0080F940 /* CashierDetailView.swift in Sources */, @@ -1894,7 +1902,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 85; + CURRENT_PROJECT_VERSION = 86; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; @@ -1907,6 +1915,7 @@ INFOPLIST_KEY_CFBundleDisplayName = "Padel Club"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.sports"; INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES; + 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; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; @@ -1937,7 +1946,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 85; + CURRENT_PROJECT_VERSION = 86; DEFINES_MODULE = YES; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_TEAM = BQ3Y44M3Q6; @@ -1948,6 +1957,7 @@ INFOPLIST_KEY_CFBundleDisplayName = "Padel Club"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.sports"; INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES; + 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; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; diff --git a/PadelClub/Data/DataStore.swift b/PadelClub/Data/DataStore.swift index a7a722a..2e9656e 100644 --- a/PadelClub/Data/DataStore.swift +++ b/PadelClub/Data/DataStore.swift @@ -249,7 +249,8 @@ class DataStore: ObservableObject { // MARK: - Convenience func runningMatches() -> [Match] { - let lastTournaments = self.tournaments.sorted(by: \Tournament.startDate).prefix(10) + let dateNow : Date = Date() + let lastTournaments = self.tournaments.filter { $0.isDeleted == false && $0.startDate <= dateNow }.sorted(by: \Tournament.startDate, order: .descending).prefix(10) var runningMatches: [Match] = [] for tournament in lastTournaments { diff --git a/PadelClub/Data/Match.swift b/PadelClub/Data/Match.swift index 738d2d6..5d4c536 100644 --- a/PadelClub/Data/Match.swift +++ b/PadelClub/Data/Match.swift @@ -541,6 +541,10 @@ defer { startDate = fromStartDate switch fieldSetup { + case .fullRandom: + if let _courtIndex = allCourts().randomElement() { + setCourt(_courtIndex) + } case .random: if let _courtIndex = availableCourts().randomElement() { setCourt(_courtIndex) @@ -579,10 +583,14 @@ defer { return false } + func allCourts() -> [Int] { + let availableCourts = Array(0.. [Int] { let courtUsed = currentTournament()?.courtUsed() ?? [] - let availableCourts = Array(0.. String { if parent != nil { - return seedInterval()?.localizedLabel(displayStyle) ?? "Round pas trouvé" + if let seedInterval = seedInterval() { + return seedInterval.localizedLabel(displayStyle) + } + print("Round pas trouvé", id, parent, index) + return "Round pas trouvé" } return RoundRule.roundName(fromRoundIndex: index, displayStyle: displayStyle) } diff --git a/PadelClub/Data/TeamRegistration.swift b/PadelClub/Data/TeamRegistration.swift index 3d81383..96c98e9 100644 --- a/PadelClub/Data/TeamRegistration.swift +++ b/PadelClub/Data/TeamRegistration.swift @@ -183,6 +183,16 @@ final class TeamRegistration: ModelObject, Storable { return players().map { $0.playerLabel(displayStyle) }.joined(separator: twoLines ? "\n" : " & ") } + func teamLabelRanked(displayRank: Bool, displayTeamName: Bool) -> String { + [displayTeamName ? name : nil, displayRank ? seedIndex() : nil, displayTeamName ? (name == nil ? teamLabel() : name) : teamLabel()].compactMap({ $0 }).joined(separator: " ") + } + + func seedIndex() -> String? { + guard let tournament = tournamentObject() else { return nil } + guard let index = index(in: tournament.selectedSortedTeams()) else { return nil } + return "(\(index + 1))" + } + func index(in teams: [TeamRegistration]) -> Int? { return teams.firstIndex(where: { $0.id == id }) } diff --git a/PadelClub/Views/Match/EditSharingView.swift b/PadelClub/Views/Match/EditSharingView.swift new file mode 100644 index 0000000..de5a331 --- /dev/null +++ b/PadelClub/Views/Match/EditSharingView.swift @@ -0,0 +1,173 @@ +// +// EditSharingView.swift +// Padel Tournament +// +// Created by Razmig Sarkissian on 03/02/2024. +// + +import SwiftUI +import TipKit +import CoreTransferable + +struct EditSharingView: View { + @Environment(Tournament.self) var tournament: Tournament + var match: Match + @State private var displayRank: Bool = false + @State private var displayTeamTitle: Bool = false + @State private var showCamera: Bool = false + @State private var newImage: UIImage? + @State private var copied: Bool = false + + var shareMessage: String { + shareMessage(displayRank: displayRank, displayTeamName: displayTeamTitle) + } + + func shareMessage(displayRank: Bool, displayTeamName: Bool) -> String { + var messageData: [String] = [] + + var locAndTime: String = "" + if let courtName = match.courtName() { + locAndTime.append("\(courtName)") + } + + if let startDate = match.startDate { + locAndTime = locAndTime + " à " + startDate.formattedAsHourMinute() + } + + if locAndTime.isEmpty == false { + messageData.append(locAndTime) + } + + messageData.append(tournament.tournamentTitle()) + + let message = [match.isLoserBracket ? "Classement" : nil, match.roundTitle(), match.isLoserBracket ? nil : ((match.index > 0 || match.isGroupStage()) ? match.matchTitle(.short) : nil)].compactMap({ $0 }).joined(separator: " ") + + messageData.append(message) + + guard let labelOne = match.team(.one)?.teamLabelRanked(displayRank: displayRank, displayTeamName: displayTeamName), let labelTwo = match.team(.two)?.teamLabelRanked(displayRank: displayRank, displayTeamName: displayTeamName) else { + return messageData.joined(separator: "\n") + } + + let players = "\(labelOne)\ncontre\n\(labelTwo)" + messageData.append(players) + + return messageData.joined(separator: "\n") + } + + + + var body: some View { + List { + + if let newImage { + Section { + let tip = SharePictureTip() + TipView(tip) + .tipStyle(tint: .green) + } + + Section { + ZStack { + Color.black + .ignoresSafeArea() + Image(uiImage: newImage) + .resizable() + .scaledToFit() + .frame(height: 200, alignment: .center) + .frame(maxWidth: .infinity, alignment: .center) + } + .listRowInsets(EdgeInsets()) + } footer: { + HStack { + Spacer() + Button("effacer", role: .destructive) { + self.newImage = nil + } + } + } + } else { + Button { + showCamera = true + } label: { + Label("Prendre une photo", systemImage: "camera") + } + + } + + Section { + Toggle(isOn: $displayRank) { + Text("Afficher leurs rangs dans ce tournoi") + } + + Toggle(isOn: $displayTeamTitle) { + Text("Afficher plutôt le nom de l'équipe") + } + } header: { + Text("Options") + } + + Section { + Text(shareMessage) + } header: { + Text("Message type généré") + } footer: { + HStack { + Spacer() + Button { + UIPasteboard.general.string = shareMessage + copied = true + } label: { + Label(copied ? "copié" : "copier", systemImage: "doc.on.doc") + } + + if shareMessage == UIPasteboard.general.string || copied == true { + Image(systemName: "checkmark") + } + } + } + } + .toolbar { + ToolbarItem(placement: .topBarTrailing) { + if let newImage { + let photo = Photo(image: Image(uiImage:newImage), caption: shareMessage) + ShareLink( + item: photo, + preview: SharePreview( + photo.caption, + image: photo.image)) { + Text("Partager") + } + .onAppear { + UIPasteboard.general.string = shareMessage + copied = true + } + } else { + ShareLink("Partager", item: shareMessage) + } + } + } + .navigationTitle("Préparation") + .navigationBarTitleDisplayMode(.inline) + .toolbarBackground(.visible, for: .navigationBar) + .fullScreenCover(isPresented: $showCamera) { + ImagePickerView(image: $newImage) + .background(Color.black.edgesIgnoringSafeArea(.all)) + } + .onChange(of: displayRank) { + copied = false + } + .onChange(of: displayTeamTitle) { + copied = false + } + } +} + +struct Photo: Transferable { + static var transferRepresentation: some TransferRepresentation { + ProxyRepresentation(exporting: \.image) + ProxyRepresentation(exporting: \.caption) + } + + public var image: Image + public var caption: String +} diff --git a/PadelClub/Views/Match/MatchDetailView.swift b/PadelClub/Views/Match/MatchDetailView.swift index 938733a..a9c7ce5 100644 --- a/PadelClub/Views/Match/MatchDetailView.swift +++ b/PadelClub/Views/Match/MatchDetailView.swift @@ -351,8 +351,11 @@ struct MatchDetailView: View { } } - //todo - //shareView + NavigationLink { + EditSharingView(match: match) + } label: { + Text("Partage sur les réseaux sociaux") + } // if let followUpMatch = match.followUpMatch { // Section { @@ -415,7 +418,8 @@ struct MatchDetailView: View { Picker(selection: $fieldSetup) { - Text("Au hasard").tag(MatchFieldSetup.random) + Text("Au hasard parmi les libres").tag(MatchFieldSetup.random) + Text("Au hasard").tag(MatchFieldSetup.fullRandom) //Text("Premier disponible").tag(MatchFieldSetup.firstAvailable) if let club = match.currentTournament()?.club() { ForEach(0.. Coordinator { + Coordinator(self) + } + + func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIImagePickerController { + let picker = UIImagePickerController() + picker.sourceType = .camera + picker.allowsEditing = true + picker.showsCameraControls = true + picker.delegate = context.coordinator + return picker + } + + func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext) { } +} + +#endif