feat : design responsive profilePage

androidCompose
Maxence GUITARD 1 year ago
parent 52aa1acaa4
commit 7cd25b50d7

@ -62,6 +62,8 @@ dependencies {
implementation("androidx.compose.ui:ui-graphics-android:1.6.3")
implementation("androidx.navigation:navigation-common-ktx:2.7.7")
implementation("androidx.navigation:navigation-compose:2.7.7")
implementation("androidx.compose.material:material-icons-core")
implementation("androidx.compose.material:material-icons-extended")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")

@ -7,6 +7,7 @@ import androidx.navigation.compose.rememberNavController
import com.example.mathseduc.ui.CreateLobbyPage
import com.example.mathseduc.ui.HomePage
import com.example.mathseduc.ui.MultiPage
import com.example.mathseduc.ui.ProfilePlayerPage
@Composable
fun AppNavigation() {
@ -17,6 +18,7 @@ fun AppNavigation() {
composable("connexion") { ConnexionPlayerContent(navController) }
composable("multiplayer") { MultiPage(navController) }
composable("createLobby") { CreateLobbyPage(navController) }
composable("profilePlayer") { ProfilePlayerPage(navController) }
//composable("serverDetails/{serverName}/{lobbyId}") { ServerDetailPage(navController) }
}
}

@ -1,12 +1,14 @@
package com.example.mathseduc.controllers
import android.os.StrictMode
import android.util.Log
import com.example.mathseduc.models.*
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import okhttp3.FormBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.mindrot.jbcrypt.BCrypt
import java.io.IOException
@ -94,6 +96,34 @@ class ControllerPlayer {
}
}
}
/*
fun updatePlayer(playerId: String,nickname: String, password: String) {
try {
val policy = StrictMode.ThreadPolicy.Builder().permitAll().build()
StrictMode.setThreadPolicy(policy)
val client = OkHttpClient()
val hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt())
val requestBody = FormBody.Builder()
.add("nickname", nickname)
.add("password", hashedPassword)
.build()
val updateRequest = Request.Builder()
.url("https://trusting-panini.87-106-126-109.plesk.page/api/update/player/${playerId}/qUOGkWdoPCgbmuqxIC8xiaX0rV1Pw1LoPafkaoHOgszEyD9P2vcOu493xCDZpAqO")
.post(requestBody)
.build()
val updateResponse: Response = client.newCall(updateRequest).execute()
if (!updateResponse.isSuccessful) {
Log.e("updatePlayer", "Error updating player")
}
} catch (e: Exception) {
Log.e("updateLobby", "Error updating lobby", e)
}
}*/
fun authenticateUser(nickname: String, password: String): Int {

@ -32,10 +32,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalConfiguration
@ -45,7 +45,6 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@ -64,11 +63,11 @@ import okhttp3.MultipartBody
@Composable
fun CreateLobbyPage(navController: NavController) {
var lobbyName by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var nbPlayers by remember { mutableStateOf("") }
var difficulty by remember { mutableStateOf("") }
var chapter by remember { mutableStateOf("") }
var lobbyName by rememberSaveable { mutableStateOf("") }
var password by rememberSaveable { mutableStateOf("") }
var nbPlayers by rememberSaveable { mutableStateOf("") }
var difficulty by rememberSaveable { mutableStateOf("") }
var chapter by rememberSaveable { mutableStateOf("") }
var expandedDifficulty by remember { mutableStateOf(false) }
var expandedChapter by remember { mutableStateOf(false) }
var size by remember { mutableStateOf(IntSize.Zero) }
@ -91,7 +90,7 @@ fun CreateLobbyPage(navController: NavController) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(if(isPortrait)16.dp else 5.dp),
.padding(if (isPortrait) 16.dp else 5.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
@ -112,7 +111,7 @@ fun CreateLobbyPage(navController: NavController) {
onValueChange = { lobbyName = it },
modifier = Modifier
.fillMaxWidth(if (isPortrait) 1f else 0.5f)
.padding(if(isPortrait) 8.dp else 4.dp),
.padding(if (isPortrait) 8.dp else 4.dp),
shape = RoundedCornerShape(8.dp),
label = { Text("Lobby Name") }
)
@ -123,7 +122,7 @@ fun CreateLobbyPage(navController: NavController) {
onValueChange = { password = it },
modifier = Modifier
.fillMaxWidth(if (isPortrait) 1f else 0.5f)
.padding(if(isPortrait) 8.dp else 4.dp),
.padding(if (isPortrait) 8.dp else 4.dp),
shape = RoundedCornerShape(8.dp),
label = { Text("Password") },
visualTransformation = PasswordVisualTransformation(),
@ -136,7 +135,7 @@ fun CreateLobbyPage(navController: NavController) {
onValueChange = { nbPlayers = it },
modifier = Modifier
.fillMaxWidth(if (isPortrait) 1f else 0.5f)
.padding(if(isPortrait) 8.dp else 4.dp),
.padding(if (isPortrait) 8.dp else 4.dp),
label = { Text("Number of Players") },
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number)
)
@ -162,7 +161,7 @@ fun CreateLobbyPage(navController: NavController) {
size = it.size
}
.fillMaxWidth(if (isPortrait) 1f else 0.5f)
.padding(if(isPortrait) 8.dp else 4.dp),
.padding(if (isPortrait) 8.dp else 4.dp),
label = { Text("Difficulté") },
trailingIcon = {
Icon(
@ -179,7 +178,7 @@ fun CreateLobbyPage(navController: NavController) {
onDismissRequest = { expandedDifficulty = false },
modifier = Modifier
.width(with(LocalDensity.current) { size.width.toDp() })
.padding(if(isPortrait) 8.dp else 4.dp)
.padding(if (isPortrait) 8.dp else 4.dp)
) {
difficultyOptions.forEach { option ->
DropdownMenuItem(
@ -216,7 +215,7 @@ fun CreateLobbyPage(navController: NavController) {
size = it.size
}
.fillMaxWidth(if (isPortrait) 1f else 0.5f)
.padding(if(isPortrait) 8.dp else 4.dp),
.padding(if (isPortrait) 8.dp else 4.dp),
label = { Text("Chapitre") },
trailingIcon = {
Icon(
@ -233,7 +232,7 @@ fun CreateLobbyPage(navController: NavController) {
onDismissRequest = { expandedChapter = false },
modifier = Modifier
.width(with(LocalDensity.current) { size.width.toDp() })
.padding(if(isPortrait) 8.dp else 4.dp)
.padding(if (isPortrait) 8.dp else 4.dp)
) {
chapterOptions?.forEach { option ->
@ -305,7 +304,7 @@ fun CreateLobbyPage(navController: NavController) {
},
modifier = Modifier
.fillMaxWidth(if (isPortrait) 1f else 0.5f)
.padding(if(isPortrait) 8.dp else 4.dp)
.padding(if (isPortrait) 8.dp else 4.dp)
) {
Text(text = "Create Lobby", color = Colors.White)
}

@ -122,21 +122,42 @@ fun HomePage(navController: NavController) {
Spacer(modifier = Modifier.height(16.dp))
Button(
onClick = {
navController.navigate("connexion")
},
shape = RoundedCornerShape(15),
colors = ButtonDefaults.buttonColors(Colors.Grey),
modifier = Modifier
.fillMaxWidth(if (isPortrait) 1f else 0.5f)
.height(48.dp)
.padding(horizontal = 16.dp)
) {
Text(
text = "Connexion",
color = Color.White
)
if(MainActivity.idPlayerConnected != -1){
Button(
onClick = {
navController.navigate("profilePlayer")
},
shape = RoundedCornerShape(15),
colors = ButtonDefaults.buttonColors(Colors.Grey),
modifier = Modifier
.fillMaxWidth(if (isPortrait) 1f else 0.5f)
.height(48.dp)
.padding(horizontal = 16.dp)
) {
Text(
text = "Profile",
color = Color.White
)
}
}
else {
Button(
onClick = {
navController.navigate("connexion")
},
shape = RoundedCornerShape(15),
colors = ButtonDefaults.buttonColors(Colors.Grey),
modifier = Modifier
.fillMaxWidth(if (isPortrait) 1f else 0.5f)
.height(48.dp)
.padding(horizontal = 16.dp)
) {
Text(
text = "Connexion",
color = Color.White
)
}
}
}
}

@ -1,2 +1,243 @@
package com.example.mathseduc.ui
import android.app.Activity
import android.content.res.Configuration
import android.widget.Toast
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Divider
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.navigation.NavController
import com.example.mathseduc.MainActivity
import com.example.mathseduc.RegisterDialog
import com.example.mathseduc.controllers.ControllerPlayer
import com.example.mathseduc.ui.theme.Colors
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ProfilePlayerPage(navController: NavController) {
val activity = LocalView.current.context as Activity
val player = ControllerPlayer.getPlayerInfoById(MainActivity.idPlayerConnected.toString())
var showDialog by rememberSaveable { mutableStateOf(false) }
val isPortrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT
WindowCompat.setDecorFitsSystemWindows(activity.window, false)
val windowInsetsController = remember {
WindowCompat.getInsetsController(activity.window, activity.window.decorView)
}
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
// Hide the status bar and navigation bar
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
TopAppBar(
colors = TopAppBarDefaults.topAppBarColors(
containerColor = Color.Transparent,
),
title = {},
navigationIcon = {
IconButton(
onClick = { navController.navigate("home") },
modifier = Modifier.size(60.dp)
) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = "Retour",
modifier = Modifier.size(36.dp),
tint = Color.White
)
}
},
)
Column(
modifier = Modifier
.fillMaxSize()
.padding(14.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Column(
modifier = Modifier
.padding(5.dp)
.fillMaxWidth(if (isPortrait) 1f else 0.5f)
.background(Color.White, RoundedCornerShape(16.dp))
.padding(vertical = 8.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Profile",
fontSize = 25.sp,
color = Color.Black,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(10.dp))
Divider(
color = Color.Gray,
thickness = 2.dp,
modifier = Modifier.padding(horizontal = 10.dp)
)
Spacer(modifier = Modifier.height(10.dp))
if (player != null) {
Text(
text = "Nickname : ${player.nickname}",
fontSize = 19.sp,
color = Colors.Black
)
}
Spacer(modifier = Modifier.height(20.dp))
Button(
onClick = { showDialog = true },
shape = RoundedCornerShape(15),
colors = ButtonDefaults.buttonColors(Colors.Blue),
modifier = Modifier
.height(48.dp)
.padding(horizontal = 6.dp)
) {
Text(
text = "Change Information",
color = Color.White
)
}
Spacer(modifier = Modifier.height(10.dp))
Button(
onClick = { },
shape = RoundedCornerShape(15),
colors = ButtonDefaults.buttonColors(Colors.Red),
modifier = Modifier
.height(48.dp)
.padding(horizontal = 16.dp)
) {
Text(
text = "Delete Account",
color = Color.White
)
}
if (showDialog) {
if (player != null) {
ChangeDialog(player.id.toString(),onDismiss = { showDialog = false })
}
}
}
}
}
@Composable
fun ChangeDialog(playerId: String,onDismiss: () -> Unit) {
val context = LocalContext.current
var nickname by rememberSaveable { mutableStateOf("") }
var password by rememberSaveable { mutableStateOf("") }
AlertDialog(
onDismissRequest = {
onDismiss()
},
title = { Text("Change Information") },
confirmButton = {
Button(
colors = ButtonDefaults.buttonColors(Colors.Cyan),
onClick = {
if (nickname.isNotBlank() && password.isNotBlank()) {
/*ControllerPlayer.updatePlayer(playerId,nickname,password)*/
onDismiss()
} else {
Toast.makeText(context, "Please fill in all fields", Toast.LENGTH_SHORT).show()
}
}
) {
Text("Save")
}
},
dismissButton = {
Button(
colors = ButtonDefaults.buttonColors(Colors.BlackGrey),
onClick = {
onDismiss()
}
) {
Text("Dismiss")
}
},
text = {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
) {
OutlinedTextField(
value = nickname,
onValueChange = { nickname = it },
label = { Text("Nickname") },
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
)
OutlinedTextField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Password
),
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
)
}
}
)
}

Loading…
Cancel
Save