fix : commit fix
continuous-integration/drone/push Build is passing Details

androidCompose
Jeremy DUCOURTHIAL 1 year ago
parent 6451a27b3a
commit 163363ba91

@ -10,6 +10,7 @@ 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
import com.example.mathseduc.ui.QuizMultiScreen import com.example.mathseduc.ui.QuizMultiScreen
import com.example.mathseduc.ui.ServerDetailPage
@Composable @Composable
fun AppNavigation() { fun AppNavigation() {

@ -40,10 +40,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember 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.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
@ -59,9 +56,8 @@ import androidx.core.view.WindowInsetsControllerCompat
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStoreOwner import androidx.lifecycle.ViewModelStoreOwner
import androidx.navigation.NavController 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.ControllerLobby
import com.example.mathseduc.controllers.ControllerPlayer
import com.example.mathseduc.controllers.ControllerUtiliser import com.example.mathseduc.controllers.ControllerUtiliser
import com.example.mathseduc.models.Player import com.example.mathseduc.models.Player
import com.example.mathseduc.ui.theme.Colors import com.example.mathseduc.ui.theme.Colors
@ -87,7 +83,7 @@ class ServerDetailsActivity : ComponentActivity() {
setContent { setContent {
val navController = rememberNavController() val navController = rememberNavController()
ServerDetailPage(navController = navController) //ServerDetailPage(navController = navController)
} }
} }
@ -109,220 +105,4 @@ class ServerDetailsActivity : ComponentActivity() {
} }
finish() 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?")
}
)
}
} }

@ -40,7 +40,7 @@ class ControllerChapter {
return null return null
} }
fun getChapterNameById(idchapter : Int): String? { fun getChapterNameById(idchapter : Int?): String? {
val policy = StrictMode.ThreadPolicy.Builder().permitAll().build() val policy = StrictMode.ThreadPolicy.Builder().permitAll().build()
StrictMode.setThreadPolicy(policy) StrictMode.setThreadPolicy(policy)

@ -109,7 +109,7 @@ class ControllerLobby {
return -1 return -1
} }
fun playerCreatorIdPresentInLobby(idPlayer: Int, lobbyId: Int): Boolean { fun playerCreatorIdPresentInLobby(idPlayer: Int, lobbyId: Int?): Boolean {
val policy = StrictMode.ThreadPolicy.Builder().permitAll().build() val policy = StrictMode.ThreadPolicy.Builder().permitAll().build()
StrictMode.setThreadPolicy(policy) StrictMode.setThreadPolicy(policy)
@ -247,7 +247,7 @@ class ControllerLobby {
} }
} }
fun updateLobbyLauched(lobbyId: Int,lobbyData: MultipartBody.Builder) { fun updateLobbyLauched(lobbyId: Int?,lobbyData: MultipartBody.Builder) {
try { try {
val policy = StrictMode.ThreadPolicy.Builder().permitAll().build() val policy = StrictMode.ThreadPolicy.Builder().permitAll().build()
StrictMode.setThreadPolicy(policy) 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() val policy = StrictMode.ThreadPolicy.Builder().permitAll().build()
StrictMode.setThreadPolicy(policy) 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() val policy = StrictMode.ThreadPolicy.Builder().permitAll().build()
StrictMode.setThreadPolicy(policy) StrictMode.setThreadPolicy(policy)

@ -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) })
}
}
}

@ -29,7 +29,7 @@ class ServerDetailsViewModel : ViewModel() {
private var refreshStateState = MutableStateFlow(true) private var refreshStateState = MutableStateFlow(true)
val refreshState : StateFlow<Boolean> = refreshStateState val refreshState : StateFlow<Boolean> = refreshStateState
fun updatePlayerList(lobbyId : Int) { fun updatePlayerList(lobbyId : Int?) {
this.playerListState.update { this.playerListState.update {
ControllerPlayer.getPlayersIdFromLobbyId(lobbyId.toString()) ?: emptyList() ControllerPlayer.getPlayersIdFromLobbyId(lobbyId.toString()) ?: emptyList()
} }
@ -41,7 +41,7 @@ class ServerDetailsViewModel : ViewModel() {
} }
} }
fun updateIsCreator(lobbyId : Int) { fun updateIsCreator(lobbyId : Int?) {
this.isCreatorState.update { this.isCreatorState.update {
ControllerLobby.playerCreatorIdPresentInLobby(MainActivity.idPlayerConnected, lobbyId) ControllerLobby.playerCreatorIdPresentInLobby(MainActivity.idPlayerConnected, lobbyId)
} }
@ -55,19 +55,19 @@ class ServerDetailsViewModel : ViewModel() {
this.showDialogState.update { bool } this.showDialogState.update { bool }
} }
fun Launchedlobby(lobbyId : Int): Boolean{ fun Launchedlobby(lobbyId : Int?): Boolean{
return ControllerLobby.lobbyIsLaunched(lobbyId) return ControllerLobby.lobbyIsLaunched(lobbyId)
} }
fun getNbPlayerInLobby(lobbyId : Int) : Int{ fun getNbPlayerInLobby(lobbyId : Int?) : Int{
return ControllerLobby.getNbPlayerInLobby(lobbyId) return ControllerLobby.getNbPlayerInLobby(lobbyId)
} }
fun getChapterNameById(chapterId: Int): String?{ fun getChapterNameById(chapterId: Int?): String?{
return ControllerChapter.getChapterNameById(chapterId) return ControllerChapter.getChapterNameById(chapterId)
} }
fun updateLobbyLauched(lobbyId : Int,formDataBuilder: MultipartBody.Builder){ fun updateLobbyLauched(lobbyId : Int?,formDataBuilder: MultipartBody.Builder){
ControllerLobby.updateLobbyLauched(lobbyId,formDataBuilder) ControllerLobby.updateLobbyLauched(lobbyId,formDataBuilder)
} }
} }
Loading…
Cancel
Save