From fa91413a985a6166c27f44584f6dbccb10df722e Mon Sep 17 00:00:00 2001 From: Yvan Date: Fri, 29 Mar 2024 14:53:46 +0100 Subject: [PATCH 1/4] feat : ServerDetail Navigation --- .../com/example/mathseduc/AppNavigation.kt | 21 +- .../mathseduc/ServerDetailsActivity.kt | 380 +++++++++--------- .../example/mathseduc/ui/activity_multi.kt | 15 +- 3 files changed, 212 insertions(+), 204 deletions(-) diff --git a/Android/app/src/main/java/com/example/mathseduc/AppNavigation.kt b/Android/app/src/main/java/com/example/mathseduc/AppNavigation.kt index 8765f97..48ba481 100644 --- a/Android/app/src/main/java/com/example/mathseduc/AppNavigation.kt +++ b/Android/app/src/main/java/com/example/mathseduc/AppNavigation.kt @@ -1,9 +1,11 @@ package com.example.mathseduc import androidx.compose.runtime.Composable +import androidx.navigation.NavType import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController +import androidx.navigation.navArgument import com.example.mathseduc.ui.CreateLobbyPage import com.example.mathseduc.ui.HomePage import com.example.mathseduc.ui.MultiPage @@ -17,6 +19,23 @@ fun AppNavigation() { composable("connexion") { ConnexionPlayerContent(navController) } composable("multiplayer") { MultiPage(navController) } composable("createLobby") { CreateLobbyPage(navController) } - //composable("serverDetails/{serverName}/{lobbyId}") { ServerDetailPage(navController) } + composable( + route = "serverDetails/{lobbyName}/{lobbyId}/{lobbyChapter}/{lobbyNbPlayers}/{lobbyDifficulty}", + arguments = listOf( + navArgument("lobbyName") { type = NavType.StringType }, + navArgument("lobbyId") { type = NavType.IntType }, + navArgument("lobbyChapter") { type = NavType.IntType }, + navArgument("lobbyNbPlayers") { type = NavType.IntType }, + navArgument("lobbyDifficulty") { type = NavType.IntType } + ) + ) { backStackEntry -> + val lobbyName = backStackEntry.arguments?.getString("lobbyName") + val lobbyId = backStackEntry.arguments?.getInt("lobbyId") + val lobbyChapter = backStackEntry.arguments?.getInt("lobbyChapter") + val lobbyNbPlayers = backStackEntry.arguments?.getInt("lobbyNbPlayers") + val lobbyDifficulty = backStackEntry.arguments?.getInt("lobbyDifficulty") + + ServerDetailPage(navController, lobbyName,lobbyId, lobbyChapter, lobbyNbPlayers, lobbyDifficulty) + } } } \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt b/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt index 2abc811..7be6123 100644 --- a/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt +++ b/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt @@ -84,7 +84,7 @@ class ServerDetailsActivity : ComponentActivity() { setContent { val navController = rememberNavController() - ServerDetailPage(navController = navController) + //ServerDetailPage(navController = navController) } } @@ -106,221 +106,215 @@ class ServerDetailsActivity : ComponentActivity() { } finish() } +} +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ServerDetailPage(navController: NavController, serverName: String?, lobbyId: Int?, chapterId: Int?, nbPlayers: Int?, lobbyDifficulty: Int?) { + + val context = LocalContext.current + + var isCreator by rememberSaveable { mutableStateOf(false) } + var playerListInfos: List by rememberSaveable { mutableStateOf(emptyList()) } + var playerList by rememberSaveable { mutableStateOf(ControllerPlayer.getPlayersIdFromLobbyId(lobbyId.toString()) ?: emptyList()) } + var refreshState by rememberSaveable { mutableStateOf(true) } + var showDialog by rememberSaveable { mutableStateOf(false) } + + val isPortrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT + val activity = LocalView.current.context as Activity + val windowInsetsController = remember { + WindowCompat.getInsetsController(activity.window, activity.window.decorView) + } - @OptIn(ExperimentalMaterial3Api::class) - @Composable - fun ServerDetailPage(navController: NavController) { - val context = LocalContext.current - - val serverName = intent.getStringExtra("serverName") - val lobbyId = intent.getIntExtra("lobbyId",-1) - val chapterId = intent.getIntExtra("chapterId",-1) - val nbPlayers = intent.getIntExtra("nbPlayers",-1) - val lobbyDifficulty = intent.getIntExtra("lobbyDifficulty",-1) - - var isCreator by rememberSaveable { mutableStateOf(false) } - var playerListInfos: List by rememberSaveable { mutableStateOf(emptyList()) } - var playerList by rememberSaveable { mutableStateOf(ControllerPlayer.getPlayersIdFromLobbyId(lobbyId.toString()) ?: emptyList()) } - var refreshState by rememberSaveable { mutableStateOf(true) } - var showDialog by rememberSaveable { mutableStateOf(false) } - - val isPortrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT - val activity = LocalView.current.context as Activity - val windowInsetsController = remember { - WindowCompat.getInsetsController(activity.window, activity.window.decorView) - } + windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + + windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + + DisposableEffect(refreshState) { + val handler = Handler(Looper.getMainLooper()) + val refreshRunnable = object : Runnable { + override fun run() { + playerList = ControllerPlayer.getPlayersIdFromLobbyId(lobbyId.toString())!! - windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) - - DisposableEffect(refreshState) { - val handler = Handler(Looper.getMainLooper()) - val refreshRunnable = object : Runnable { - override fun run() { - playerList = ControllerPlayer.getPlayersIdFromLobbyId(lobbyId.toString())!! - - playerListInfos = playerList.mapNotNull { playerId -> - ControllerPlayer.getPlayerInfoById(playerId.toString()) - } - - isCreator = ControllerLobby.playerCreatorIdPresentInLobby(MainActivity.idPlayerConnected, lobbyId) - - if(ControllerLobby.lobbyIsLaunched(lobbyId)){ - val intent = Intent(context, QuizMultiActivity::class.java) - intent.putExtra("serverName", serverName) - intent.putExtra("lobbyId", lobbyId) - intent.putExtra("chapterId", chapterId) - intent.putExtra("nbPlayers", nbPlayers) - intent.putExtra("lobbyDifficulty", lobbyDifficulty) - context.startActivity(intent) - refreshState = false - } - - if (refreshState){ - handler.postDelayed(this,3000) - Log.e("MainActivity", "Refresh ServerDetails") - } + playerListInfos = playerList.mapNotNull { playerId -> + ControllerPlayer.getPlayerInfoById(playerId.toString()) } - } - handler.post(refreshRunnable) + isCreator = ControllerLobby.playerCreatorIdPresentInLobby(MainActivity.idPlayerConnected, lobbyId!!) + + if(ControllerLobby.lobbyIsLaunched(lobbyId)){ + val intent = Intent(context, QuizMultiActivity::class.java) + intent.putExtra("serverName", serverName) + intent.putExtra("lobbyId", lobbyId) + intent.putExtra("chapterId", chapterId) + intent.putExtra("nbPlayers", nbPlayers) + intent.putExtra("lobbyDifficulty", lobbyDifficulty) + context.startActivity(intent) + refreshState = false + } - onDispose { - refreshState = false - handler.removeCallbacks(refreshRunnable) + if (refreshState){ + handler.postDelayed(this,3000) + Log.e("MainActivity", "Refresh ServerDetails") + } } } - TopAppBar( - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - ), - title = {}, - navigationIcon = { - IconButton( - onClick = { showDialog = true }, - modifier = Modifier.size(60.dp) - ) { - Icon( - imageVector = Icons.Filled.ArrowBack, - contentDescription = "Retour", - modifier = Modifier.size(36.dp), - tint = Color.White - ) - } - }, + handler.post(refreshRunnable) + + onDispose { + refreshState = false + handler.removeCallbacks(refreshRunnable) + } + } + + TopAppBar( + colors = TopAppBarDefaults.topAppBarColors( + containerColor = Color.Transparent, + ), + title = {}, + navigationIcon = { + IconButton( + onClick = { showDialog = true }, + modifier = Modifier.size(60.dp) + ) { + Icon( + imageVector = Icons.Filled.ArrowBack, + contentDescription = "Retour", + modifier = Modifier.size(36.dp), + tint = Color.White + ) + } + }, + ) + + val modifier = Modifier + .fillMaxSize() + .padding(start = 16.dp, end = 16.dp, bottom = 16.dp, top = 8.dp) + + Column( + modifier = modifier, + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = serverName!!, + color = Color.White, + fontSize = 30.sp, + fontWeight = FontWeight.Bold ) - val modifier = Modifier - .fillMaxSize() - .padding(start = 16.dp, end = 16.dp, bottom = 16.dp, top = 8.dp) + Spacer(modifier = Modifier.height(if(isPortrait)25.dp else 10.dp)) - Column( - modifier = modifier, - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { Text( - text = serverName!!, - color = Color.White, - fontSize = 30.sp, - fontWeight = FontWeight.Bold + text = "Lobby Settings", + fontSize = 23.sp, + color = Color.White, + fontWeight = FontWeight.Bold + ) + Text( + text = "Chapter : ${ControllerChapter.getChapterNameById(chapterId!!).toString()}", + fontSize = 19.sp, + color = Color.White + ) + Row { + Text( + text = "Players : ${ControllerLobby.getNbPlayerInLobby(lobbyId!!)}/${nbPlayers}", + fontSize = 19.sp, + color = (if(ControllerLobby.getNbPlayerInLobby(lobbyId)==nbPlayers) Color.Red else Color.White) + ) + Spacer(modifier = Modifier.width(40.dp)) + Text( + text = "Difficulty : $lobbyDifficulty", + fontSize = 19.sp, + color = Colors.White, ) + } - Spacer(modifier = Modifier.height(if(isPortrait)25.dp else 10.dp)) + Spacer(modifier = Modifier.height(if(isPortrait)30.dp else 10.dp)) + Text( + text = "Player Name", + fontSize = 19.sp, + modifier = Modifier.background(Color.Black), + color = Colors.White, + ) + Divider( + color = Color.Gray, + thickness = 2.dp, + modifier = Modifier.fillMaxWidth() + ) + LazyColumn( + modifier = Modifier + .fillMaxSize() + .weight(0.75f) + .padding(top = 1.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + items(playerListInfos) { player -> Text( - text = "Lobby Settings", - fontSize = 23.sp, - color = Color.White, - fontWeight = FontWeight.Bold - ) - Text( - text = "Chapter : ${ControllerChapter.getChapterNameById(chapterId).toString()}", - fontSize = 19.sp, - color = Color.White - ) - Row { - Text( - text = "Players : ${ControllerLobby.getNbPlayerInLobby(lobbyId)}/${nbPlayers}", - fontSize = 19.sp, - color = (if(ControllerLobby.getNbPlayerInLobby(lobbyId)==nbPlayers) Color.Red else Color.White) - ) - Spacer(modifier = Modifier.width(40.dp)) - Text( - text = "Difficulty : $lobbyDifficulty", - fontSize = 19.sp, - color = Colors.White, + text = player.nickname, + fontSize = 18.sp, + color = Colors.White, + modifier = Modifier + .weight(1f) + .padding(top = if (isPortrait) 5.dp else 1.dp) ) } - - Spacer(modifier = Modifier.height(if(isPortrait)30.dp else 10.dp)) - - Text( - text = "Player Name", - fontSize = 19.sp, - modifier = Modifier.background(Color.Black), - color = Colors.White, - ) - Divider( - color = Color.Gray, - thickness = 2.dp, - modifier = Modifier.fillMaxWidth() - ) - LazyColumn( + } + if (isCreator) { + val formDataBuilder = MultipartBody.Builder().setType(MultipartBody.FORM) + formDataBuilder.addFormDataPart("launched", "1") + Button( + onClick = { + ControllerLobby.updateLobbyLauched(lobbyId!!,formDataBuilder) + }, + shape = RoundedCornerShape(15), + enabled = isCreator, + colors = ButtonDefaults.buttonColors(Colors.Green), modifier = Modifier - .fillMaxSize() - .weight(0.75f) - .padding(top = 1.dp), - horizontalAlignment = Alignment.CenterHorizontally + .fillMaxWidth() + .height(48.dp) ) { - items(playerListInfos) { player -> - Text( - text = player.nickname, - fontSize = 18.sp, - color = Colors.White, - modifier = Modifier - .weight(1f) - .padding(top = if (isPortrait) 5.dp else 1.dp) - ) - } + Text( + text = "LAUNCH", + color = Color.White, + fontWeight = FontWeight.Bold + ) } - if (isCreator) { - val formDataBuilder = MultipartBody.Builder().setType(MultipartBody.FORM) - formDataBuilder.addFormDataPart("launched", "1") + } + if (showDialog) { + LeaveLobbyDialog(serverName, onConfirmLeave = {navController.navigate("multiplayer")},onCancelLeave = { showDialog = false }) + } + } +} +@Composable +fun LeaveLobbyDialog(namelobby: String, onConfirmLeave: () -> Unit, onCancelLeave: () -> Unit) { + val context = LocalContext.current + + AlertDialog( + onDismissRequest = onCancelLeave, + title = { Text("Confirm leaving lobby") }, + confirmButton = { Button( - onClick = { - ControllerLobby.updateLobbyLauched(lobbyId,formDataBuilder) - }, - shape = RoundedCornerShape(15), - enabled = isCreator, - colors = ButtonDefaults.buttonColors(Colors.Green), - modifier = Modifier - .fillMaxWidth() - .height(48.dp) + onClick = { + onConfirmLeave() + } ) { - Text( - text = "LAUNCH", - color = Color.White, - fontWeight = FontWeight.Bold - ) + Text("Leave") } - } - if (showDialog) { - LeaveLobbyDialog(serverName, onConfirmLeave = {navController.navigate("multiplayer")},onCancelLeave = { showDialog = false }) - } - } - } - @Composable - fun LeaveLobbyDialog(namelobby: String, onConfirmLeave: () -> Unit, onCancelLeave: () -> Unit) { - val context = LocalContext.current - - AlertDialog( - onDismissRequest = onCancelLeave, - title = { Text("Confirm leaving lobby") }, - confirmButton = { - Button( - onClick = { - onConfirmLeave() - } - ) { - Text("Leave") - } - }, - dismissButton = { - Button( - onClick = { - onCancelLeave() - } - ) { - Text("Cancel") - } - }, - text = { - Text("Are you sure you want to leave the lobby $namelobby?") + }, + dismissButton = { + Button( + onClick = { + onCancelLeave() + } + ) { + Text("Cancel") } - ) - } - + }, + text = { + Text("Are you sure you want to leave the lobby $namelobby?") + } + ) } + diff --git a/Android/app/src/main/java/com/example/mathseduc/ui/activity_multi.kt b/Android/app/src/main/java/com/example/mathseduc/ui/activity_multi.kt index 3db7d83..682599e 100644 --- a/Android/app/src/main/java/com/example/mathseduc/ui/activity_multi.kt +++ b/Android/app/src/main/java/com/example/mathseduc/ui/activity_multi.kt @@ -2,7 +2,6 @@ package com.example.mathseduc.ui import android.app.Activity import android.content.Context -import android.content.Intent import android.content.res.Configuration import android.util.Log import android.widget.Toast @@ -57,7 +56,6 @@ import androidx.core.view.WindowInsetsControllerCompat import androidx.lifecycle.ViewModelProvider import androidx.navigation.NavController import com.example.mathseduc.MainActivity -import com.example.mathseduc.ServerDetailsActivity import com.example.mathseduc.controllers.ControllerChapter import com.example.mathseduc.controllers.ControllerLobby import com.example.mathseduc.controllers.ControllerUtiliser @@ -65,6 +63,7 @@ import com.example.mathseduc.models.Lobby import com.example.mathseduc.ui.theme.Colors import com.example.mathseduc.viewModel.MultiPageViewModel import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.MultipartBody @@ -224,14 +223,10 @@ private suspend fun createUtiliserForLobby(context: Context, lobby: Lobby, navCo ControllerUtiliser.createUtiliserByIdLobby(formDataBuilder) // Naviguer vers l'activité ServerDetails avec les détails du lobby - val intent = Intent(context, ServerDetailsActivity::class.java) - intent.putExtra("serverName", lobby.name) - intent.putExtra("lobbyId", lobby.id) - intent.putExtra("chapterId", lobby.idchapter) - intent.putExtra("nbPlayers", lobby.nbplayers) - intent.putExtra("lobbyDifficulty", lobby.difficulty) - context.startActivity(intent) - //navController.navigate("serverDetails/${lobby.name}/${lobby.id}") + val mainScope = MainScope() + mainScope.launch { + navController.navigate("serverDetails/${lobby.name}/${lobby.id}/${lobby.idchapter}/${lobby.nbplayers}/${lobby.difficulty}") + } } } From 69e477b3ca7daf3a0890803c31766c3e7256be87 Mon Sep 17 00:00:00 2001 From: Yvan Date: Fri, 29 Mar 2024 17:07:39 +0100 Subject: [PATCH 2/4] feat : Navigation createLobby to ServerDetail + launch --- .../com/example/mathseduc/AppNavigation.kt | 10 ++++++++ .../example/mathseduc/QuizMultiActivity.kt | 7 +++--- .../mathseduc/ServerDetailsActivity.kt | 14 ++++------- .../mathseduc/ui/activity_create_lobby.kt | 13 +--------- .../mathseduc/ui/activity_quiz_multi.kt | 24 +++++++++---------- 5 files changed, 29 insertions(+), 39 deletions(-) diff --git a/Android/app/src/main/java/com/example/mathseduc/AppNavigation.kt b/Android/app/src/main/java/com/example/mathseduc/AppNavigation.kt index 48ba481..9865efd 100644 --- a/Android/app/src/main/java/com/example/mathseduc/AppNavigation.kt +++ b/Android/app/src/main/java/com/example/mathseduc/AppNavigation.kt @@ -9,6 +9,7 @@ import androidx.navigation.navArgument import com.example.mathseduc.ui.CreateLobbyPage import com.example.mathseduc.ui.HomePage import com.example.mathseduc.ui.MultiPage +import com.example.mathseduc.ui.QuizMultiScreen @Composable fun AppNavigation() { @@ -37,5 +38,14 @@ fun AppNavigation() { ServerDetailPage(navController, lobbyName,lobbyId, lobbyChapter, lobbyNbPlayers, lobbyDifficulty) } + composable( + route = "quizMultiScreen/{lobbyId}", + arguments = listOf( + navArgument("lobbyId") { type = NavType.IntType } + ) + ) { backStackEntry -> + val lobbyId = backStackEntry.arguments?.getInt("lobbyId") + QuizMultiScreen(navController, lobbyId) + } } } \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/mathseduc/QuizMultiActivity.kt b/Android/app/src/main/java/com/example/mathseduc/QuizMultiActivity.kt index 6e5190c..188152a 100644 --- a/Android/app/src/main/java/com/example/mathseduc/QuizMultiActivity.kt +++ b/Android/app/src/main/java/com/example/mathseduc/QuizMultiActivity.kt @@ -4,9 +4,6 @@ import android.os.Bundle import android.os.CountDownTimer import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.runtime.Composable -import androidx.compose.ui.tooling.preview.Preview -import com.example.mathseduc.ui.QuizMultiScreen import com.example.mathseduc.ui.theme.MathsEducTheme @@ -20,10 +17,12 @@ class QuizMultiActivity : ComponentActivity() { setContent { MathsEducTheme { + /* val lobbyId = intent.getIntExtra("lobbyId",-1) val serverName = intent.getStringExtra("serverName") - QuizMultiScreen(lobbyId, serverName!!, activity = this@QuizMultiActivity) //TODO sus + QuizMultiScreen(lobbyId, serverName!!) //TODO sus + */ } } } diff --git a/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt b/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt index 7be6123..a500454 100644 --- a/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt +++ b/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt @@ -1,7 +1,6 @@ package com.example.mathseduc import android.app.Activity -import android.content.Intent import android.content.res.Configuration import android.os.Bundle import android.os.Handler @@ -56,7 +55,6 @@ import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsControllerCompat import androidx.navigation.NavController -import androidx.navigation.compose.rememberNavController import com.example.mathseduc.controllers.ControllerChapter import com.example.mathseduc.controllers.ControllerLobby import com.example.mathseduc.controllers.ControllerPlayer @@ -83,8 +81,10 @@ class ServerDetailsActivity : ComponentActivity() { onBackPressedDispatcher.addCallback(this, onBackPressedCallback) setContent { + /* val navController = rememberNavController() - //ServerDetailPage(navController = navController) + ServerDetailPage(navController = navController) + */ } } @@ -142,13 +142,7 @@ fun ServerDetailPage(navController: NavController, serverName: String?, lobbyId: isCreator = ControllerLobby.playerCreatorIdPresentInLobby(MainActivity.idPlayerConnected, lobbyId!!) if(ControllerLobby.lobbyIsLaunched(lobbyId)){ - val intent = Intent(context, QuizMultiActivity::class.java) - intent.putExtra("serverName", serverName) - intent.putExtra("lobbyId", lobbyId) - intent.putExtra("chapterId", chapterId) - intent.putExtra("nbPlayers", nbPlayers) - intent.putExtra("lobbyDifficulty", lobbyDifficulty) - context.startActivity(intent) + navController.navigate("quizMultiScreen/${lobbyId}") refreshState = false } diff --git a/Android/app/src/main/java/com/example/mathseduc/ui/activity_create_lobby.kt b/Android/app/src/main/java/com/example/mathseduc/ui/activity_create_lobby.kt index 1d85b70..1c88851 100644 --- a/Android/app/src/main/java/com/example/mathseduc/ui/activity_create_lobby.kt +++ b/Android/app/src/main/java/com/example/mathseduc/ui/activity_create_lobby.kt @@ -2,7 +2,6 @@ package com.example.mathseduc.ui import android.app.Activity -import android.content.Intent import android.content.res.Configuration import android.util.Log import android.widget.Toast @@ -35,7 +34,6 @@ import androidx.compose.runtime.remember 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 +43,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 @@ -53,9 +50,7 @@ import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsControllerCompat import androidx.navigation.NavController -import androidx.navigation.compose.rememberNavController import com.example.mathseduc.MainActivity -import com.example.mathseduc.ServerDetailsActivity import com.example.mathseduc.controllers.ControllerChapter import com.example.mathseduc.controllers.ControllerLobby import com.example.mathseduc.controllers.ControllerUtiliser @@ -286,13 +281,7 @@ fun CreateLobbyPage(navController: NavController) { ControllerUtiliser.createUtiliserByIdLobby(formDataBuilderConnexion) Toast.makeText(context, "Lobby created successfully!", Toast.LENGTH_SHORT).show() - val intent = Intent(context, ServerDetailsActivity::class.java) - intent.putExtra("lobbyId", lobbyId) - intent.putExtra("serverName", lobbyName) - intent.putExtra("chapterId", selectedChapter.id.toInt()) - intent.putExtra("nbPlayers", nbPlayers.toInt()) - intent.putExtra("lobbyDifficulty", difficultyNum) - context.startActivity(intent) + navController.navigate("serverDetails/${lobbyName}/${lobbyId}/${selectedChapter.id.toInt()}/${nbPlayers}/${difficultyNum}") } else { Toast.makeText(context, "Failed to create lobby. Please try again.", Toast.LENGTH_SHORT).show() } diff --git a/Android/app/src/main/java/com/example/mathseduc/ui/activity_quiz_multi.kt b/Android/app/src/main/java/com/example/mathseduc/ui/activity_quiz_multi.kt index 682a9b9..8bdd02c 100644 --- a/Android/app/src/main/java/com/example/mathseduc/ui/activity_quiz_multi.kt +++ b/Android/app/src/main/java/com/example/mathseduc/ui/activity_quiz_multi.kt @@ -1,6 +1,6 @@ package com.example.mathseduc.ui -import android.content.Intent +import android.app.Activity import android.widget.Toast import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement @@ -26,15 +26,15 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView import androidx.compose.ui.text.style.TextAlign 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.QuizMultiActivity -import com.example.mathseduc.ServerDetailsActivity import com.example.mathseduc.controllers.ControllerLobby import com.example.mathseduc.controllers.ControllerQuestion import com.example.mathseduc.ui.theme.Colors @@ -43,16 +43,17 @@ import okhttp3.MultipartBody @Composable -fun QuizMultiScreen(lobbyId: Int,serverName: String,activity: QuizMultiActivity) { +fun QuizMultiScreen(navController: NavController, lobbyId: Int?) { val context = LocalContext.current + val activity = LocalView.current.context as Activity var chronoValue by remember { mutableStateOf(0.0f) } - var listQuestion by remember { mutableStateOf(ControllerQuestion.getQuestionsForLobby(ControllerLobby.getIdQuestionsLobby(lobbyId))) } - var listPlayer by remember { mutableStateOf(ControllerLobby.getPlayerInLobby(lobbyId)) } + var listQuestion by remember { mutableStateOf(ControllerQuestion.getQuestionsForLobby(ControllerLobby.getIdQuestionsLobby(lobbyId!!))) } + var listPlayer by remember { mutableStateOf(ControllerLobby.getPlayerInLobby(lobbyId!!)) } var currentQuestionIndex by remember { mutableIntStateOf(0) } val progressBarValues by remember { mutableStateOf(Array(listPlayer.size) { 0.0f }) } val progressBarTotalValues by remember { mutableStateOf(Array(listPlayer.size) { 0.0f }) } - var quizFinished by remember { mutableStateOf(false) } // Variable pour indiquer si le quiz est terminé ou non + var quizFinished by remember { mutableStateOf(false) } val windowInsetsController = remember { WindowCompat.getInsetsController(activity.window, activity.window.decorView) @@ -81,7 +82,7 @@ fun QuizMultiScreen(lobbyId: Int,serverName: String,activity: QuizMultiActivity) val timer = ticker(delayMillis = 3000) for (tick in timer) { if (quizFinished) break - var valueBD = ControllerLobby.getPlayerInLobby(lobbyId) + var valueBD = ControllerLobby.getPlayerInLobby(lobbyId!!) for ((index, player) in listPlayer.withIndex()) { progressBarTotalValues[index] = progressBarValues[index] + valueBD[index].playertime } @@ -150,7 +151,7 @@ fun QuizMultiScreen(lobbyId: Int,serverName: String,activity: QuizMultiActivity) Toast.makeText(context, "Oh ouii !!", Toast.LENGTH_SHORT).show() val formDataBuilder = MultipartBody.Builder().setType(MultipartBody.FORM) - val playertime = ControllerLobby.getLobbyUtiliserPlayerTime(lobbyId,MainActivity.idPlayerConnected) + 10 + val playertime = ControllerLobby.getLobbyUtiliserPlayerTime(lobbyId!!,MainActivity.idPlayerConnected) + 10 formDataBuilder.addFormDataPart("playertime", playertime.toString()) ControllerLobby.updateLobbyUtiliserPlayerTime(lobbyId,MainActivity.idPlayerConnected,formDataBuilder) @@ -191,10 +192,7 @@ fun QuizMultiScreen(lobbyId: Int,serverName: String,activity: QuizMultiActivity) } } else { Toast.makeText(context, "Fini !!", Toast.LENGTH_SHORT).show() - val intent = Intent(context, MainActivity::class.java) - //intent.putExtra("serverName", serverName) - //intent.putExtra("lobbyId", lobbyId) - context.startActivity(intent) + navController.navigate("home") quizFinished = true } } From f6f63d73ad640b4da12b29e0dd1a0a8808b58a8c Mon Sep 17 00:00:00 2001 From: "jeremy.ducourthial" Date: Fri, 29 Mar 2024 18:32:51 +0100 Subject: [PATCH 3/4] feat : finition ServerDetailsViewModel + ajout CreateLobbyViewModel --- Android/app/build.gradle.kts | 1 + .../example/mathseduc/CreateLobbyActivity.kt | 4 +- .../mathseduc/ServerDetailsActivity.kt | 46 ++++++----- .../mathseduc/ui/activity_create_lobby.kt | 60 ++++++++------- .../example/mathseduc/ui/activity_multi.kt | 2 +- .../viewModel/CreateLobbyViewModel.kt | 77 +++++++++++++++++++ .../mathseduc/viewModel/MultiPageViewModel.kt | 8 -- .../viewModel/ServerDetailsViewModel.kt | 64 +++++++++++++-- 8 files changed, 198 insertions(+), 64 deletions(-) create mode 100644 Android/app/src/main/java/com/example/mathseduc/viewModel/CreateLobbyViewModel.kt diff --git a/Android/app/build.gradle.kts b/Android/app/build.gradle.kts index 3aa618f..6e075ee 100644 --- a/Android/app/build.gradle.kts +++ b/Android/app/build.gradle.kts @@ -62,6 +62,7 @@ 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.navigation:navigation-runtime-ktx:2.7.7") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") diff --git a/Android/app/src/main/java/com/example/mathseduc/CreateLobbyActivity.kt b/Android/app/src/main/java/com/example/mathseduc/CreateLobbyActivity.kt index de6a233..df6a9be 100644 --- a/Android/app/src/main/java/com/example/mathseduc/CreateLobbyActivity.kt +++ b/Android/app/src/main/java/com/example/mathseduc/CreateLobbyActivity.kt @@ -3,6 +3,8 @@ package com.example.mathseduc import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.ViewModelStoreOwner import androidx.navigation.compose.rememberNavController import com.example.mathseduc.ui.CreateLobbyPage @@ -11,7 +13,7 @@ class CreateLobbyActivity : ComponentActivity() { super.onCreate(savedInstanceState) setContent { val navController = rememberNavController() - CreateLobbyPage(navController) + CreateLobbyPage(navController = navController) } } } \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt b/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt index 2abc811..3b74863 100644 --- a/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt +++ b/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt @@ -38,6 +38,7 @@ import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -55,6 +56,8 @@ import androidx.compose.ui.unit.sp import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsControllerCompat +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.ViewModelStoreOwner import androidx.navigation.NavController import androidx.navigation.compose.rememberNavController import com.example.mathseduc.controllers.ControllerChapter @@ -63,6 +66,7 @@ import com.example.mathseduc.controllers.ControllerPlayer import com.example.mathseduc.controllers.ControllerUtiliser import com.example.mathseduc.models.Player import com.example.mathseduc.ui.theme.Colors +import com.example.mathseduc.viewModel.ServerDetailsViewModel import okhttp3.MultipartBody class ServerDetailsActivity : ComponentActivity() { @@ -111,6 +115,8 @@ class ServerDetailsActivity : ComponentActivity() { @Composable fun ServerDetailPage(navController: NavController) { val context = LocalContext.current + val viewModelStoreOwner = LocalContext.current as ViewModelStoreOwner + val viewModel = ViewModelProvider(viewModelStoreOwner).get(ServerDetailsViewModel::class.java) val serverName = intent.getStringExtra("serverName") val lobbyId = intent.getIntExtra("lobbyId",-1) @@ -118,14 +124,15 @@ class ServerDetailsActivity : ComponentActivity() { val nbPlayers = intent.getIntExtra("nbPlayers",-1) val lobbyDifficulty = intent.getIntExtra("lobbyDifficulty",-1) - var isCreator by rememberSaveable { mutableStateOf(false) } - var playerListInfos: List by rememberSaveable { mutableStateOf(emptyList()) } - var playerList by rememberSaveable { mutableStateOf(ControllerPlayer.getPlayersIdFromLobbyId(lobbyId.toString()) ?: emptyList()) } - var refreshState by rememberSaveable { mutableStateOf(true) } - var showDialog by rememberSaveable { mutableStateOf(false) } + val playerList by viewModel.playerList.collectAsState(initial = emptyList()) + val playerListInfos by viewModel.playerListInfos.collectAsState(initial = emptyList()) + val isCreator by viewModel.isCreator.collectAsState(false) + val refreshState by viewModel.refreshState.collectAsState(true) + val showDialog by viewModel.showDialog.collectAsState(false) val isPortrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT val activity = LocalView.current.context as Activity + val windowInsetsController = remember { WindowCompat.getInsetsController(activity.window, activity.window.decorView) } @@ -138,15 +145,11 @@ class ServerDetailsActivity : ComponentActivity() { val handler = Handler(Looper.getMainLooper()) val refreshRunnable = object : Runnable { override fun run() { - playerList = ControllerPlayer.getPlayersIdFromLobbyId(lobbyId.toString())!! - - playerListInfos = playerList.mapNotNull { playerId -> - ControllerPlayer.getPlayerInfoById(playerId.toString()) - } - - isCreator = ControllerLobby.playerCreatorIdPresentInLobby(MainActivity.idPlayerConnected, lobbyId) + viewModel.updatePlayerList(lobbyId) + viewModel.updatePlayerListInfos() + viewModel.updateIsCreator(lobbyId) - if(ControllerLobby.lobbyIsLaunched(lobbyId)){ + if(viewModel.Launchedlobby(lobbyId)){ val intent = Intent(context, QuizMultiActivity::class.java) intent.putExtra("serverName", serverName) intent.putExtra("lobbyId", lobbyId) @@ -154,7 +157,7 @@ class ServerDetailsActivity : ComponentActivity() { intent.putExtra("nbPlayers", nbPlayers) intent.putExtra("lobbyDifficulty", lobbyDifficulty) context.startActivity(intent) - refreshState = false + viewModel.updateRefresh(false) } if (refreshState){ @@ -167,7 +170,7 @@ class ServerDetailsActivity : ComponentActivity() { handler.post(refreshRunnable) onDispose { - refreshState = false + viewModel.updateRefresh(false) handler.removeCallbacks(refreshRunnable) } } @@ -179,7 +182,7 @@ class ServerDetailsActivity : ComponentActivity() { title = {}, navigationIcon = { IconButton( - onClick = { showDialog = true }, + onClick = { viewModel.updateShowDialog(true) }, modifier = Modifier.size(60.dp) ) { Icon( @@ -217,15 +220,15 @@ class ServerDetailsActivity : ComponentActivity() { fontWeight = FontWeight.Bold ) Text( - text = "Chapter : ${ControllerChapter.getChapterNameById(chapterId).toString()}", + text = "Chapter : ${viewModel.getChapterNameById(chapterId).toString()}", fontSize = 19.sp, color = Color.White ) Row { Text( - text = "Players : ${ControllerLobby.getNbPlayerInLobby(lobbyId)}/${nbPlayers}", + text = "Players : ${playerListInfos.size}/${nbPlayers}", fontSize = 19.sp, - color = (if(ControllerLobby.getNbPlayerInLobby(lobbyId)==nbPlayers) Color.Red else Color.White) + color = (if(viewModel.getNbPlayerInLobby(lobbyId)==nbPlayers) Color.Red else Color.White) ) Spacer(modifier = Modifier.width(40.dp)) Text( @@ -271,7 +274,7 @@ class ServerDetailsActivity : ComponentActivity() { formDataBuilder.addFormDataPart("launched", "1") Button( onClick = { - ControllerLobby.updateLobbyLauched(lobbyId,formDataBuilder) + viewModel.updateLobbyLauched(lobbyId,formDataBuilder) }, shape = RoundedCornerShape(15), enabled = isCreator, @@ -288,7 +291,7 @@ class ServerDetailsActivity : ComponentActivity() { } } if (showDialog) { - LeaveLobbyDialog(serverName, onConfirmLeave = {navController.navigate("multiplayer")},onCancelLeave = { showDialog = false }) + LeaveLobbyDialog(serverName, onConfirmLeave = {navController.navigate("multiplayer")},onCancelLeave = { viewModel.updateShowDialog(false) }) } } } @@ -302,6 +305,7 @@ class ServerDetailsActivity : ComponentActivity() { confirmButton = { Button( onClick = { + myBackPressed() onConfirmLeave() } ) { diff --git a/Android/app/src/main/java/com/example/mathseduc/ui/activity_create_lobby.kt b/Android/app/src/main/java/com/example/mathseduc/ui/activity_create_lobby.kt index 1d85b70..1da9cd5 100644 --- a/Android/app/src/main/java/com/example/mathseduc/ui/activity_create_lobby.kt +++ b/Android/app/src/main/java/com/example/mathseduc/ui/activity_create_lobby.kt @@ -29,6 +29,7 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -52,29 +53,36 @@ import androidx.compose.ui.unit.sp import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsControllerCompat +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.ViewModelStoreOwner import androidx.navigation.NavController -import androidx.navigation.compose.rememberNavController import com.example.mathseduc.MainActivity import com.example.mathseduc.ServerDetailsActivity import com.example.mathseduc.controllers.ControllerChapter import com.example.mathseduc.controllers.ControllerLobby import com.example.mathseduc.controllers.ControllerUtiliser import com.example.mathseduc.ui.theme.Colors +import com.example.mathseduc.viewModel.CreateLobbyViewModel +import com.example.mathseduc.viewModel.ServerDetailsViewModel 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 expandedDifficulty by remember { mutableStateOf(false) } - var expandedChapter by remember { mutableStateOf(false) } - var size by remember { mutableStateOf(IntSize.Zero) } + val viewModelStoreOwner = LocalContext.current as ViewModelStoreOwner + + val viewModel = ViewModelProvider(viewModelStoreOwner).get(CreateLobbyViewModel::class.java) val difficultyOptions = listOf("Facile", "Moyen", "Difficile") + val lobbyName by viewModel.lobbyName.collectAsState("") + val password by viewModel.password.collectAsState("") + val nbPlayers by viewModel.nbPlayers.collectAsState("") + val difficulty by viewModel.difficulty.collectAsState("") + val chapter by viewModel.chapter.collectAsState("") + val expandedDifficulty by viewModel.expandedDifficulty.collectAsState(false) + val expandedChapter by viewModel.expandedChapter.collectAsState(false) + val size by viewModel.size.collectAsState(IntSize.Zero) + val context = LocalContext.current val activity = LocalView.current.context as Activity val keyboardController = LocalSoftwareKeyboardController.current @@ -109,7 +117,7 @@ fun CreateLobbyPage(navController: NavController) { ) { TextField( value = lobbyName, - onValueChange = { lobbyName = it }, + onValueChange = { viewModel.updateLobbyName(it) }, modifier = Modifier .fillMaxWidth(if (isPortrait) 1f else 0.5f) .padding(if(isPortrait) 8.dp else 4.dp), @@ -120,7 +128,7 @@ fun CreateLobbyPage(navController: NavController) { TextField( value = password, - onValueChange = { password = it }, + onValueChange = { viewModel.updatePassword(it) }, modifier = Modifier .fillMaxWidth(if (isPortrait) 1f else 0.5f) .padding(if(isPortrait) 8.dp else 4.dp), @@ -133,7 +141,7 @@ fun CreateLobbyPage(navController: NavController) { TextField( value = nbPlayers, - onValueChange = { nbPlayers = it }, + onValueChange = { viewModel.updateNbPlayers(it) }, modifier = Modifier .fillMaxWidth(if (isPortrait) 1f else 0.5f) .padding(if(isPortrait) 8.dp else 4.dp), @@ -145,7 +153,7 @@ fun CreateLobbyPage(navController: NavController) { Box{ TextField( value = difficulty, - onValueChange = { difficulty = it }, + onValueChange = { viewModel.updateDifficulty(it) }, readOnly = true, enabled = false, colors = TextFieldDefaults.colors( @@ -156,10 +164,10 @@ fun CreateLobbyPage(navController: NavController) { ), modifier = Modifier .clickable(onClick = { - expandedDifficulty = !expandedDifficulty + viewModel.updateExpandedDifficulty(!expandedDifficulty) }) .onGloballyPositioned { - size = it.size + viewModel.updateSize(it.size) } .fillMaxWidth(if (isPortrait) 1f else 0.5f) .padding(if(isPortrait) 8.dp else 4.dp), @@ -169,14 +177,14 @@ fun CreateLobbyPage(navController: NavController) { Icons.Default.ArrowDropDown, contentDescription = null, Modifier.clickable { - expandedDifficulty = !expandedDifficulty + viewModel.updateExpandedDifficulty(!expandedDifficulty) } ) } ) DropdownMenu( expanded = expandedDifficulty, - onDismissRequest = { expandedDifficulty = false }, + onDismissRequest = { viewModel.updateExpandedDifficulty(false) }, modifier = Modifier .width(with(LocalDensity.current) { size.width.toDp() }) .padding(if(isPortrait) 8.dp else 4.dp) @@ -185,8 +193,8 @@ fun CreateLobbyPage(navController: NavController) { DropdownMenuItem( text = { Text(option, color = Colors.Black) }, onClick = { - difficulty = option - expandedDifficulty = false + viewModel.updateDifficulty(option) + viewModel.updateExpandedDifficulty(false) keyboardController?.hide() } ) @@ -199,7 +207,7 @@ fun CreateLobbyPage(navController: NavController) { val chapterOptions = ControllerChapter.getChapters() TextField( value = chapter, - onValueChange = { chapter = it }, + onValueChange = { viewModel.updatechapter(it) }, readOnly = true, enabled = false, colors = TextFieldDefaults.colors( @@ -210,10 +218,10 @@ fun CreateLobbyPage(navController: NavController) { ), modifier = Modifier .clickable(onClick = { - expandedChapter = !expandedChapter + viewModel.updateExpandedChapter(!expandedChapter) }) .onGloballyPositioned { - size = it.size + viewModel.updateSize(it.size) } .fillMaxWidth(if (isPortrait) 1f else 0.5f) .padding(if(isPortrait) 8.dp else 4.dp), @@ -223,14 +231,14 @@ fun CreateLobbyPage(navController: NavController) { Icons.Default.ArrowDropDown, contentDescription = null, Modifier.clickable { - expandedChapter = !expandedChapter + viewModel.updateExpandedChapter(!expandedChapter) } ) } ) DropdownMenu( expanded = expandedChapter, - onDismissRequest = { expandedChapter = false }, + onDismissRequest = { viewModel.updateExpandedChapter(false) }, modifier = Modifier .width(with(LocalDensity.current) { size.width.toDp() }) .padding(if(isPortrait) 8.dp else 4.dp) @@ -240,8 +248,8 @@ fun CreateLobbyPage(navController: NavController) { DropdownMenuItem( text = { Text(option.name, color = Colors.Black) }, onClick = { - chapter = option.name - expandedChapter = false + viewModel.updatechapter( option.name ) + viewModel.updateExpandedChapter(false) keyboardController?.hide() } ) diff --git a/Android/app/src/main/java/com/example/mathseduc/ui/activity_multi.kt b/Android/app/src/main/java/com/example/mathseduc/ui/activity_multi.kt index 3db7d83..180d7d4 100644 --- a/Android/app/src/main/java/com/example/mathseduc/ui/activity_multi.kt +++ b/Android/app/src/main/java/com/example/mathseduc/ui/activity_multi.kt @@ -91,7 +91,7 @@ fun MultiPage(navController: NavController) { windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - // Hide the status bar and navigation bar FERME TA GUEULE !!! + // Hide the status bar and navigation bar windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) diff --git a/Android/app/src/main/java/com/example/mathseduc/viewModel/CreateLobbyViewModel.kt b/Android/app/src/main/java/com/example/mathseduc/viewModel/CreateLobbyViewModel.kt new file mode 100644 index 0000000..73b26b1 --- /dev/null +++ b/Android/app/src/main/java/com/example/mathseduc/viewModel/CreateLobbyViewModel.kt @@ -0,0 +1,77 @@ +package com.example.mathseduc.viewModel + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.unit.IntSize +import androidx.lifecycle.ViewModel +import com.example.mathseduc.MainActivity +import com.example.mathseduc.controllers.ControllerChapter +import com.example.mathseduc.controllers.ControllerLobby +import com.example.mathseduc.controllers.ControllerPlayer +import com.example.mathseduc.models.Lobby +import com.example.mathseduc.models.Player +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.update +import okhttp3.MultipartBody + +class CreateLobbyViewModel : ViewModel() { + + private var lobbyNameState = MutableStateFlow("") + val lobbyName : StateFlow = lobbyNameState + + private var passwordState = MutableStateFlow("") + val password: StateFlow = passwordState + + private var nbPlayersState = MutableStateFlow("") + val nbPlayers: StateFlow = nbPlayersState + + private var difficultyState = MutableStateFlow("") + val difficulty: StateFlow = difficultyState + + private var chapterState = MutableStateFlow("") + val chapter : StateFlow = chapterState + + private var expandedDifficultyState = MutableStateFlow(false) + val expandedDifficulty: StateFlow = expandedDifficultyState + + private var expandedChapterState = MutableStateFlow(false) + val expandedChapter: StateFlow = expandedChapterState + + private var sizeState = MutableStateFlow(IntSize.Zero) + val size : StateFlow = sizeState + + fun updateLobbyName(lobbyName : String) { + this.lobbyNameState.update { lobbyName } + } + + fun updatePassword(password : String) { + this.passwordState.update { password } + } + + fun updateNbPlayers(nbPlayers : String) { + this.nbPlayersState.update { nbPlayers } + } + + fun updateDifficulty(difficulty : String) { + this.difficultyState.update { difficulty } + } + + fun updatechapter(chapter : String) { + this.chapterState.update { chapter } + } + + fun updateExpandedChapter(expandedChapter : Boolean) { + this.expandedChapterState.update { expandedChapter } + } + + fun updateExpandedDifficulty(expandedDifficulty : Boolean) { + this.expandedDifficultyState.update { expandedDifficulty } + } + + fun updateSize(size : IntSize) { + this.sizeState.update { size } + } +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/mathseduc/viewModel/MultiPageViewModel.kt b/Android/app/src/main/java/com/example/mathseduc/viewModel/MultiPageViewModel.kt index 95ad37e..ca98827 100644 --- a/Android/app/src/main/java/com/example/mathseduc/viewModel/MultiPageViewModel.kt +++ b/Android/app/src/main/java/com/example/mathseduc/viewModel/MultiPageViewModel.kt @@ -17,14 +17,6 @@ class MultiPageViewModel : ViewModel() { private var lobbyListState = MutableStateFlow>(emptyList()) val lobbyList : StateFlow> = lobbyListState - /* - var isCreator by rememberSaveable { mutableStateOf(false) } - var playerListInfos: List by rememberSaveable { mutableStateOf(emptyList()) } - var playerList by rememberSaveable { mutableStateOf(ControllerPlayer.getPlayersIdFromLobbyId(lobbyId.toString()) ?: emptyList()) } - var refreshState by rememberSaveable { mutableStateOf(true) } - */ - - fun updateLobbyList() { this.lobbyListState.update { ControllerLobby.getLobbies() ?: emptyList() diff --git a/Android/app/src/main/java/com/example/mathseduc/viewModel/ServerDetailsViewModel.kt b/Android/app/src/main/java/com/example/mathseduc/viewModel/ServerDetailsViewModel.kt index 1385a2c..745502f 100644 --- a/Android/app/src/main/java/com/example/mathseduc/viewModel/ServerDetailsViewModel.kt +++ b/Android/app/src/main/java/com/example/mathseduc/viewModel/ServerDetailsViewModel.kt @@ -1,23 +1,73 @@ package com.example.mathseduc.viewModel import androidx.lifecycle.ViewModel +import com.example.mathseduc.MainActivity +import com.example.mathseduc.controllers.ControllerChapter import com.example.mathseduc.controllers.ControllerLobby +import com.example.mathseduc.controllers.ControllerPlayer import com.example.mathseduc.models.Lobby +import com.example.mathseduc.models.Player import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.update +import okhttp3.MultipartBody + class ServerDetailsViewModel : ViewModel() { - private var lobbyListState = MutableStateFlow>(emptyList()) - val lobbyList : StateFlow> = lobbyListState + private var playerListState = MutableStateFlow>(emptyList()) + val playerList : StateFlow> = playerListState + + private var playerListInfosState = MutableStateFlow>(emptyList()) + val playerListInfos: StateFlow> = playerListInfosState + + private var isCreatorState = MutableStateFlow(false) + val isCreator: StateFlow = isCreatorState + + private var showDialogState = MutableStateFlow(false) + val showDialog: StateFlow = showDialogState + + private var refreshStateState = MutableStateFlow(true) + val refreshState : StateFlow = refreshStateState + + fun updatePlayerList(lobbyId : Int) { + this.playerListState.update { + ControllerPlayer.getPlayersIdFromLobbyId(lobbyId.toString()) ?: emptyList() + } + } + + fun updatePlayerListInfos() { + this.playerListInfosState.update { + playerList.value.mapNotNull { playerId -> ControllerPlayer.getPlayerInfoById(playerId.toString()) } + } + } - fun updateLobbyList() { - this.lobbyListState.update { - ControllerLobby.getLobbies() ?: emptyList() + fun updateIsCreator(lobbyId : Int) { + this.isCreatorState.update { + ControllerLobby.playerCreatorIdPresentInLobby(MainActivity.idPlayerConnected, lobbyId) } } - fun getNbPlayerInLobby(selectedItem : Lobby) : Int { - return ControllerLobby.getNbPlayerInLobby(selectedItem!!.id) + fun updateRefresh(bool : Boolean) { + this.refreshStateState.update { bool } + } + + fun updateShowDialog(bool : Boolean) { + this.showDialogState.update { bool } + } + + fun Launchedlobby(lobbyId : Int): Boolean{ + return ControllerLobby.lobbyIsLaunched(lobbyId) + } + + fun getNbPlayerInLobby(lobbyId : Int) : Int{ + return ControllerLobby.getNbPlayerInLobby(lobbyId) + } + + fun getChapterNameById(chapterId: Int): String?{ + return ControllerChapter.getChapterNameById(chapterId) + } + + fun updateLobbyLauched(lobbyId : Int,formDataBuilder: MultipartBody.Builder){ + ControllerLobby.updateLobbyLauched(lobbyId,formDataBuilder) } } \ No newline at end of file From 163363ba9158405954b644b2b4a74c3b6a9d83da Mon Sep 17 00:00:00 2001 From: "jeremy.ducourthial" Date: Fri, 29 Mar 2024 19:41:50 +0100 Subject: [PATCH 4/4] fix : commit fix --- .../com/example/mathseduc/AppNavigation.kt | 1 + .../mathseduc/ServerDetailsActivity.kt | 224 +-------------- .../controllers/ControllerChapter.kt | 2 +- .../mathseduc/controllers/ControllerLobby.kt | 8 +- .../mathseduc/ui/activity_server_detail.kt | 268 ++++++++++++++++++ .../viewModel/ServerDetailsViewModel.kt | 12 +- 6 files changed, 282 insertions(+), 233 deletions(-) create mode 100644 Android/app/src/main/java/com/example/mathseduc/ui/activity_server_detail.kt diff --git a/Android/app/src/main/java/com/example/mathseduc/AppNavigation.kt b/Android/app/src/main/java/com/example/mathseduc/AppNavigation.kt index 9865efd..2b8be14 100644 --- a/Android/app/src/main/java/com/example/mathseduc/AppNavigation.kt +++ b/Android/app/src/main/java/com/example/mathseduc/AppNavigation.kt @@ -10,6 +10,7 @@ import com.example.mathseduc.ui.CreateLobbyPage import com.example.mathseduc.ui.HomePage import com.example.mathseduc.ui.MultiPage import com.example.mathseduc.ui.QuizMultiScreen +import com.example.mathseduc.ui.ServerDetailPage @Composable fun AppNavigation() { diff --git a/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt b/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt index 7b49bd2..363b42a 100644 --- a/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt +++ b/Android/app/src/main/java/com/example/mathseduc/ServerDetailsActivity.kt @@ -40,10 +40,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.collectAsState 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 @@ -59,9 +56,8 @@ import androidx.core.view.WindowInsetsControllerCompat import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStoreOwner import androidx.navigation.NavController -import com.example.mathseduc.controllers.ControllerChapter +import androidx.navigation.compose.rememberNavController import com.example.mathseduc.controllers.ControllerLobby -import com.example.mathseduc.controllers.ControllerPlayer import com.example.mathseduc.controllers.ControllerUtiliser import com.example.mathseduc.models.Player import com.example.mathseduc.ui.theme.Colors @@ -87,7 +83,7 @@ class ServerDetailsActivity : ComponentActivity() { setContent { val navController = rememberNavController() - ServerDetailPage(navController = navController) + //ServerDetailPage(navController = navController) } } @@ -109,220 +105,4 @@ class ServerDetailsActivity : ComponentActivity() { } finish() } - - @OptIn(ExperimentalMaterial3Api::class) - @Composable - fun ServerDetailPage(navController: NavController) { - val context = LocalContext.current - val viewModelStoreOwner = LocalContext.current as ViewModelStoreOwner - val viewModel = ViewModelProvider(viewModelStoreOwner).get(ServerDetailsViewModel::class.java) - - val serverName = intent.getStringExtra("serverName") - val lobbyId = intent.getIntExtra("lobbyId",-1) - val chapterId = intent.getIntExtra("chapterId",-1) - val nbPlayers = intent.getIntExtra("nbPlayers",-1) - val lobbyDifficulty = intent.getIntExtra("lobbyDifficulty",-1) - - val playerList by viewModel.playerList.collectAsState(initial = emptyList()) - val playerListInfos by viewModel.playerListInfos.collectAsState(initial = emptyList()) - val isCreator by viewModel.isCreator.collectAsState(false) - val refreshState by viewModel.refreshState.collectAsState(true) - val showDialog by viewModel.showDialog.collectAsState(false) - - val isPortrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT - val activity = LocalView.current.context as Activity - - val windowInsetsController = remember { - WindowCompat.getInsetsController(activity.window, activity.window.decorView) - } - - windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) - - DisposableEffect(refreshState) { - val handler = Handler(Looper.getMainLooper()) - val refreshRunnable = object : Runnable { - override fun run() { - viewModel.updatePlayerList(lobbyId) - viewModel.updatePlayerListInfos() - viewModel.updateIsCreator(lobbyId) - - if(viewModel.Launchedlobby(lobbyId)){ - val intent = Intent(context, QuizMultiActivity::class.java) - intent.putExtra("serverName", serverName) - intent.putExtra("lobbyId", lobbyId) - intent.putExtra("chapterId", chapterId) - intent.putExtra("nbPlayers", nbPlayers) - intent.putExtra("lobbyDifficulty", lobbyDifficulty) - context.startActivity(intent) - viewModel.updateRefresh(false) - } - - if (refreshState){ - handler.postDelayed(this,3000) - Log.e("MainActivity", "Refresh ServerDetails") - } - } - } - - handler.post(refreshRunnable) - - onDispose { - viewModel.updateRefresh(false) - handler.removeCallbacks(refreshRunnable) - } - } - - TopAppBar( - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - ), - title = {}, - navigationIcon = { - IconButton( - onClick = { viewModel.updateShowDialog(true) }, - modifier = Modifier.size(60.dp) - ) { - Icon( - imageVector = Icons.Filled.ArrowBack, - contentDescription = "Retour", - modifier = Modifier.size(36.dp), - tint = Color.White - ) - } - }, - ) - - val modifier = Modifier - .fillMaxSize() - .padding(start = 16.dp, end = 16.dp, bottom = 16.dp, top = 8.dp) - - Column( - modifier = modifier, - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = serverName!!, - color = Color.White, - fontSize = 30.sp, - fontWeight = FontWeight.Bold - ) - - Spacer(modifier = Modifier.height(if(isPortrait)25.dp else 10.dp)) - - Text( - text = "Lobby Settings", - fontSize = 23.sp, - color = Color.White, - fontWeight = FontWeight.Bold - ) - Text( - text = "Chapter : ${viewModel.getChapterNameById(chapterId).toString()}", - fontSize = 19.sp, - color = Color.White - ) - Row { - Text( - text = "Players : ${playerListInfos.size}/${nbPlayers}", - fontSize = 19.sp, - color = (if(viewModel.getNbPlayerInLobby(lobbyId)==nbPlayers) Color.Red else Color.White) - ) - Spacer(modifier = Modifier.width(40.dp)) - Text( - text = "Difficulty : $lobbyDifficulty", - fontSize = 19.sp, - color = Colors.White, - ) - } - - Spacer(modifier = Modifier.height(if(isPortrait)30.dp else 10.dp)) - - Text( - text = "Player Name", - fontSize = 19.sp, - modifier = Modifier.background(Color.Black), - color = Colors.White, - ) - Divider( - color = Color.Gray, - thickness = 2.dp, - modifier = Modifier.fillMaxWidth() - ) - LazyColumn( - modifier = Modifier - .fillMaxSize() - .weight(0.75f) - .padding(top = 1.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - items(playerListInfos) { player -> - Text( - text = player.nickname, - fontSize = 18.sp, - color = Colors.White, - modifier = Modifier - .weight(1f) - .padding(top = if (isPortrait) 5.dp else 1.dp) - ) - } - } - if (isCreator) { - val formDataBuilder = MultipartBody.Builder().setType(MultipartBody.FORM) - formDataBuilder.addFormDataPart("launched", "1") - Button( - onClick = { - viewModel.updateLobbyLauched(lobbyId,formDataBuilder) - }, - shape = RoundedCornerShape(15), - enabled = isCreator, - colors = ButtonDefaults.buttonColors(Colors.Green), - modifier = Modifier - .fillMaxWidth() - .height(48.dp) - ) { - Text( - text = "LAUNCH", - color = Color.White, - fontWeight = FontWeight.Bold - ) - } - } - if (showDialog) { - LeaveLobbyDialog(serverName, onConfirmLeave = {navController.navigate("multiplayer")},onCancelLeave = { viewModel.updateShowDialog(false) }) - } - } - } - @Composable - fun LeaveLobbyDialog(namelobby: String, onConfirmLeave: () -> Unit, onCancelLeave: () -> Unit) { - val context = LocalContext.current - - AlertDialog( - onDismissRequest = onCancelLeave, - title = { Text("Confirm leaving lobby") }, - confirmButton = { - Button( - onClick = { - onConfirmLeave() - } - ) { - Text("Leave") - } - }, - dismissButton = { - Button( - onClick = { - onCancelLeave() - } - ) { - Text("Cancel") - } - }, - text = { - Text("Are you sure you want to leave the lobby $namelobby?") - } - ) - } - } diff --git a/Android/app/src/main/java/com/example/mathseduc/controllers/ControllerChapter.kt b/Android/app/src/main/java/com/example/mathseduc/controllers/ControllerChapter.kt index 38e8bb5..e63a5f9 100644 --- a/Android/app/src/main/java/com/example/mathseduc/controllers/ControllerChapter.kt +++ b/Android/app/src/main/java/com/example/mathseduc/controllers/ControllerChapter.kt @@ -40,7 +40,7 @@ class ControllerChapter { return null } - fun getChapterNameById(idchapter : Int): String? { + fun getChapterNameById(idchapter : Int?): String? { val policy = StrictMode.ThreadPolicy.Builder().permitAll().build() StrictMode.setThreadPolicy(policy) diff --git a/Android/app/src/main/java/com/example/mathseduc/controllers/ControllerLobby.kt b/Android/app/src/main/java/com/example/mathseduc/controllers/ControllerLobby.kt index 8934f2d..692a635 100644 --- a/Android/app/src/main/java/com/example/mathseduc/controllers/ControllerLobby.kt +++ b/Android/app/src/main/java/com/example/mathseduc/controllers/ControllerLobby.kt @@ -109,7 +109,7 @@ class ControllerLobby { return -1 } - fun playerCreatorIdPresentInLobby(idPlayer: Int, lobbyId: Int): Boolean { + fun playerCreatorIdPresentInLobby(idPlayer: Int, lobbyId: Int?): Boolean { val policy = StrictMode.ThreadPolicy.Builder().permitAll().build() StrictMode.setThreadPolicy(policy) @@ -247,7 +247,7 @@ class ControllerLobby { } } - fun updateLobbyLauched(lobbyId: Int,lobbyData: MultipartBody.Builder) { + fun updateLobbyLauched(lobbyId: Int?,lobbyData: MultipartBody.Builder) { try { val policy = StrictMode.ThreadPolicy.Builder().permitAll().build() StrictMode.setThreadPolicy(policy) @@ -275,7 +275,7 @@ class ControllerLobby { } } - fun getNbPlayerInLobby(lobbyId: Int): Int { + fun getNbPlayerInLobby(lobbyId: Int?): Int { val policy = StrictMode.ThreadPolicy.Builder().permitAll().build() StrictMode.setThreadPolicy(policy) @@ -326,7 +326,7 @@ class ControllerLobby { } } - fun lobbyIsLaunched(lobbyId: Int): Boolean { + fun lobbyIsLaunched(lobbyId: Int?): Boolean { val policy = StrictMode.ThreadPolicy.Builder().permitAll().build() StrictMode.setThreadPolicy(policy) diff --git a/Android/app/src/main/java/com/example/mathseduc/ui/activity_server_detail.kt b/Android/app/src/main/java/com/example/mathseduc/ui/activity_server_detail.kt new file mode 100644 index 0000000..89b8a04 --- /dev/null +++ b/Android/app/src/main/java/com/example/mathseduc/ui/activity_server_detail.kt @@ -0,0 +1,268 @@ +package com.example.mathseduc.ui + +import android.app.Activity +import android.content.Intent +import android.content.res.Configuration +import android.os.Handler +import android.os.Looper +import android.util.Log +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.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +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.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +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.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.lifecycle.ViewModelProvider +import androidx.lifecycle.ViewModelStoreOwner +import androidx.navigation.NavController +import com.example.mathseduc.QuizMultiActivity +import com.example.mathseduc.ui.theme.Colors +import com.example.mathseduc.viewModel.ServerDetailsViewModel +import okhttp3.MultipartBody + +@Composable +fun LeaveLobbyDialog(namelobby: String, onConfirmLeave: () -> Unit, onCancelLeave: () -> Unit) { + val context = LocalContext.current + + AlertDialog( + onDismissRequest = onCancelLeave, + title = { Text("Confirm leaving lobby") }, + confirmButton = { + Button( + onClick = { + onConfirmLeave() + } + ) { + Text("Leave") + } + }, + dismissButton = { + Button( + onClick = { + onCancelLeave() + } + ) { + Text("Cancel") + } + }, + text = { + Text("Are you sure you want to leave the lobby $namelobby?") + } + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ServerDetailPage(navController: NavController, serverName: String?, lobbyId: Int?, chapterId: Int?, nbPlayers: Int?, lobbyDifficulty: Int?) { + val context = LocalContext.current + val viewModelStoreOwner = LocalContext.current as ViewModelStoreOwner + val viewModel = ViewModelProvider(viewModelStoreOwner).get(ServerDetailsViewModel::class.java) + + val playerList by viewModel.playerList.collectAsState(initial = emptyList()) + val playerListInfos by viewModel.playerListInfos.collectAsState(initial = emptyList()) + val isCreator by viewModel.isCreator.collectAsState(false) + val refreshState by viewModel.refreshState.collectAsState(true) + val showDialog by viewModel.showDialog.collectAsState(false) + + val isPortrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT + val activity = LocalView.current.context as Activity + + val windowInsetsController = remember { + WindowCompat.getInsetsController(activity.window, activity.window.decorView) + } + + windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + + windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + + DisposableEffect(refreshState) { + val handler = Handler(Looper.getMainLooper()) + val refreshRunnable = object : Runnable { + override fun run() { + viewModel.updatePlayerList(lobbyId) + viewModel.updatePlayerListInfos() + viewModel.updateIsCreator(lobbyId) + + if(viewModel.Launchedlobby(lobbyId)){ + val intent = Intent(context, QuizMultiActivity::class.java) + intent.putExtra("serverName", serverName) + intent.putExtra("lobbyId", lobbyId) + intent.putExtra("chapterId", chapterId) + intent.putExtra("nbPlayers", nbPlayers) + intent.putExtra("lobbyDifficulty", lobbyDifficulty) + context.startActivity(intent) + viewModel.updateRefresh(false) + } + + if (refreshState){ + handler.postDelayed(this,3000) + Log.e("MainActivity", "Refresh ServerDetails") + } + } + } + + handler.post(refreshRunnable) + + onDispose { + viewModel.updateRefresh(false) + handler.removeCallbacks(refreshRunnable) + } + } + + TopAppBar( + colors = TopAppBarDefaults.topAppBarColors( + containerColor = Color.Transparent, + ), + title = {}, + navigationIcon = { + IconButton( + onClick = { viewModel.updateShowDialog(true) }, + modifier = Modifier.size(60.dp) + ) { + Icon( + imageVector = Icons.Filled.ArrowBack, + contentDescription = "Retour", + modifier = Modifier.size(36.dp), + tint = Color.White + ) + } + }, + ) + + val modifier = Modifier + .fillMaxSize() + .padding(start = 16.dp, end = 16.dp, bottom = 16.dp, top = 8.dp) + + Column( + modifier = modifier, + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = serverName!!, + color = Color.White, + fontSize = 30.sp, + fontWeight = FontWeight.Bold + ) + + Spacer(modifier = Modifier.height(if(isPortrait)25.dp else 10.dp)) + + Text( + text = "Lobby Settings", + fontSize = 23.sp, + color = Color.White, + fontWeight = FontWeight.Bold + ) + Text( + text = "Chapter : ${viewModel.getChapterNameById(chapterId).toString()}", + fontSize = 19.sp, + color = Color.White + ) + Row { + Text( + text = "Players : ${playerListInfos.size}/${nbPlayers}", + fontSize = 19.sp, + color = (if(viewModel.getNbPlayerInLobby(lobbyId)==nbPlayers) Color.Red else Color.White) + ) + Spacer(modifier = Modifier.width(40.dp)) + Text( + text = "Difficulty : $lobbyDifficulty", + fontSize = 19.sp, + color = Colors.White, + ) + } + + Spacer(modifier = Modifier.height(if(isPortrait)30.dp else 10.dp)) + + Text( + text = "Player Name", + fontSize = 19.sp, + modifier = Modifier.background(Color.Black), + color = Colors.White, + ) + Divider( + color = Color.Gray, + thickness = 2.dp, + modifier = Modifier.fillMaxWidth() + ) + LazyColumn( + modifier = Modifier + .fillMaxSize() + .weight(0.75f) + .padding(top = 1.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + items(playerListInfos) { player -> + Text( + text = player.nickname, + fontSize = 18.sp, + color = Colors.White, + modifier = Modifier + .weight(1f) + .padding(top = if (isPortrait) 5.dp else 1.dp) + ) + } + } + if (isCreator) { + val formDataBuilder = MultipartBody.Builder().setType(MultipartBody.FORM) + formDataBuilder.addFormDataPart("launched", "1") + Button( + onClick = { + viewModel.updateLobbyLauched(lobbyId,formDataBuilder) + }, + shape = RoundedCornerShape(15), + enabled = isCreator, + colors = ButtonDefaults.buttonColors(Colors.Green), + modifier = Modifier + .fillMaxWidth() + .height(48.dp) + ) { + Text( + text = "LAUNCH", + color = Color.White, + fontWeight = FontWeight.Bold + ) + } + } + if (showDialog) { + LeaveLobbyDialog(serverName, onConfirmLeave = {navController.navigate("multiplayer")},onCancelLeave = { viewModel.updateShowDialog(false) }) + } + } +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/mathseduc/viewModel/ServerDetailsViewModel.kt b/Android/app/src/main/java/com/example/mathseduc/viewModel/ServerDetailsViewModel.kt index 745502f..802d0f2 100644 --- a/Android/app/src/main/java/com/example/mathseduc/viewModel/ServerDetailsViewModel.kt +++ b/Android/app/src/main/java/com/example/mathseduc/viewModel/ServerDetailsViewModel.kt @@ -29,7 +29,7 @@ class ServerDetailsViewModel : ViewModel() { private var refreshStateState = MutableStateFlow(true) val refreshState : StateFlow = refreshStateState - fun updatePlayerList(lobbyId : Int) { + fun updatePlayerList(lobbyId : Int?) { this.playerListState.update { ControllerPlayer.getPlayersIdFromLobbyId(lobbyId.toString()) ?: emptyList() } @@ -41,7 +41,7 @@ class ServerDetailsViewModel : ViewModel() { } } - fun updateIsCreator(lobbyId : Int) { + fun updateIsCreator(lobbyId : Int?) { this.isCreatorState.update { ControllerLobby.playerCreatorIdPresentInLobby(MainActivity.idPlayerConnected, lobbyId) } @@ -55,19 +55,19 @@ class ServerDetailsViewModel : ViewModel() { this.showDialogState.update { bool } } - fun Launchedlobby(lobbyId : Int): Boolean{ + fun Launchedlobby(lobbyId : Int?): Boolean{ return ControllerLobby.lobbyIsLaunched(lobbyId) } - fun getNbPlayerInLobby(lobbyId : Int) : Int{ + fun getNbPlayerInLobby(lobbyId : Int?) : Int{ return ControllerLobby.getNbPlayerInLobby(lobbyId) } - fun getChapterNameById(chapterId: Int): String?{ + fun getChapterNameById(chapterId: Int?): String?{ return ControllerChapter.getChapterNameById(chapterId) } - fun updateLobbyLauched(lobbyId : Int,formDataBuilder: MultipartBody.Builder){ + fun updateLobbyLauched(lobbyId : Int?,formDataBuilder: MultipartBody.Builder){ ControllerLobby.updateLobbyLauched(lobbyId,formDataBuilder) } } \ No newline at end of file