diff --git a/ArkitDoushiQi/ArkitDoushiQi/ArkitDoushiQiApp.swift b/ArkitDoushiQi/ArkitDoushiQi/ArkitDoushiQiApp.swift index 18a5811..69ad0b1 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/ArkitDoushiQiApp.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/ArkitDoushiQiApp.swift @@ -21,7 +21,7 @@ struct ArkitDoushiQiApp: App { @StateObject private var languageSettings = LanguageSettings(selectedLanguage: .English) var body: some Scene { WindowGroup { - MainMenu() + MainMenu(playButtonText: "Play", registeredGamesButtonText: "Registered Games") .environmentObject(LanguageSettings(selectedLanguage: .French) ) .environmentObject(languageSettings) diff --git a/ArkitDoushiQi/ArkitDoushiQi/MainMenu.swift b/ArkitDoushiQi/ArkitDoushiQi/MainMenu.swift index eb7a5d9..bbefbbb 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/MainMenu.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/MainMenu.swift @@ -4,10 +4,13 @@ // // Created by Johan LACHENAL on 16/05/2024. // + import SwiftUI struct MainMenu: View { @EnvironmentObject var languageSettings: LanguageSettings + let playButtonText: LocalizedStringKey + let registeredGamesButtonText: LocalizedStringKey @State private var action: Int? = 0 @AppStorage("isDarkMode") private var isDarkMode = false @State private var reloadView = false @@ -16,14 +19,15 @@ struct MainMenu: View { @Environment(\.colorScheme) var colorScheme var body: some View { - NavigationView { + NavigationStack { ZStack { VStack { + Spacer().frame(height: 50) + Text("DOUSHIQI") .font(.custom("Nuku Nuku", size: 48, relativeTo: .largeTitle)) .padding() .foregroundColor(colorScheme == .dark ? .white : .black) - .offset(x: 0, y: 15) Text("GAME") .font(.custom("Nuku Nuku", size: 48, relativeTo: .largeTitle)) @@ -32,7 +36,7 @@ struct MainMenu: View { Spacer() NavigationLink(destination: GameParametersMenuView()) { - Text(LocalizedStringKey("Play")) + Text(playButtonText) .font(.custom("Nuku Nuku", size: 32, relativeTo: .title)) .bold() .frame(maxWidth: .infinity) @@ -52,7 +56,7 @@ struct MainMenu: View { Spacer().frame(height: 40) NavigationLink(destination: PartyListView()) { - Text(LocalizedStringKey("Registered Games")) + Text(registeredGamesButtonText) .font(.custom("Nuku Nuku", size: 18, relativeTo: .body)) .padding() .background(Color.gray.opacity(0.7)) @@ -76,7 +80,6 @@ struct MainMenu: View { } Button(action: { - // Afficher le sélecteur de langue showLanguagePicker.toggle() }) { Image(systemName: "globe") @@ -97,7 +100,7 @@ struct MainMenu: View { } .environmentObject(languageSettings) .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("LanguageChanged"))) { _ in - self.reloadView.toggle() // Changez la valeur pour forcer le rechargement + self.reloadView.toggle() } } } @@ -105,7 +108,7 @@ struct MainMenu: View { struct MainMenu_Previews: PreviewProvider { static var previews: some View { - MainMenu() + MainMenu(playButtonText: "Play", registeredGamesButtonText: "Registered Games") .environmentObject(LanguageSettings(selectedLanguage: .French)) } } diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ItemCollectionParty.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ItemCollectionParty.swift index af2969b..61fc0e3 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ItemCollectionParty.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ItemCollectionParty.swift @@ -13,70 +13,56 @@ struct ItemCollectionParty: View { var body: some View { VStack { HStack { - Text(party.date) + Text(party.formattedDate) .font(.headline) .foregroundColor(.gray) Spacer() } .padding(.bottom, 5) - GeometryReader { geometry in - HStack(spacing: 10) { - HStack { - Image(party.player1Image) - .resizable() - .aspectRatio(contentMode: .fill) - .frame(width: geometry.size.width * 0.15, height: geometry.size.width * 0.15) - .clipShape(Circle()) - .overlay(Circle().stroke(Color.purple, lineWidth: 2)) + HStack(spacing: 10) { + HStack { + ProfileComponent(color: Color.purple, profileWidth: 60, profileHeight: 60, image: Image(party.player1Image)) + + VStack(alignment: .leading) { + Text(party.player1Name) + .fontWeight(.bold) + .foregroundColor(.purple) + .lineLimit(1) + .minimumScaleFactor(0.5) + .frame(maxWidth: .infinity, alignment: .leading) - VStack(alignment: .leading) { - Text(party.player1Name) - .fontWeight(.bold) - .foregroundColor(.purple) - .lineLimit(1) - .minimumScaleFactor(0.5) - .frame(maxWidth: geometry.size.width * 0.25, alignment: .leading) - - Text("\(party.player1Score)") - .fontWeight(.bold) - .foregroundColor(.red) // Perdent en vert - } + Text(LocalizedStringKey(party.player1Score)) + .fontWeight(.bold) + .foregroundColor(party.player1Score == "Défaite" ? .red : .green) // Défaite en rouge, Victoire en vert } - - Text("vs") - .font(.headline) - .foregroundColor(.gray) - - HStack { - VStack(alignment: .trailing) { - Text(party.player2Name) - .fontWeight(.bold) - .foregroundColor(.purple) - .lineLimit(1) - .minimumScaleFactor(0.5) - .frame(maxWidth: geometry.size.width * 0.25, alignment: .trailing) - - Text("\(party.player2Score)") - - .fontWeight(.bold) - .foregroundColor(.green) // Gagnant en rouge - } + } + + Text("vs") + .font(.headline) + .foregroundColor(.gray) + + HStack { + VStack(alignment: .trailing) { + Text(party.player2Name) + .fontWeight(.bold) + .foregroundColor(.purple) + .lineLimit(1) + .minimumScaleFactor(0.5) + .frame(maxWidth: .infinity, alignment: .trailing) - Image(party.player2Image) - .resizable() - .aspectRatio(contentMode: .fill) - .frame(width: geometry.size.width * 0.15, height: geometry.size.width * 0.15) - .clipShape(Circle()) - .overlay(Circle().stroke(Color.purple, lineWidth: 2)) + Text(LocalizedStringKey(party.player2Score)) + .fontWeight(.bold) + .foregroundColor(party.player2Score == "Victoire" ? .green : .red) // Victoire en vert, Défaite en rouge } + + ProfileComponent(color: Color.purple, profileWidth: 60, profileHeight: 60, image: Image(party.player2Image)) } - .padding() - .background(Color.white) - .cornerRadius(15) - .shadow(radius: 3) // Réduction de l'ombre pour un effet plus léger } - .frame(height: 120) // Ajustez la hauteur en fonction de votre contenu + .padding() + .background(Color(UIColor.systemBackground)) + .cornerRadius(15) + .shadow(radius: 3) // Réduction de l'ombre pour un effet plus léger } .padding(.horizontal) } @@ -84,7 +70,7 @@ struct ItemCollectionParty: View { struct ItemCollectionParty_Previews: PreviewProvider { static var previews: some View { - ItemCollectionParty(party: Party(player1Name: "L'invaincu du samedi", player1Score: "Défaite", player1Image: "Perceval", player2Name: "Le gars du dimanche", player2Score: "Victoire", player2Image: "Perceval", date: "Samedi soir")) + ItemCollectionParty(party: Party(player1Name: "L'invaincu du samedi", player1Score: "Défaite", player1Image: "Perceval", player2Name: "Le gars du dimanche", player2Score: "Victoire", player2Image: "Perceval", date: Date())) .previewLayout(.sizeThatFits) .padding() } diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ProfileEdit.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ProfileEdit.swift index bc309c6..6cf8b76 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ProfileEdit.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/Views/Components/Visuals/ProfileEdit.swift @@ -2,7 +2,7 @@ // ProfileEdit.swift // ArkitDoushiQi // -// Created by Johan LACHENAL on 28/05/2024. +// Created by Johan LACHENAL, Louis DUFOUR on 28/05/2024. // import SwiftUI @@ -16,33 +16,36 @@ struct ProfileEdit: View { let playerNameKey: LocalizedStringKey var body: some View { - VStack(alignment: .leading) { + VStack(alignment: .leading, spacing: 10) { EditImageComponent( color: color, profileWidth: profileWidth, profileHeight: profileHeight, defaultImage: defaultImage, imageTextChange: imageTextChange - ).padding(EdgeInsets(top: 0, leading: 32, bottom: 0, trailing: 32)) - - VStack(alignment: .trailing) { - HStack { - EditTextComponent(explanation: playerNameKey, value: playerNameKey == "Nom du Joueur 1" ? "Joueur 1" : "Joueur 2") - } + ).padding(.horizontal) + + VStack(alignment: .leading, spacing: 5) { + Text(playerNameKey) + .font(.headline) + .foregroundColor(.gray) + TextField("", text: .constant("")) // Modifier ici selon votre logique + .textFieldStyle(RoundedBorderTextFieldStyle()) + .font(.title3) // Taille de police augmentée } + .padding(.horizontal) } } } struct ProfileEdit_Previews: PreviewProvider { static var previews: some View { - ProfileEdit( - color: Color(.red), - profileWidth: 100, - profileHeight: 100, - defaultImage: Image("profil"), - imageTextChange: LocalizedStringKey("Changer d'avatar"), - playerNameKey: LocalizedStringKey("Nom du Joueur 1") + ProfileEdit(color: Color(.red), + profileWidth: 80, + profileHeight: 80, + defaultImage: Image("profil"), + imageTextChange: "Changer d'avatar", + playerNameKey: "Nom du Joueur 1" ) } } diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/Data/Stub.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/Data/Stub.swift index 5501b88..39af388 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/Views/Data/Stub.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/Views/Data/Stub.swift @@ -6,6 +6,7 @@ // import SwiftUI +import Foundation struct Party: Identifiable { let id = UUID() @@ -15,5 +16,21 @@ struct Party: Identifiable { let player2Name: String let player2Score: String let player2Image: String - let date: String + let date: Date + + var localizedPlayer1Score: LocalizedStringKey { + LocalizedStringKey(player1Score) + } + + var localizedPlayer2Score: LocalizedStringKey { + LocalizedStringKey(player2Score) + } + + var formattedDate: String { + let dateFormatter = DateFormatter() + dateFormatter.dateStyle = .full + dateFormatter.timeStyle = .none + dateFormatter.locale = Locale.current + return dateFormatter.string(from: date) + } } diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/EventTriggers/KeyboardReadable.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/EventTriggers/KeyboardReadable.swift index dec17a6..897a899 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/Views/EventTriggers/KeyboardReadable.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/Views/EventTriggers/KeyboardReadable.swift @@ -2,29 +2,28 @@ // KeyboardReadable.swift // ArkitDoushiQi // -// Created by Johan LACHENAL on 31/05/2024. +// Created by Johan LACHENAL, Louis DUFOUR on 31/05/2024. // -import Foundation import Combine import UIKit - // Publisher to read keyboard changes. protocol KeyboardReadable { - var keyboardPublisher: AnyPublisher { get } + var keyboardPublisher: AnyPublisher { get } } extension KeyboardReadable { - var keyboardPublisher: AnyPublisher { + var keyboardPublisher: AnyPublisher { Publishers.Merge( NotificationCenter.default .publisher(for: UIResponder.keyboardWillShowNotification) - .map { _ in true }, - + .compactMap { notification in + (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height + }, NotificationCenter.default .publisher(for: UIResponder.keyboardWillHideNotification) - .map { _ in false } + .map { _ in CGFloat(0) } ) .eraseToAnyPublisher() } diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/GameParametersMenuView.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/GameParametersMenuView.swift index 6bffc7f..e17f2a3 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/Views/GameParametersMenuView.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/Views/GameParametersMenuView.swift @@ -2,7 +2,7 @@ // GameParametersMenuView.swift // ArkitDoushiQi // -// Created by Johan LACHENAL on 24/05/2024. +// Created by Johan LACHENAL, Louis DUFOUR on 24/05/2024. // import SwiftUI @@ -12,44 +12,55 @@ struct GameParametersMenuView: View, KeyboardReadable { @State private var selectedGameType: GameType = .PvP @State private var selectedAIOption: AI = .RandomAction @State private var selectedRulesOption: Rules = .Regular - @State private var isKeyboardVisible = false - + @State private var keyboardHeight: CGFloat = 0 + var body: some View { - NavigationView { - VStack(alignment: .leading) { - HStack(alignment: .center) { - Text(LocalizedStringKey("Paramètres de partie")).bold().font(.title) - }.frame(maxWidth: .infinity) - - // Sélecteur pour le type de partie + NavigationStack { + VStack(alignment: .leading, spacing: 15) { + Text(LocalizedStringKey("Paramètres de partie")) + .bold() + .font(.largeTitle) + .padding(.top, 20) + PickerComponent(title: LocalizedStringKey("Sélectionne le type de partie :"), selectedOption: $selectedGameType, options: GameType.allCases) - + .padding(.horizontal) + PickerComponent(title: LocalizedStringKey("Sélectionne les règles :"), selectedOption: $selectedRulesOption, options: Rules.allCases) - + .padding(.horizontal) + if selectedGameType == .PvAI { PickerComponent(title: LocalizedStringKey("Sélectionne une IA :"), selectedOption: $selectedAIOption, options: AI.allCases) + .padding(.horizontal) } - - ProfileEdit(color: Color(.red), profileWidth: 100, profileHeight: 100, defaultImage: Image("profil"), imageTextChange: LocalizedStringKey("changer l'avatar du joueur 1"), playerNameKey: LocalizedStringKey("Nom du Joueur 1")) - + + ProfileEdit(color: Color(.red), profileWidth: 80, profileHeight: 80, defaultImage: Image("profil"), imageTextChange: LocalizedStringKey("changer l'avatar du joueur 1"), playerNameKey: LocalizedStringKey("Nom du Joueur 1")) + if selectedGameType == .PvP { - ProfileEdit(color: Color(.blue), profileWidth: 100, profileHeight: 100, defaultImage: Image("profil"), imageTextChange: LocalizedStringKey("changer l'avatar du joueur 2"), playerNameKey: LocalizedStringKey("Nom du Joueur 2")) + ProfileEdit(color: Color(.blue), profileWidth: 80, profileHeight: 80, defaultImage: Image("profil"), imageTextChange: LocalizedStringKey("changer l'avatar du joueur 2"), playerNameKey: LocalizedStringKey("Nom du Joueur 2")) } - - if !isKeyboardVisible { - ButtonComponent(title: LocalizedStringKey("Lancer la partie")) { - GameView() - }.padding(EdgeInsets(top: 10, leading: 32, bottom: 10, trailing: 32)) + + Spacer() + + ButtonComponent(title: LocalizedStringKey("Lancer la partie")) { + GameView() + } + .padding(.horizontal, 32) + .padding(.bottom, 20) + } + .onReceive(keyboardPublisher) { height in + withAnimation { + self.keyboardHeight = height } } - .onReceive(keyboardPublisher) { value in isKeyboardVisible = value } - .frame(maxHeight: .infinity, alignment: .top) + .padding(.horizontal, 20) + .padding(.bottom, keyboardHeight) // Ajouter le padding en bas pour éviter le clavier + .padding(.top, 20) // Ajuster le padding en haut si nécessaire } } } diff --git a/ArkitDoushiQi/ArkitDoushiQi/Views/PartyEnregistery.swift b/ArkitDoushiQi/ArkitDoushiQi/Views/PartyEnregistery.swift index 73aeaaa..f3c9649 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/Views/PartyEnregistery.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/Views/PartyEnregistery.swift @@ -9,18 +9,20 @@ import SwiftUI struct PartyListView: View { let parties: [Party] = [ - Party(player1Name: "Jack", player1Score: "Défaite", player1Image: "Perceval", player2Name: "Le gars du dimanche", player2Score: "Victoire", player2Image: "Perceval", date: "Samedi soir"), - Party(player1Name: "Le gars du dimanche", player1Score: "Victoire", player1Image: "Perceval", player2Name: "Jack", player2Score: "Défaite", player2Image: "Perceval", date: "Vendredi soir") + Party(player1Name: "Jack", player1Score: "Défaite", player1Image: "Perceval", player2Name: "Le gars du dimanche", player2Score: "Victoire", player2Image: "Perceval", date: Date()), + Party(player1Name: "Le gars du dimanche", player1Score: "Victoire", player1Image: "Perceval", player2Name: "Jack", player2Score: "Défaite", player2Image: "Perceval", date: Date().addingTimeInterval(-86400)) // Ajoutez plus de parties ici ] var body: some View { - NavigationView { + NavigationStack { List(parties) { party in ItemCollectionParty(party: party) .padding(.vertical, 5) + .listRowInsets(EdgeInsets()) // Supprimer le padding } - .navigationTitle("Liste des Parties") + .navigationTitle(LocalizedStringKey("Liste des Parties")) + .frame(maxWidth: .infinity) // Utiliser toute la largeur disponible } } } diff --git a/ArkitDoushiQi/Ressources/en.lproj/Localizable.strings b/ArkitDoushiQi/Ressources/en.lproj/Localizable.strings index ed69893..897dccf 100644 --- a/ArkitDoushiQi/Ressources/en.lproj/Localizable.strings +++ b/ArkitDoushiQi/Ressources/en.lproj/Localizable.strings @@ -34,5 +34,7 @@ "Nom du Joueur 2" = "Player 2 Name"; "Lancer la partie" = "Start Game"; "Changer d'avatar" = "Change Avatar"; - +"Liste des Parties" = "Party List"; +"Victoire" = "Victory"; +"Défaite" = "Defeat"; diff --git a/ArkitDoushiQi/Ressources/fr.lproj/Localizable.strings b/ArkitDoushiQi/Ressources/fr.lproj/Localizable.strings index f045190..e24345e 100644 --- a/ArkitDoushiQi/Ressources/fr.lproj/Localizable.strings +++ b/ArkitDoushiQi/Ressources/fr.lproj/Localizable.strings @@ -34,3 +34,7 @@ "Nom du Joueur 2" = "Nom du Joueur 2"; "Lancer la partie" = "Lancer la partie"; "Changer d'avatar" = "Changer d'avatar"; +"Liste des Parties" = "Liste des Parties"; +"Liste des Parties" = "Liste des Parties"; +"Victoire" = "Victoire"; +"Défaite" = "Défaite";