Compare commits

...

12 Commits

@ -51,7 +51,7 @@ android {
} }
dependencies { dependencies {
implementation("io.coil-kt:coil-compose:1.4.0") implementation(libs.coil.compose.v140)
implementation(libs.bcrypt) // pour hacher les mdp implementation(libs.bcrypt) // pour hacher les mdp
implementation(libs.androidx.core.ktx) implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.lifecycle.runtime.ktx)
@ -76,5 +76,9 @@ dependencies {
//ViewModel //ViewModel
implementation(libs.android.lifecycle.viewmodel) implementation(libs.android.lifecycle.viewmodel)
implementation(libs.android.lifecycle.viewmodel.runtime.ktx) implementation(libs.android.lifecycle.viewmodel.runtime.ktx)
//Retrofit
implementation(libs.retrofit)
implementation(libs.converter.gson)
implementation(libs.gson)
} }

@ -1,6 +1,11 @@
package com.example.what_the_fantasy.data.model package com.example.what_the_fantasy.data.model
import com.google.gson.annotations.SerializedName
data class Image( data class Image(
@SerializedName("idImage")
val id: Int, val id: Int,
@SerializedName("imagePath")
val url: String val url: String
) )

@ -1,16 +1,37 @@
package com.example.what_the_fantasy.data.model package com.example.what_the_fantasy.data.model
import java.util.Date import com.google.gson.annotations.SerializedName
data class Quote ( data class Quote (
@SerializedName("id")
val id: Int, val id: Int,
@SerializedName("content")
val content: String, val content: String,
@SerializedName("like")
var likes: Int, var likes: Int,
@SerializedName("langage")
val language: SrcLanguage, val language: SrcLanguage,
@SerializedName("character")
val character: String, val character: String,
@SerializedName("titleSource")
val source: String, val source: String,
@SerializedName("imagePath")
val imgUrl: String, val imgUrl: String,
val type: SrcType,
val date: Int @SerializedName("type")
val type: SrcType ,
@SerializedName("dateSource")
val date: Int,
@SerializedName("isValide")
val isValide : Boolean = true
) )

@ -1,6 +1,31 @@
package com.example.what_the_fantasy.data.model package com.example.what_the_fantasy.data.model
import com.google.gson.*
import java.lang.reflect.Type
enum class SrcLanguage(val code:Int) {
vf(1),
vo(0);
companion object {
fun fromCode(code: Int): SrcLanguage? = values().find { it.code == code }
}
}
class LangAdapter : JsonSerializer<SrcLanguage>, JsonDeserializer<SrcLanguage> {
override fun serialize(
src: SrcLanguage?,
typeOfSrc: Type?,
context: JsonSerializationContext?
): JsonElement = JsonPrimitive(src?.code)
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): SrcLanguage {
val code = json?.asInt
return SrcLanguage.fromCode(code ?: throw JsonParseException("Code null"))
?: throw JsonParseException("Unknown Status code: $code")
}
enum class SrcLanguage {
vf,
vo
} }

@ -2,9 +2,50 @@ package com.example.what_the_fantasy.data.model
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import com.example.what_the_fantasy.R import com.example.what_the_fantasy.R
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonParseException
import com.google.gson.JsonPrimitive
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import java.lang.reflect.Type
enum class SrcType (val value: String) { enum class SrcType (val value: String) {
Movie("movie" ), Movie("movie" ),
VideoGame("videoGame"), VideoGame("videoGame"),
Series("series"), Series("series");
companion object {
fun fromCode(value: Int): SrcType? = SrcType.values().find {
if (value==0){
it.value == "movie"
}
else if (value==1){
it.value == "videoGame"
}
else{
it.value == "series"
}
}
}
}
class SrcTypeAdapter : JsonSerializer<SrcType>, JsonDeserializer<SrcType> {
override fun serialize(
src: SrcType?,
typeOfSrc: Type?,
context: JsonSerializationContext?
): JsonElement = JsonPrimitive(src?.value)
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): SrcType {
val value = json?.asInt
return SrcType.fromCode(value ?: throw JsonParseException("Code null"))
?: throw JsonParseException("Unknown Status code: $value")
}
} }

@ -1,11 +1,22 @@
package com.example.what_the_fantasy.data.model package com.example.what_the_fantasy.data.model
import com.google.gson.annotations.SerializedName
class User( class User(
@SerializedName("id")
val id:Int, val id:Int,
@SerializedName("pseudo")
var username:String, var username:String,
@SerializedName("email")
var email:String, var email:String,
@SerializedName("date")
var date:String, var date:String,
@SerializedName("imageProfil")
val imgUrl: String, val imgUrl: String,
@SerializedName("password")
var password: String, var password: String,
@SerializedName("lang")
var langage : SrcLanguage var langage : SrcLanguage
) )

@ -0,0 +1,107 @@
package com.example.what_the_fantasy.data.retrofit
import com.example.what_the_fantasy.data.model.Image
import com.example.what_the_fantasy.data.model.LangAdapter
import com.example.what_the_fantasy.data.model.SrcTypeAdapter
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.SrcType
import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.data.services.APIReponceList
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Path
import retrofit2.http.Query
interface ApiService {
@GET("users/username")
suspend fun getUserByUsername(
@Query("username") username: String
): User
@GET("users/{id}")
suspend fun getUserById(
@Path("id") id: Int
): User
@GET("users/existusername")
suspend fun checkIfUsernameExists(
@Query("username") username: String
): Boolean
@GET("users/existemail")
suspend fun checkIfEmailExists(
@Query("email") email: String
): Boolean
@PUT("users")
suspend fun updateUsername(
@Query("id") id: Int,
@Body user: User // Envoie un objet `User` avec les nouvelles données
): Response<Unit>
@POST("users")
suspend fun addUser(
@Body newUser: User
): Response<Unit>
@GET("quote/dailyquote")
suspend fun getDailyQuote(
@Query("year") year: Int,
@Query("month") month: Int,
@Query("day") day: Int,
@Query("lang") lang: SrcLanguage
): Quote
@GET("quote/{id}")
suspend fun getQuoteById(
@Path("id")id : Int
):Quote
@GET("quote/all")
suspend fun getAllQuote(
@Query("index") index: Int,
@Query("count") count: Int
): APIReponceList<Quote>
@GET("image/all")
suspend fun getAllImages(
@Query("index") index: Int,
@Query("count") count: Int
): List<Image>
@GET("image/{id}")
suspend fun getImageById(
@Path("id") id: Int
): Image
}
object RetrofitInstance {
private const val BASE_URL = "https://codefirst.iut.uca.fr/containers/WhatTheFantasy-web-services/api/v1/"
private val gson: Gson = GsonBuilder()
.registerTypeAdapter(SrcLanguage::class.java, LangAdapter())
.registerTypeAdapter(SrcType::class.java, SrcTypeAdapter())
.create()
val api: ApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
.create(ApiService::class.java)
}
}

