diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..c5871cc --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/android/.idea/appInsightsSettings.xml b/android/.idea/appInsightsSettings.xml new file mode 100644 index 0000000..6bbe2ae --- /dev/null +++ b/android/.idea/appInsightsSettings.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/android/.idea/deploymentTargetDropDown.xml b/android/.idea/deploymentTargetDropDown.xml index 3d7ae4a..0c0c338 100644 --- a/android/.idea/deploymentTargetDropDown.xml +++ b/android/.idea/deploymentTargetDropDown.xml @@ -2,24 +2,8 @@ - - - - - - - - - - - - - - - - - + diff --git a/android/app/src/main/java/fr/iut/sciencequest/model/buisness/Scientifique/ScientifiqueRequestService.kt b/android/app/src/main/java/fr/iut/sciencequest/model/buisness/Scientifique/ScientifiqueRequestService.kt index b3a5342..396ae00 100644 --- a/android/app/src/main/java/fr/iut/sciencequest/model/buisness/Scientifique/ScientifiqueRequestService.kt +++ b/android/app/src/main/java/fr/iut/sciencequest/model/buisness/Scientifique/ScientifiqueRequestService.kt @@ -1,13 +1,8 @@ package fr.iut.sciencequest.model.buisness.Scientifique -import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import fr.iut.sciencequest.model.dto.ScientifiqueDTOs.ScientifiqueDTO import fr.iut.sciencequest.model.dto.ScientifiqueDTOs.ScientifiqueListDTO -import kotlinx.serialization.json.Json -import okhttp3.MediaType -import okhttp3.OkHttpClient -import retrofit2.Call -import retrofit2.Retrofit +import fr.iut.sciencequest.model.dto.ScientifiqueDTOs.ScientifiqueListInfosDTO import retrofit2.http.GET import retrofit2.http.Path import retrofit2.http.Query @@ -16,6 +11,9 @@ interface ScientifiqueRequestService { @GET("scientifiques?page") suspend fun getScientifiques(@Query("page") index: Int): ScientifiqueListDTO + @GET("scientifiques") + suspend fun getScientifiquesListInfos(): ScientifiqueListInfosDTO + @GET("scientifiques/{id}") suspend fun getScientifique(@Path("id") id: Int): ScientifiqueDTO } \ No newline at end of file diff --git a/android/app/src/main/java/fr/iut/sciencequest/model/buisness/Scientifique/ScientifiquesRequestor.kt b/android/app/src/main/java/fr/iut/sciencequest/model/buisness/Scientifique/ScientifiquesRequestor.kt new file mode 100644 index 0000000..8269e18 --- /dev/null +++ b/android/app/src/main/java/fr/iut/sciencequest/model/buisness/Scientifique/ScientifiquesRequestor.kt @@ -0,0 +1,36 @@ +package fr.iut.sciencequest.model.buisness.Scientifique + +import android.util.Log +import fr.iut.sciencequest.model.buisness.createRequestService +import kotlinx.coroutines.flow.flow +import retrofit2.create + +suspend fun fetchScientifiqueById(id: Int) = flow { + val serviceClient = createRequestService().create() + try { + val response = serviceClient.getScientifique(id) + emit(response) + } catch (e: Exception) { + Log.e("Requete API",e.message.toString()) + } +} + +fun fetchScientifiques(index: Int) = flow { + val serviceClient = createRequestService().create() + try { + val response = serviceClient.getScientifiques(index) + emit(response) + } catch (e: Exception) { + Log.e("Requete API",e.message.toString()) + } +} + +fun fetchScientifiquesInfos() = flow { + val serviceClient = createRequestService().create() + try { + val response = serviceClient.getScientifiquesListInfos().page + emit(response) + } catch (e: Exception) { + Log.e("Requete API",e.message.toString()) + } +} \ No newline at end of file diff --git a/android/app/src/main/java/fr/iut/sciencequest/model/buisness/ServiceUtils.kt b/android/app/src/main/java/fr/iut/sciencequest/model/buisness/ServiceUtils.kt index 9029826..3742b19 100644 --- a/android/app/src/main/java/fr/iut/sciencequest/model/buisness/ServiceUtils.kt +++ b/android/app/src/main/java/fr/iut/sciencequest/model/buisness/ServiceUtils.kt @@ -6,7 +6,7 @@ import okhttp3.MediaType import okhttp3.OkHttpClient import retrofit2.Retrofit -const val API_BASE_URL = "https://sae-java.alix-jdlm.fr/api/v1/" +const val API_BASE_URL = "https://codefirst.iut.uca.fr/containers/tombiard-api/api/v1/" val httpClient = OkHttpClient() diff --git a/android/app/src/main/java/fr/iut/sciencequest/model/dto/ScientifiqueDTOs/ScientifiqueListInfosDTO.kt b/android/app/src/main/java/fr/iut/sciencequest/model/dto/ScientifiqueDTOs/ScientifiqueListInfosDTO.kt new file mode 100644 index 0000000..c6e5a82 --- /dev/null +++ b/android/app/src/main/java/fr/iut/sciencequest/model/dto/ScientifiqueDTOs/ScientifiqueListInfosDTO.kt @@ -0,0 +1,21 @@ +package fr.iut.sciencequest.model.dto.ScientifiqueDTOs + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +open class ScientifiqueListInfosPageDTO( + @SerialName("totalElements") + val nbScientfiques: Int, + + @SerialName("totalPages") + val nbPages: Int, + + @SerialName("size") + val nbScientifiquesParPage: Int +) + +@Serializable +open class ScientifiqueListInfosDTO ( + val page: ScientifiqueListInfosPageDTO +) \ No newline at end of file diff --git a/android/app/src/main/java/fr/iut/sciencequest/navigation/NavHost.kt b/android/app/src/main/java/fr/iut/sciencequest/navigation/NavHost.kt index 8307321..cd50bd8 100644 --- a/android/app/src/main/java/fr/iut/sciencequest/navigation/NavHost.kt +++ b/android/app/src/main/java/fr/iut/sciencequest/navigation/NavHost.kt @@ -11,6 +11,7 @@ import fr.iut.sciencequest.view.HomeScreen import fr.iut.sciencequest.view.LoginScreen import fr.iut.sciencequest.view.games.KahootScreen import fr.iut.sciencequest.view.games.PenduScreen +import fr.iut.sciencequest.view.games.QuiScreen import fr.iut.sciencequest.view.scientifiques.scientifiqueListeScreen @@ -35,6 +36,9 @@ fun NavHost() { }, goToKahoot = { navController.navigate("kahoot") + }, + goToQui = { + navController.navigate("qui") } ) } @@ -73,16 +77,28 @@ fun NavHost() { } composable(route= "kahoot"){ - KahootScreen( goToAccount = { + KahootScreen( + goToAccount = { navController.navigate("account") }, + goToHome = { + navController.navigate("home") + } + ) + } + + composable(route= "qui"){ + QuiScreen(goToAccount = { + navController.navigate("account") + }, goToHome = { navController.navigate("home") }) } composable(route = "listeScientifiques") { - scientifiqueListeScreen(goToAccount = { + scientifiqueListeScreen( + goToAccount = { navController.navigate("account") }, goToHome = { diff --git a/android/app/src/main/java/fr/iut/sciencequest/view/HomeScreen.kt b/android/app/src/main/java/fr/iut/sciencequest/view/HomeScreen.kt index 10d6995..376271c 100644 --- a/android/app/src/main/java/fr/iut/sciencequest/view/HomeScreen.kt +++ b/android/app/src/main/java/fr/iut/sciencequest/view/HomeScreen.kt @@ -19,21 +19,22 @@ import androidx.compose.ui.unit.sp fun HomeScreen(goToHome: () -> Unit, goToAccount: () -> Unit, goToPendu: () -> Unit, - goToKahoot: () -> Unit) { + goToKahoot: () -> Unit, + goToQui: () -> Unit) { Column (modifier = Modifier.fillMaxWidth()){ TopBar(goToAccount, goToHome) - MainContent(goToPendu, goToKahoot) + MainContent(goToPendu, goToKahoot, goToQui) } } @Preview @Composable fun HomeScreenPreview() { - HomeScreen({},{},{}, {}) + HomeScreen({},{},{},{},{}) } @Composable -fun MainContent(goToPendu: () -> Unit, goToKahoot: () -> Unit) { +fun MainContent(goToPendu: () -> Unit, goToKahoot: () -> Unit, goToQui: () -> Unit) { val context = LocalContext.current; val comingSoon = Toast.makeText(context, "Coming soon", Toast.LENGTH_SHORT); @@ -45,7 +46,7 @@ fun MainContent(goToPendu: () -> Unit, goToKahoot: () -> Unit) { Button(onClick = goToKahoot, Modifier.fillMaxWidth()) { Text(text = "Kahoot", fontSize = 13.sp) } - Button(onClick = { comingSoon.show() }, Modifier.fillMaxWidth()) { + Button(onClick = goToQui, Modifier.fillMaxWidth()) { Text(text = "Qui est ce ?", fontSize = 13.sp) } } diff --git a/android/app/src/main/java/fr/iut/sciencequest/view/games/Kahoot.kt b/android/app/src/main/java/fr/iut/sciencequest/view/games/Kahoot.kt index 22a2ba3..a25a34a 100644 --- a/android/app/src/main/java/fr/iut/sciencequest/view/games/Kahoot.kt +++ b/android/app/src/main/java/fr/iut/sciencequest/view/games/Kahoot.kt @@ -4,6 +4,7 @@ import android.widget.Toast import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid @@ -19,6 +20,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel import fr.iut.sciencequest.R import fr.iut.sciencequest.viewModels.KahootViewModel @@ -38,6 +40,7 @@ fun KahootScreen(viewModel: KahootViewModel = viewModel(factory = KahootViewMode } Column(modifier = Modifier.fillMaxWidth()) { TopBar(goToAccount, goToHome, stringResource(id = R.string.kahoot)) + KahootPlayer(state.value.question) { viewModel.ajouterPoints(it) } @@ -62,9 +65,14 @@ fun KahootPlayerPreview(){ @Composable fun KahootPlayer(question: QuestionWithSimpleReponse, sendReponse: (Long) -> Unit){ + val context = LocalContext.current; val currTime = System.currentTimeMillis() - Column (horizontalAlignment = Alignment.CenterHorizontally){ + Column ( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceEvenly, + modifier = Modifier.fillMaxHeight() + ) { KahootQuestion(question = question.question) KahootReponses(reponses = question.reponses) { sendReponse(currTime - System.currentTimeMillis()) @@ -92,5 +100,5 @@ fun KahootReponses(reponses : List, action: (ReponseSimple)->Unit @Composable fun KahootQuestion(question: String){ - Text(question, textAlign = TextAlign.Center) + Text(question, textAlign = TextAlign.Center, fontSize = 20.sp) } \ No newline at end of file diff --git a/android/app/src/main/java/fr/iut/sciencequest/view/games/Pendu.kt b/android/app/src/main/java/fr/iut/sciencequest/view/games/Pendu.kt index eb21bf8..44c7c6a 100644 --- a/android/app/src/main/java/fr/iut/sciencequest/view/games/Pendu.kt +++ b/android/app/src/main/java/fr/iut/sciencequest/view/games/Pendu.kt @@ -2,8 +2,10 @@ package fr.iut.sciencequest.view.games import android.content.Context import android.widget.Toast +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button @@ -17,6 +19,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel import fr.iut.sciencequest.R import fr.iut.sciencequest.viewModels.PenduViewModel @@ -25,23 +28,40 @@ import fr.iut.sciencequest.view.TopBar @Composable fun PenduScreen(viewModel: PenduViewModel = viewModel(factory = PenduViewModel.ApiFactory), goToAccount: () -> Unit, - goToHome: () -> Unit) { + goToHome: () -> Unit +) { val state = viewModel.uiState.collectAsState() val context = LocalContext.current; Column(modifier = Modifier.fillMaxWidth()) { TopBar(goToAccount, goToHome, stringResource(id = R.string.pendu)) //Text(text = stringResource(id = R.string.pendu), modifier = Modifier.padding(top=10.dp)) - Column(modifier = Modifier.align(Alignment.CenterHorizontally)) - { - Text(text = state.value.motATrou) - TextField(value = "", - onValueChange = { onLetterEntered(it, viewModel, context, goToHome) }, - modifier = Modifier.padding(20.dp)) - afficherVies(state.value.nbViesRestantes) + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceAround, + modifier = Modifier.fillMaxSize() + ) { + Text(text = state.value.motATrou, fontSize = 20.sp) + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceBetween, + ) { + TextField(value = "", + onValueChange = { onLetterEntered(it, viewModel, context, goToHome) }, + modifier = Modifier.padding(20.dp), + enabled = !state.value.isWon && state.value.nbViesRestantes > 0, + placeholder = { Text(if(!state.value.isWon) "Entrez une lettre" else "Cliquez sur Nouvelle Partie") } + ) + afficherVies(state.value.nbViesRestantes) + Text("Lettres utilisées: " + state.value.lettresUtilises) + if(state.value.isWon) { + Text(modifier = Modifier.padding(top=10.dp), text = "Vous avez gagné !") + } else if (state.value.nbViesRestantes == 0) { + Text(modifier = Modifier.padding(top=10.dp), text = "Vous avez perdu :(") + } + } Button(onClick = { viewModel.InitPartie() }) { Text(text = stringResource(id = R.string.reset_game)) } - Text("Lettres utilisées: " + state.value.lettresUtilises) } } } @@ -54,7 +74,7 @@ fun onLetterEntered(entered: String, if (entered.isNotEmpty()) { vm.PlayAction(entered[0]) if ((!state.value.isWon) && (state.value.nbViesRestantes == 0)) { - goToHome() + Toast.makeText(context,"Vous avez perdu :(",Toast.LENGTH_LONG).show() } else if (state.value.isWon) { Toast.makeText(context,"Vous avez gagné !",Toast.LENGTH_LONG).show() } diff --git a/android/app/src/main/java/fr/iut/sciencequest/view/games/Qui.kt b/android/app/src/main/java/fr/iut/sciencequest/view/games/Qui.kt new file mode 100644 index 0000000..3ce5cb6 --- /dev/null +++ b/android/app/src/main/java/fr/iut/sciencequest/view/games/Qui.kt @@ -0,0 +1,95 @@ +package fr.iut.sciencequest.view.games + +import android.widget.Toast +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import fr.iut.sciencequest.R +import fr.iut.sciencequest.model.dto.extensions.ToModel +import fr.iut.sciencequest.model.dto.question.QuestionWithSimpleResponseDTO +import fr.iut.sciencequest.model.dto.reponse.ReponseSimpleDTO +import fr.iut.sciencequest.model.metier.question.QuestionWithSimpleReponse +import fr.iut.sciencequest.model.metier.reponse.ReponseSimple +import fr.iut.sciencequest.stub.StubQuestionWithReponses +import fr.iut.sciencequest.view.TopBar +import fr.iut.sciencequest.viewModels.KahootViewModel +import java.util.Timer + +@Composable +fun QuiScreen(viewModel: KahootViewModel = viewModel(), + goToAccount: () -> Unit, + goToHome: () -> Unit) { + val state = viewModel.uiState.collectAsState() + Column(modifier = Modifier.fillMaxWidth()) { + TopBar(goToAccount, goToHome, stringResource(id = R.string.kahoot)) + QuiPlayer(state.value.question) { + viewModel.ajouterPoints(it) + } + } +} + +@Preview +@Composable +fun QuiScreenPreview(){ + QuiScreen(goToAccount = {}, goToHome = {}) +} + + +@Preview +@Composable +fun QuiPlayerPreview(){ + val i = 0 + QuiPlayer(question = StubQuestionWithReponses.ToModel()) {} +} + + +@Composable +fun QuiPlayer(question: QuestionWithSimpleReponse, + sendReponse: (Long) -> Unit){ + val context = LocalContext.current; + val currTime = System.currentTimeMillis() + Column (horizontalAlignment = Alignment.CenterHorizontally){ + QuiQuestion(question = question.question) + QuiReponses(reponses = question.reponses) { + sendReponse(currTime - System.currentTimeMillis()) + Toast.makeText(context, it.reponse, Toast.LENGTH_SHORT).show() + } + } +} + + +@Composable +fun QuiReponses(reponses : List, action: (ReponseSimple)->Unit) { + LazyVerticalGrid(columns = GridCells.Fixed(2), + contentPadding = PaddingValues(12.dp), + verticalArrangement = Arrangement.spacedBy(10.dp), + horizontalArrangement = Arrangement.spacedBy(10.dp)) { + reponses.forEach { + item() { + Button(onClick = {action(it)}){ + Text(it.reponse) + } + } + } + } +} + +@Composable +fun QuiQuestion(question: String){ + Text(question, textAlign = TextAlign.Center) +} \ No newline at end of file diff --git a/android/app/src/main/java/fr/iut/sciencequest/viewModels/PenduViewModel.kt b/android/app/src/main/java/fr/iut/sciencequest/viewModels/PenduViewModel.kt index 9316e4f..f2f1d94 100644 --- a/android/app/src/main/java/fr/iut/sciencequest/viewModels/PenduViewModel.kt +++ b/android/app/src/main/java/fr/iut/sciencequest/viewModels/PenduViewModel.kt @@ -29,13 +29,14 @@ class PenduViewModel( } else { '_' } + uiState.value = PenduUIState( + isActionGood = true, + motATrouver = nomComplet, + motATrou = motATrou + ) } - uiState.value = PenduUIState( - isActionGood = true, - motATrouver = nomComplet, - motATrou = motATrou - ) } + } // mot : mot à trouver @@ -62,10 +63,9 @@ class PenduViewModel( nvMotATrou = nvMotATrou.replaceRange(index,index + 1, letterToCheck.toString()) } } - var isWon = false - if (nvMotATrou.equals(uiState.value.motATrouver)) { - isWon = true - } + + val isWon = nvMotATrou == uiState.value.motATrouver + uiState.value = PenduUIState(isWon, true, uiState.value.nbViesRestantes, diff --git a/quiestce b/quiestce new file mode 100644 index 0000000..7633d57 --- /dev/null +++ b/quiestce @@ -0,0 +1,8 @@ +Description dérive Qui-est-ce: + +- Image flou du scientifique à trouver +- 1 seul indice au début en dessous de la photo exemple: femme - 1967 +- 4 réponse possible comme kahoot, 1 seul essai +- maximum de point si la personne trouve du premier coup +- possibilité d'avoir + d'indice / diminution du flou mais gagne moins de points au fur et à mesure +- Plus simple à implémenter qu'un réel qui-est-ce.