Merge pull request 'dev_views_Players' (#10) from dev_views_Players into dev_views
Reviewed-on: #10dev_views_Settings^2
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "doushouqi-cat.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "doushouqi-dog.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 5.7 KiB |
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "doushouqi-elephant.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 5.8 KiB |
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "doushouqi-leopard.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 16 KiB |
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "doushouqi-lion.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 8.7 KiB |
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "doushouqi-rat.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 8.2 KiB |
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "doushouqi-wolf.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 326 KiB |
@ -0,0 +1,150 @@
|
|||||||
|
//
|
||||||
|
// AddPlayerView.swift
|
||||||
|
// DouShouQi_App
|
||||||
|
//
|
||||||
|
// Created by étudiant on 28/05/2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
struct AddPlayerView: View {
|
||||||
|
@Binding var isPresented: Bool
|
||||||
|
@Binding var players: [Player]
|
||||||
|
@State private var playerName: String = ""
|
||||||
|
@State private var showAlert = false
|
||||||
|
@State private var showImagePicker = false
|
||||||
|
@State private var profileImage: UIImage? = nil
|
||||||
|
@State private var profileImagePath: String = ""
|
||||||
|
@State private var imagePickerSourceType: UIImagePickerController.SourceType = .photoLibrary
|
||||||
|
@State private var showActionSheet = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 20) {
|
||||||
|
Text("Add New Player")
|
||||||
|
.font(.headline)
|
||||||
|
|
||||||
|
TextField("Player Name", text: $playerName)
|
||||||
|
.padding()
|
||||||
|
.background(Color(.systemGray6))
|
||||||
|
.cornerRadius(10)
|
||||||
|
|
||||||
|
if let profileImage = profileImage {
|
||||||
|
Image(uiImage: profileImage)
|
||||||
|
.resizable()
|
||||||
|
.frame(width: 100, height: 100)
|
||||||
|
.clipShape(Circle())
|
||||||
|
} else {
|
||||||
|
Button(action: {
|
||||||
|
showActionSheet = true
|
||||||
|
}) {
|
||||||
|
Text("Select Profile Photo")
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.padding()
|
||||||
|
.background(Color.blue)
|
||||||
|
.cornerRadius(10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
Button(action: {
|
||||||
|
if players.contains(where: { $0.name.lowercased() == playerName.lowercased() }) {
|
||||||
|
showAlert = true
|
||||||
|
} else {
|
||||||
|
if let image = profileImage, let imageData = image.jpegData(compressionQuality: 0.8) {
|
||||||
|
let filename = UUID().uuidString + ".jpg"
|
||||||
|
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
|
||||||
|
let documentsDirectory = paths[0]
|
||||||
|
let fileURL = documentsDirectory.appendingPathComponent(filename)
|
||||||
|
try? imageData.write(to: fileURL)
|
||||||
|
profileImagePath = fileURL.path
|
||||||
|
}
|
||||||
|
let newPlayer = Player(name: playerName, wins: 0, losses: 0, photo: profileImagePath)
|
||||||
|
players.append(newPlayer)
|
||||||
|
isPresented = false
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Text("Add")
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.padding()
|
||||||
|
.background(Color.blue)
|
||||||
|
.cornerRadius(10)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(action: {
|
||||||
|
isPresented = false
|
||||||
|
}) {
|
||||||
|
Text("Cancel")
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.padding()
|
||||||
|
.background(Color.red)
|
||||||
|
.cornerRadius(10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.frame(maxWidth: 300)
|
||||||
|
.background(Color.white)
|
||||||
|
.cornerRadius(20)
|
||||||
|
.shadow(radius: 10)
|
||||||
|
.alert(isPresented: $showAlert) {
|
||||||
|
Alert(title: Text("Error"), message: Text("Player already exists."), dismissButton: .default(Text("OK")))
|
||||||
|
}
|
||||||
|
.actionSheet(isPresented: $showActionSheet) {
|
||||||
|
ActionSheet(title: Text("Select Photo"), message: Text("Choose a photo from the library or take a new one."), buttons: [
|
||||||
|
.default(Text("Photo Library")) {
|
||||||
|
imagePickerSourceType = .photoLibrary
|
||||||
|
showImagePicker = true
|
||||||
|
},
|
||||||
|
.default(Text("Camera")) {
|
||||||
|
imagePickerSourceType = .camera
|
||||||
|
showImagePicker = true
|
||||||
|
},
|
||||||
|
.cancel()
|
||||||
|
])
|
||||||
|
}
|
||||||
|
.sheet(isPresented: $showImagePicker) {
|
||||||
|
ImagePicker(image: $profileImage, sourceType: imagePickerSourceType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ImagePicker: UIViewControllerRepresentable {
|
||||||
|
@Binding var image: UIImage?
|
||||||
|
var sourceType: UIImagePickerController.SourceType
|
||||||
|
|
||||||
|
class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
|
||||||
|
var parent: ImagePicker
|
||||||
|
|
||||||
|
init(parent: ImagePicker) {
|
||||||
|
self.parent = parent
|
||||||
|
}
|
||||||
|
|
||||||
|
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
|
||||||
|
if let uiImage = info[.originalImage] as? UIImage {
|
||||||
|
parent.image = uiImage
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.presentationMode.wrappedValue.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
|
||||||
|
parent.presentationMode.wrappedValue.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeCoordinator() -> Coordinator {
|
||||||
|
Coordinator(parent: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(\.presentationMode) var presentationMode
|
||||||
|
|
||||||
|
func makeUIViewController(context: Context) -> UIImagePickerController {
|
||||||
|
let picker = UIImagePickerController()
|
||||||
|
picker.delegate = context.coordinator
|
||||||
|
picker.sourceType = sourceType
|
||||||
|
return picker
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
|
||||||
|
}
|