feat : ServerDetail Navigation
continuous-integration/drone/push Build is passing Details

androidCompose
Yvan CALATAYUD 1 year ago
parent 820ec2b59b
commit fa91413a98

@ -1,9 +1,11 @@
package com.example.mathseduc package com.example.mathseduc
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.example.mathseduc.ui.CreateLobbyPage import com.example.mathseduc.ui.CreateLobbyPage
import com.example.mathseduc.ui.HomePage import com.example.mathseduc.ui.HomePage
import com.example.mathseduc.ui.MultiPage import com.example.mathseduc.ui.MultiPage
@ -17,6 +19,23 @@ fun AppNavigation() {
composable("connexion") { ConnexionPlayerContent(navController) } composable("connexion") { ConnexionPlayerContent(navController) }
composable("multiplayer") { MultiPage(navController) } composable("multiplayer") { MultiPage(navController) }
composable("createLobby") { CreateLobbyPage(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)
}
} }
} }

@ -84,7 +84,7 @@ class ServerDetailsActivity : ComponentActivity() {
setContent { setContent {
val navController = rememberNavController() val navController = rememberNavController()
ServerDetailPage(navController = navController) //ServerDetailPage(navController = navController)
} }
} }
@ -106,221 +106,215 @@ class ServerDetailsActivity : ComponentActivity() {
} }
finish() 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<Player> 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) windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
@Composable
fun ServerDetailPage(navController: NavController) { windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
val context = LocalContext.current
DisposableEffect(refreshState) {
val serverName = intent.getStringExtra("serverName") val handler = Handler(Looper.getMainLooper())
val lobbyId = intent.getIntExtra("lobbyId",-1) val refreshRunnable = object : Runnable {
val chapterId = intent.getIntExtra("chapterId",-1) override fun run() {
val nbPlayers = intent.getIntExtra("nbPlayers",-1) playerList = ControllerPlayer.getPlayersIdFromLobbyId(lobbyId.toString())!!
val lobbyDifficulty = intent.getIntExtra("lobbyDifficulty",-1)
var isCreator by rememberSaveable { mutableStateOf(false) }
var playerListInfos: List<Player> 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 playerListInfos = playerList.mapNotNull { playerId ->
ControllerPlayer.getPlayerInfoById(playerId.toString())
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")
}
} }
}
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 { if (refreshState){
refreshState = false handler.postDelayed(this,3000)
handler.removeCallbacks(refreshRunnable) Log.e("MainActivity", "Refresh ServerDetails")
}
} }
} }
TopAppBar( handler.post(refreshRunnable)
colors = TopAppBarDefaults.topAppBarColors(
containerColor = Color.Transparent, onDispose {
), refreshState = false
title = {}, handler.removeCallbacks(refreshRunnable)
navigationIcon = { }
IconButton( }
onClick = { showDialog = true },
modifier = Modifier.size(60.dp) TopAppBar(
) { colors = TopAppBarDefaults.topAppBarColors(
Icon( containerColor = Color.Transparent,
imageVector = Icons.Filled.ArrowBack, ),
contentDescription = "Retour", title = {},
modifier = Modifier.size(36.dp), navigationIcon = {
tint = Color.White 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 Spacer(modifier = Modifier.height(if(isPortrait)25.dp else 10.dp))
.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(
text = serverName!!, text = "Lobby Settings",
color = Color.White, fontSize = 23.sp,
fontSize = 30.sp, color = Color.White,
fontWeight = FontWeight.Bold 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(
text = "Lobby Settings", text = player.nickname,
fontSize = 23.sp, fontSize = 18.sp,
color = Color.White, color = Colors.White,
fontWeight = FontWeight.Bold modifier = Modifier
) .weight(1f)
Text( .padding(top = if (isPortrait) 5.dp else 1.dp)
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)30.dp else 10.dp)) if (isCreator) {
val formDataBuilder = MultipartBody.Builder().setType(MultipartBody.FORM)
Text( formDataBuilder.addFormDataPart("launched", "1")
text = "Player Name", Button(
fontSize = 19.sp, onClick = {
modifier = Modifier.background(Color.Black), ControllerLobby.updateLobbyLauched(lobbyId!!,formDataBuilder)
color = Colors.White, },
) shape = RoundedCornerShape(15),
Divider( enabled = isCreator,
color = Color.Gray, colors = ButtonDefaults.buttonColors(Colors.Green),
thickness = 2.dp,
modifier = Modifier.fillMaxWidth()
)
LazyColumn(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxWidth()
.weight(0.75f) .height(48.dp)
.padding(top = 1.dp),
horizontalAlignment = Alignment.CenterHorizontally
) { ) {
items(playerListInfos) { player -> Text(
Text( text = "LAUNCH",
text = player.nickname, color = Color.White,
fontSize = 18.sp, fontWeight = FontWeight.Bold
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) if (showDialog) {
formDataBuilder.addFormDataPart("launched", "1") 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( Button(
onClick = { onClick = {
ControllerLobby.updateLobbyLauched(lobbyId,formDataBuilder) onConfirmLeave()
}, }
shape = RoundedCornerShape(15),
enabled = isCreator,
colors = ButtonDefaults.buttonColors(Colors.Green),
modifier = Modifier
.fillMaxWidth()
.height(48.dp)
) { ) {
Text( Text("Leave")
text = "LAUNCH",
color = Color.White,
fontWeight = FontWeight.Bold
)
} }
} },
if (showDialog) { dismissButton = {
LeaveLobbyDialog(serverName, onConfirmLeave = {navController.navigate("multiplayer")},onCancelLeave = { showDialog = false }) Button(
} onClick = {
} onCancelLeave()
} }
@Composable ) {
fun LeaveLobbyDialog(namelobby: String, onConfirmLeave: () -> Unit, onCancelLeave: () -> Unit) { Text("Cancel")
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?")
} }
) },
} text = {
Text("Are you sure you want to leave the lobby $namelobby?")
}
)
} }

@ -2,7 +2,6 @@ package com.example.mathseduc.ui
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent
import android.content.res.Configuration import android.content.res.Configuration
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
@ -57,7 +56,6 @@ import androidx.core.view.WindowInsetsControllerCompat
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.mathseduc.MainActivity import com.example.mathseduc.MainActivity
import com.example.mathseduc.ServerDetailsActivity
import com.example.mathseduc.controllers.ControllerChapter import com.example.mathseduc.controllers.ControllerChapter
import com.example.mathseduc.controllers.ControllerLobby import com.example.mathseduc.controllers.ControllerLobby
import com.example.mathseduc.controllers.ControllerUtiliser 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.ui.theme.Colors
import com.example.mathseduc.viewModel.MultiPageViewModel import com.example.mathseduc.viewModel.MultiPageViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import okhttp3.MultipartBody import okhttp3.MultipartBody
@ -224,14 +223,10 @@ private suspend fun createUtiliserForLobby(context: Context, lobby: Lobby, navCo
ControllerUtiliser.createUtiliserByIdLobby(formDataBuilder) ControllerUtiliser.createUtiliserByIdLobby(formDataBuilder)
// Naviguer vers l'activité ServerDetails avec les détails du lobby // Naviguer vers l'activité ServerDetails avec les détails du lobby
val intent = Intent(context, ServerDetailsActivity::class.java) val mainScope = MainScope()
intent.putExtra("serverName", lobby.name) mainScope.launch {
intent.putExtra("lobbyId", lobby.id) navController.navigate("serverDetails/${lobby.name}/${lobby.id}/${lobby.idchapter}/${lobby.nbplayers}/${lobby.difficulty}")
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}")
} }
} }

Loading…
Cancel
Save