@ -0,0 +1,17 @@
package com.example.what_the_fantasy.data.services
import com.google.gson.annotations.SerializedName
data class APIReponceList<T> (
@SerializedName("totalCount")
val totalCount: Int,
@SerializedName("pageIndex")
val index: Int,
@SerializedName("countPerPage")
val count: Int,
@SerializedName("items")
val items: MutableList<T>,
)

@ -6,38 +6,41 @@ 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.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 com.example.what_the_fantasy.ui.states.AuthUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
interface IServices { interface IServices {
fun validLogin(username : String, suspend fun validLogin(username : String,
passwd : String, passwd : String,
navController: (Int) -> Unit, navController: (Int) -> Unit,
initialierCurrentUser : (Int) ->Unit): Boolean initialierCurrentUser : (Int) ->Unit,
currentUserViewModel: CurrentUserViewModel
fun EditUsername(username : String, index : Int) : Boolean ): Boolean
fun EditEmail(email : String, index : Int) : Boolean
fun EditPasswd(passwd : String, index : Int) suspend fun EditUsername(username : String, index : Int, currentUserViewModel: CurrentUserViewModel) : Boolean
fun EditImage(index : Int) : String suspend fun EditEmail(email : String, index : Int,currentUserViewModel: CurrentUserViewModel) : Boolean
fun ChangeLangage(index : Int): SrcLanguage suspend fun EditPasswd(passwd : String, index : Int,currentUserViewModel : CurrentUserViewModel): Boolean
suspend fun EditImage(index : Int,currentUserViewModel : CurrentUserViewModel) : String
suspend fun ChangeLangage(index : Int, currentUserViewModel : CurrentUserViewModel): SrcLanguage
fun isUsernameExist(username : String) : Boolean fun isUsernameExist(username : String) : Boolean
fun isEmailExist(email : String) : Boolean fun isEmailExist(email : String) : Boolean
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) : Boolean suspend 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>
fun getUserById(id: Int): User? suspend fun getUserById(id: Int): User?
fun getQuote( id : Int): Quote? fun getQuote( id : Int): Quote?
fun isFavorite(idQuote : Int, iduser: Int): Boolean suspend fun isFavorite(idQuote : Int, iduser: Int): Boolean
fun getAllFavorite(): List<Favorite> fun getAllFavorite(): List<Favorite>
fun getAllQuote(): List<Quote> fun getAllQuote(): List<Quote>
fun getSomeQuotes(nb: Int, page: Int) : MutableList<Quote> suspend fun getSomeQuotes(nb: Int, page: Int) : MutableList<Quote>
suspend fun getDalyQuote(langage : SrcLanguage) : Quote
fun search(type : String ,search:String ,indexCount: Int): List<Quote> fun search(type : String ,search:String ,indexCount: Int): List<Quote>
} }

