diff --git a/What_The_Fantasy/app/build.gradle.kts b/What_The_Fantasy/app/build.gradle.kts index 090bb7f..3b20b0e 100644 --- a/What_The_Fantasy/app/build.gradle.kts +++ b/What_The_Fantasy/app/build.gradle.kts @@ -71,7 +71,10 @@ dependencies { androidTestImplementation(libs.androidx.ui.test.junit4) debugImplementation(libs.androidx.ui.tooling) 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")) + //ViewModel + implementation(libs.android.lifecycle.viewmodel) + implementation(libs.android.lifecycle.viewmodel.runtime.ktx) } \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt index 0863cd4..5c50ae7 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/UserStub.kt @@ -6,16 +6,16 @@ import com.example.what_the_fantasy.data.model.User object UserStub { //LE MOT DE PASSE POUR TOUS LES UTILISATEURS EST : 1234 val users: MutableList = 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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 ) } \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/services/IServices.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/services/IServices.kt index eb0de96..b07f8de 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/services/IServices.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/services/IServices.kt @@ -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.Comment 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.ui.states.AuthUserState +import kotlinx.coroutines.flow.StateFlow interface IServices { + + fun validLogin(username : String, + passwd : String, + navController: (Int) -> Unit, + initialierCurrentUser : (Int) ->Unit): Boolean + fun EditUsername(username : String, index : Int) : Boolean fun EditEmail(email : String, index : Int) : Boolean fun EditPasswd(passwd : 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 SupFav(userId: Int, QuoteId : Int) 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 fun getAllUsers(): List fun getComment(quoteId : Int) : List diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/services/ServicesAPI.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/services/ServicesAPI.kt index 9033c65..0f8fc31 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/services/ServicesAPI.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/services/ServicesAPI.kt @@ -1,89 +1,89 @@ 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.Favorite -import com.example.what_the_fantasy.data.model.Quote -import com.example.what_the_fantasy.data.model.User -//import com.example.what_the_fantasy.ui.navigations.Destination - -class ServicesAPI : IServices { - override fun EditUsername(username: String, index : Int): Boolean { - TODO("Not yet implemented") - } - - override fun EditEmail(email: String, index : Int): Boolean { - TODO("Not yet implemented") - } - - override fun EditPasswd(passwd: String, index : Int) { - TODO("Not yet implemented") - } - - override fun EditImage(imageURL: String, index : Int) { - TODO("Not yet implemented") - } - - override fun ChangeLangage(user: User) { - TODO("Not yet implemented") - } - - override fun AddFav(userId: Int, QuoteId: Int) { - TODO("Not yet implemented") - } - - override fun SupFav(userId: Int, QuoteId: Int) { - TODO("Not yet implemented") - } - - override fun AddComment(content: String) { - TODO("Not yet implemented") - } - - override fun CreateUser(username: String, email: String, passwd: String, services: IServices) : Boolean { - TODO("Not yet implemented") - } - - override fun getFavorite(user: User): List { - TODO("Not yet implemented") - } - - override fun SearchQuote(quote: String) { - TODO("Not yet implemented") - } - - override fun getQuote(id: Int): Quote? { - TODO("Not yet implemented") - } - - override fun isFavorite(id: Int, user: User): Boolean { - TODO("Not yet implemented") - } - - override fun getAllFavorite(): List { - TODO("Not yet implemented") - } - - override fun getAllQuote(): List { - TODO("Not yet implemented") - } - - override fun getSomeQuotes(nb: Int, page: Int): MutableList { - TODO("Not yet implemented") - } - - override fun getAllUsers(): List { - TODO("Not yet implemented") - } - - override fun getComment(quoteId: Int): List { - TODO("Not yet implemented") - } - - override fun getUserById(id: Int): User? { - TODO("Not yet implemented") - } - - override fun search(type : String ,search:String ,indexCount: Int): List{ - TODO("Not yet implemented") - } -} \ No newline at end of file +//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.Quote +//import com.example.what_the_fantasy.data.model.User +////import com.example.what_the_fantasy.ui.navigations.Destination + +//class ServicesAPI : IServices { +// override fun EditUsername(username: String, index : Int): Boolean { +// TODO("Not yet implemented") +// } +// +// override fun EditEmail(email: String, index : Int): Boolean { +// TODO("Not yet implemented") +// } +// +// override fun EditPasswd(passwd: String, index : Int) { +// TODO("Not yet implemented") +// } +// +// override fun EditImage(imageURL: String, index : Int) { +// TODO("Not yet implemented") +// } +// +// override fun ChangeLangage(user: User) { +// TODO("Not yet implemented") +// } +// +// override fun AddFav(userId: Int, QuoteId: Int) { +// TODO("Not yet implemented") +// } +// +// override fun SupFav(userId: Int, QuoteId: Int) { +// TODO("Not yet implemented") +// } +// +// override fun AddComment(content: String) { +// TODO("Not yet implemented") +// } +// +// override fun CreateUser(username: String, email: String, passwd: String, services: IServices) : Boolean { +// TODO("Not yet implemented") +// } +// +// override fun getFavorite(user: User): List { +// TODO("Not yet implemented") +// } +// +// override fun SearchQuote(quote: String) { +// TODO("Not yet implemented") +// } +// +// override fun getQuote(id: Int): Quote? { +// TODO("Not yet implemented") +// } +// +// override fun isFavorite(id: Int, user: User): Boolean { +// TODO("Not yet implemented") +// } +// +// override fun getAllFavorite(): List { +// TODO("Not yet implemented") +// } +// +// override fun getAllQuote(): List { +// TODO("Not yet implemented") +// } +// +// override fun getSomeQuotes(nb: Int, page: Int): MutableList { +// TODO("Not yet implemented") +// } +// +// override fun getAllUsers(): List { +// TODO("Not yet implemented") +// } +// +// override fun getComment(quoteId: Int): List { +// TODO("Not yet implemented") +// } +// +// override fun getUserById(id: Int): User? { +// TODO("Not yet implemented") +// } +// +// override fun search(type : String ,search:String ,indexCount: Int): List{ +// TODO("Not yet implemented") +// } +//} \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/services/ServicesStub.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/services/ServicesStub.kt index 382cd2e..1c07192 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/services/ServicesStub.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/services/ServicesStub.kt @@ -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.logs.LogsUsers 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.model.Favorite import com.example.what_the_fantasy.data.local.CommentStub.comments @@ -16,6 +17,25 @@ import java.time.LocalDate class ServicesStub : IServices { 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{ val user = getUserById(index) @@ -54,14 +74,16 @@ class ServicesStub : IServices { TODO("Not yet implemented") } - override fun ChangeLangage(user: User) { - if(user.langage == SrcLanguage.vo){ - user.langage = SrcLanguage.vf + override fun ChangeLangage(index : Int) : SrcLanguage{ + if(getAllUsers()[index].langage == SrcLanguage.vo){ + getAllUsers()[index].langage = SrcLanguage.vf } 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) { @@ -78,15 +100,17 @@ class ServicesStub : IServices { //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 passwordhash = hashPassword(passwd) + val services = ServicesStub() val userStub = services.getAllUsers() val nbUser = userStub.size 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 //Afficher tous les users @@ -98,8 +122,7 @@ class ServicesStub : IServices { override fun getFavorite(user: User): List { val favorite = favorites - return favorite[user.id-1].quote - //return emptyList() + return favorite[0].quote } override fun getAllFavorite(): List = favorites @@ -109,7 +132,7 @@ class ServicesStub : IServices { override fun getComment(quoteId: Int): List = comments override fun getUserById(id: Int): User? { - return (users.find { it.id == id+1 }) + return (users.find { it.id == id }) } override fun SearchQuote(quote: String) { @@ -143,8 +166,16 @@ class ServicesStub : IServices { return date.toString() } - fun randomImage(usersImage : List) : String{ - return "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg" + fun randomImage() : String{ + 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{ diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/repository/AuthRepository.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/repository/AuthRepository.kt new file mode 100644 index 0000000..cab157c --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/repository/AuthRepository.kt @@ -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 {} diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/NavBar.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/NavBar.kt index a067088..de73f97 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/NavBar.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/NavBar.kt @@ -1,5 +1,6 @@ package com.example.what_the_fantasy.ui.components +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement 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.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding 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.rounded.* import androidx.compose.material3.BottomAppBar @@ -18,27 +22,37 @@ import androidx.compose.material3.IconButtonColors import androidx.compose.material3.MaterialTheme import androidx.compose.material3.NavigationBar 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.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource 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.ui.states.CurrentUserState +import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel @Composable -fun NavBar(onProfile : Boolean = false , - onFavorite : Boolean = false , - onAccueil : Boolean = false , - onQuiz : Boolean = false , +fun NavBar(onProfile : Boolean = false, + onFavorite : Boolean = false, + onAccueil : Boolean = false, + onQuiz : Boolean = false, + currentUserVM : CurrentUserViewModel, + currentUserState : CurrentUserState, navControllerProfil: () -> Unit = {}, - navControllerFavorite:() -> Unit = {}, - navControllerAccueil: () -> Unit = {}, - navControllerQuiz: () -> Unit = {}, + navControllerFavorite:() -> Unit= {}, + navControllerAccueil: () -> Unit= {}, + navControllerQuiz: () -> Unit= {}, navControllerSearch: () -> Unit = {}, - content : @Composable ()-> Unit ) { Column( @@ -56,7 +70,7 @@ fun NavBar(onProfile : Boolean = false , Arrangement.SpaceBetween, 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) } @@ -99,7 +113,7 @@ fun NavBar(onProfile : Boolean = false , } @Composable -fun ButtonIconVector(img : ImageVector, name : String, nav : ()->Unit,onPage : Boolean){ +fun ButtonIconVectorInt(img : String, 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é @@ -107,14 +121,34 @@ fun ButtonIconVector(img : ImageVector, name : String, nav : ()->Unit,onPage : B modifier = Modifier .size(60.dp) ) { - Icon(img, + + Image( + painter = rememberAsyncImagePainter(img), contentDescription = name, modifier = Modifier .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 fun ButtonIconPainter(img : Painter, name : String, nav : ()->Unit,onPage : Boolean){ diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/VisibleIconPasswordComponent.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/VisibleIconPasswordComponent.kt new file mode 100644 index 0000000..cc502b9 --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/components/VisibleIconPasswordComponent.kt @@ -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 + ) +} \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt index 310b4d6..032f314 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt @@ -6,13 +6,19 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.toRoute import com.example.what_the_fantasy.data.services.ServicesStub 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 @Serializable @@ -63,11 +69,24 @@ fun AppNavigator() { val navController = rememberNavController() 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( modifier = Modifier.fillMaxSize(), containerColor = MaterialTheme.colorScheme.onPrimary ) { paddingValues -> Box(modifier = Modifier.padding(paddingValues)) { + NavHost(navController, startDestination = Login) { composable { LoginPage( @@ -77,61 +96,81 @@ fun AppNavigator() { popUpTo(Login) { inclusive = true } } }, - services = services + authUserVM = authUserVM, + authState = authState, + initialierCurrentUser ={currentUserVM.initialiseCurrentUser(it)} ) } + composable { - val accueil: Accueil = it.toRoute() + //val accueil: Accueil = it.toRoute() AccueilPage( - index = accueil.userIndex, - navFavorite = { navController.navigate(Favorite(accueil.userIndex)) }, - navQuiz = { navController.navigate(QuizMenu(accueil.userIndex)) }, - navProfil = { navController.navigate(Profil(accueil.userIndex)) }, - navQuote = { quoteId -> navController.navigate(OneQuote(quoteId,accueil.userIndex)) }, - navSearch = { navController.navigate(Search(accueil.userIndex))}, - services = services + navFavorite = { navController.navigate(Favorite(currentUserState.id)) }, + navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) }, + navProfil = { navController.navigate(Profil(currentUserState.id)) }, + navQuote = { quoteId -> + navController.navigate( + OneQuote( + quoteId, + currentUserState.id + ) + ) + }, + navSearch = { navController.navigate(Search(currentUserState.id))}, + services = services, + currentUserVM = currentUserVM, + currentUserState = currentUserState, ) } composable { - val favorite: Favorite = it.toRoute() + //val favorite: Favorite = it.toRoute() FavoritePage( - index = favorite.userIndex, - navAccueil = { navController.navigate(Accueil(favorite.userIndex)) }, - navQuiz = { navController.navigate(QuizMenu(favorite.userIndex)) }, - navProfil = { navController.navigate(Profil(favorite.userIndex)) }, - navQuote = { quoteId -> navController.navigate(OneQuote(quoteId,favorite.userIndex)) }, - navSearch = { navController.navigate(Search(favorite.userIndex))}, - services = services + navAccueil = { navController.navigate(Accueil(currentUserState.id)) }, + navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) }, + navProfil = { navController.navigate(Profil(currentUserState.id)) }, + navQuote = { quoteId -> + navController.navigate( + OneQuote( + quoteId, + currentUserState.id + ) + ) + }, + navSearch = { navController.navigate(Search(currentUserState.id))}, + services = services, + currentUserVM = currentUserVM, + currentUserState = currentUserState, ) } composable { val profil: Profil = it.toRoute() ProfilPage( - index = profil.userIndex, - navFavorite = { navController.navigate(Favorite(profil.userIndex)) }, - navAccueil = { navController.navigate(Accueil(profil.userIndex)) }, - navQuiz = { navController.navigate(QuizMenu(profil.userIndex)) }, - navSubmitQuote = { navController.navigate(SubmitQuote(profil.userIndex)) }, + navFavorite = { navController.navigate(Favorite(currentUserState.id)) }, + navAccueil = { navController.navigate(Accueil(currentUserState.id)) }, + navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) }, + navSubmitQuote = { navController.navigate(SubmitQuote(currentUserState.id)) }, navUnLog = { navController.navigate(Login) { popUpTo(profil) { inclusive = true } } }, + currentUserVM = currentUserVM, + currentUserState = currentUserState, navSearch = { navController.navigate(Search(profil.userIndex))}, - services = services ) } composable { val quote: OneQuote = it.toRoute() QuotePage( 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, - index = quote.userIndex, - navAccueil = { navController.navigate(Accueil(quote.userIndex)) }, - navQuiz = { navController.navigate(QuizMenu(quote.userIndex)) }, - navProfil = { navController.navigate(Profil(quote.userIndex)) }, - navFavorite = { navController.navigate(Favorite(quote.userIndex)) }, - navSearch = { navController.navigate(Search(quote.userIndex))} + currentUserVM = currentUserVM, + currentUserState = currentUserState, + navSearch = { navController.navigate(Search(currentUserState.id))} ) } composable { @@ -145,7 +184,9 @@ fun AppNavigator() { navSearch = {type,newSearch -> navController.navigate(Search(search.userIndex,type,newSearch))}, services = services, type = search.type, - search = search.search + search = search.search, + currentUserVM = currentUserVM, + currentUserState = currentUserState, ) } composable { @@ -155,68 +196,77 @@ fun AppNavigator() { popUpTo(Login) { inclusive = true } } }, - services = services + signInUserVM = signInUserVM, + signInState = signInState ) } composable { - val submitQuote: SubmitQuote = it.toRoute() + //val submitQuote: SubmitQuote = it.toRoute() SubmitQuotePage( - navAccueil = { navController.navigate(Accueil(submitQuote.userIndex)) }, - navFavorite = { navController.navigate(Favorite(submitQuote.userIndex)) }, - navProfil = { navController.navigate(Profil(submitQuote.userIndex)) }, - navQuiz = { navController.navigate(QuizMenu(submitQuote.userIndex)) }, + navAccueil = { navController.navigate(Accueil(currentUserState.id)) }, + navFavorite = { navController.navigate(Favorite(currentUserState.id)) }, + navProfil = { navController.navigate(Profil(currentUserState.id)) }, + navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) }, navRecap = { quoteContent, character, source -> navController.navigate( RecapSubmit( - submitQuote.userIndex, + currentUserState.id, quoteContent, character, source ) ) - } + }, + currentUserVM = currentUserVM, + currentUserState = currentUserState, ) } composable { val recapSubmit: RecapSubmit = it.toRoute() RecapSubmitPage( - index = recapSubmit.userIndex, quoteContent = recapSubmit.quoteContent, character = recapSubmit.character, source = recapSubmit.source, - navAccueil = { navController.navigate(Accueil(recapSubmit.userIndex)) }, - navFavorite = { navController.navigate(Favorite(recapSubmit.userIndex)) }, - navProfil = { navController.navigate(Profil(recapSubmit.userIndex)) }, - navSearch = { navController.navigate(Search(recapSubmit.userIndex))}, - navQuiz = { navController.navigate(QuizMenu(recapSubmit.userIndex)) } - ) + navAccueil = { navController.navigate(Accueil(currentUserState.id)) }, + navFavorite = { navController.navigate(Favorite(currentUserState.id)) }, + navProfil = { navController.navigate(Profil(currentUserState.id)) }, + navSearch = { navController.navigate(Search(currentUserState.id))}, + navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) }, + currentUserVM = currentUserVM, + currentUserState = currentUserState, + ) } composable { - val quizMenu: QuizMenu = it.toRoute() + //val quizMenu: QuizMenu = it.toRoute() QuizMenu( - navAccueil = { navController.navigate(Accueil(quizMenu.userIndex)) }, - navFavorite = { navController.navigate(Favorite(quizMenu.userIndex)) }, - navProfil = { navController.navigate(Profil(quizMenu.userIndex)) }, - navSearch = { navController.navigate(Search(quizMenu.userIndex))}, + currentUserVM = currentUserVM, + currentUserState = currentUserState, + navAccueil = { navController.navigate(Accueil(currentUserState.id)) }, + navFavorite = { navController.navigate(Favorite(currentUserState.id)) }, + navProfil = { navController.navigate(Profil(currentUserState.id)) }, + navSearch = { navController.navigate(Search(currentUserState.id))}, 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 { val quiz: Quiz = it.toRoute() QuizPage( - navAccueil = { navController.navigate(Accueil(quiz.userIndex)) }, - navFavorite = { navController.navigate(Favorite(quiz.userIndex)) }, - navProfil = { navController.navigate(Profil(quiz.userIndex)) }, - navQuiz = { navController.navigate(QuizMenu(quiz.userIndex)) }, + navAccueil = { navController.navigate(Accueil(currentUserState.id)) }, + navFavorite = { navController.navigate(Favorite(currentUserState.id)) }, + navProfil = { navController.navigate(Profil(currentUserState.id)) }, + navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) }, navControllerQuizEnd = { idQuiz, pts -> - navController.navigate(QuizEnd(quiz.userIndex, idQuiz, pts)) + navController.navigate(QuizEnd(currentUserState.id, idQuiz, pts)) }, - navSearch = { navController.navigate(Search(quiz.userIndex))}, - idQuiz = quiz.idQuiz + navSearch = { navController.navigate(Search(currentUserState.id))}, + idQuiz = quiz.idQuiz, + currentUserVM = currentUserVM, + currentUserState = currentUserState, ) } composable { @@ -224,11 +274,13 @@ fun AppNavigator() { QuizEndPage( idQuiz = quizEnd.idQuiz, points = quizEnd.pts, - navAccueil = { navController.navigate(Accueil(quizEnd.userIndex)) }, - navFavorite = { navController.navigate(Favorite(quizEnd.userIndex)) }, - navProfil = { navController.navigate(Profil(quizEnd.userIndex)) }, - navQuiz = { navController.navigate(QuizMenu(quizEnd.userIndex)) }, - navSearch = { navController.navigate(Search(quizEnd.userIndex))} + navAccueil = { navController.navigate(Accueil(currentUserState.id)) }, + navFavorite = { navController.navigate(Favorite(currentUserState.id)) }, + navProfil = { navController.navigate(Profil(currentUserState.id)) }, + navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) }, + navSearch = { navController.navigate(Search(currentUserState.id))}, + currentUserVM = currentUserVM, + currentUserState = currentUserState, ) } @@ -243,6 +295,8 @@ fun AppNavigator() { navControllerQuizEnd = { idQuiz, pts -> navController.navigate(QuizEnd(quizRandom.userIndex, idQuiz, pts)) }, + currentUserVM = currentUserVM, + currentUserState = currentUserState, ) } } diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/AccueilPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/AccueilPage.kt index ced3eee..3a5842c 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/AccueilPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/AccueilPage.kt @@ -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.ui.components.NavBar 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 @Composable fun AccueilPage( - index: Int, navFavorite: () -> Unit, navQuiz: () -> Unit, navProfil: () -> Unit, - navSearch: () -> Unit, navQuote: (Int) -> Unit, - services: IServices + navSearch: () -> Unit, + services: IServices, + currentUserVM : CurrentUserViewModel, + currentUserState : CurrentUserState, ) { val dailyQuote = DailyQuoteStub.dailyQuote - val user = services.getUserById(index) ?: return val titleDalyQuote = stringResource(R.string.TitleHomeDailyQuote) val titleSuggestion = stringResource(R.string.TitleHomeSuggestion) - val page = remember { mutableStateOf(1) } + val page = remember { mutableIntStateOf(1) } val quotes = remember { mutableStateListOf() } val state = rememberLazyListState() - val layoutInfo = state.layoutInfo + val layoutInfo = remember { derivedStateOf { state.layoutInfo } } val isLoading = remember { mutableStateOf(false) } - val visibleItemsInfo = layoutInfo.visibleItemsInfo + val visibleItemsInfo = layoutInfo.value.visibleItemsInfo val fullyVisibleItemsInfo = visibleItemsInfo.toMutableList() val lastItem = if (fullyVisibleItemsInfo.isNotEmpty()) fullyVisibleItemsInfo.last() else null - LaunchedEffect(page.value) { + LaunchedEffect(page.intValue) { if (!isLoading.value) { isLoading.value = true 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 } } if (uniqueQuotes.isNotEmpty()) { quotes.addAll(uniqueQuotes) } else { - println("Aucune nouvelle quote à la page ${page.value}, stop pagination.") + println("Aucune nouvelle quote à la page ${page.intValue}, stop pagination.") } isLoading.value = false } @@ -71,8 +74,9 @@ fun AccueilPage( NavBar( onAccueil = true, + currentUserVM = currentUserVM, + currentUserState = currentUserState, navControllerFavorite = navFavorite, - navControllerAccueil = { }, navControllerProfil = navProfil, navControllerQuiz = navQuiz, navControllerSearch = navSearch @@ -109,7 +113,7 @@ fun AccueilPage( } items(quotes) { quote -> - if (quote.language == user.langage) { + if (quote.language == currentUserState.langage) { Column(Modifier.clickable { navQuote(quote.id ) }) { QuoteLittle(quote) Spacer(modifier = Modifier.height(16.dp)) @@ -128,11 +132,11 @@ fun AccueilPage( CircularProgressIndicator() } } 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()) { val lastVisibleItem = state.layoutInfo.visibleItemsInfo.last() if (lastVisibleItem.index >= state.layoutInfo.totalItemsCount - 1) { - page.value++ + page.intValue++ } } } diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/FavoritePage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/FavoritePage.kt index 9ae741b..45ba076 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/FavoritePage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/FavoritePage.kt @@ -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.ui.components.NavBar 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 fun FavoritePage( - index: Int, navAccueil: () -> Unit, navQuiz: () -> Unit, navProfil: () -> Unit, - navSearch: () -> 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 titlePage = stringResource(R.string.TitleFavorite) NavBar(onFavorite = true, + currentUserVM = currentUserVM, + currentUserState = currentUserState, + navControllerFavorite = { }, navControllerAccueil = navAccueil, navControllerProfil = navProfil, navControllerQuiz = navQuiz, diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt index 511ed28..88399f2 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/LoginPage.kt @@ -1,5 +1,6 @@ package com.example.what_the_fantasy.ui.screens +import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box @@ -16,6 +17,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -30,6 +32,7 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp 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.R 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.TitlePageComponent 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 -fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: (Int) -> Unit, services : IServices) { - val users = services.getAllUsers() +fun LoginPage(navControllerSignUp: () -> Unit, + navControllerProfil: (Int) -> Unit, + authUserVM : AuthUserViewModel, + authState : AuthUserState, + initialierCurrentUser : (Int) -> Unit) { + Box( modifier = Modifier @@ -61,7 +71,15 @@ fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: (Int) -> Uni TitlePageComponent(R.string.titleLogin, MaterialTheme.colorScheme.primary) 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) CreateAccountButton(R.string.ButtonCreateLogin,12, MaterialTheme.colorScheme.primary, navControllerSignUp) } @@ -70,13 +88,13 @@ fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: (Int) -> Uni @Composable -fun IdentifiantTextField(textIdentifiantResId : Int) : String{ +fun IdentifiantTextField(textIdentifiantResId : Int, username : String, onValueChange: (String) -> Unit ) : String{ val textIdentifiant = stringResource(id = textIdentifiantResId) - var identifiant by remember { mutableStateOf("") } + Column(modifier = Modifier.padding(top = 16.dp)) { OutlinedTextField( - value = identifiant, - onValueChange = { identifiant = it }, + value = username, + onValueChange = onValueChange, label = { Text(textIdentifiant) }, modifier = Modifier .fillMaxWidth() @@ -86,18 +104,18 @@ fun IdentifiantTextField(textIdentifiantResId : Int) : String{ shape = RoundedCornerShape(16.dp) ) } - return identifiant; + return username; } @Composable -fun PassWdTextField(textpasswdResId : Int) : String{ +fun PassWdTextField(textpasswdResId : Int, password : String, onValueChange: (String) -> Unit) : String{ val textpasswd = stringResource(id = textpasswdResId) - var passwd by remember { mutableStateOf("") } var passwordVisible by remember { mutableStateOf(false) } + Column(modifier = Modifier.padding(top = 10.dp, bottom = 30.dp)) { OutlinedTextField( - value = passwd, - onValueChange = { passwd = it }, + value = password, + onValueChange = onValueChange, label = { Text(textpasswd) }, modifier = Modifier .fillMaxWidth() @@ -107,21 +125,22 @@ fun PassWdTextField(textpasswdResId : Int) : String{ visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), trailingIcon = { IconButton(onClick = { passwordVisible = !passwordVisible }) { + VisibleIconPasswordComponent(passwordVisible) } }, shape = RoundedCornerShape(16.dp) ) } - return passwd; + return password; } @Composable -fun ConnexionButtonLogin(userStub : List, 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) var showError by remember { mutableStateOf(false) } Button( - onClick = { showError = !validLogin(id, passwd, userStub, navController) + onClick = { showError = !authUserVM.validLogin(username, passwd, navController, initialierCurrentUser) }, colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background), modifier = Modifier @@ -136,19 +155,6 @@ fun ConnexionButtonLogin(userStub : List, id : String, passwd : String, ti } -fun validLogin(identifiant : String, passwd : String, users : List, 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 fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: () -> Unit) { diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt index 346cb6e..867fe14 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/ProfilPage.kt @@ -1,5 +1,6 @@ package com.example.what_the_fantasy.ui.screens +import android.util.Log import android.util.Patterns import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -47,26 +48,28 @@ import androidx.compose.ui.unit.sp import coil.compose.AsyncImage import com.example.what_the_fantasy.logs.LogsUsers 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.NavBar 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.VisibleIconPasswordComponent +import com.example.what_the_fantasy.ui.states.CurrentUserState +import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel @Composable -fun ProfilPage(index: Int, - navFavorite: () -> Unit, +fun ProfilPage(navFavorite: () -> Unit, navAccueil: () -> Unit, navQuiz: () -> Unit, - navSearch: () -> Unit, navUnLog: () -> Unit, navSubmitQuote: () -> Unit, - services: IServices + navSearch: () -> Unit, + currentUserVM : CurrentUserViewModel, + currentUserState : CurrentUserState, ) { - val user = services.getUserById(index) ?: return NavBar(onProfile = true, + currentUserVM = currentUserVM, + currentUserState = currentUserState, navControllerFavorite = navFavorite, navControllerAccueil = navAccueil, navControllerQuiz = navQuiz, @@ -93,25 +96,25 @@ fun ProfilPage(index: Int, TitlePageComponent(R.string.titleProfile, MaterialTheme.colorScheme.onBackground) SpaceHeightComponent(16) - // Image de profil - ImageProfil(user.imgUrl, 120) - SpaceHeightComponent(16) + // Image de profil + ImageProfil(currentUserState.imagePath, 120) + SpaceHeightComponent(16) - EditUsername(user.username, index, services)// Édition du Username - SpaceHeightComponent(16) + EditUsername(currentUserState.username, currentUserState.id, currentUserVM)// Édition du Username + SpaceHeightComponent(16) - EditEmail(user.email,index, services)// Édition du Email - Spacer(modifier = Modifier.height(8.dp)) + EditEmail(currentUserState.email,currentUserState.id, currentUserVM)// Édition du Email + Spacer(modifier = Modifier.height(8.dp)) - EditPasswd(index, services) - SpaceHeightComponent(16) + EditPasswd(currentUserState.id, currentUserVM) + SpaceHeightComponent(16) - // Bouton - ButtonProfile(R.string.ButtonAddQuoteprofile, 18, MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.background,navSubmitQuote) // Pas encore de navigation definie - SpaceHeightComponent(16) - ButtonLanguage(R.string.ButtonLanguageprofile, 18, MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.background,services, user) - SpaceHeightComponent(16) - ButtonUnLog(R.string.ButtonUnlogprofile, 18, MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.background,navUnLog) + // Bouton + ButtonProfile(R.string.ButtonAddQuoteprofile, 18, MaterialTheme.colorScheme.primary,MaterialTheme.colorScheme.background,navSubmitQuote) // Pas encore de navigation definie + SpaceHeightComponent(16) + ButtonLanguage(R.string.ButtonLanguageprofile, 18, MaterialTheme.colorScheme.primary,MaterialTheme.colorScheme.background,currentUserVM, currentUserState) + SpaceHeightComponent(16) + ButtonUnLog(R.string.ButtonUnlogprofile, 18,MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.background, navUnLog,currentUserVM) @@ -134,13 +137,13 @@ fun ImageProfil(imgProfil : String, size :Int){ } @Composable -fun EditEmail(userEmail: String, index: Int, service: IServices) { - var email by remember { mutableStateOf(userEmail) } +fun EditEmail(emailState: String, index: Int, currentUserVM: CurrentUserViewModel) { + var email by remember { mutableStateOf(emailState) } var isEditingEmail by remember { mutableStateOf(false) } var emailError by remember { mutableStateOf(false) } fun onDoneEditing() { - isEditingEmail =!service.EditEmail(email, index) + isEditingEmail =!currentUserVM.editEmail(email, index) } @@ -221,12 +224,12 @@ fun DisplayEmail(email: String, onEdit: () -> Unit) { @Composable -fun EditUsername(userName: String, index: Int, service : IServices) { - var username by remember { mutableStateOf(userName) } +fun EditUsername(usernameState: String, index: Int, currentUserVM : CurrentUserViewModel) { + var username by remember { mutableStateOf(usernameState) } var isEditingUsername by remember { mutableStateOf(false) } fun onDoneEditing() { - isEditingUsername= !service.EditUsername(username, index) + isEditingUsername= !currentUserVM.editUsername(username, index) } if (isEditingUsername) { @@ -290,7 +293,7 @@ fun DisplayUsername(username: String, onEdit: () -> Unit) { @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 isEditingPassword by remember { mutableStateOf(false) } 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 fun onDoneEditing() { // Appeler EditPasswd pour mettre à jour le mot de passe de l'utilisateur - service.EditPasswd(newPassword, index) + currentUserVM.editPassword(newPassword, index) isEditingPassword = false } @@ -314,18 +317,20 @@ fun EditPasswd(index: Int, service: IServices) { confirmPassword = it passwordError = newPassword != it // Vérifier si les mots de passe correspondent }, + passwordVisible = passwordVisible, onPasswordVisibilityChange = { passwordVisible = it }, passwordError = passwordError, onDone = { 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 { - DisplayPassword(onEdit = { isEditingPassword = true }) // Afficher l'option pour modifier le mot de passe + DisplayPassword(onEdit = { isEditingPassword = true }) // pour modifier le mot de passe } + } @Composable @@ -399,7 +404,7 @@ fun PasswordTextField( visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), trailingIcon = { IconButton(onClick = { onPasswordVisibilityChange(!passwordVisible) }) { - // Ajout d'une icône pour montrer/masquer le mot de passe + VisibleIconPasswordComponent(passwordVisible) } }, isError = isError @@ -442,14 +447,16 @@ fun DisplayPassword(onEdit: () -> Unit) { } @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 logsUser = LogsUsers() //gestion des logs pour les utilisateurs Button( onClick = { + currentUserVM.clearCurrentUser() navController() logsUser.unlogInformationUserConnect("UserUnLog") + }, colors = ButtonDefaults.buttonColors(containerColor = colorButton), modifier = Modifier.fillMaxWidth(), @@ -459,23 +466,22 @@ fun ButtonUnLog(textResId : Int, size :Int, colorTexte : Color, colorButton : Co } @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 currentLangage = remember { mutableStateOf(user.langage) } + Button( onClick = { - service.ChangeLangage(user) - currentLangage.value = user.langage + currentUserVM.editLangue(currentUserState.id) }, colors = ButtonDefaults.buttonColors(containerColor = colorButton), modifier = Modifier.fillMaxWidth(), ) { - Text("${text} (${currentLangage.value})", fontSize = size.sp, color = colorTexte) + Text("${text} (${currentUserState.langage})", fontSize = size.sp, color = colorTexte) } } @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) Button( diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt index 7c9379d..f6b7633 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt @@ -18,6 +18,8 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp 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.states.CurrentUserState +import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel val gradient = Brush.linearGradient( colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)), @@ -34,8 +36,12 @@ fun QuizEndPage( navProfil:() -> Unit, navQuiz: () -> Unit, navSearch: () -> Unit, + currentUserVM : CurrentUserViewModel, + currentUserState : CurrentUserState, ) { NavBar( + currentUserVM = currentUserVM, + currentUserState = currentUserState, navControllerFavorite = navFavorite, navControllerAccueil = navAccueil, navControllerProfil = navProfil, diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizMenu.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizMenu.kt index d67d8b8..21e001e 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizMenu.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizMenu.kt @@ -33,17 +33,24 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp 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.states.CurrentUserState +import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel @Composable fun QuizMenu( + currentUserVM : CurrentUserViewModel, + currentUserState : CurrentUserState, navFavorite: () -> Unit, navAccueil: () -> Unit, navProfil:() -> Unit, - navSearch: () -> Unit, navControllerQuiz: (Int) -> Unit, + navSearch: () -> Unit, navControllerRandomQuiz:() -> Unit + ) { NavBar(onQuiz = true, + currentUserVM = currentUserVM, + currentUserState = currentUserState, navControllerFavorite = navFavorite, navControllerAccueil = navAccueil, navControllerProfil = navProfil, diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt index 0bfc05c..efcd0d4 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizPage.kt @@ -19,9 +19,13 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp 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.states.CurrentUserState +import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel @Composable fun QuizPage( + currentUserVM : CurrentUserViewModel, + currentUserState : CurrentUserState, navFavorite: () -> Unit, navAccueil: () -> Unit, navProfil:() -> Unit, @@ -57,6 +61,8 @@ fun QuizPage( else navControllerQuizEnd(idQuiz, pts) // Retour menu } NavBar( + currentUserVM = currentUserVM, + currentUserState = currentUserState, navControllerFavorite = navFavorite, navControllerAccueil = navAccueil, navControllerProfil = navProfil, diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizRandom.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizRandom.kt index e13b60b..a3b0e56 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizRandom.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizRandom.kt @@ -20,6 +20,8 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp 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.states.CurrentUserState +import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel @Composable fun QuizRandom( @@ -29,6 +31,8 @@ fun QuizRandom( navQuiz: () -> Unit, navSearch: () -> Unit, navControllerQuizEnd: (Int, Int) -> Unit, + currentUserVM : CurrentUserViewModel, + currentUserState : CurrentUserState, ) { val questions = QuestionStub.shuffleRandomQuestions var idCurrentQuestion by remember { mutableIntStateOf(0) } @@ -66,7 +70,9 @@ fun QuizRandom( navControllerAccueil = navAccueil, navControllerProfil = navProfil, navControllerQuiz = navQuiz, - navControllerSearch = navSearch + navControllerSearch = navSearch, + currentUserVM = currentUserVM, + currentUserState = currentUserState, ){ Column ( modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B)) diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuotePage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuotePage.kt index fcc8da0..80f31d8 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuotePage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuotePage.kt @@ -53,6 +53,13 @@ import coil.compose.AsyncImage import com.example.what_the_fantasy.data.model.Comment 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.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) @@ -60,20 +67,23 @@ var isCommentVisible by mutableStateOf(false) fun QuotePage( quoteId : Int, service : IServices, - index : Int, navAccueil: () -> Unit, navFavorite:() -> Unit, navQuiz: () -> Unit, + navProfil:() -> Unit, navSearch: () -> Unit, - navProfil:() -> Unit) + currentUserVM : CurrentUserViewModel, + currentUserState : CurrentUserState, + ) { // utiliser ViewModel val quote = service.getQuote(quoteId) ?: return 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)) } - - NavBar( + NavBar(onProfile = true, + currentUserVM = currentUserVM, + currentUserState = currentUserState, navControllerFavorite = navFavorite, navControllerAccueil = navAccueil, navControllerProfil = navProfil, @@ -101,7 +111,7 @@ fun QuotePage( FunctionalIcon( isFavorite = favorite, - userId = index, + userId = currentUserState.id, id = quoteId, context = context, service = service @@ -148,7 +158,7 @@ fun QuotePage( ) { Box(modifier = Modifier.fillMaxWidth().background(MaterialTheme.colorScheme.primary).fillMaxSize()){ Column { - AddComment(index, service) + AddComment(currentUserState.id, service) LstComment(service.getComment(quoteId)) } } @@ -337,8 +347,6 @@ fun AddComment(userId: Int, service: IServices) { ) } } - - @Composable fun LstComment(lst: List) { LazyColumn( @@ -381,5 +389,3 @@ fun LstComment(lst: List) { } } } - - diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/RecapSubmitPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/RecapSubmitPage.kt index 8176610..036a1e8 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/RecapSubmitPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/RecapSubmitPage.kt @@ -30,21 +30,27 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight 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 fun RecapSubmitPage( - index: Int, navFavorite: () -> Unit, navAccueil: () -> Unit, navProfil:() -> Unit, - navQuiz: () -> Unit, navSearch: () -> Unit, + navQuiz : () -> Unit, quoteContent : String, character: String, - source: String + source: String, + currentUserVM : CurrentUserViewModel, + currentUserState : CurrentUserState, ) { - NavBar( + NavBar(onQuiz = true, + currentUserVM = currentUserVM, + currentUserState = currentUserState, navControllerFavorite = navFavorite, navControllerAccueil = navAccueil, navControllerProfil = navProfil, diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SearchPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SearchPage.kt index 8c5f996..e8653db 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SearchPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SearchPage.kt @@ -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.ui.components.NavBar 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 @Composable @@ -40,7 +42,9 @@ fun SearchPage( navSearch: (String, String) -> Unit, services: IServices, type: String, - search: String + search: String, + currentUserVM : CurrentUserViewModel, + currentUserState : CurrentUserState, ) { var newSearch by remember { mutableStateOf(search) } val filtre = listOf("contenue", "personnage", "titre") @@ -70,7 +74,10 @@ fun SearchPage( navControllerAccueil = navAccueil, navControllerProfil = navProfil, navControllerQuiz = navQuiz, - navControllerSearch = { navSearch("contenue", "") } + navControllerSearch = { navSearch("contenue", "") }, + currentUserVM = currentUserVM, + currentUserState = currentUserState, + ) { Column( modifier = Modifier diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt index 6c4840f..d812798 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SignUpPage.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardOptions @@ -21,6 +22,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -29,25 +31,26 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp 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.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.TitlePageComponent 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 -fun SignUpPage(navControllerLogin: () -> Unit, services : IServices) { - 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) } +fun SignUpPage(navControllerLogin: () -> Unit, signInUserVM :SignInUserViewModel,signInState : SignInUserState) { + Box( modifier = Modifier @@ -66,23 +69,35 @@ fun SignUpPage(navControllerLogin: () -> Unit, services : IServices) { horizontalAlignment = Alignment.CenterHorizontally ) { - TitlePageComponent(R.string.titleSignUp,MaterialTheme.colorScheme.onBackground) - IdentifiantTextFieldSign(R.string.IdentifiantLogin,identifiant = username,onValueChange = { username = it }) - EmailTextFieldSign(R.string.EmailSignUp, email, onValueChange = { email = it }) - PassWdTextFieldSign(R.string.PasswdLogin,password, onValueChange = { password = it },passwordVisible,onPasswordVisibilityChange = { passwordVisible = !passwordVisible }) - PassWdConfirmTextFieldSign(R.string.ConfirmPassWdSignUp,confirmPassword,onValueChange = { confirmPassword = it },passwordVisible,onPasswordVisibilityChange = { passwordVisible = !passwordVisible }) + TitlePageComponent(R.string.titleSignUp,MaterialTheme.colorScheme.onBackground) // Page Title + + IdentifiantTextFieldSign(R.string.IdentifiantLogin,signInState.username){ // Username + signInUserVM.setUsername(it) + } + + 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) - 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) - ReturnLogin(R.string.ButtonLogin,12, MaterialTheme.colorScheme.primary, navController = navControllerLogin) + + ReturnLogin(R.string.ButtonLogin,12, Color.White, navController = navControllerLogin) } } } - - @Composable fun IdentifiantTextFieldSign(textIdentifiantResId : Int, identifiant: String, onValueChange: (String) -> Unit){ val textIdentifiant = stringResource(id = textIdentifiantResId) @@ -119,8 +134,10 @@ fun EmailTextFieldSign(textIdentifiantResId: Int, email: String, onValueChange: } @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) + var passwordVisible by remember { mutableStateOf(false) } + Column(modifier = Modifier.padding(top = 10.dp)) { OutlinedTextField( value = passwd, @@ -132,8 +149,10 @@ fun PassWdTextFieldSign(textpasswdResId : Int, passwd: String, onValueChange: (S keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), trailingIcon = { - IconButton(onClick = onPasswordVisibilityChange) { - Icon(imageVector = Icons.Default.Check, contentDescription = "Valider") + IconButton(onClick = { + passwordVisible = !passwordVisible + }) { + VisibleIconPasswordComponent(passwordVisible) } }, shape = RoundedCornerShape(16.dp) @@ -142,8 +161,10 @@ fun PassWdTextFieldSign(textpasswdResId : Int, passwd: String, onValueChange: (S } @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) + var passwordVisible by remember { mutableStateOf(false) } + Column(modifier = Modifier.padding(top = 10.dp)) { OutlinedTextField( value = confirmPassword, @@ -155,8 +176,8 @@ fun PassWdConfirmTextFieldSign(textpasswdResId : Int,confirmPassword: String, on keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), trailingIcon = { - IconButton(onClick = onPasswordVisibilityChange) { - Icon(imageVector = Icons.Default.Check, contentDescription = "Valider") + IconButton(onClick = {passwordVisible = !passwordVisible}) { + VisibleIconPasswordComponent(passwordVisible) } }, shape = RoundedCornerShape(16.dp) @@ -186,7 +207,7 @@ fun ConnexionButtonSign( email: String, password: String, confirmPassword: String, - service: IServices, + viewModel: SignInUserViewModel, navController: ()-> Unit ) { val title = stringResource(id = titleResId) @@ -206,7 +227,7 @@ fun ConnexionButtonSign( passwordErrorEmpty = password.isBlank() || confirmPassword.isBlank() if (!emailError && !passwordError && !usernameError && !passwordErrorEmpty) { - usernameErrorExist = !service.CreateUser(username, email, password, service) + usernameErrorExist = !viewModel.createUser(username, email, password) if(!usernameErrorExist){ navController() // retour à la page login } diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SubmitQuotePage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SubmitQuotePage.kt index ed84c81..fbce607 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SubmitQuotePage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/SubmitQuotePage.kt @@ -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.SpaceHeightComponent 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 fun SubmitQuotePage( @@ -41,9 +45,13 @@ fun SubmitQuotePage( navAccueil: () -> Unit, navProfil:() -> Unit, navQuiz: () -> Unit, - navRecap: (String, String, String) -> Unit + navRecap: (String, String, String) -> Unit, + currentUserVM : CurrentUserViewModel, + currentUserState : CurrentUserState, ) { NavBar( + currentUserVM = currentUserVM, + currentUserState = currentUserState, navControllerFavorite = navFavorite, navControllerAccueil = navAccueil, navControllerProfil = navProfil, diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/states/AuthUserState.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/states/AuthUserState.kt new file mode 100644 index 0000000..10e361d --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/states/AuthUserState.kt @@ -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 = "", +) \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/states/CurrentUserState.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/states/CurrentUserState.kt new file mode 100644 index 0000000..cc1a7f6 --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/states/CurrentUserState.kt @@ -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 +) \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/states/SignInUserState.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/states/SignInUserState.kt new file mode 100644 index 0000000..ec44087 --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/states/SignInUserState.kt @@ -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 ="", +) \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/viewModels/AuthUserViewModel.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/viewModels/AuthUserViewModel.kt new file mode 100644 index 0000000..5d762d3 --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/viewModels/AuthUserViewModel.kt @@ -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 = _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) + } +} \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/viewModels/CurrentUserViewModel.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/viewModels/CurrentUserViewModel.kt new file mode 100644 index 0000000..2085ba2 --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/viewModels/CurrentUserViewModel.kt @@ -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.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) + } + } +} \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/viewModels/SignInUserViewModel.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/viewModels/SignInUserViewModel.kt new file mode 100644 index 0000000..42033f8 --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/viewModels/SignInUserViewModel.kt @@ -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 = _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) } + } + +} \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/res/drawable/password_no_visible.xml b/What_The_Fantasy/app/src/main/res/drawable/password_no_visible.xml new file mode 100644 index 0000000..0487de8 --- /dev/null +++ b/What_The_Fantasy/app/src/main/res/drawable/password_no_visible.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/What_The_Fantasy/app/src/main/res/drawable/password_visible.xml b/What_The_Fantasy/app/src/main/res/drawable/password_visible.xml new file mode 100644 index 0000000..b966f2a --- /dev/null +++ b/What_The_Fantasy/app/src/main/res/drawable/password_visible.xml @@ -0,0 +1,14 @@ + + + + diff --git a/What_The_Fantasy/gradle/libs.versions.toml b/What_The_Fantasy/gradle/libs.versions.toml index 26f2026..a855f46 100644 --- a/What_The_Fantasy/gradle/libs.versions.toml +++ b/What_The_Fantasy/gradle/libs.versions.toml @@ -14,6 +14,7 @@ composeBom = "2024.04.01" navigationCompose = "2.8.6" navigationCommonAndroid = "2.9.0-alpha05" engageCore = "1.5.6" +lifecycle = "2.8.0" [libraries] 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" } 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] android-application = { id = "com.android.application", version.ref = "agp" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }