Compare commits

..

3 Commits

@ -51,7 +51,7 @@ android {
} }
dependencies { dependencies {
implementation(libs.coil.compose.v140) implementation("io.coil-kt:coil-compose:1.4.0")
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,9 +76,5 @@ 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,11 +1,6 @@
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,37 +1,16 @@
package com.example.what_the_fantasy.data.model package com.example.what_the_fantasy.data.model
import com.google.gson.annotations.SerializedName import java.util.Date
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,
@SerializedName("type") val date: Int
val type: SrcType ,
@SerializedName("dateSource")
val date: Int,
@SerializedName("isValide")
val isValide : Boolean = true
) )

@ -1,31 +1,6 @@
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,50 +2,9 @@ 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,22 +1,11 @@
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
) )

@ -1,107 +0,0 @@
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)
}
}

@ -1,17 +0,0 @@
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,41 +6,38 @@ 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 {
suspend fun validLogin(username : String, fun validLogin(username : String,
passwd : String, passwd : String,
navController: (Int) -> Unit, navController: (Int) -> Unit,
initialierCurrentUser : (Int) ->Unit, initialierCurrentUser : (Int) ->Unit): Boolean
currentUserViewModel: CurrentUserViewModel
): Boolean fun EditUsername(username : String, index : Int) : Boolean
fun EditEmail(email : String, index : Int) : Boolean
suspend fun EditUsername(username : String, index : Int, currentUserViewModel: CurrentUserViewModel) : Boolean fun EditPasswd(passwd : String, index : Int)
suspend fun EditEmail(email : String, index : Int,currentUserViewModel: CurrentUserViewModel) : Boolean fun EditImage(index : Int) : String
suspend fun EditPasswd(passwd : String, index : Int,currentUserViewModel : CurrentUserViewModel): Boolean fun ChangeLangage(index : Int): SrcLanguage
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)
suspend fun CreateUser(username : String, email : String, passwd : String) : Boolean fun CreateUser(username : String, email : String, passwd : String) : Boolean
fun getFavorite(user: User): List<Quote> fun getFavorite(user: User): List<Quote>
fun getAllUsers(): List<User> fun getAllUsers(): List<User>
fun getComment(quoteId : Int) : List<Comment> fun getComment(quoteId : Int) : List<Comment>
suspend fun getUserById(id: Int): User? fun getUserById(id: Int): User?
fun getQuote( id : Int): Quote? fun getQuote( id : Int): Quote?
suspend fun isFavorite(idQuote : Int, iduser: Int): Boolean fun isFavorite(idQuote : Int, iduser: Int): Boolean
fun getAllFavorite(): List<Favorite> fun getAllFavorite(): List<Favorite>
fun getAllQuote(): List<Quote> fun getAllQuote(): List<Quote>
suspend fun getSomeQuotes(nb: Int, page: Int) : MutableList<Quote> 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,302 +1,89 @@
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 {
override suspend fun validLogin( // TODO("Not yet implemented")
username: String, // }
passwd: String, //
navController: (Int) -> Unit, // override fun EditEmail(email: String, index : Int): Boolean {
initialierCurrentUser: (Int) -> Unit, // TODO("Not yet implemented")
currentUserViewModel: CurrentUserViewModel // }
): Boolean { //
try { // override fun EditPasswd(passwd: String, index : Int) {
val response = RetrofitInstance.api.getUserByUsername(username) // on récupère l'utilisateur // TODO("Not yet implemented")
val hashedPasswordAPI = response.password // récupère le mot de passe de l'api // }
val index =response.id //
//val hashPassWd = hashPassword(passwd)// hache mot de passe demandé // override fun EditImage(imageURL: String, index : Int) {
// TODO("Not yet implemented")
if (passwd == hashedPasswordAPI) { // on compare les deux mots de passe // }
navController(index) //
initialierCurrentUser(index) // override fun ChangeLangage(user: User) {
currentUserViewModel.setUser(response) // TODO("Not yet implemented")
return true // }
} //
else { // override fun AddFav(userId: Int, QuoteId: Int) {
return false // TODO("Not yet implemented")
} // }
} catch (e: Exception) { //
return false // override fun SupFav(userId: Int, QuoteId: Int) {
} // TODO("Not yet implemented")
} // }
//
override suspend fun EditUsername(username: String, index: Int, currentUserViewModel: CurrentUserViewModel): Boolean { // override fun AddComment(content: String) {
try { // TODO("Not yet implemented")
val userExistsResponse = RetrofitInstance.api.checkIfUsernameExists(username) // }
//
Log.d("EditUsername", "Username check: $username exists = $userExistsResponse") // override fun CreateUser(username: String, email: String, passwd: String, services: IServices) : Boolean {
// TODO("Not yet implemented")
if (userExistsResponse) { // }
Log.d("EditUsername", "Username $username already exists, cannot update.") //
return false // override fun getFavorite(user: User): List<Quote> {
} // TODO("Not yet implemented")
// }
val responseUser = RetrofitInstance.api.getUserById(index) //
// override fun SearchQuote(quote: String) {
val updatedUser = User( // TODO("Not yet implemented")
id = index, // }
username = username, // Nouveau nom d'utilisateur //
email = responseUser.email, // override fun getQuote(id: Int): Quote? {
password = responseUser.password, // TODO("Not yet implemented")
imgUrl = responseUser.imgUrl, // }
langage = responseUser.langage, //
date = responseUser.date // override fun isFavorite(id: Int, user: User): Boolean {
) // TODO("Not yet implemented")
// }
val response = RetrofitInstance.api.updateUsername(index, updatedUser) //
// override fun getAllFavorite(): List<Favorite> {
if (response.isSuccessful) { // TODO("Not yet implemented")
currentUserViewModel.setUser(updatedUser) // }
Log.d("EditUsername", "Username updated successfully.") //
return true // override fun getAllQuote(): List<Quote> {
} else { // TODO("Not yet implemented")
Log.d("EditUsername", "Failed to update username, API response not successful.") // }
return false //
} // override fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
} catch (e: Exception) { // TODO("Not yet implemented")
e.printStackTrace() // }
Log.d("EditUsername", "Exception occurred: ${e.message}") //
return false // override fun getAllUsers(): List<User> {
} // TODO("Not yet implemented")
} // }
//
// override fun getComment(quoteId: Int): List<Comment> {
override suspend fun EditEmail(email: String, index: Int,currentUserViewModel: CurrentUserViewModel): Boolean { // TODO("Not yet implemented")
try { // }
val userExistsResponse = RetrofitInstance.api.checkIfEmailExists(email) //
// override fun getUserById(id: Int): User? {
if (userExistsResponse) { // TODO("Not yet implemented")
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,19 +12,16 @@ 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 suspend fun validLogin(username : String, override fun validLogin(username : String,
passwd : String, passwd : String,
navController: (Int) -> Unit, navController: (Int) -> Unit,
initialierCurrentUser : (Int) ->Unit, initialierCurrentUser : (Int) ->Unit): Boolean{
currentUserViewModel: CurrentUserViewModel
): Boolean{
users.forEachIndexed { index, user -> users.forEachIndexed { index, user ->
val hashPassWd = hashPassword(passwd) val hashPassWd = hashPassword(passwd)
@ -39,7 +36,7 @@ class ServicesStub : IServices {
} }
override suspend fun EditUsername(username: String, index : Int,currentUserViewModel: CurrentUserViewModel) : Boolean{ override fun EditUsername(username: String, index : Int) : Boolean{
val user = getUserById(index) val user = getUserById(index)
if(!isUsernameExist(username)){ if(!isUsernameExist(username)){
@ -52,7 +49,7 @@ class ServicesStub : IServices {
return false return false
} }
override suspend fun EditEmail(email: String, index : Int,currentUserViewModel: CurrentUserViewModel) : Boolean { override fun EditEmail(email: String,index : Int) : Boolean {
val user = getUserById(index) val user = getUserById(index)
if(!isEmailExist(email)){ if(!isEmailExist(email)){
@ -64,20 +61,20 @@ class ServicesStub : IServices {
return false return false
} }
override suspend fun EditPasswd(passwd: String, index: Int, currentUserViewModel: CurrentUserViewModel): Boolean { override fun EditPasswd(passwd: String,index : Int) {
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 suspend fun EditImage(index : Int,currentUserViewModel : CurrentUserViewModel) : String { override fun EditImage(index : Int) : String {
return randomImage() return randomImage()
} }
override suspend fun ChangeLangage(index : Int,currentUserViewModel : CurrentUserViewModel) : SrcLanguage{ override fun ChangeLangage(index : Int) : SrcLanguage{
if(getAllUsers()[index].langage == SrcLanguage.vo){ if(getAllUsers()[index].langage == SrcLanguage.vo){
getAllUsers()[index].langage = SrcLanguage.vf getAllUsers()[index].langage = SrcLanguage.vf
} }
@ -104,14 +101,16 @@ class ServicesStub : IServices {
} }
override suspend fun CreateUser(username: String, email: String, passwd: String) : Boolean { override fun CreateUser(username: String, email: String, passwd: String) : Boolean {
val date =dateDuJour() val date =dateDuJour()
val passwordhash = hashPassword(passwd) val passwordhash = hashPassword(passwd)
val services = ServicesStub() val services = ServicesStub()
val userStub = services.getAllUsers() val userStub = services.getAllUsers()
val nbUser = userStub.size val nbUser = userStub.size
if(username == "" || email == "" || passwd == ""){
return false
}
if(!isUsernameExist(username) && !isEmailExist(email)){ if(!isUsernameExist(username) && !isEmailExist(email)){
val user = User(nbUser,username, email, date,randomImage(), passwordhash, SrcLanguage.vo) val user = User(nbUser,username, email, date,randomImage(), passwordhash, SrcLanguage.vo)
users.add(user)//ajout au stub users.add(user)//ajout au stub
@ -134,7 +133,7 @@ class ServicesStub : IServices {
override fun getComment(quoteId: Int): List<Comment> = comments override fun getComment(quoteId: Int): List<Comment> = comments
override suspend fun getUserById(id: Int): User? { override fun getUserById(id: Int): User? {
return (users.find { it.id == id }) return (users.find { it.id == id })
} }
@ -143,23 +142,21 @@ class ServicesStub : IServices {
return (quotes.find { it.id == id }) return (quotes.find { it.id == id })
} }
override suspend fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> { override fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
var nbQuote = nb var nbQuote = nb
var nbPage = page
if(nb < 0) nbQuote = 1 if(nb < 0) nbQuote = 1
if(nbPage < 0) nbPage = 1
val fromIndex = (page - 1) * nbQuote val fromIndex = (nbPage - 1) * nbQuote
val toIndex = minOf(page * nbQuote, quotes.size) val toIndex = minOf(nbPage * nbQuote, quotes.size)
if (fromIndex >= quotes.size) return mutableListOf() if (fromIndex >= quotes.size) return mutableListOf()
return quotes.subList(fromIndex, toIndex).toMutableList() return quotes.subList(fromIndex, toIndex).toMutableList()
} }
override suspend fun getDalyQuote(langage: SrcLanguage): Quote { override fun isFavorite(idQuote: Int, idUser: Int): Boolean {
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,6 +1,5 @@
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
@ -9,14 +8,12 @@ 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
@ -24,7 +21,6 @@ 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
@ -74,8 +70,7 @@ data class RecapSubmit(val userIndex: Int,
@Composable @Composable
fun AppNavigator() { fun AppNavigator() {
val navController = rememberNavController() val navController = rememberNavController()
val servicesStub = ServicesStub() val services = ServicesStub()
val services = ServicesAPI()
//ViewModel pour l'authentification //ViewModel pour l'authentification
val authUserVM : AuthUserViewModel = viewModel() val authUserVM : AuthUserViewModel = viewModel()
@ -105,7 +100,6 @@ 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 ->
@ -115,12 +109,7 @@ fun AppNavigator() {
}, },
authUserVM = authUserVM, authUserVM = authUserVM,
authState = authState, authState = authState,
currentUserViewModel = currentUserVM, initialierCurrentUser ={currentUserVM.initialiseCurrentUser(it)}
initialierCurrentUser ={
coroutineScope.launch {
currentUserVM.initialiseCurrentUser(it)
}
}
) )
} }
@ -159,7 +148,7 @@ fun AppNavigator() {
) )
}, },
navSearch = { navController.navigate(Search(currentUserState.id))}, navSearch = { navController.navigate(Search(currentUserState.id))},
services = servicesStub, services = services,
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
) )
@ -189,7 +178,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 = servicesStub, service = services,
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
navSearch = { navController.navigate(Search(currentUserState.id))}, navSearch = { navController.navigate(Search(currentUserState.id))},

@ -1,7 +1,5 @@
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.*
@ -21,19 +19,14 @@ 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,
@ -46,13 +39,12 @@ 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(0) } val page = remember { mutableIntStateOf(1) }
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 } }
@ -61,10 +53,6 @@ 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) {
@ -99,35 +87,20 @@ fun AccueilPage(
.background(MaterialTheme.colorScheme.background) .background(MaterialTheme.colorScheme.background)
) { ) {
LazyColumn(modifier = Modifier.weight(1f), state = state) { LazyColumn(modifier = Modifier.weight(1f), state = state) {
if(dailyQuote.value.id!=-1) { item {
item { Column(Modifier.clickable { navQuote(dailyQuote.id) }) {
Column(Modifier.clickable { navQuote(dailyQuote.value.id) }) { Text(
Text( text = titleDalyQuote,
text = titleDalyQuote, color = MaterialTheme.colorScheme.onBackground,
color = MaterialTheme.colorScheme.onBackground, fontSize = 24.sp,
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),
contentAlignment = Alignment.Center textAlign = TextAlign.Center
) { )
CircularProgressIndicator() QuoteLittle(dailyQuote)
}
} }
}
item {
Text( Text(
text = titleSuggestion, text = titleSuggestion,
color = MaterialTheme.colorScheme.onBackground, color = MaterialTheme.colorScheme.onBackground,

@ -33,10 +33,9 @@ fun FavoritePage(
currentUserVM : CurrentUserViewModel, currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState, currentUserState : CurrentUserState,
) { ) {
val user = services.getUserById(currentUserState.id) ?: return
//val user = services.getUserById(currentUserState.id) ?: return val quotes = services.getFavorite(user)
//val quotes = services.getFavorite(user)
val titlePage = stringResource(R.string.TitleFavorite) val titlePage = stringResource(R.string.TitleFavorite)
NavBar(onFavorite = true, NavBar(onFavorite = true,
@ -66,12 +65,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,7 +21,6 @@ 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
@ -45,15 +44,12 @@ 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) {
@ -81,7 +77,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,currentUserViewModel,navControllerProfil){ }, R.string.ButtonLogin,18,navControllerProfil){
initialierCurrentUser(it) initialierCurrentUser(it)
} }
SpaceHeightComponent(16) SpaceHeightComponent(16)
@ -140,25 +136,12 @@ fun PassWdTextField(textpasswdResId : Int, password : String, onValueChange: (St
@Composable @Composable
fun ConnexionButtonLogin(authUserVM : AuthUserViewModel, fun ConnexionButtonLogin(authUserVM : AuthUserViewModel, username : String, passwd : String, titleResId : Int, size : Int, navController: (Int) -> Unit, initialierCurrentUser : (Int) -> Unit){
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 = { onClick = { showError = !authUserVM.validLogin(username, passwd, navController, initialierCurrentUser)
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,7 +33,6 @@ 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
@ -58,8 +57,6 @@ 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,
@ -132,18 +129,13 @@ 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{ .clickable{currentUserVM.editImage(index)}
coroutineScope.launch {
currentUserVM.editImage(index)
}
}
) )
} }
@ -153,14 +145,12 @@ 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() {
coroutineScope.launch { if (email != originalEmail) {
if (email != originalEmail) { isEditingEmail = !currentUserVM.editEmail(email, index)
isEditingEmail = !currentUserVM.editEmail(email, index) } else {
} else { isEditingEmail = false
isEditingEmail = false
}
} }
} }
@ -245,15 +235,12 @@ 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() {
coroutineScope.launch { if (username != originalUsername) {
if (username != originalUsername) { isEditingUsername = !currentUserVM.editUsername(username, index)
isEditingUsername = !currentUserVM.editUsername(username, index) } else {
} else { isEditingUsername = false
isEditingUsername = false
}
} }
} }
@ -325,14 +312,12 @@ 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() {
coroutineScope.launch { // Appeler EditPasswd pour mettre à jour le mot de passe de l'utilisateur
// Appeler EditPasswd pour mettre à jour le mot de passe de l'utilisateur currentUserVM.editPassword(newPassword, index)
currentUserVM.editPassword(newPassword, index) isEditingPassword = false
isEditingPassword = false
}
} }
if (isEditingPassword) { if (isEditingPassword) {
@ -495,12 +480,10 @@ 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,7 +26,6 @@ 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
@ -48,7 +47,6 @@ 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) {
@ -93,7 +91,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, MaterialTheme.colorScheme.onBackground, navController = navControllerLogin) ReturnLogin(R.string.ButtonLogin,12, Color.White, navController = navControllerLogin)
} }
} }
@ -221,21 +219,17 @@ fun ConnexionButtonSign(
val invalidRegex = """^[a-zA-Z0-9]*$""".toRegex() val invalidRegex = """^[a-zA-Z0-9]*$""".toRegex()
val coroutineScope = rememberCoroutineScope()
Button( Button(
onClick = { onClick = {
coroutineScope.launch { emailError = !isValidEmail(email)
emailError = !isValidEmail(email) passwordError = !arePasswordsMatching(password, confirmPassword)
passwordError = !arePasswordsMatching(password, confirmPassword) usernameError = username.isBlank() && !username.matches(invalidRegex)
usernameError = username.isBlank() && !username.matches(invalidRegex) passwordErrorEmpty = password.isBlank() || confirmPassword.isBlank()
passwordErrorEmpty = password.isBlank() || confirmPassword.isBlank()
if (!emailError && !passwordError && !usernameError && !passwordErrorEmpty) {
if (!emailError && !passwordError && !usernameError && !passwordErrorEmpty) { usernameErrorExist = !viewModel.createUser(username, email, password)
usernameErrorExist = !viewModel.createUser(username, email, password) if(!usernameErrorExist){
if (!usernameErrorExist) { navController() // retour à la page login
navController() // retour à la page login
}
} }
} }
}, },

@ -2,7 +2,6 @@ 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
@ -11,8 +10,7 @@ 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() 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(AuthUserState()) private val _userState = MutableStateFlow(AuthUserState())
val userState : StateFlow<AuthUserState> = _userState.asStateFlow() val userState : StateFlow<AuthUserState> = _userState.asStateFlow()
@ -26,7 +24,7 @@ class AuthUserViewModel : ViewModel(){
_userState.update { it.copy(password=password) } _userState.update { it.copy(password=password) }
} }
suspend fun validLogin(username : String, passwd : String, navController: (Int) -> Unit, initialierCurrentUser : (Int) -> Unit, currentUserViewModel: CurrentUserViewModel) : Boolean{ fun validLogin(username : String, passwd : String, navController: (Int) -> Unit, initialierCurrentUser : (Int) -> Unit) : Boolean{
return services.validLogin(username,passwd, navController, initialierCurrentUser,currentUserViewModel) return services.validLogin(username,passwd, navController, initialierCurrentUser)
} }
} }

@ -3,8 +3,6 @@ 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
@ -13,31 +11,21 @@ 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() 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 _currentUserState = MutableStateFlow(CurrentUserState()) private val _currentUserState = MutableStateFlow(CurrentUserState())
var currentUserState : StateFlow<CurrentUserState> = _currentUserState.asStateFlow() var currentUserState : StateFlow<CurrentUserState> = _currentUserState.asStateFlow()
suspend fun initialiseCurrentUser(index : Int){ 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) // A rajouter quand on aura le langage setLangue(it.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(){
@ -71,44 +59,36 @@ class CurrentUserViewModel : ViewModel(){
suspend fun editUsername(username: String, index: Int): Boolean { fun editUsername(username : String, index : Int) : Boolean{
if (!services.EditUsername(username, index, this)) { _currentUserState.update {it.copy(username = username)}
_currentUserState.update { return services.EditUsername(username, index)
it.copy(username = username)
}
return true
}
return false
} }
suspend fun editEmail(email : String, index : Int) : Boolean{ fun editEmail(email : String, index : Int) : Boolean{
_currentUserState.update {
if(!services.EditEmail(email, index, this)){ it.copy(email = email)
_currentUserState.update {
it.copy(email = email)
}
return true
} }
return false return services.EditEmail(email, index)
} }
fun editPassword(password : String, index : Int){
suspend fun editPassword(password : String, index : Int){ services.EditPasswd(password, index)
services.EditPasswd(password, index, this)
} }
suspend fun editLangue(index : Int){ fun editLangue(index : Int){
val langage = services.ChangeLangage(index, this) val langage = services.ChangeLangage(index)
_currentUserState.update { _currentUserState.update {
it.copy(langage = langage) it.copy(langage = langage)
} }
} }
suspend fun editImage(index : Int){ fun editImage(index : Int){
// _currentUserState.update { val image = services.EditImage(index)
// it.copy(imagePath = services.EditImage(index, this))
// } _currentUserState.update {
it.copy(imagePath = image)
}
} }
} }

@ -1,23 +1,20 @@
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 = ServicesAPI() // faire repository qui gère les services Stub et API private val services = ServicesStub() // 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()
suspend fun createUser(username: String, email: String, passwd: String) : Boolean{ 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){

@ -4,16 +4,24 @@ import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
import com.example.what_the_fantasy.data.services.IServices import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.data.services.ServicesStub import com.example.what_the_fantasy.data.services.ServicesStub
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
class UnitTestQuote { class UnitTestQuote {
private val services : IServices = ServicesStub() private val services : IServices = ServicesStub()
@Test @Test
fun testGetQuote(){ fun testGetQuote_OK(){
val quote = services.getQuote(1) val quote = services.getQuote(1)
assertEquals("All we have to decide is what to do with the time that is given us.",quote?.content) assertEquals("All we have to decide is what to do with the time that is given us.",quote?.content)
} }
@Test
fun testGetQuote_Fake(){
val quote = services.getQuote(-1)
assertEquals(null,quote?.content)
}
@Test @Test
fun testGetSomeQuote_OK(){ fun testGetSomeQuote_OK(){
val quote = services.getSomeQuotes(4,1) val quote = services.getSomeQuotes(4,1)
@ -21,13 +29,19 @@ class UnitTestQuote {
} }
@Test @Test
fun testGetSomeQuoteNegatif(){ fun testGetSomeQuoteIndexNegatif(){
val quote = services.getSomeQuotes(-1,1) val quote = services.getSomeQuotes(-1,1)
assertEquals(1,quote.size) assertEquals(1,quote.size)
} }
@Test @Test
fun testGetSomeQuote0(){ fun testGetSomeQuotePageNegatif(){
val quote = services.getSomeQuotes(1,-1)
assertEquals(1,quote.size)
}
@Test
fun testGetSomeQuoteIndex0(){
val quote = services.getSomeQuotes(0,1) val quote = services.getSomeQuotes(0,1)
assertEquals(0,quote.size) assertEquals(0,quote.size)
} }
@ -126,5 +140,22 @@ class UnitTestQuote {
assertEquals(0,quote.size) assertEquals(0,quote.size)
} }
@Test
fun testIsFavorite_OK(){
assertTrue(services.isFavorite(1,10))
}
@Test
fun testIsFavorite_FakeQuote(){
assertFalse(services.isFavorite(-1,10))
}
@Test
fun testIsFavorite_FakeUser(){
assertFalse(services.isFavorite(1,-1))
}
} }

@ -34,6 +34,23 @@ class UnitTestUser {
) )
} }
@Test
fun testCreateUserEmptyUsername(){
assertFalse(services.CreateUser("", "email", "passwd")
)
}
@Test
fun testCreateUserEmptyEmail(){
assertFalse(services.CreateUser("usernameEmptyEmail", "", "passwd")
)
}
@Test
fun testCreateUserEmptyPassword(){
assertFalse(services.CreateUser("usernameEmptyPassword", "email", "")
)
}
@Test @Test
fun testUserEditUsername_OK(){ fun testUserEditUsername_OK(){
services.CreateUser("username4", "email4", "passwd") services.CreateUser("username4", "email4", "passwd")

@ -3,9 +3,6 @@ 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"
@ -18,16 +15,12 @@ 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" }
@ -47,7 +40,6 @@ 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