@ -1,89 +1,302 @@
package com.example.what_the_fantasy.data.services package com.example.what_the_fantasy.data.services
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.example.what_the_fantasy.data.local.ImageStub.allImages
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.SrcLanguage
import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.data.retrofit.RetrofitInstance
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import java.time.LocalDate
import java.util.Calendar
import java.util.Date
//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 {
// TODO("Not yet implemented") override suspend fun validLogin(
// } username: String,
// passwd: String,
// override fun EditEmail(email: String, index : Int): Boolean { navController: (Int) -> Unit,
// TODO("Not yet implemented") initialierCurrentUser: (Int) -> Unit,
// } currentUserViewModel: CurrentUserViewModel
// ): Boolean {
// override fun EditPasswd(passwd: String, index : Int) { try {
// TODO("Not yet implemented") val response = RetrofitInstance.api.getUserByUsername(username) // on récupère l'utilisateur
// } val hashedPasswordAPI = response.password // récupère le mot de passe de l'api
// val index =response.id
// override fun EditImage(imageURL: String, index : Int) { //val hashPassWd = hashPassword(passwd)// hache mot de passe demandé
// TODO("Not yet implemented")
// } if (passwd == hashedPasswordAPI) { // on compare les deux mots de passe
// navController(index)
// override fun ChangeLangage(user: User) { initialierCurrentUser(index)
// TODO("Not yet implemented") currentUserViewModel.setUser(response)
// } return true
// }
// override fun AddFav(userId: Int, QuoteId: Int) { else {
// TODO("Not yet implemented") return false
// } }
// } catch (e: Exception) {
// override fun SupFav(userId: Int, QuoteId: Int) { return false
// TODO("Not yet implemented") }
// } }
//
// override fun AddComment(content: String) { override suspend fun EditUsername(username: String, index: Int, currentUserViewModel: CurrentUserViewModel): Boolean {
// TODO("Not yet implemented") try {
// } val userExistsResponse = RetrofitInstance.api.checkIfUsernameExists(username)
//
// override fun CreateUser(username: String, email: String, passwd: String, services: IServices) : Boolean { Log.d("EditUsername", "Username check: $username exists = $userExistsResponse")
// TODO("Not yet implemented")
// } if (userExistsResponse) {
// Log.d("EditUsername", "Username $username already exists, cannot update.")
// override fun getFavorite(user: User): List<Quote> { return false
// TODO("Not yet implemented") }
// }
// val responseUser = RetrofitInstance.api.getUserById(index)
// override fun SearchQuote(quote: String) {
// TODO("Not yet implemented") val updatedUser = User(
// } id = index,
// username = username, // Nouveau nom d'utilisateur
// override fun getQuote(id: Int): Quote? { email = responseUser.email,
// TODO("Not yet implemented") password = responseUser.password,
// } imgUrl = responseUser.imgUrl,
// langage = responseUser.langage,
// override fun isFavorite(id: Int, user: User): Boolean { date = responseUser.date
// TODO("Not yet implemented") )
// }
// val response = RetrofitInstance.api.updateUsername(index, updatedUser)
// override fun getAllFavorite(): List<Favorite> {
// TODO("Not yet implemented") if (response.isSuccessful) {
// } currentUserViewModel.setUser(updatedUser)
// Log.d("EditUsername", "Username updated successfully.")
// override fun getAllQuote(): List<Quote> { return true
// TODO("Not yet implemented") } else {
// } Log.d("EditUsername", "Failed to update username, API response not successful.")
// return false
// override fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> { }
// TODO("Not yet implemented") } catch (e: Exception) {
// } e.printStackTrace()
// Log.d("EditUsername", "Exception occurred: ${e.message}")
// override fun getAllUsers(): List<User> { return false
// TODO("Not yet implemented") }
// } }
//
// override fun getComment(quoteId: Int): List<Comment> {
// TODO("Not yet implemented") override suspend fun EditEmail(email: String, index: Int,currentUserViewModel: CurrentUserViewModel): Boolean {
// } try {
// val userExistsResponse = RetrofitInstance.api.checkIfEmailExists(email)
// override fun getUserById(id: Int): User? {
// TODO("Not yet implemented") if (userExistsResponse) {
// } Log.d("EditEmail", "Exception occurred: The email alredy exist")
// return false
// override fun search(type : String ,search:String ,indexCount: Int): List<Quote>{ }
// TODO("Not yet implemented")
// } val responseUser = RetrofitInstance.api.getUserById(index)
//}
val updatedUser = User(
id = index,
username = responseUser.username,
email = email,// Nouvel email d'utilisateur
password = responseUser.password,
imgUrl = responseUser.imgUrl,
langage = responseUser.langage,
date = responseUser.date
)
val response = RetrofitInstance.api.updateUsername(index, updatedUser)
if (response.isSuccessful) {
currentUserViewModel.setUser(updatedUser)
return true
} else {
return false
}
} catch (e: Exception) {
e.printStackTrace()
Log.d("EditEmail", "Exception occurred: ${e.message}")
return false
}
}
override suspend fun EditPasswd(passwd: String, index: Int, currentUserViewModel: CurrentUserViewModel): Boolean {
try {
val responseUser = RetrofitInstance.api.getUserById(index)
val updatedUser = User(
id = index,
username = responseUser.username,
email = responseUser.username,
password = passwd,
//password = hashPassword(passwd),
imgUrl = responseUser.imgUrl,
langage = responseUser.langage,
date = responseUser.date
)
val response = RetrofitInstance.api.updateUsername(index, updatedUser)
if (response.isSuccessful) {
currentUserViewModel.setUser(updatedUser)
return true
} else {
return false
}
} catch (e: Exception) {
e.printStackTrace()
Log.d("EditPasswd", "Exception occurred: ${e.message}")
return false
}
}
override suspend fun EditImage(index: Int, currentUserViewModel : CurrentUserViewModel): String {
try {
val responseUser = RetrofitInstance.api.getUserById(index)
val updatedUser = User(
id = index,
username = responseUser.username,
email = responseUser.email,// Nouvel email d'utilisateur
password = responseUser.password,
imgUrl = randomImage(),
langage = responseUser.langage,
date = responseUser.date
)
val response = RetrofitInstance.api.updateUsername(index, updatedUser)
if (response.isSuccessful) {
currentUserViewModel.setUser(updatedUser)
return updatedUser.imgUrl
} else {
return responseUser.imgUrl
}
} catch (e: Exception) {
e.printStackTrace()
return ""
Log.d("EditEmail", "Exception occurred: ${e.message}")
}
}
override suspend fun ChangeLangage(index: Int, currentUserViewModel : CurrentUserViewModel): SrcLanguage {
val responseUser = RetrofitInstance.api.getUserById(index)
var langage : SrcLanguage
if(responseUser.langage == SrcLanguage.vf){
langage = SrcLanguage.vo
}
else{
langage = SrcLanguage.vf
}
val updatedUser = User(
id = index,
username = responseUser.username,
email = responseUser.email,
password = responseUser.password,
imgUrl = responseUser.imgUrl,
langage = langage,
date = responseUser.date
)
RetrofitInstance.api.updateUsername(index, updatedUser)
currentUserViewModel.setUser(updatedUser)
return langage
}
override fun isUsernameExist(username: String): Boolean {
TODO("Not yet implemented")
}
override fun isEmailExist(email: String): Boolean {
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 suspend fun CreateUser(username: String, email: String, passwd: String): Boolean {
val today = Calendar.getInstance().time
val rep =RetrofitInstance.api.addUser( User(15,username,email,today.toString(),"img",passwd,SrcLanguage.vo))
Log.d("test",rep.toString())
if(rep.code() in 200..299) return true
return false
}
override fun getFavorite(user: User): List<Quote> {
TODO("Not yet implemented")
}
override fun getAllUsers(): List<User> {
TODO("Not yet implemented")
}
override fun getComment(quoteId: Int): List<Comment> {
TODO("Not yet implemented")
}
override suspend fun getUserById(id: Int): User {
return RetrofitInstance.api.getUserById(id)
}
override fun getQuote(id: Int): Quote? {
TODO("Not yet implemented")
}
override suspend fun isFavorite(idQuote: Int, iduser: Int): Boolean {
TODO("Not yet implemented")
}
override fun getAllFavorite(): List<Favorite> {
TODO("Not yet implemented")
}
override fun getAllQuote(): List<Quote> {
TODO("Not yet implemented")
}
override suspend fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
val result = RetrofitInstance.api.getAllQuote(page,nb)
return result.items
}
@RequiresApi(Build.VERSION_CODES.O)
override suspend fun getDalyQuote(langage : SrcLanguage): Quote {
val today = LocalDate.now()
return RetrofitInstance.api.getDailyQuote(today.year, today.monthValue, today.dayOfMonth, langage)
}
override fun search(type: String, search: String, indexCount: Int): List<Quote> {
TODO("Not yet implemented")
}
//-------------------------------------------------------
suspend fun randomImage() : String{
val imagesList = RetrofitInstance.api.getAllImages(0, 300)
val sizeList = imagesList.size
return RetrofitInstance.api.getImageById((0..sizeList).random()).url
}
}

