viewModelAgain #51

Merged
leni.beaulaton merged 17 commits from viewModelAgain into master 3 weeks ago

@ -71,7 +71,10 @@ dependencies {
androidTestImplementation(libs.androidx.ui.test.junit4) androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest) debugImplementation(libs.androidx.ui.test.manifest)
implementation(libs.coil.compose) //gére les url des image implementation(libs.coil.compose) //gére les url des images
implementation(kotlin("script-runtime")) implementation(kotlin("script-runtime"))
//ViewModel
implementation(libs.android.lifecycle.viewmodel)
implementation(libs.android.lifecycle.viewmodel.runtime.ktx)
} }

@ -6,16 +6,16 @@ import com.example.what_the_fantasy.data.model.User
object UserStub { object UserStub {
//LE MOT DE PASSE POUR TOUS LES UTILISATEURS EST : 1234 //LE MOT DE PASSE POUR TOUS LES UTILISATEURS EST : 1234
val users: MutableList<User> = mutableListOf( val users: MutableList<User> = mutableListOf(
User(1, "Aragorn123", "aragorn@example.com", "2022-01-15", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-fantaisie_1045-185.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vf), //1234 User(0, "Aragorn123", "aragorn@example.com", "2022-01-15", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-fantaisie_1045-185.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vf), //1234
User(2, "Legolas456", "legolas@example.com", "2021-05-23", "https://img.freepik.com/vecteurs-libre/personnage-elfe-fantaisie_1045-186.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vf),//1234 User(1, "Legolas456", "legolas@example.com", "2021-05-23", "https://img.freepik.com/vecteurs-libre/personnage-elfe-fantaisie_1045-186.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vf),//1234
User(3, "Gandalf789", "gandalf@example.com", "2020-09-10", "https://img.freepik.com/vecteurs-libre/personnage-magicien-fantaisie_1045-187.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vf),//1234 User(2, "Gandalf789", "gandalf@example.com", "2020-09-10", "https://img.freepik.com/vecteurs-libre/personnage-magicien-fantaisie_1045-187.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vf),//1234
User(4, "FrodoBaggins", "frodo@example.com", "2023-03-18", "https://img.freepik.com/vecteurs-libre/personnage-hobbit-fantaisie_1045-188.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vf),//1234 User(3, "FrodoBaggins", "frodo@example.com", "2023-03-18", "https://img.freepik.com/vecteurs-libre/personnage-hobbit-fantaisie_1045-188.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vf),//1234
User(5, "Gimli999", "gimli@example.com", "2022-07-04", "https://img.freepik.com/vecteurs-libre/personnage-nain-fantaisie_1045-189.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234 User(4, "Gimli999", "gimli@example.com", "2022-07-04", "https://img.freepik.com/vecteurs-libre/personnage-nain-fantaisie_1045-189.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234
User(6, "Galadriel321", "galadriel@example.com", "2021-11-30", "https://img.freepik.com/vecteurs-libre/personnage-elfe-femme-fantaisie_1045-190.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234 User(5, "Galadriel321", "galadriel@example.com", "2021-11-30", "https://img.freepik.com/vecteurs-libre/personnage-elfe-femme-fantaisie_1045-190.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234
User(7, "Boromir654", "boromir@example.com", "2023-06-22", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-191.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234 User(6, "Boromir654", "boromir@example.com", "2023-06-22", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-191.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234
User(8, "Eowyn777", "eowyn@example.com", "2022-04-11", "https://img.freepik.com/vecteurs-libre/personnage-guerriere-femme-fantaisie_1045-192.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234 User(7, "Eowyn777", "eowyn@example.com", "2022-04-11", "https://img.freepik.com/vecteurs-libre/personnage-guerriere-femme-fantaisie_1045-192.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234
User(9, "Saruman888", "saruman@example.com", "2021-08-15", "https://img.freepik.com/vecteurs-libre/personnage-magicien-malefique-fantaisie_1045-193.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234 User(8, "Saruman888", "saruman@example.com", "2021-08-15", "https://img.freepik.com/vecteurs-libre/personnage-magicien-malefique-fantaisie_1045-193.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234
User(10, "Faramir222", "faramir@example.com", "2023-02-08", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234 User(9, "Faramir222", "faramir@example.com", "2023-02-08", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234
User(11, "dev", "testeur@example.com", "2023-02-08", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo)//1234 User(10, "dev", "testeur@example.com", "2023-02-08", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo)//1234
) )
} }

@ -3,19 +3,28 @@ package com.example.what_the_fantasy.data.services
import com.example.what_the_fantasy.data.model.Favorite import com.example.what_the_fantasy.data.model.Favorite
import com.example.what_the_fantasy.data.model.Comment import com.example.what_the_fantasy.data.model.Comment
import com.example.what_the_fantasy.data.model.Quote import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.data.model.User import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.ui.states.AuthUserState
import kotlinx.coroutines.flow.StateFlow
interface IServices { interface IServices {
fun validLogin(username : String,
passwd : String,
navController: (Int) -> Unit,
initialierCurrentUser : (Int) ->Unit): Boolean
fun EditUsername(username : String, index : Int) : Boolean fun EditUsername(username : String, index : Int) : Boolean
fun EditEmail(email : String, index : Int) : Boolean fun EditEmail(email : String, index : Int) : Boolean
fun EditPasswd(passwd : String, index : Int) fun EditPasswd(passwd : String, index : Int)
fun EditImage(imageURL : String, index : Int) fun EditImage(imageURL : String, index : Int)
fun ChangeLangage(user: User) fun ChangeLangage(index : Int): SrcLanguage
fun AddFav(userId: Int, QuoteId : Int) fun AddFav(userId: Int, QuoteId : Int)
fun SupFav(userId: Int, QuoteId : Int) fun SupFav(userId: Int, QuoteId : Int)
fun AddComment(content : String) fun AddComment(content : String)
fun CreateUser(username : String, email : String, passwd : String, services : IServices) : Boolean fun CreateUser(username : String, email : String, passwd : String) : Boolean
fun getFavorite(user: User): List<Quote> fun getFavorite(user: User): List<Quote>
fun getAllUsers(): List<User> fun getAllUsers(): List<User>
fun getComment(quoteId : Int) : List<Comment> fun getComment(quoteId : Int) : List<Comment>

@ -1,89 +1,89 @@
package com.example.what_the_fantasy.data.services package com.example.what_the_fantasy.data.services
import com.example.what_the_fantasy.data.model.Comment //import com.example.what_the_fantasy.data.model.Comment
import com.example.what_the_fantasy.data.model.Favorite //import com.example.what_the_fantasy.data.model.Favorite
import com.example.what_the_fantasy.data.model.Quote //import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.model.User //import com.example.what_the_fantasy.data.model.User
//import com.example.what_the_fantasy.ui.navigations.Destination ////import com.example.what_the_fantasy.ui.navigations.Destination
class ServicesAPI : IServices { //class ServicesAPI : IServices {
override fun EditUsername(username: String, index : Int): Boolean { // override fun EditUsername(username: String, index : Int): Boolean {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun EditEmail(email: String, index : Int): Boolean { // override fun EditEmail(email: String, index : Int): Boolean {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun EditPasswd(passwd: String, index : Int) { // override fun EditPasswd(passwd: String, index : Int) {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun EditImage(imageURL: String, index : Int) { // override fun EditImage(imageURL: String, index : Int) {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun ChangeLangage(user: User) { // override fun ChangeLangage(user: User) {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun AddFav(userId: Int, QuoteId: Int) { // override fun AddFav(userId: Int, QuoteId: Int) {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun SupFav(userId: Int, QuoteId: Int) { // override fun SupFav(userId: Int, QuoteId: Int) {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun AddComment(content: String) { // override fun AddComment(content: String) {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun CreateUser(username: String, email: String, passwd: String, services: IServices) : Boolean { // override fun CreateUser(username: String, email: String, passwd: String, services: IServices) : Boolean {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun getFavorite(user: User): List<Quote> { // override fun getFavorite(user: User): List<Quote> {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun SearchQuote(quote: String) { // override fun SearchQuote(quote: String) {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun getQuote(id: Int): Quote? { // override fun getQuote(id: Int): Quote? {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun isFavorite(id: Int, user: User): Boolean { // override fun isFavorite(id: Int, user: User): Boolean {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun getAllFavorite(): List<Favorite> { // override fun getAllFavorite(): List<Favorite> {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun getAllQuote(): List<Quote> { // override fun getAllQuote(): List<Quote> {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> { // override fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun getAllUsers(): List<User> { // override fun getAllUsers(): List<User> {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun getComment(quoteId: Int): List<Comment> { // override fun getComment(quoteId: Int): List<Comment> {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun getUserById(id: Int): User? { // override fun getUserById(id: Int): User? {
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
//
override fun search(type : String ,search:String ,indexCount: Int): List<Quote>{ // override fun search(type : String ,search:String ,indexCount: Int): List<Quote>{
TODO("Not yet implemented") // TODO("Not yet implemented")
} // }
} //}

@ -5,6 +5,7 @@ import com.example.what_the_fantasy.data.local.UserStub.users
import com.example.what_the_fantasy.data.model.User import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.logs.LogsUsers import com.example.what_the_fantasy.logs.LogsUsers
import com.example.what_the_fantasy.data.local.FavoriteStub.favorites import com.example.what_the_fantasy.data.local.FavoriteStub.favorites
import com.example.what_the_fantasy.data.local.ImageStub.allImages
import com.example.what_the_fantasy.data.local.QuoteStub.quotes import com.example.what_the_fantasy.data.local.QuoteStub.quotes
import com.example.what_the_fantasy.data.model.Favorite import com.example.what_the_fantasy.data.model.Favorite
import com.example.what_the_fantasy.data.local.CommentStub.comments import com.example.what_the_fantasy.data.local.CommentStub.comments
@ -16,6 +17,25 @@ import java.time.LocalDate
class ServicesStub : IServices { class ServicesStub : IServices {
val logsUser = LogsUsers() //gestion des logs pour les utilisateurs val logsUser = LogsUsers() //gestion des logs pour les utilisateurs
override fun validLogin(username : String,
passwd : String,
navController: (Int) -> Unit,
initialierCurrentUser : (Int) ->Unit): Boolean{
users.forEachIndexed { index, user ->
val hashPassWd = hashPassword(passwd)
if (user.username == username && user.password == hashPassWd) {
initialierCurrentUser(index)
navController(index)
logsUser.logInformationUserConnect(user, "UserConnect")
return true
}
}
return false
}
override fun EditUsername(username: String, index : Int) : Boolean{ override fun EditUsername(username: String, index : Int) : Boolean{
val user = getUserById(index) val user = getUserById(index)
@ -54,14 +74,16 @@ class ServicesStub : IServices {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override fun ChangeLangage(user: User) { override fun ChangeLangage(index : Int) : SrcLanguage{
if(user.langage == SrcLanguage.vo){ if(getAllUsers()[index].langage == SrcLanguage.vo){
user.langage = SrcLanguage.vf getAllUsers()[index].langage = SrcLanguage.vf
} }
else{ else{
user.langage = SrcLanguage.vo getAllUsers()[index].langage = SrcLanguage.vo
} }
logsUser.logDebugUserLangage(user, "ChangeLangue")
logsUser.logDebugUserLangage(getAllUsers()[index], "ChangeLangue")
return getAllUsers()[index].langage
} }
override fun AddFav(userId: Int, QuoteId: Int) { override fun AddFav(userId: Int, QuoteId: Int) {
@ -78,15 +100,17 @@ class ServicesStub : IServices {
//comments.add(Comment(content = content,)) //comments.add(Comment(content = content,))
} }
override fun CreateUser(username: String, email: String, passwd: String, services : IServices) : Boolean {
override fun CreateUser(username: String, email: String, passwd: String) : Boolean {
val date =dateDuJour() val date =dateDuJour()
val passwordhash = hashPassword(passwd) val passwordhash = hashPassword(passwd)
val services = ServicesStub()
val userStub = services.getAllUsers() val userStub = services.getAllUsers()
val nbUser = userStub.size val nbUser = userStub.size
if(!isUsernameExist(username) && !isEmailExist(email)){ if(!isUsernameExist(username) && !isEmailExist(email)){
val user = User(nbUser+1,username, email, date,randomImage(userStub), passwordhash, SrcLanguage.vo) val user = User(nbUser,username, email, date,randomImage(), passwordhash, SrcLanguage.vo)
users.add(user)//ajout au stub users.add(user)//ajout au stub
//Afficher tous les users //Afficher tous les users
@ -98,8 +122,7 @@ class ServicesStub : IServices {
override fun getFavorite(user: User): List<Quote> { override fun getFavorite(user: User): List<Quote> {
val favorite = favorites val favorite = favorites
return favorite[user.id-1].quote return favorite[0].quote
//return emptyList()
} }
override fun getAllFavorite(): List<Favorite> = favorites override fun getAllFavorite(): List<Favorite> = favorites
@ -109,7 +132,7 @@ class ServicesStub : IServices {
override fun getComment(quoteId: Int): List<Comment> = comments override fun getComment(quoteId: Int): List<Comment> = comments
override fun getUserById(id: Int): User? { override fun getUserById(id: Int): User? {
return (users.find { it.id == id+1 }) return (users.find { it.id == id })
} }
override fun SearchQuote(quote: String) { override fun SearchQuote(quote: String) {
@ -143,8 +166,16 @@ class ServicesStub : IServices {
return date.toString() return date.toString()
} }
fun randomImage(usersImage : List<User>) : String{ fun randomImage() : String{
return "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg" val sizeList = allImages.size
val randomNb = (0..sizeList).random()
allImages.forEach{image ->
if(image.id == randomNb){
return image.url
}
}
return allImages[0].url
} }
fun isUsernameExist(username : String) : Boolean{ fun isUsernameExist(username : String) : Boolean{

@ -0,0 +1,6 @@
package com.example.what_the_fantasy.repository
import com.example.what_the_fantasy.data.services.IServices
import okhttp3.Request
class AuthRepository {}

@ -1,5 +1,6 @@
package com.example.what_the_fantasy.ui.components package com.example.what_the_fantasy.ui.components
import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -8,7 +9,10 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.* import androidx.compose.material.icons.rounded.*
import androidx.compose.material3.BottomAppBar import androidx.compose.material3.BottomAppBar
@ -18,27 +22,37 @@ import androidx.compose.material3.IconButtonColors
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBar
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
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.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.rememberAsyncImagePainter
import coil.compose.rememberImagePainter
import com.example.what_the_fantasy.R import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable @Composable
fun NavBar(onProfile : Boolean = false , fun NavBar(onProfile : Boolean = false,
onFavorite : Boolean = false , onFavorite : Boolean = false,
onAccueil : Boolean = false , onAccueil : Boolean = false,
onQuiz : Boolean = false , onQuiz : Boolean = false,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
navControllerProfil: () -> Unit = {}, navControllerProfil: () -> Unit = {},
navControllerFavorite:() -> Unit = {}, navControllerFavorite:() -> Unit= {},
navControllerAccueil: () -> Unit = {}, navControllerAccueil: () -> Unit= {},
navControllerQuiz: () -> Unit = {}, navControllerQuiz: () -> Unit= {},
navControllerSearch: () -> Unit = {}, navControllerSearch: () -> Unit = {},
content : @Composable ()-> Unit ) { content : @Composable ()-> Unit ) {
Column( Column(
@ -56,7 +70,7 @@ fun NavBar(onProfile : Boolean = false ,
Arrangement.SpaceBetween, Arrangement.SpaceBetween,
verticalAlignment = Alignment.Bottom verticalAlignment = Alignment.Bottom
) { ) {
ButtonIconVector(Icons.Rounded.AccountCircle,stringResource(R.string.NavProfile),navControllerProfil,onProfile) ButtonIconVectorInt(currentUserState.imagePath,"Profile",navControllerProfil,onProfile)
ButtonIconVector(Icons.Rounded.Search,stringResource(R.string.NavSearch),navControllerSearch,false) ButtonIconVector(Icons.Rounded.Search,stringResource(R.string.NavSearch),navControllerSearch,false)
} }
@ -99,7 +113,7 @@ fun NavBar(onProfile : Boolean = false ,
} }
@Composable @Composable
fun ButtonIconVector(img : ImageVector, name : String, nav : ()->Unit,onPage : Boolean){ fun ButtonIconVectorInt(img : String, name : String, nav : ()->Unit ,onPage : Boolean){
IconButton(onClick = {nav()}, IconButton(onClick = {nav()},
enabled = !onPage, enabled = !onPage,
colors = IconButtonColors(Color.Transparent, MaterialTheme.colorScheme.onBackground,//couleur quand il n'est pas selectionné colors = IconButtonColors(Color.Transparent, MaterialTheme.colorScheme.onBackground,//couleur quand il n'est pas selectionné
@ -107,14 +121,34 @@ fun ButtonIconVector(img : ImageVector, name : String, nav : ()->Unit,onPage : B
modifier = Modifier modifier = Modifier
.size(60.dp) .size(60.dp)
) { ) {
Icon(img,
Image(
painter = rememberAsyncImagePainter(img),
contentDescription = name, contentDescription = name,
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.clip(CircleShape) // Pour rendre l'image circulaire
) )
} }
} }
@Composable
fun ButtonIconVector(img : ImageVector, name : String, nav : ()->Unit ,onPage : Boolean){
IconButton(onClick = {nav()},
enabled = !onPage,
colors = IconButtonColors(Color.Transparent, MaterialTheme.colorScheme.onBackground,//couleur quand il n'est pas selectionné
Color.Transparent, MaterialTheme.colorScheme.primary),//couleur quand il est selectionné
modifier = Modifier
.size(60.dp)
) {
Image(img,
contentDescription = name,
modifier = Modifier
.fillMaxSize()
.clip(CircleShape) // Pour rendre l'image circulaire
)
}
}
@Composable @Composable
fun ButtonIconPainter(img : Painter, name : String, nav : ()->Unit,onPage : Boolean){ fun ButtonIconPainter(img : Painter, name : String, nav : ()->Unit,onPage : Boolean){

@ -0,0 +1,28 @@
package com.example.what_the_fantasy.ui.components
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.example.what_the_fantasy.R
@Composable
fun VisibleIconPasswordComponent(passwordVisible : Boolean){
Icon(
painterResource(
if(passwordVisible){
R.drawable.password_visible
}
else{
R.drawable.password_no_visible
}
),
contentDescription = "visible",
modifier = Modifier
.size(20.dp),
tint = MaterialTheme.colorScheme.primary
)
}

@ -6,13 +6,19 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.lifecycle.viewmodel.compose.viewModel
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.toRoute import androidx.navigation.toRoute
import com.example.what_the_fantasy.data.services.ServicesStub import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.screens.* import com.example.what_the_fantasy.ui.screens.*
import com.example.what_the_fantasy.ui.viewModels.AuthUserViewModel
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import com.example.what_the_fantasy.ui.viewModels.SignInUserViewModel
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
@ -63,11 +69,24 @@ fun AppNavigator() {
val navController = rememberNavController() val navController = rememberNavController()
val services = ServicesStub() val services = ServicesStub()
//ViewModel pour l'authentification
val authUserVM : AuthUserViewModel = viewModel()
val authState by authUserVM.userState.collectAsState()
//ViewModel pour l'inscription
val signInUserVM : SignInUserViewModel = viewModel()
val signInState by signInUserVM.userState.collectAsState()
//ViewModel pour l'utilisateur
val currentUserVM : CurrentUserViewModel = viewModel()
val currentUserState by currentUserVM.currentUserState.collectAsState()
Scaffold( Scaffold(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
containerColor = MaterialTheme.colorScheme.onPrimary containerColor = MaterialTheme.colorScheme.onPrimary
) { paddingValues -> ) { paddingValues ->
Box(modifier = Modifier.padding(paddingValues)) { Box(modifier = Modifier.padding(paddingValues)) {
NavHost(navController, startDestination = Login) { NavHost(navController, startDestination = Login) {
composable<Login> { composable<Login> {
LoginPage( LoginPage(
@ -77,61 +96,81 @@ fun AppNavigator() {
popUpTo(Login) { inclusive = true } popUpTo(Login) { inclusive = true }
} }
}, },
services = services authUserVM = authUserVM,
authState = authState,
initialierCurrentUser ={currentUserVM.initialiseCurrentUser(it)}
) )
} }
composable<Accueil> { composable<Accueil> {
val accueil: Accueil = it.toRoute() //val accueil: Accueil = it.toRoute()
AccueilPage( AccueilPage(
index = accueil.userIndex, navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(accueil.userIndex)) }, navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
navQuiz = { navController.navigate(QuizMenu(accueil.userIndex)) }, navProfil = { navController.navigate(Profil(currentUserState.id)) },
navProfil = { navController.navigate(Profil(accueil.userIndex)) }, navQuote = { quoteId ->
navQuote = { quoteId -> navController.navigate(OneQuote(quoteId,accueil.userIndex)) }, navController.navigate(
navSearch = { navController.navigate(Search(accueil.userIndex))}, OneQuote(
services = services quoteId,
currentUserState.id
)
)
},
navSearch = { navController.navigate(Search(currentUserState.id))},
services = services,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
) )
} }
composable<Favorite> { composable<Favorite> {
val favorite: Favorite = it.toRoute() //val favorite: Favorite = it.toRoute()
FavoritePage( FavoritePage(
index = favorite.userIndex, navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navAccueil = { navController.navigate(Accueil(favorite.userIndex)) }, navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
navQuiz = { navController.navigate(QuizMenu(favorite.userIndex)) }, navProfil = { navController.navigate(Profil(currentUserState.id)) },
navProfil = { navController.navigate(Profil(favorite.userIndex)) }, navQuote = { quoteId ->
navQuote = { quoteId -> navController.navigate(OneQuote(quoteId,favorite.userIndex)) }, navController.navigate(
navSearch = { navController.navigate(Search(favorite.userIndex))}, OneQuote(
services = services quoteId,
currentUserState.id
)
)
},
navSearch = { navController.navigate(Search(currentUserState.id))},
services = services,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
) )
} }
composable<Profil> { composable<Profil> {
val profil: Profil = it.toRoute() val profil: Profil = it.toRoute()
ProfilPage( ProfilPage(
index = profil.userIndex, navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(profil.userIndex)) }, navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navAccueil = { navController.navigate(Accueil(profil.userIndex)) }, navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
navQuiz = { navController.navigate(QuizMenu(profil.userIndex)) }, navSubmitQuote = { navController.navigate(SubmitQuote(currentUserState.id)) },
navSubmitQuote = { navController.navigate(SubmitQuote(profil.userIndex)) },
navUnLog = { navUnLog = {
navController.navigate(Login) { navController.navigate(Login) {
popUpTo(profil) { inclusive = true } popUpTo(profil) { inclusive = true }
} }
}, },
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navSearch = { navController.navigate(Search(profil.userIndex))}, navSearch = { navController.navigate(Search(profil.userIndex))},
services = services
) )
} }
composable<OneQuote> { composable<OneQuote> {
val quote: OneQuote = it.toRoute() val quote: OneQuote = it.toRoute()
QuotePage( QuotePage(
quoteId = quote.quoteId, quoteId = quote.quoteId,
navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
navProfil = { navController.navigate(Profil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
service = services, service = services,
index = quote.userIndex, currentUserVM = currentUserVM,
navAccueil = { navController.navigate(Accueil(quote.userIndex)) }, currentUserState = currentUserState,
navQuiz = { navController.navigate(QuizMenu(quote.userIndex)) }, navSearch = { navController.navigate(Search(currentUserState.id))}
navProfil = { navController.navigate(Profil(quote.userIndex)) },
navFavorite = { navController.navigate(Favorite(quote.userIndex)) },
navSearch = { navController.navigate(Search(quote.userIndex))}
) )
} }
composable<Search> { composable<Search> {
@ -145,7 +184,9 @@ fun AppNavigator() {
navSearch = {type,newSearch -> navController.navigate(Search(search.userIndex,type,newSearch))}, navSearch = {type,newSearch -> navController.navigate(Search(search.userIndex,type,newSearch))},
services = services, services = services,
type = search.type, type = search.type,
search = search.search search = search.search,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
) )
} }
composable<SignUp> { composable<SignUp> {
@ -155,68 +196,77 @@ fun AppNavigator() {
popUpTo(Login) { inclusive = true } popUpTo(Login) { inclusive = true }
} }
}, },
services = services signInUserVM = signInUserVM,
signInState = signInState
) )
} }
composable<SubmitQuote> { composable<SubmitQuote> {
val submitQuote: SubmitQuote = it.toRoute() //val submitQuote: SubmitQuote = it.toRoute()
SubmitQuotePage( SubmitQuotePage(
navAccueil = { navController.navigate(Accueil(submitQuote.userIndex)) }, navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(submitQuote.userIndex)) }, navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(submitQuote.userIndex)) }, navProfil = { navController.navigate(Profil(currentUserState.id)) },
navQuiz = { navController.navigate(QuizMenu(submitQuote.userIndex)) }, navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
navRecap = { quoteContent, character, source -> navRecap = { quoteContent, character, source ->
navController.navigate( navController.navigate(
RecapSubmit( RecapSubmit(
submitQuote.userIndex, currentUserState.id,
quoteContent, quoteContent,
character, character,
source source
) )
) )
} },
currentUserVM = currentUserVM,
currentUserState = currentUserState,
) )
} }
composable<RecapSubmit> { composable<RecapSubmit> {
val recapSubmit: RecapSubmit = it.toRoute() val recapSubmit: RecapSubmit = it.toRoute()
RecapSubmitPage( RecapSubmitPage(
index = recapSubmit.userIndex,
quoteContent = recapSubmit.quoteContent, quoteContent = recapSubmit.quoteContent,
character = recapSubmit.character, character = recapSubmit.character,
source = recapSubmit.source, source = recapSubmit.source,
navAccueil = { navController.navigate(Accueil(recapSubmit.userIndex)) }, navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(recapSubmit.userIndex)) }, navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(recapSubmit.userIndex)) }, navProfil = { navController.navigate(Profil(currentUserState.id)) },
navSearch = { navController.navigate(Search(recapSubmit.userIndex))}, navSearch = { navController.navigate(Search(currentUserState.id))},
navQuiz = { navController.navigate(QuizMenu(recapSubmit.userIndex)) } navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
) currentUserVM = currentUserVM,
currentUserState = currentUserState,
)
} }
composable<QuizMenu> { composable<QuizMenu> {
val quizMenu: QuizMenu = it.toRoute() //val quizMenu: QuizMenu = it.toRoute()
QuizMenu( QuizMenu(
navAccueil = { navController.navigate(Accueil(quizMenu.userIndex)) }, currentUserVM = currentUserVM,
navFavorite = { navController.navigate(Favorite(quizMenu.userIndex)) }, currentUserState = currentUserState,
navProfil = { navController.navigate(Profil(quizMenu.userIndex)) }, navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navSearch = { navController.navigate(Search(quizMenu.userIndex))}, navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(currentUserState.id)) },
navSearch = { navController.navigate(Search(currentUserState.id))},
navControllerQuiz = { idQuiz -> navControllerQuiz = { idQuiz ->
navController.navigate(Quiz(quizMenu.userIndex, idQuiz)) navController.navigate(Quiz(currentUserState.id, idQuiz))
}, },
navControllerRandomQuiz = { navController.navigate(QuizRandom(quizMenu.userIndex)) } navControllerRandomQuiz = { navController.navigate(QuizRandom(currentUserState.id)) }
) )
} }
composable<Quiz> { composable<Quiz> {
val quiz: Quiz = it.toRoute() val quiz: Quiz = it.toRoute()
QuizPage( QuizPage(
navAccueil = { navController.navigate(Accueil(quiz.userIndex)) }, navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(quiz.userIndex)) }, navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(quiz.userIndex)) }, navProfil = { navController.navigate(Profil(currentUserState.id)) },
navQuiz = { navController.navigate(QuizMenu(quiz.userIndex)) }, navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
navControllerQuizEnd = { idQuiz, pts -> navControllerQuizEnd = { idQuiz, pts ->
navController.navigate(QuizEnd(quiz.userIndex, idQuiz, pts)) navController.navigate(QuizEnd(currentUserState.id, idQuiz, pts))
}, },
navSearch = { navController.navigate(Search(quiz.userIndex))}, navSearch = { navController.navigate(Search(currentUserState.id))},
idQuiz = quiz.idQuiz idQuiz = quiz.idQuiz,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
) )
} }
composable<QuizEnd> { composable<QuizEnd> {
@ -224,11 +274,13 @@ fun AppNavigator() {
QuizEndPage( QuizEndPage(
idQuiz = quizEnd.idQuiz, idQuiz = quizEnd.idQuiz,
points = quizEnd.pts, points = quizEnd.pts,
navAccueil = { navController.navigate(Accueil(quizEnd.userIndex)) }, navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(quizEnd.userIndex)) }, navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(quizEnd.userIndex)) }, navProfil = { navController.navigate(Profil(currentUserState.id)) },
navQuiz = { navController.navigate(QuizMenu(quizEnd.userIndex)) }, navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
navSearch = { navController.navigate(Search(quizEnd.userIndex))} navSearch = { navController.navigate(Search(currentUserState.id))},
currentUserVM = currentUserVM,
currentUserState = currentUserState,
) )
} }
@ -243,6 +295,8 @@ fun AppNavigator() {
navControllerQuizEnd = { idQuiz, pts -> navControllerQuizEnd = { idQuiz, pts ->
navController.navigate(QuizEnd(quizRandom.userIndex, idQuiz, pts)) navController.navigate(QuizEnd(quizRandom.userIndex, idQuiz, pts))
}, },
currentUserVM = currentUserVM,
currentUserState = currentUserState,
) )
} }
} }

@ -22,46 +22,49 @@ import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.services.IServices import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.QuoteLittle import com.example.what_the_fantasy.ui.components.QuoteLittle
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import com.example.what_the_fantasy.ui.theme.colorBackground
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@Composable @Composable
fun AccueilPage( fun AccueilPage(
index: Int,
navFavorite: () -> Unit, navFavorite: () -> Unit,
navQuiz: () -> Unit, navQuiz: () -> Unit,
navProfil: () -> Unit, navProfil: () -> Unit,
navSearch: () -> Unit,
navQuote: (Int) -> Unit, navQuote: (Int) -> Unit,
services: IServices navSearch: () -> Unit,
services: IServices,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) { ) {
val dailyQuote = DailyQuoteStub.dailyQuote val dailyQuote = DailyQuoteStub.dailyQuote
val user = services.getUserById(index) ?: return
val titleDalyQuote = stringResource(R.string.TitleHomeDailyQuote) val titleDalyQuote = stringResource(R.string.TitleHomeDailyQuote)
val titleSuggestion = stringResource(R.string.TitleHomeSuggestion) val titleSuggestion = stringResource(R.string.TitleHomeSuggestion)
val page = remember { mutableStateOf(1) } val page = remember { mutableIntStateOf(1) }
val quotes = remember { mutableStateListOf<Quote>() } val quotes = remember { mutableStateListOf<Quote>() }
val state = rememberLazyListState() val state = rememberLazyListState()
val layoutInfo = state.layoutInfo val layoutInfo = remember { derivedStateOf { state.layoutInfo } }
val isLoading = remember { mutableStateOf(false) } val isLoading = remember { mutableStateOf(false) }
val visibleItemsInfo = layoutInfo.visibleItemsInfo val visibleItemsInfo = layoutInfo.value.visibleItemsInfo
val fullyVisibleItemsInfo = visibleItemsInfo.toMutableList() val fullyVisibleItemsInfo = visibleItemsInfo.toMutableList()
val lastItem = if (fullyVisibleItemsInfo.isNotEmpty()) fullyVisibleItemsInfo.last() else null val lastItem = if (fullyVisibleItemsInfo.isNotEmpty()) fullyVisibleItemsInfo.last() else null
LaunchedEffect(page.value) { LaunchedEffect(page.intValue) {
if (!isLoading.value) { if (!isLoading.value) {
isLoading.value = true isLoading.value = true
delay(500) delay(500)
val newQuotes = services.getSomeQuotes(15, page.value) val newQuotes = services.getSomeQuotes(15, page.intValue)
val uniqueQuotes = newQuotes.filterNot { new -> quotes.any { it.id == new.id } } val uniqueQuotes = newQuotes.filterNot { new -> quotes.any { it.id == new.id } }
if (uniqueQuotes.isNotEmpty()) { if (uniqueQuotes.isNotEmpty()) {
quotes.addAll(uniqueQuotes) quotes.addAll(uniqueQuotes)
} else { } else {
println("Aucune nouvelle quote à la page ${page.value}, stop pagination.") println("Aucune nouvelle quote à la page ${page.intValue}, stop pagination.")
} }
isLoading.value = false isLoading.value = false
} }
@ -71,8 +74,9 @@ fun AccueilPage(
NavBar( NavBar(
onAccueil = true, onAccueil = true,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = { },
navControllerProfil = navProfil, navControllerProfil = navProfil,
navControllerQuiz = navQuiz, navControllerQuiz = navQuiz,
navControllerSearch = navSearch navControllerSearch = navSearch
@ -109,7 +113,7 @@ fun AccueilPage(
} }
items(quotes) { quote -> items(quotes) { quote ->
if (quote.language == user.langage) { if (quote.language == currentUserState.langage) {
Column(Modifier.clickable { navQuote(quote.id ) }) { Column(Modifier.clickable { navQuote(quote.id ) }) {
QuoteLittle(quote) QuoteLittle(quote)
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
@ -128,11 +132,11 @@ fun AccueilPage(
CircularProgressIndicator() CircularProgressIndicator()
} }
} else { } else {
LaunchedEffect(remember { derivedStateOf { state.firstVisibleItemIndex } }, state.layoutInfo.totalItemsCount) { LaunchedEffect(remember { derivedStateOf { state.firstVisibleItemIndex } }, remember { derivedStateOf { state.layoutInfo } }.value.totalItemsCount) {
if (!isLoading.value && state.layoutInfo.visibleItemsInfo.isNotEmpty()) { if (!isLoading.value && state.layoutInfo.visibleItemsInfo.isNotEmpty()) {
val lastVisibleItem = state.layoutInfo.visibleItemsInfo.last() val lastVisibleItem = state.layoutInfo.visibleItemsInfo.last()
if (lastVisibleItem.index >= state.layoutInfo.totalItemsCount - 1) { if (lastVisibleItem.index >= state.layoutInfo.totalItemsCount - 1) {
page.value++ page.intValue++
} }
} }
} }

@ -18,23 +18,30 @@ import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.services.IServices import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.QuoteLittle import com.example.what_the_fantasy.ui.components.QuoteLittle
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.theme.colorBackground
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable @Composable
fun FavoritePage( fun FavoritePage(
index: Int,
navAccueil: () -> Unit, navAccueil: () -> Unit,
navQuiz: () -> Unit, navQuiz: () -> Unit,
navProfil: () -> Unit, navProfil: () -> Unit,
navSearch: () -> Unit,
navQuote: (Int) -> Unit, navQuote: (Int) -> Unit,
services: IServices navSearch: () -> Unit,
services: IServices,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) { ) {
val user = services.getUserById(index) ?: return val user = services.getUserById(currentUserState.id) ?: return
val quotes = services.getFavorite(user) val quotes = services.getFavorite(user)
val titlePage = stringResource(R.string.TitleFavorite) val titlePage = stringResource(R.string.TitleFavorite)
NavBar(onFavorite = true, NavBar(onFavorite = true,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navControllerFavorite = { },
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,
navControllerQuiz = navQuiz, navControllerQuiz = navQuiz,

@ -1,5 +1,6 @@
package com.example.what_the_fantasy.ui.screens package com.example.what_the_fantasy.ui.screens
import android.util.Log
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -16,6 +17,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -30,6 +32,7 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.what_the_fantasy.logs.LogsUsers import com.example.what_the_fantasy.logs.LogsUsers
import com.example.what_the_fantasy.R import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.model.User import com.example.what_the_fantasy.data.model.User
@ -38,10 +41,17 @@ import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent
import com.example.what_the_fantasy.ui.components.SpaceHeightComponent import com.example.what_the_fantasy.ui.components.SpaceHeightComponent
import com.example.what_the_fantasy.ui.components.TitlePageComponent import com.example.what_the_fantasy.ui.components.TitlePageComponent
import com.example.what_the_fantasy.data.services.hashPassword import com.example.what_the_fantasy.data.services.hashPassword
import com.example.what_the_fantasy.ui.components.VisibleIconPasswordComponent
import com.example.what_the_fantasy.ui.states.AuthUserState
import com.example.what_the_fantasy.ui.viewModels.AuthUserViewModel
@Composable @Composable
fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: (Int) -> Unit, services : IServices) { fun LoginPage(navControllerSignUp: () -> Unit,
val users = services.getAllUsers() navControllerProfil: (Int) -> Unit,
authUserVM : AuthUserViewModel,
authState : AuthUserState,
initialierCurrentUser : (Int) -> Unit) {
Box( Box(
modifier = Modifier modifier = Modifier
@ -61,7 +71,15 @@ fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: (Int) -> Uni
TitlePageComponent(R.string.titleLogin, MaterialTheme.colorScheme.primary) TitlePageComponent(R.string.titleLogin, MaterialTheme.colorScheme.primary)
SpaceHeightComponent(20) SpaceHeightComponent(20)
ConnexionButtonLogin(users,IdentifiantTextField(R.string.IdentifiantLogin), PassWdTextField(R.string.PasswdLogin), R.string.ButtonLogin,18, Color.White, Color.Black,navControllerProfil)
ConnexionButtonLogin(authUserVM,
IdentifiantTextField(R.string.IdentifiantLogin, authState.username){
authUserVM.setUsername(it)
}, PassWdTextField(R.string.PasswdLogin, authState.password){
authUserVM.setPassword(it)
}, R.string.ButtonLogin,18,navControllerProfil){
initialierCurrentUser(it)
}
SpaceHeightComponent(16) SpaceHeightComponent(16)
CreateAccountButton(R.string.ButtonCreateLogin,12, MaterialTheme.colorScheme.primary, navControllerSignUp) CreateAccountButton(R.string.ButtonCreateLogin,12, MaterialTheme.colorScheme.primary, navControllerSignUp)
} }
@ -70,13 +88,13 @@ fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: (Int) -> Uni
@Composable @Composable
fun IdentifiantTextField(textIdentifiantResId : Int) : String{ fun IdentifiantTextField(textIdentifiantResId : Int, username : String, onValueChange: (String) -> Unit ) : String{
val textIdentifiant = stringResource(id = textIdentifiantResId) val textIdentifiant = stringResource(id = textIdentifiantResId)
var identifiant by remember { mutableStateOf("") }
Column(modifier = Modifier.padding(top = 16.dp)) { Column(modifier = Modifier.padding(top = 16.dp)) {
OutlinedTextField( OutlinedTextField(
value = identifiant, value = username,
onValueChange = { identifiant = it }, onValueChange = onValueChange,
label = { Text(textIdentifiant) }, label = { Text(textIdentifiant) },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -86,18 +104,18 @@ fun IdentifiantTextField(textIdentifiantResId : Int) : String{
shape = RoundedCornerShape(16.dp) shape = RoundedCornerShape(16.dp)
) )
} }
return identifiant; return username;
} }
@Composable @Composable
fun PassWdTextField(textpasswdResId : Int) : String{ fun PassWdTextField(textpasswdResId : Int, password : String, onValueChange: (String) -> Unit) : String{
val textpasswd = stringResource(id = textpasswdResId) val textpasswd = stringResource(id = textpasswdResId)
var passwd by remember { mutableStateOf("") }
var passwordVisible by remember { mutableStateOf(false) } var passwordVisible by remember { mutableStateOf(false) }
Column(modifier = Modifier.padding(top = 10.dp, bottom = 30.dp)) { Column(modifier = Modifier.padding(top = 10.dp, bottom = 30.dp)) {
OutlinedTextField( OutlinedTextField(
value = passwd, value = password,
onValueChange = { passwd = it }, onValueChange = onValueChange,
label = { Text(textpasswd) }, label = { Text(textpasswd) },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -107,21 +125,22 @@ fun PassWdTextField(textpasswdResId : Int) : String{
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = { trailingIcon = {
IconButton(onClick = { passwordVisible = !passwordVisible }) { IconButton(onClick = { passwordVisible = !passwordVisible }) {
VisibleIconPasswordComponent(passwordVisible)
} }
}, },
shape = RoundedCornerShape(16.dp) shape = RoundedCornerShape(16.dp)
) )
} }
return passwd; return password;
} }
@Composable @Composable
fun ConnexionButtonLogin(userStub : List<User>, id : String, passwd : String, titleResId : Int, size : Int, colorButton : Color, colorText : Color, navController: (Int) -> Unit){ fun ConnexionButtonLogin(authUserVM : AuthUserViewModel, username : String, passwd : String, titleResId : Int, size : Int, navController: (Int) -> Unit, initialierCurrentUser : (Int) -> Unit){
val title = stringResource(id = titleResId) val title = stringResource(id = titleResId)
var showError by remember { mutableStateOf(false) } var showError by remember { mutableStateOf(false) }
Button( Button(
onClick = { showError = !validLogin(id, passwd, userStub, navController) onClick = { showError = !authUserVM.validLogin(username, passwd, navController, initialierCurrentUser)
}, },
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background), colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background),
modifier = Modifier modifier = Modifier
@ -136,19 +155,6 @@ fun ConnexionButtonLogin(userStub : List<User>, id : String, passwd : String, ti
} }
fun validLogin(identifiant : String, passwd : String, users : List<User>, navController: (Int) -> Unit): Boolean {
val logsUser = LogsUsers() //gestion des logs pour les utilisateurs
users.forEachIndexed { index, user ->
val hashPassWd = hashPassword(passwd)
if (user.username == identifiant && user.password == hashPassWd) {
navController(index)
logsUser.logInformationUserConnect(user, "UserConnect")
return true
}
}
return false
}
@Composable @Composable
fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: () -> Unit) { fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: () -> Unit) {

@ -1,5 +1,6 @@
package com.example.what_the_fantasy.ui.screens package com.example.what_the_fantasy.ui.screens
import android.util.Log
import android.util.Patterns import android.util.Patterns
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -47,26 +48,28 @@ import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage import coil.compose.AsyncImage
import com.example.what_the_fantasy.logs.LogsUsers import com.example.what_the_fantasy.logs.LogsUsers
import com.example.what_the_fantasy.R import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.SpaceHeightComponent import com.example.what_the_fantasy.ui.components.SpaceHeightComponent
import com.example.what_the_fantasy.ui.components.TitlePageComponent import com.example.what_the_fantasy.ui.components.TitlePageComponent
import com.example.what_the_fantasy.ui.components.VisibleIconPasswordComponent
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable @Composable
fun ProfilPage(index: Int, fun ProfilPage(navFavorite: () -> Unit,
navFavorite: () -> Unit,
navAccueil: () -> Unit, navAccueil: () -> Unit,
navQuiz: () -> Unit, navQuiz: () -> Unit,
navSearch: () -> Unit,
navUnLog: () -> Unit, navUnLog: () -> Unit,
navSubmitQuote: () -> Unit, navSubmitQuote: () -> Unit,
services: IServices navSearch: () -> Unit,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) { ) {
val user = services.getUserById(index) ?: return
NavBar(onProfile = true, NavBar(onProfile = true,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerQuiz = navQuiz, navControllerQuiz = navQuiz,
@ -93,25 +96,25 @@ fun ProfilPage(index: Int,
TitlePageComponent(R.string.titleProfile, MaterialTheme.colorScheme.onBackground) TitlePageComponent(R.string.titleProfile, MaterialTheme.colorScheme.onBackground)
SpaceHeightComponent(16) SpaceHeightComponent(16)
// Image de profil // Image de profil
ImageProfil(user.imgUrl, 120) ImageProfil(currentUserState.imagePath, 120)
SpaceHeightComponent(16) SpaceHeightComponent(16)
EditUsername(user.username, index, services)// Édition du Username EditUsername(currentUserState.username, currentUserState.id, currentUserVM)// Édition du Username
SpaceHeightComponent(16) SpaceHeightComponent(16)
EditEmail(user.email,index, services)// Édition du Email EditEmail(currentUserState.email,currentUserState.id, currentUserVM)// Édition du Email
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
EditPasswd(index, services) EditPasswd(currentUserState.id, currentUserVM)
SpaceHeightComponent(16) SpaceHeightComponent(16)
// Bouton // Bouton
ButtonProfile(R.string.ButtonAddQuoteprofile, 18, MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.background,navSubmitQuote) // Pas encore de navigation definie ButtonProfile(R.string.ButtonAddQuoteprofile, 18, MaterialTheme.colorScheme.primary,MaterialTheme.colorScheme.background,navSubmitQuote) // Pas encore de navigation definie
SpaceHeightComponent(16) SpaceHeightComponent(16)
ButtonLanguage(R.string.ButtonLanguageprofile, 18, MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.background,services, user) ButtonLanguage(R.string.ButtonLanguageprofile, 18, MaterialTheme.colorScheme.primary,MaterialTheme.colorScheme.background,currentUserVM, currentUserState)
SpaceHeightComponent(16) SpaceHeightComponent(16)
ButtonUnLog(R.string.ButtonUnlogprofile, 18, MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.background,navUnLog) ButtonUnLog(R.string.ButtonUnlogprofile, 18,MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.background, navUnLog,currentUserVM)
@ -134,13 +137,13 @@ fun ImageProfil(imgProfil : String, size :Int){
} }
@Composable @Composable
fun EditEmail(userEmail: String, index: Int, service: IServices) { fun EditEmail(emailState: String, index: Int, currentUserVM: CurrentUserViewModel) {
var email by remember { mutableStateOf(userEmail) } var email by remember { mutableStateOf(emailState) }
var isEditingEmail by remember { mutableStateOf(false) } var isEditingEmail by remember { mutableStateOf(false) }
var emailError by remember { mutableStateOf(false) } var emailError by remember { mutableStateOf(false) }
fun onDoneEditing() { fun onDoneEditing() {
isEditingEmail =!service.EditEmail(email, index) isEditingEmail =!currentUserVM.editEmail(email, index)
} }
@ -221,12 +224,12 @@ fun DisplayEmail(email: String, onEdit: () -> Unit) {
@Composable @Composable
fun EditUsername(userName: String, index: Int, service : IServices) { fun EditUsername(usernameState: String, index: Int, currentUserVM : CurrentUserViewModel) {
var username by remember { mutableStateOf(userName) } var username by remember { mutableStateOf(usernameState) }
var isEditingUsername by remember { mutableStateOf(false) } var isEditingUsername by remember { mutableStateOf(false) }
fun onDoneEditing() { fun onDoneEditing() {
isEditingUsername= !service.EditUsername(username, index) isEditingUsername= !currentUserVM.editUsername(username, index)
} }
if (isEditingUsername) { if (isEditingUsername) {
@ -290,7 +293,7 @@ fun DisplayUsername(username: String, onEdit: () -> Unit) {
@Composable @Composable
fun EditPasswd(index: Int, service: IServices) { fun EditPasswd(index: Int, currentUserVM: CurrentUserViewModel) {
var password by remember { mutableStateOf("*******") } // Mot de passe actuel (affiché comme un masque) var password by remember { mutableStateOf("*******") } // Mot de passe actuel (affiché comme un masque)
var isEditingPassword by remember { mutableStateOf(false) } var isEditingPassword by remember { mutableStateOf(false) }
var newPassword by remember { mutableStateOf("") } var newPassword by remember { mutableStateOf("") }
@ -301,7 +304,7 @@ fun EditPasswd(index: Int, service: IServices) {
// Fonction pour finaliser l'édition du mot de passe et appeler la méthode EditPasswd2 // Fonction pour finaliser l'édition du mot de passe et appeler la méthode EditPasswd2
fun onDoneEditing() { fun onDoneEditing() {
// Appeler EditPasswd pour mettre à jour le mot de passe de l'utilisateur // Appeler EditPasswd pour mettre à jour le mot de passe de l'utilisateur
service.EditPasswd(newPassword, index) currentUserVM.editPassword(newPassword, index)
isEditingPassword = false isEditingPassword = false
} }
@ -314,18 +317,20 @@ fun EditPasswd(index: Int, service: IServices) {
confirmPassword = it confirmPassword = it
passwordError = newPassword != it // Vérifier si les mots de passe correspondent passwordError = newPassword != it // Vérifier si les mots de passe correspondent
}, },
passwordVisible = passwordVisible, passwordVisible = passwordVisible,
onPasswordVisibilityChange = { passwordVisible = it }, onPasswordVisibilityChange = { passwordVisible = it },
passwordError = passwordError, passwordError = passwordError,
onDone = { onDone = {
if (!passwordError && newPassword.isNotEmpty()) { if (!passwordError && newPassword.isNotEmpty()) {
onDoneEditing() // Appeler la fonction onDoneEditing() pour mettre à jour le mot de passe onDoneEditing() // pour mettre à jour le mot de passe
} }
} }
) )
} else { } else {
DisplayPassword(onEdit = { isEditingPassword = true }) // Afficher l'option pour modifier le mot de passe DisplayPassword(onEdit = { isEditingPassword = true }) // pour modifier le mot de passe
} }
} }
@Composable @Composable
@ -399,7 +404,7 @@ fun PasswordTextField(
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = { trailingIcon = {
IconButton(onClick = { onPasswordVisibilityChange(!passwordVisible) }) { IconButton(onClick = { onPasswordVisibilityChange(!passwordVisible) }) {
// Ajout d'une icône pour montrer/masquer le mot de passe VisibleIconPasswordComponent(passwordVisible)
} }
}, },
isError = isError isError = isError
@ -442,14 +447,16 @@ fun DisplayPassword(onEdit: () -> Unit) {
} }
@Composable @Composable
fun ButtonUnLog(textResId : Int, size :Int, colorTexte : Color, colorButton : Color,navController: () -> Unit){ fun ButtonUnLog(textResId : Int, size :Int, colorTexte : Color,colorButton : Color, navController: () -> Unit, currentUserVM: CurrentUserViewModel){
val text = stringResource(id = textResId) val text = stringResource(id = textResId)
val logsUser = LogsUsers() //gestion des logs pour les utilisateurs val logsUser = LogsUsers() //gestion des logs pour les utilisateurs
Button( Button(
onClick = { onClick = {
currentUserVM.clearCurrentUser()
navController() navController()
logsUser.unlogInformationUserConnect("UserUnLog") logsUser.unlogInformationUserConnect("UserUnLog")
}, },
colors = ButtonDefaults.buttonColors(containerColor = colorButton), colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@ -459,23 +466,22 @@ fun ButtonUnLog(textResId : Int, size :Int, colorTexte : Color, colorButton : Co
} }
@Composable @Composable
fun ButtonLanguage(textResId : Int, size :Int, colorTexte : Color, colorButton : Color, service: IServices, user : User){ fun ButtonLanguage(textResId : Int, size :Int,colorTexte : Color, colorButton : Color, currentUserVM: CurrentUserViewModel, currentUserState : CurrentUserState){
val text = stringResource(id = textResId) val text = stringResource(id = textResId)
val currentLangage = remember { mutableStateOf(user.langage) }
Button( Button(
onClick = { onClick = {
service.ChangeLangage(user) currentUserVM.editLangue(currentUserState.id)
currentLangage.value = user.langage
}, },
colors = ButtonDefaults.buttonColors(containerColor = colorButton), colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
) { ) {
Text("${text} (${currentLangage.value})", fontSize = size.sp, color = colorTexte) Text("${text} (${currentUserState.langage})", fontSize = size.sp, color = colorTexte)
} }
} }
@Composable @Composable
fun ButtonProfile(textResId : Int, size :Int, colorTexte : Color, colorButton : Color,navController: () -> Unit){ fun ButtonProfile(textResId : Int, size :Int,colorTexte : Color, colorButton : Color,navController: () -> Unit){
val text = stringResource(id = textResId) val text = stringResource(id = textResId)
Button( Button(

@ -18,6 +18,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.data.local.QuizStub import com.example.what_the_fantasy.data.local.QuizStub
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
val gradient = Brush.linearGradient( val gradient = Brush.linearGradient(
colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)),
@ -34,8 +36,12 @@ fun QuizEndPage(
navProfil:() -> Unit, navProfil:() -> Unit,
navQuiz: () -> Unit, navQuiz: () -> Unit,
navSearch: () -> Unit, navSearch: () -> Unit,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) { ) {
NavBar( NavBar(
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,

@ -33,17 +33,24 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.data.local.QuizStub import com.example.what_the_fantasy.data.local.QuizStub
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable @Composable
fun QuizMenu( fun QuizMenu(
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
navFavorite: () -> Unit, navFavorite: () -> Unit,
navAccueil: () -> Unit, navAccueil: () -> Unit,
navProfil:() -> Unit, navProfil:() -> Unit,
navSearch: () -> Unit,
navControllerQuiz: (Int) -> Unit, navControllerQuiz: (Int) -> Unit,
navSearch: () -> Unit,
navControllerRandomQuiz:() -> Unit navControllerRandomQuiz:() -> Unit
) { ) {
NavBar(onQuiz = true, NavBar(onQuiz = true,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,

@ -19,9 +19,13 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.data.local.QuizStub import com.example.what_the_fantasy.data.local.QuizStub
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable @Composable
fun QuizPage( fun QuizPage(
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
navFavorite: () -> Unit, navFavorite: () -> Unit,
navAccueil: () -> Unit, navAccueil: () -> Unit,
navProfil:() -> Unit, navProfil:() -> Unit,
@ -57,6 +61,8 @@ fun QuizPage(
else navControllerQuizEnd(idQuiz, pts) // Retour menu else navControllerQuizEnd(idQuiz, pts) // Retour menu
} }
NavBar( NavBar(
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,

@ -20,6 +20,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.data.local.QuestionStub import com.example.what_the_fantasy.data.local.QuestionStub
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable @Composable
fun QuizRandom( fun QuizRandom(
@ -29,6 +31,8 @@ fun QuizRandom(
navQuiz: () -> Unit, navQuiz: () -> Unit,
navSearch: () -> Unit, navSearch: () -> Unit,
navControllerQuizEnd: (Int, Int) -> Unit, navControllerQuizEnd: (Int, Int) -> Unit,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) { ) {
val questions = QuestionStub.shuffleRandomQuestions val questions = QuestionStub.shuffleRandomQuestions
var idCurrentQuestion by remember { mutableIntStateOf(0) } var idCurrentQuestion by remember { mutableIntStateOf(0) }
@ -66,7 +70,9 @@ fun QuizRandom(
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,
navControllerQuiz = navQuiz, navControllerQuiz = navQuiz,
navControllerSearch = navSearch navControllerSearch = navSearch,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
){ ){
Column ( Column (
modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B)) modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B))

@ -53,6 +53,13 @@ import coil.compose.AsyncImage
import com.example.what_the_fantasy.data.model.Comment import com.example.what_the_fantasy.data.model.Comment
import com.example.what_the_fantasy.data.services.IServices import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.theme.colorBackground
import com.example.what_the_fantasy.ui.theme.gradienBox
import com.example.what_the_fantasy.ui.theme.iconText
import com.example.what_the_fantasy.ui.theme.likeIcon
import com.example.what_the_fantasy.ui.theme.whiteBackcgroundText
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
var isCommentVisible by mutableStateOf(false) var isCommentVisible by mutableStateOf(false)
@ -60,20 +67,23 @@ var isCommentVisible by mutableStateOf(false)
fun QuotePage( fun QuotePage(
quoteId : Int, quoteId : Int,
service : IServices, service : IServices,
index : Int,
navAccueil: () -> Unit, navAccueil: () -> Unit,
navFavorite:() -> Unit, navFavorite:() -> Unit,
navQuiz: () -> Unit, navQuiz: () -> Unit,
navProfil:() -> Unit,
navSearch: () -> Unit, navSearch: () -> Unit,
navProfil:() -> Unit) currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
)
{ {
// utiliser ViewModel // utiliser ViewModel
val quote = service.getQuote(quoteId) ?: return val quote = service.getQuote(quoteId) ?: return
val context = LocalContext.current val context = LocalContext.current
val user = service.getUserById(index) ?: return val user = service.getUserById(currentUserState.id) ?: return
val favorite by remember { mutableStateOf(service.isFavorite(id = quoteId, user = user)) } val favorite by remember { mutableStateOf(service.isFavorite(id = quoteId, user = user)) }
NavBar(onProfile = true,
NavBar( currentUserVM = currentUserVM,
currentUserState = currentUserState,
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,
@ -101,7 +111,7 @@ fun QuotePage(
FunctionalIcon( FunctionalIcon(
isFavorite = favorite, isFavorite = favorite,
userId = index, userId = currentUserState.id,
id = quoteId, id = quoteId,
context = context, context = context,
service = service service = service
@ -148,7 +158,7 @@ fun QuotePage(
) { ) {
Box(modifier = Modifier.fillMaxWidth().background(MaterialTheme.colorScheme.primary).fillMaxSize()){ Box(modifier = Modifier.fillMaxWidth().background(MaterialTheme.colorScheme.primary).fillMaxSize()){
Column { Column {
AddComment(index, service) AddComment(currentUserState.id, service)
LstComment(service.getComment(quoteId)) LstComment(service.getComment(quoteId))
} }
} }
@ -337,8 +347,6 @@ fun AddComment(userId: Int, service: IServices) {
) )
} }
} }
@Composable @Composable
fun LstComment(lst: List<Comment>) { fun LstComment(lst: List<Comment>) {
LazyColumn( LazyColumn(
@ -381,5 +389,3 @@ fun LstComment(lst: List<Comment>) {
} }
} }
} }

@ -30,21 +30,27 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import com.example.what_the_fantasy.data.model.Character
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable @Composable
fun RecapSubmitPage( fun RecapSubmitPage(
index: Int,
navFavorite: () -> Unit, navFavorite: () -> Unit,
navAccueil: () -> Unit, navAccueil: () -> Unit,
navProfil:() -> Unit, navProfil:() -> Unit,
navQuiz: () -> Unit,
navSearch: () -> Unit, navSearch: () -> Unit,
navQuiz : () -> Unit,
quoteContent : String, quoteContent : String,
character: String, character: String,
source: String source: String,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) { ) {
NavBar( NavBar(onQuiz = true,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,

@ -28,6 +28,8 @@ import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.services.IServices import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.QuoteLittle import com.example.what_the_fantasy.ui.components.QuoteLittle
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@Composable @Composable
@ -40,7 +42,9 @@ fun SearchPage(
navSearch: (String, String) -> Unit, navSearch: (String, String) -> Unit,
services: IServices, services: IServices,
type: String, type: String,
search: String search: String,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) { ) {
var newSearch by remember { mutableStateOf(search) } var newSearch by remember { mutableStateOf(search) }
val filtre = listOf("contenue", "personnage", "titre") val filtre = listOf("contenue", "personnage", "titre")
@ -70,7 +74,10 @@ fun SearchPage(
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,
navControllerQuiz = navQuiz, navControllerQuiz = navQuiz,
navControllerSearch = { navSearch("contenue", "") } navControllerSearch = { navSearch("contenue", "") },
currentUserVM = currentUserVM,
currentUserState = currentUserState,
) { ) {
Column( Column(
modifier = Modifier modifier = Modifier

@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
@ -21,6 +22,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -29,25 +31,26 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.what_the_fantasy.R import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.services.IServices import com.example.what_the_fantasy.data.model.Image
import com.example.what_the_fantasy.ui.components.SpaceHeightComponent import com.example.what_the_fantasy.ui.components.SpaceHeightComponent
import com.example.what_the_fantasy.ui.components.TitlePageComponent import com.example.what_the_fantasy.ui.components.TitlePageComponent
import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent
import com.example.what_the_fantasy.ui.components.VisibleIconPasswordComponent
import com.example.what_the_fantasy.ui.states.SignInUserState
import com.example.what_the_fantasy.ui.viewModels.SignInUserViewModel
@Composable @Composable
fun SignUpPage(navControllerLogin: () -> Unit, services : IServices) { fun SignUpPage(navControllerLogin: () -> Unit, signInUserVM :SignInUserViewModel,signInState : SignInUserState) {
var username by remember { mutableStateOf("") }
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var confirmPassword by remember { mutableStateOf("") }
var passwordVisible by remember { mutableStateOf(false) }
Box( Box(
modifier = Modifier modifier = Modifier
@ -66,23 +69,35 @@ fun SignUpPage(navControllerLogin: () -> Unit, services : IServices) {
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
TitlePageComponent(R.string.titleSignUp,MaterialTheme.colorScheme.onBackground) TitlePageComponent(R.string.titleSignUp,MaterialTheme.colorScheme.onBackground) // Page Title
IdentifiantTextFieldSign(R.string.IdentifiantLogin,identifiant = username,onValueChange = { username = it })
EmailTextFieldSign(R.string.EmailSignUp, email, onValueChange = { email = it }) IdentifiantTextFieldSign(R.string.IdentifiantLogin,signInState.username){ // Username
PassWdTextFieldSign(R.string.PasswdLogin,password, onValueChange = { password = it },passwordVisible,onPasswordVisibilityChange = { passwordVisible = !passwordVisible }) signInUserVM.setUsername(it)
PassWdConfirmTextFieldSign(R.string.ConfirmPassWdSignUp,confirmPassword,onValueChange = { confirmPassword = it },passwordVisible,onPasswordVisibilityChange = { passwordVisible = !passwordVisible }) }
EmailTextFieldSign(R.string.EmailSignUp, signInState.email){ // Email
signInUserVM.setEmail(it)
}
PassWdTextFieldSign(R.string.PasswdLogin,signInState.password){ // Password
signInUserVM.setPassword(it)
}
PassWdConfirmTextFieldSign(R.string.ConfirmPassWdSignUp,signInState.confirmPassword){ // confirm Password
signInUserVM.setConfirmPassword(it)
}
SpaceHeightComponent(16) SpaceHeightComponent(16)
ConnexionButtonSign(R.string.ButtonSignUp,18, MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.onBackground, username, email, password, confirmPassword, services, navControllerLogin)
ConnexionButtonSign(R.string.ButtonSignUp,18, Color.White, Color.Black, signInState.username, signInState.email, signInState.password, signInState.confirmPassword, signInUserVM, navControllerLogin)
SpaceHeightComponent(16) SpaceHeightComponent(16)
ReturnLogin(R.string.ButtonLogin,12, MaterialTheme.colorScheme.primary, navController = navControllerLogin)
ReturnLogin(R.string.ButtonLogin,12, Color.White, navController = navControllerLogin)
} }
} }
} }
@Composable @Composable
fun IdentifiantTextFieldSign(textIdentifiantResId : Int, identifiant: String, onValueChange: (String) -> Unit){ fun IdentifiantTextFieldSign(textIdentifiantResId : Int, identifiant: String, onValueChange: (String) -> Unit){
val textIdentifiant = stringResource(id = textIdentifiantResId) val textIdentifiant = stringResource(id = textIdentifiantResId)
@ -119,8 +134,10 @@ fun EmailTextFieldSign(textIdentifiantResId: Int, email: String, onValueChange:
} }
@Composable @Composable
fun PassWdTextFieldSign(textpasswdResId : Int, passwd: String, onValueChange: (String) -> Unit, passwordVisible: Boolean, onPasswordVisibilityChange: () -> Unit){ fun PassWdTextFieldSign(textpasswdResId : Int, passwd: String, onValueChange: (String) -> Unit){
val textpasswd = stringResource(id = textpasswdResId) val textpasswd = stringResource(id = textpasswdResId)
var passwordVisible by remember { mutableStateOf(false) }
Column(modifier = Modifier.padding(top = 10.dp)) { Column(modifier = Modifier.padding(top = 10.dp)) {
OutlinedTextField( OutlinedTextField(
value = passwd, value = passwd,
@ -132,8 +149,10 @@ fun PassWdTextFieldSign(textpasswdResId : Int, passwd: String, onValueChange: (S
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = { trailingIcon = {
IconButton(onClick = onPasswordVisibilityChange) { IconButton(onClick = {
Icon(imageVector = Icons.Default.Check, contentDescription = "Valider") passwordVisible = !passwordVisible
}) {
VisibleIconPasswordComponent(passwordVisible)
} }
}, },
shape = RoundedCornerShape(16.dp) shape = RoundedCornerShape(16.dp)
@ -142,8 +161,10 @@ fun PassWdTextFieldSign(textpasswdResId : Int, passwd: String, onValueChange: (S
} }
@Composable @Composable
fun PassWdConfirmTextFieldSign(textpasswdResId : Int,confirmPassword: String, onValueChange: (String) -> Unit, passwordVisible: Boolean, onPasswordVisibilityChange: () -> Unit){ fun PassWdConfirmTextFieldSign(textpasswdResId : Int,confirmPassword: String, onValueChange: (String) -> Unit){
val textpasswd = stringResource(id = textpasswdResId) val textpasswd = stringResource(id = textpasswdResId)
var passwordVisible by remember { mutableStateOf(false) }
Column(modifier = Modifier.padding(top = 10.dp)) { Column(modifier = Modifier.padding(top = 10.dp)) {
OutlinedTextField( OutlinedTextField(
value = confirmPassword, value = confirmPassword,
@ -155,8 +176,8 @@ fun PassWdConfirmTextFieldSign(textpasswdResId : Int,confirmPassword: String, on
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = { trailingIcon = {
IconButton(onClick = onPasswordVisibilityChange) { IconButton(onClick = {passwordVisible = !passwordVisible}) {
Icon(imageVector = Icons.Default.Check, contentDescription = "Valider") VisibleIconPasswordComponent(passwordVisible)
} }
}, },
shape = RoundedCornerShape(16.dp) shape = RoundedCornerShape(16.dp)
@ -186,7 +207,7 @@ fun ConnexionButtonSign(
email: String, email: String,
password: String, password: String,
confirmPassword: String, confirmPassword: String,
service: IServices, viewModel: SignInUserViewModel,
navController: ()-> Unit navController: ()-> Unit
) { ) {
val title = stringResource(id = titleResId) val title = stringResource(id = titleResId)
@ -206,7 +227,7 @@ fun ConnexionButtonSign(
passwordErrorEmpty = password.isBlank() || confirmPassword.isBlank() passwordErrorEmpty = password.isBlank() || confirmPassword.isBlank()
if (!emailError && !passwordError && !usernameError && !passwordErrorEmpty) { if (!emailError && !passwordError && !usernameError && !passwordErrorEmpty) {
usernameErrorExist = !service.CreateUser(username, email, password, service) usernameErrorExist = !viewModel.createUser(username, email, password)
if(!usernameErrorExist){ if(!usernameErrorExist){
navController() // retour à la page login navController() // retour à la page login
} }

@ -34,6 +34,10 @@ import com.example.what_the_fantasy.ui.components.ErrorMessageSubmitQuoteCompone
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.SpaceHeightComponent import com.example.what_the_fantasy.ui.components.SpaceHeightComponent
import com.example.what_the_fantasy.ui.components.TitlePageComponent import com.example.what_the_fantasy.ui.components.TitlePageComponent
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.theme.colorBackground
import com.example.what_the_fantasy.ui.theme.gradienBox
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable @Composable
fun SubmitQuotePage( fun SubmitQuotePage(
@ -41,9 +45,13 @@ fun SubmitQuotePage(
navAccueil: () -> Unit, navAccueil: () -> Unit,
navProfil:() -> Unit, navProfil:() -> Unit,
navQuiz: () -> Unit, navQuiz: () -> Unit,
navRecap: (String, String, String) -> Unit navRecap: (String, String, String) -> Unit,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) { ) {
NavBar( NavBar(
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,

@ -0,0 +1,9 @@
package com.example.what_the_fantasy.ui.states
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.data.model.User
data class AuthUserState (
val username : String = "",
val password: String = "",
)

@ -0,0 +1,13 @@
package com.example.what_the_fantasy.ui.states
import com.example.what_the_fantasy.data.model.SrcLanguage
data class CurrentUserState (
var id : Int = -1,
val imagePath : String ="",
var username :String="",
var email : String="",
var password : String="",
var confirmPassword : String="",
val langage : SrcLanguage = SrcLanguage.vo
)

@ -0,0 +1,8 @@
package com.example.what_the_fantasy.ui.states
data class SignInUserState (
val username : String ="",
val email : String ="",
val password : String ="",
val confirmPassword : String ="",
)

@ -0,0 +1,30 @@
package com.example.what_the_fantasy.ui.viewModels
import android.util.Log
import androidx.lifecycle.ViewModel
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.states.AuthUserState
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
class AuthUserViewModel : ViewModel(){
private val services = ServicesStub() // faire repository qui gère les services Stub et API
private val _userState = MutableStateFlow(AuthUserState())
val userState : StateFlow<AuthUserState> = _userState.asStateFlow()
fun setUsername(username : String){
_userState.update { it.copy(username=username) }
}
fun setPassword(password : String){
_userState.update { it.copy(password=password) }
}
fun validLogin(username : String, passwd : String, navController: (Int) -> Unit, initialierCurrentUser : (Int) -> Unit) : Boolean{
return services.validLogin(username,passwd, navController, initialierCurrentUser)
}
}

@ -0,0 +1,89 @@
package com.example.what_the_fantasy.ui.viewModels
import android.util.Log
import androidx.lifecycle.ViewModel
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.states.CurrentUserState
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
class CurrentUserViewModel : ViewModel(){
private val services = ServicesStub() // faire repository qui gère les services Stub et API
private val _currentUserState = MutableStateFlow(CurrentUserState())
var currentUserState : StateFlow<CurrentUserState> = _currentUserState.asStateFlow()
fun initialiseCurrentUser(index : Int){
services.getUserById(index)?.let {
setId(it.id)
setUsername(it.username)
setEmail(it.email)
setPassword(it.password)
setLangue(it.langage)
setImage(it.imgUrl)
}
}
fun clearCurrentUser(){
_currentUserState.value = CurrentUserState()
}
fun setId(id : Int){
_currentUserState.update {it.copy(id = id)}
}
fun setUsername(username : String){
_currentUserState.update {it.copy(username = username)}
}
fun setEmail(email : String){
_currentUserState.update {it.copy(email = email)}
}
fun setPassword(password : String){
_currentUserState.update {it.copy(password = password)}
}
fun setConfirmPassword(password : String){
_currentUserState.update {it.copy(confirmPassword = password)}
}
fun setLangue(langue : SrcLanguage){
_currentUserState.update {it.copy(langage = langue)}
}
fun setImage(imagePath : String){
_currentUserState.update {it.copy(imagePath = imagePath)}
}
fun editUsername(username : String, index : Int) : Boolean{
_currentUserState.update {it.copy(username = username)}
return services.EditUsername(username, index)
}
fun editEmail(email : String, index : Int) : Boolean{
_currentUserState.update {
it.copy(email = email)
}
return services.EditEmail(email, index)
}
fun editPassword(password : String, index : Int){
services.EditPasswd(password, index)
}
fun editLangue(index : Int){
val langage = services.ChangeLangage(index)
_currentUserState.update {
it.copy(langage = langage)
}
}
}

@ -0,0 +1,35 @@
package com.example.what_the_fantasy.ui.viewModels
import androidx.lifecycle.ViewModel
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.states.SignInUserState
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
class SignInUserViewModel: ViewModel() {
private val services = ServicesStub() // faire repository qui gère les services Stub et API
private val _userState = MutableStateFlow(SignInUserState())
val userState : StateFlow<SignInUserState> = _userState.asStateFlow()
fun createUser(username: String, email: String, passwd: String) : Boolean{
return services.CreateUser(username, email, passwd)
}
fun setUsername(username : String){
_userState.update { it.copy(username=username) }
}
fun setEmail(email : String){
_userState.update { it.copy(email=email) }
}
fun setPassword(password : String){
_userState.update { it.copy(password=password) }
}
fun setConfirmPassword(confirmPassword : String){
_userState.update { it.copy(confirmPassword=confirmPassword) }
}
}

@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="96dp"
android:height="96dp"
android:viewportWidth="96"
android:viewportHeight="96">
<path
android:pathData="M45.6,45.8c-38,38.1 -40.4,41 -35.2,42 1.3,0.3 5,-2.8 12.1,-9.8l10.2,-10.2 4.3,2.8c3.7,2.5 5.4,2.9 11,2.9 5.5,-0 7.3,-0.4 10.7,-2.7 6.3,-4.1 8.8,-9 8.8,-16.9 0,-5.5 -0.4,-7.2 -2.9,-10.9l-2.8,-4.3 4.4,-4.3 4.3,-4.4 4.6,3.8c6.1,5 10.6,10.9 13.5,17.9 1.9,4.7 2.7,5.8 4.6,5.8 2,-0 2.3,-0.5 2.1,-3.3 -0.2,-5.8 -5.2,-14.3 -12.8,-21.8l-7.3,-7.2 6.5,-6.3c4.3,-4.3 6.3,-7.1 6.1,-8.4 -0.8,-5.5 -4,-2.9 -42.2,35.3zM60,47.2c7.6,12.4 -9,27.1 -20.1,17.9l-2.4,-2 2.6,-2.6c2.3,-2.3 2.8,-2.5 5.2,-1.4 5.4,2.5 10.5,-2.9 7.7,-8.1 -1,-1.8 -0.8,-2.6 1.1,-4.6 2.9,-3.1 3.5,-3 5.9,0.8z"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
<path
android:pathData="M36,19.6c-9.3,2.5 -16.2,6.4 -23.1,13.3 -10.1,10.2 -15.8,24.1 -10.1,24.9 1.4,0.2 2.4,-0.3 2.8,-1.5 7.1,-21 25.4,-33.7 46,-31.9 6.6,0.5 7.3,0.4 9.3,-1.8l2.3,-2.4 -5.2,-1.1c-6.8,-1.5 -15.3,-1.3 -22,0.5z"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
<path
android:pathData="M41.2,35.1c-6.6,1.9 -14.3,12.8 -13,18.4 0.2,0.7 4.9,-3.3 10.7,-9.1 10.8,-10.9 11,-11.8 2.3,-9.3z"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
</vector>

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="96dp"
android:height="96dp"
android:viewportWidth="96"
android:viewportHeight="96">
<path
android:pathData="M36,19.6c-9.3,2.5 -16.2,6.4 -23.1,13.3 -10.1,10.2 -15.8,24.1 -10.1,24.9 1.4,0.2 2.4,-0.3 2.8,-1.5 2.4,-7.2 6.8,-14.6 11.2,-19 22.4,-22.4 59.9,-14.8 71.8,14.6 1.9,4.5 2.7,5.6 4.6,5.6 5.9,-0 -0.1,-14.5 -10.1,-24.5 -12.9,-12.7 -30.6,-17.8 -47.1,-13.4z"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
<path
android:pathData="M40.5,35.9c-12.5,5.8 -15.5,20.7 -6.1,30.9 11.1,12.2 32.6,3.5 32.6,-13.2 0,-2.5 -0.5,-5.7 -1.1,-7.3 -2.4,-6.4 -10.9,-12.3 -17.9,-12.3 -1.9,-0 -5.3,0.9 -7.5,1.9zM53.5,41.4c10.4,4.4 9.8,20 -1,24.1 -4.5,1.8 -8.8,1.2 -12.5,-1.8 -7.5,-5.8 -6.2,-18.6 2.3,-22.2 4.1,-1.8 6.9,-1.8 11.2,-0.1z"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
</vector>

@ -14,6 +14,7 @@ composeBom = "2024.04.01"
navigationCompose = "2.8.6" navigationCompose = "2.8.6"
navigationCommonAndroid = "2.9.0-alpha05" navigationCommonAndroid = "2.9.0-alpha05"
engageCore = "1.5.6" engageCore = "1.5.6"
lifecycle = "2.8.0"
[libraries] [libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@ -37,6 +38,8 @@ androidx-navigation-compose = { group = "androidx.navigation", name = "navigatio
androidx-navigation-common-android = { group = "androidx.navigation", name = "navigation-common-android", version.ref = "navigationCommonAndroid" } androidx-navigation-common-android = { group = "androidx.navigation", name = "navigation-common-android", version.ref = "navigationCommonAndroid" }
engage-core = { group = "com.google.android.engage", name = "engage-core", version.ref = "engageCore" } engage-core = { group = "com.google.android.engage", name = "engage-core", version.ref = "engageCore" }
android-lifecycle-viewmodel ={ group = "androidx.lifecycle", name ="lifecycle-viewmodel-compose", version.ref ="lifecycle"}
android-lifecycle-viewmodel-runtime-ktx ={ group = "androidx.lifecycle", name ="lifecycle-viewmodel-ktx", version.ref ="lifecycle"}
[plugins] [plugins]
android-application = { id = "com.android.application", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

Loading…
Cancel
Save