@ -12,16 +12,19 @@ import com.example.what_the_fantasy.data.local.CommentStub.comments
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.SrcLanguage
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import java.time.LocalDate 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, override suspend fun validLogin(username : String,
passwd : String, passwd : String,
navController: (Int) -> Unit, navController: (Int) -> Unit,
initialierCurrentUser : (Int) ->Unit): Boolean{ initialierCurrentUser : (Int) ->Unit,
currentUserViewModel: CurrentUserViewModel
): Boolean{
users.forEachIndexed { index, user -> users.forEachIndexed { index, user ->
val hashPassWd = hashPassword(passwd) val hashPassWd = hashPassword(passwd)
@ -36,7 +39,7 @@ class ServicesStub : IServices {
} }
override fun EditUsername(username: String, index : Int) : Boolean{ override suspend fun EditUsername(username: String, index : Int,currentUserViewModel: CurrentUserViewModel) : Boolean{
val user = getUserById(index) val user = getUserById(index)
if(!isUsernameExist(username)){ if(!isUsernameExist(username)){
@ -49,7 +52,7 @@ class ServicesStub : IServices {
return false return false
} }
override fun EditEmail(email: String,index : Int) : Boolean { override suspend fun EditEmail(email: String, index : Int,currentUserViewModel: CurrentUserViewModel) : Boolean {
val user = getUserById(index) val user = getUserById(index)
if(!isEmailExist(email)){ if(!isEmailExist(email)){
@ -61,20 +64,20 @@ class ServicesStub : IServices {
return false return false
} }
override fun EditPasswd(passwd: String,index : Int) { override suspend fun EditPasswd(passwd: String, index: Int, currentUserViewModel: CurrentUserViewModel): Boolean {
val user = getUserById(index) val user = getUserById(index)
val passwordhash = hashPassword(passwd) val passwordhash = hashPassword(passwd)
user?.password = passwordhash user?.password = passwordhash
return true
//Afficher tous les users en log //Afficher tous les users en log
//logsUser.logDebugAllUsers(getAllUsers(), "PasswordUpdate") //logsUser.logDebugAllUsers(getAllUsers(), "PasswordUpdate")
} }
override fun EditImage(index : Int) : String { override suspend fun EditImage(index : Int,currentUserViewModel : CurrentUserViewModel) : String {
return randomImage() return randomImage()
} }
override fun ChangeLangage(index : Int) : SrcLanguage{ override suspend fun ChangeLangage(index : Int,currentUserViewModel : CurrentUserViewModel) : SrcLanguage{
if(getAllUsers()[index].langage == SrcLanguage.vo){ if(getAllUsers()[index].langage == SrcLanguage.vo){
getAllUsers()[index].langage = SrcLanguage.vf getAllUsers()[index].langage = SrcLanguage.vf
} }
@ -101,7 +104,7 @@ class ServicesStub : IServices {
} }
override fun CreateUser(username: String, email: String, passwd: String) : Boolean { override suspend 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 services = ServicesStub()
@ -131,7 +134,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 suspend fun getUserById(id: Int): User? {
return (users.find { it.id == id }) return (users.find { it.id == id })
} }
@ -140,7 +143,7 @@ class ServicesStub : IServices {
return (quotes.find { it.id == id }) return (quotes.find { it.id == id })
} }
override fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> { override suspend fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
var nbQuote = nb var nbQuote = nb
if(nb < 0) nbQuote = 1 if(nb < 0) nbQuote = 1
@ -151,7 +154,12 @@ class ServicesStub : IServices {
return quotes.subList(fromIndex, toIndex).toMutableList() return quotes.subList(fromIndex, toIndex).toMutableList()
} }
override fun isFavorite(idQuote: Int, idUser: Int): Boolean {
override suspend fun getDalyQuote(langage: SrcLanguage): Quote {
return quotes.first()
}
override suspend fun isFavorite(idQuote: Int, idUser: Int): Boolean {
val user = getUserById(idUser) ?: return false val user = getUserById(idUser) ?: return false
val quote = getFavorite(user) val quote = getFavorite(user)
return quote.find{ it.id == idQuote } != null return quote.find{ it.id == idQuote } != null

@ -1,5 +1,6 @@
package com.example.what_the_fantasy.ui.navigations package com.example.what_the_fantasy.ui.navigations
import android.util.Log
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -8,12 +9,14 @@ import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.lifecycle.viewmodel.compose.viewModel 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.ServicesAPI
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.AuthUserViewModel
@ -21,6 +24,7 @@ import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import com.example.what_the_fantasy.ui.viewModels.QuoteInformationUserViewModel import com.example.what_the_fantasy.ui.viewModels.QuoteInformationUserViewModel
import com.example.what_the_fantasy.ui.viewModels.SearchViewModel import com.example.what_the_fantasy.ui.viewModels.SearchViewModel
import com.example.what_the_fantasy.ui.viewModels.SignInUserViewModel import com.example.what_the_fantasy.ui.viewModels.SignInUserViewModel
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
@ -70,7 +74,8 @@ data class RecapSubmit(val userIndex: Int,
@Composable @Composable
fun AppNavigator() { fun AppNavigator() {
val navController = rememberNavController() val navController = rememberNavController()
val services = ServicesStub() val servicesStub = ServicesStub()
val services = ServicesAPI()
//ViewModel pour l'authentification //ViewModel pour l'authentification
val authUserVM : AuthUserViewModel = viewModel() val authUserVM : AuthUserViewModel = viewModel()
@ -100,6 +105,7 @@ fun AppNavigator() {
NavHost(navController, startDestination = Login) { NavHost(navController, startDestination = Login) {
composable<Login> { composable<Login> {
val coroutineScope = rememberCoroutineScope()
LoginPage( LoginPage(
navControllerSignUp = { navController.navigate(SignUp) }, navControllerSignUp = { navController.navigate(SignUp) },
navControllerProfil = { userIndex -> navControllerProfil = { userIndex ->
@ -109,7 +115,12 @@ fun AppNavigator() {
}, },
authUserVM = authUserVM, authUserVM = authUserVM,
authState = authState, authState = authState,
initialierCurrentUser ={currentUserVM.initialiseCurrentUser(it)} currentUserViewModel = currentUserVM,
initialierCurrentUser ={
coroutineScope.launch {
currentUserVM.initialiseCurrentUser(it)
}
}
) )
} }
@ -148,7 +159,7 @@ fun AppNavigator() {
) )
}, },
navSearch = { navController.navigate(Search(currentUserState.id))}, navSearch = { navController.navigate(Search(currentUserState.id))},
services = services, services = servicesStub,
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
) )
@ -178,7 +189,7 @@ fun AppNavigator() {
navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) }, navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
navProfil = { navController.navigate(Profil(currentUserState.id)) }, navProfil = { navController.navigate(Profil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(currentUserState.id)) }, navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
service = services, service = servicesStub,
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
navSearch = { navController.navigate(Search(currentUserState.id))}, navSearch = { navController.navigate(Search(currentUserState.id))},

@ -1,5 +1,7 @@
package com.example.what_the_fantasy.ui.screens package com.example.what_the_fantasy.ui.screens
import android.annotation.SuppressLint
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.* import androidx.compose.foundation.layout.*
@ -19,14 +21,19 @@ import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.R import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.local.DailyQuoteStub import com.example.what_the_fantasy.data.local.DailyQuoteStub
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.SrcType
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.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import com.example.what_the_fantasy.ui.theme.colorBackground import com.example.what_the_fantasy.ui.theme.colorBackground
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@SuppressLint("CoroutineCreationDuringComposition")
@Composable @Composable
fun AccueilPage( fun AccueilPage(
navFavorite: () -> Unit, navFavorite: () -> Unit,
@ -39,12 +46,13 @@ fun AccueilPage(
currentUserState : CurrentUserState, currentUserState : CurrentUserState,
) { ) {
val dailyQuote = DailyQuoteStub.dailyQuote
//val dailyQuote = DailyQuoteStub.dailyQuote
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 { mutableIntStateOf(1) } val page = remember { mutableIntStateOf(0) }
val quotes = remember { mutableStateListOf<Quote>() } val quotes = remember { mutableStateListOf<Quote>() }
val state = rememberLazyListState() val state = rememberLazyListState()
val layoutInfo = remember { derivedStateOf { state.layoutInfo } } val layoutInfo = remember { derivedStateOf { state.layoutInfo } }
@ -53,6 +61,10 @@ fun AccueilPage(
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
val dailyQuote = remember { mutableStateOf(Quote(-1,"",0,SrcLanguage.vo,"","","",SrcType.Movie,0)) }
LaunchedEffect(true){
dailyQuote.value=services.getDalyQuote(currentUserState.langage)
}
LaunchedEffect(page.intValue) { LaunchedEffect(page.intValue) {
if (!isLoading.value) { if (!isLoading.value) {
@ -87,20 +99,35 @@ fun AccueilPage(
.background(MaterialTheme.colorScheme.background) .background(MaterialTheme.colorScheme.background)
) { ) {
LazyColumn(modifier = Modifier.weight(1f), state = state) { LazyColumn(modifier = Modifier.weight(1f), state = state) {
item { if(dailyQuote.value.id!=-1) {
Column(Modifier.clickable { navQuote(dailyQuote.id) }) { item {
Text( Column(Modifier.clickable { navQuote(dailyQuote.value.id) }) {
text = titleDalyQuote, Text(
color = MaterialTheme.colorScheme.onBackground, text = titleDalyQuote,
fontSize = 24.sp, color = MaterialTheme.colorScheme.onBackground,
fontSize = 24.sp,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
textAlign = TextAlign.Center
)
QuoteLittle(dailyQuote.value)
}
}
}
else{
item {
Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(16.dp), .padding(16.dp),
textAlign = TextAlign.Center contentAlignment = Alignment.Center
) ) {
QuoteLittle(dailyQuote) CircularProgressIndicator()
}
} }
}
item {
Text( Text(
text = titleSuggestion, text = titleSuggestion,
color = MaterialTheme.colorScheme.onBackground, color = MaterialTheme.colorScheme.onBackground,

@ -33,9 +33,10 @@ fun FavoritePage(
currentUserVM : CurrentUserViewModel, currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState, currentUserState : CurrentUserState,
) { ) {
val user = services.getUserById(currentUserState.id) ?: return
val quotes = services.getFavorite(user) //val user = services.getUserById(currentUserState.id) ?: return
//val quotes = services.getFavorite(user)
val titlePage = stringResource(R.string.TitleFavorite) val titlePage = stringResource(R.string.TitleFavorite)
NavBar(onFavorite = true, NavBar(onFavorite = true,
@ -65,12 +66,12 @@ fun FavoritePage(
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
} }
items(quotes) { quote -> // items(quotes) { quote ->
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))
} // }
} // }
} }
} }
} }

@ -21,6 +21,7 @@ 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
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue 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
@ -44,12 +45,15 @@ 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.components.VisibleIconPasswordComponent
import com.example.what_the_fantasy.ui.states.AuthUserState import com.example.what_the_fantasy.ui.states.AuthUserState
import com.example.what_the_fantasy.ui.viewModels.AuthUserViewModel import com.example.what_the_fantasy.ui.viewModels.AuthUserViewModel
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import kotlinx.coroutines.launch
@Composable @Composable
fun LoginPage(navControllerSignUp: () -> Unit, fun LoginPage(navControllerSignUp: () -> Unit,
navControllerProfil: (Int) -> Unit, navControllerProfil: (Int) -> Unit,
authUserVM : AuthUserViewModel, authUserVM : AuthUserViewModel,
authState : AuthUserState, authState : AuthUserState,
currentUserViewModel : CurrentUserViewModel,
initialierCurrentUser : (Int) -> Unit) { initialierCurrentUser : (Int) -> Unit) {
@ -77,7 +81,7 @@ fun LoginPage(navControllerSignUp: () -> Unit,
authUserVM.setUsername(it) authUserVM.setUsername(it)
}, PassWdTextField(R.string.PasswdLogin, authState.password){ }, PassWdTextField(R.string.PasswdLogin, authState.password){
authUserVM.setPassword(it) authUserVM.setPassword(it)
}, R.string.ButtonLogin,18,navControllerProfil){ }, R.string.ButtonLogin,18,currentUserViewModel,navControllerProfil){
initialierCurrentUser(it) initialierCurrentUser(it)
} }
SpaceHeightComponent(16) SpaceHeightComponent(16)
@ -136,12 +140,25 @@ fun PassWdTextField(textpasswdResId : Int, password : String, onValueChange: (St
@Composable @Composable
fun ConnexionButtonLogin(authUserVM : AuthUserViewModel, username : String, passwd : String, titleResId : Int, size : Int, navController: (Int) -> Unit, initialierCurrentUser : (Int) -> Unit){ fun ConnexionButtonLogin(authUserVM : AuthUserViewModel,
username : String,
passwd : String,
titleResId : Int,
size : Int,
currentUserViewModel: CurrentUserViewModel,
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) }
val coroutineScope = rememberCoroutineScope()
Button( Button(
onClick = { showError = !authUserVM.validLogin(username, passwd, navController, initialierCurrentUser) onClick = {
}, coroutineScope.launch {
val result = authUserVM.validLogin(username, passwd, navController, initialierCurrentUser, currentUserViewModel)
showError = !result
}
},
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background), colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background),
modifier = Modifier modifier = Modifier
.fillMaxWidth(), .fillMaxWidth(),

@ -33,6 +33,7 @@ import androidx.compose.runtime.Composable
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
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue 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
@ -57,6 +58,8 @@ 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.components.VisibleIconPasswordComponent
import com.example.what_the_fantasy.ui.states.CurrentUserState 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.viewModels.CurrentUserViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable @Composable
fun ProfilPage(navFavorite: () -> Unit, fun ProfilPage(navFavorite: () -> Unit,
@ -129,13 +132,18 @@ fun ProfilPage(navFavorite: () -> Unit,
@Composable @Composable
fun ImageProfil(size :Int,index: Int, currentUserVM: CurrentUserViewModel, currentUserState: CurrentUserState){ fun ImageProfil(size :Int,index: Int, currentUserVM: CurrentUserViewModel, currentUserState: CurrentUserState){
val coroutineScope = rememberCoroutineScope()
AsyncImage( AsyncImage(
model = currentUserState.imagePath, model = currentUserState.imagePath,
contentDescription = "Photo de profil", contentDescription = "Photo de profil",
modifier = Modifier modifier = Modifier
.size(size.dp) .size(size.dp)
.clip(CircleShape) .clip(CircleShape)
.clickable{currentUserVM.editImage(index)} .clickable{
coroutineScope.launch {
currentUserVM.editImage(index)
}
}
) )
} }
@ -145,12 +153,14 @@ fun EditEmail(emailState: String, index: Int, currentUserVM: CurrentUserViewMode
var originalEmail by remember { mutableStateOf(emailState) } var originalEmail 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) }
val coroutineScope = rememberCoroutineScope()
fun onDoneEditing() { fun onDoneEditing() {
if (email != originalEmail) { coroutineScope.launch {
isEditingEmail = !currentUserVM.editEmail(email, index) if (email != originalEmail) {
} else { isEditingEmail = !currentUserVM.editEmail(email, index)
isEditingEmail = false } else {
isEditingEmail = false
}
} }
} }
@ -235,12 +245,15 @@ fun EditUsername(usernameState: String, index: Int, currentUserVM: CurrentUserVi
var username by remember { mutableStateOf(usernameState) } var username by remember { mutableStateOf(usernameState) }
var originalUsername by remember { mutableStateOf(usernameState) } var originalUsername by remember { mutableStateOf(usernameState) }
var isEditingUsername by remember { mutableStateOf(false) } var isEditingUsername by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
fun onDoneEditing() { fun onDoneEditing() {
if (username != originalUsername) { coroutineScope.launch {
isEditingUsername = !currentUserVM.editUsername(username, index) if (username != originalUsername) {
} else { isEditingUsername = !currentUserVM.editUsername(username, index)
isEditingUsername = false } else {
isEditingUsername = false
}
} }
} }
@ -312,12 +325,14 @@ fun EditPasswd(index: Int, currentUserVM: CurrentUserViewModel) {
var confirmPassword by remember { mutableStateOf("") } var confirmPassword by remember { mutableStateOf("") }
var passwordVisible by remember { mutableStateOf(false) } var passwordVisible by remember { mutableStateOf(false) }
var passwordError by remember { mutableStateOf(false) } var passwordError by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
// 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 coroutineScope.launch {
currentUserVM.editPassword(newPassword, index) // Appeler EditPasswd pour mettre à jour le mot de passe de l'utilisateur
isEditingPassword = false currentUserVM.editPassword(newPassword, index)
isEditingPassword = false
}
} }
if (isEditingPassword) { if (isEditingPassword) {
@ -480,10 +495,12 @@ fun ButtonUnLog(textResId : Int, size :Int, colorTexte : Color,colorButton : Col
@Composable @Composable
fun ButtonLanguage(textResId : Int, size :Int,colorTexte : Color, colorButton : Color, currentUserVM: CurrentUserViewModel, currentUserState : CurrentUserState){ 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 coroutineScope = rememberCoroutineScope()
Button( Button(
onClick = { onClick = {
coroutineScope.launch {
currentUserVM.editLangue(currentUserState.id) currentUserVM.editLangue(currentUserState.id)
}
}, },
colors = ButtonDefaults.buttonColors(containerColor = colorButton), colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),

@ -87,9 +87,9 @@ fun QuotePage(
val quote = service.getQuote(quoteId) ?: return val quote = service.getQuote(quoteId) ?: return
val context = LocalContext.current val context = LocalContext.current
val favorite by remember { mutableStateOf(service.isFavorite( //val favorite by remember { mutableStateOf(service.isFavorite(
idQuote = quoteId, // idQuote = quoteId,
iduser = currentUserState.id)) } // iduser = currentUserState.id)) }
NavBar( NavBar(
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
@ -120,15 +120,15 @@ fun QuotePage(
) )
Column { Column {
FunctionalIcon( // FunctionalIcon(
isFavorite = favorite, // isFavorite = favorite,
userId = currentUserState.id, // userId = currentUserState.id,
quoteId = quoteId, // quoteId = quoteId,
context = context, // context = context,
quoteInformationUserVM = quoteInformationUserVM, // quoteInformationUserVM = quoteInformationUserVM,
quoteInformationUserState = quoteInformationUserState, // quoteInformationUserState = quoteInformationUserState,
quote = quote // quote = quote
) // )
QuoteText( QuoteText(
text = '"' + quote.content + '"' text = '"' + quote.content + '"'
) )

@ -26,6 +26,7 @@ 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
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue 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
@ -47,6 +48,7 @@ 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.components.VisibleIconPasswordComponent
import com.example.what_the_fantasy.ui.states.SignInUserState import com.example.what_the_fantasy.ui.states.SignInUserState
import com.example.what_the_fantasy.ui.viewModels.SignInUserViewModel import com.example.what_the_fantasy.ui.viewModels.SignInUserViewModel
import kotlinx.coroutines.launch
@Composable @Composable
fun SignUpPage(navControllerLogin: () -> Unit, signInUserVM :SignInUserViewModel,signInState : SignInUserState) { fun SignUpPage(navControllerLogin: () -> Unit, signInUserVM :SignInUserViewModel,signInState : SignInUserState) {
@ -91,7 +93,7 @@ fun SignUpPage(navControllerLogin: () -> Unit, signInUserVM :SignInUserViewModel
ConnexionButtonSign(R.string.ButtonSignUp,18, Color.White, Color.Black, signInState.username, signInState.email, signInState.password, signInState.confirmPassword, signInUserVM, 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, Color.White, navController = navControllerLogin) ReturnLogin(R.string.ButtonLogin,12, MaterialTheme.colorScheme.onBackground, navController = navControllerLogin)
} }
} }
@ -219,17 +221,21 @@ fun ConnexionButtonSign(
val invalidRegex = """^[a-zA-Z0-9]*$""".toRegex() val invalidRegex = """^[a-zA-Z0-9]*$""".toRegex()
val coroutineScope = rememberCoroutineScope()
Button( Button(
onClick = { onClick = {
emailError = !isValidEmail(email) coroutineScope.launch {
passwordError = !arePasswordsMatching(password, confirmPassword) emailError = !isValidEmail(email)
usernameError = username.isBlank() && !username.matches(invalidRegex) passwordError = !arePasswordsMatching(password, confirmPassword)
passwordErrorEmpty = password.isBlank() || confirmPassword.isBlank() usernameError = username.isBlank() && !username.matches(invalidRegex)
passwordErrorEmpty = password.isBlank() || confirmPassword.isBlank()
if (!emailError && !passwordError && !usernameError && !passwordErrorEmpty) {
usernameErrorExist = !viewModel.createUser(username, email, password) if (!emailError && !passwordError && !usernameError && !passwordErrorEmpty) {
if(!usernameErrorExist){ usernameErrorExist = !viewModel.createUser(username, email, password)
navController() // retour à la page login if (!usernameErrorExist) {
navController() // retour à la page login
}
} }
} }
}, },

@ -2,6 +2,7 @@ package com.example.what_the_fantasy.ui.viewModels
import android.util.Log import android.util.Log
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.example.what_the_fantasy.data.services.ServicesAPI
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.states.AuthUserState import com.example.what_the_fantasy.ui.states.AuthUserState
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@ -10,7 +11,8 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
class AuthUserViewModel : ViewModel(){ class AuthUserViewModel : ViewModel(){
private val services = ServicesStub() // faire repository qui gère les services Stub et API //private val services = ServicesStub()
private val services = ServicesAPI() // faire repository qui gère les services Stub et API
private val _userState = MutableStateFlow(AuthUserState()) private val _userState = MutableStateFlow(AuthUserState())
val userState : StateFlow<AuthUserState> = _userState.asStateFlow() val userState : StateFlow<AuthUserState> = _userState.asStateFlow()
@ -24,7 +26,7 @@ class AuthUserViewModel : ViewModel(){
_userState.update { it.copy(password=password) } _userState.update { it.copy(password=password) }
} }
fun validLogin(username : String, passwd : String, navController: (Int) -> Unit, initialierCurrentUser : (Int) -> Unit) : Boolean{ suspend fun validLogin(username : String, passwd : String, navController: (Int) -> Unit, initialierCurrentUser : (Int) -> Unit, currentUserViewModel: CurrentUserViewModel) : Boolean{
return services.validLogin(username,passwd, navController, initialierCurrentUser) return services.validLogin(username,passwd, navController, initialierCurrentUser,currentUserViewModel)
} }
} }

@ -3,6 +3,8 @@ package com.example.what_the_fantasy.ui.viewModels
import android.util.Log import android.util.Log
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.example.what_the_fantasy.data.model.SrcLanguage 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.services.ServicesAPI
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.states.CurrentUserState import com.example.what_the_fantasy.ui.states.CurrentUserState
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@ -11,21 +13,31 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
class CurrentUserViewModel : ViewModel(){ class CurrentUserViewModel : ViewModel(){
private val services = ServicesStub() // faire repository qui gère les services Stub et API //private val services = ServicesStub()
private val services = ServicesAPI() // faire repository qui gère les services Stub et API
private val _currentUserState = MutableStateFlow(CurrentUserState()) private val _currentUserState = MutableStateFlow(CurrentUserState())
var currentUserState : StateFlow<CurrentUserState> = _currentUserState.asStateFlow() var currentUserState : StateFlow<CurrentUserState> = _currentUserState.asStateFlow()
fun initialiseCurrentUser(index : Int){ suspend fun initialiseCurrentUser(index : Int){
services.getUserById(index)?.let { services.getUserById(index).let {
setId(it.id) setId(it.id)
setUsername(it.username) setUsername(it.username)
setEmail(it.email) setEmail(it.email)
setPassword(it.password) setPassword(it.password)
setLangue(it.langage) setLangue(it.langage) // A rajouter quand on aura le langage
setImage(it.imgUrl) setImage(it.imgUrl)
} }
}
fun setUser(user: User) {
_currentUserState.value = CurrentUserState(
id = user.id,
username = user.username,
email = user.email,
password = user.password,
imagePath = user.imgUrl,
)
} }
fun clearCurrentUser(){ fun clearCurrentUser(){
@ -59,36 +71,44 @@ class CurrentUserViewModel : ViewModel(){
fun editUsername(username : String, index : Int) : Boolean{ suspend fun editUsername(username: String, index: Int): Boolean {
_currentUserState.update {it.copy(username = username)} if (!services.EditUsername(username, index, this)) {
return services.EditUsername(username, index) _currentUserState.update {
it.copy(username = username)
}
return true
}
return false
} }
fun editEmail(email : String, index : Int) : Boolean{ suspend fun editEmail(email : String, index : Int) : Boolean{
_currentUserState.update {
it.copy(email = email) if(!services.EditEmail(email, index, this)){
_currentUserState.update {
it.copy(email = email)
}
return true
} }
return services.EditEmail(email, index) return false
} }
fun editPassword(password : String, index : Int){
services.EditPasswd(password, index) suspend fun editPassword(password : String, index : Int){
services.EditPasswd(password, index, this)
} }
fun editLangue(index : Int){ suspend fun editLangue(index : Int){
val langage = services.ChangeLangage(index) val langage = services.ChangeLangage(index, this)
_currentUserState.update { _currentUserState.update {
it.copy(langage = langage) it.copy(langage = langage)
} }
} }
fun editImage(index : Int){ suspend fun editImage(index : Int){
val image = services.EditImage(index) // _currentUserState.update {
// it.copy(imagePath = services.EditImage(index, this))
_currentUserState.update { // }
it.copy(imagePath = image)
}
} }
} }

@ -1,20 +1,23 @@
package com.example.what_the_fantasy.ui.viewModels package com.example.what_the_fantasy.ui.viewModels
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.example.what_the_fantasy.data.services.ServicesAPI
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.states.SignInUserState import com.example.what_the_fantasy.ui.states.SignInUserState
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
class SignInUserViewModel: ViewModel() { class SignInUserViewModel: ViewModel() {
private val services = ServicesStub() // faire repository qui gère les services Stub et API private val services = ServicesAPI() // faire repository qui gère les services Stub et API
private val _userState = MutableStateFlow(SignInUserState()) private val _userState = MutableStateFlow(SignInUserState())
val userState : StateFlow<SignInUserState> = _userState.asStateFlow() val userState : StateFlow<SignInUserState> = _userState.asStateFlow()
fun createUser(username: String, email: String, passwd: String) : Boolean{ suspend fun createUser(username: String, email: String, passwd: String) : Boolean{
return services.CreateUser(username, email, passwd) return services.CreateUser(username, email, passwd)
} }
fun setUsername(username : String){ fun setUsername(username : String){

@ -3,6 +3,9 @@ agp = "8.6.0"
bcrypt = "0.4" bcrypt = "0.4"
coilCompose = "2.2.1" coilCompose = "2.2.1"
coilComposeVersion = "1.4.0"
converterGson = "2.9.0"
gson = "2.10.1"
kotlin = "1.9.0" kotlin = "1.9.0"
coreKtx = "1.10.1" coreKtx = "1.10.1"
junit = "4.13.2" junit = "4.13.2"
@ -15,12 +18,16 @@ 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" lifecycle = "2.8.0"
retrofit = "2.9.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" }
bcrypt = { module = "org.mindrot:jbcrypt", version.ref = "bcrypt" } bcrypt = { module = "org.mindrot:jbcrypt", version.ref = "bcrypt" }
coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" } coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" }
coil-compose-v140 = { module = "io.coil-kt:coil-compose", version.ref = "coilComposeVersion" }
converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "converterGson" }
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
junit = { group = "junit", name = "junit", version.ref = "junit" } junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
@ -40,6 +47,7 @@ engage-core = { group = "com.google.android.engage", name = "engage-core", versi
android-lifecycle-viewmodel ={ group = "androidx.lifecycle", name ="lifecycle-viewmodel-compose", version.ref ="lifecycle"} 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"} android-lifecycle-viewmodel-runtime-ktx ={ group = "androidx.lifecycle", name ="lifecycle-viewmodel-ktx", version.ref ="lifecycle"}
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
[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