Commencement avec le lien de l'API pour login

ConnectAPI
Leni BEAULATON 2 weeks ago
parent ad5ae952ac
commit 09be084651

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

@ -0,0 +1,51 @@
package com.example.what_the_fantasy.data.retrofit
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.data.model.User
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.Query
data class UserUpdateRequest(
val username: String,
val email: String,
val passwd: String,
val langage: SrcLanguage,
val imgUrl: String
)
interface UserApiService {
@GET("users/username")
suspend fun getUserByUsername(
@Query("username") username: String
): User
@GET("users/")
suspend fun getUserById(
@Query("id") id: Int
): User
@POST("users")
suspend fun updateUser(
@Query("id") id: Int,
@Body userUpdate: UserUpdateRequest
): Response<User>
}
object RetrofitInstance {
private const val BASE_URL = "https://codefirst.iut.uca.fr/containers/WhatTheFantasy-web-services/api/v1/"
val api: UserApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(UserApiService::class.java)
}
}

@ -10,14 +10,14 @@ import kotlinx.coroutines.flow.StateFlow
interface IServices {
fun validLogin(username : String,
suspend fun validLogin(username : String,
passwd : String,
navController: (Int) -> Unit,
initialierCurrentUser : (Int) ->Unit): Boolean
fun EditUsername(username : String, index : Int) : Boolean
fun EditEmail(email : String, index : Int) : Boolean
fun EditPasswd(passwd : String, index : Int)
suspend fun EditUsername(username : String, index : Int) : Boolean
suspend fun EditEmail(email : String, index : Int) : Boolean
suspend fun EditPasswd(passwd : String, index : Int)
fun EditImage(index : Int) : String
fun ChangeLangage(index : Int): SrcLanguage
fun isUsernameExist(username : String) : Boolean
@ -30,11 +30,11 @@ interface IServices {
fun getFavorite(user: User): List<Quote>
fun getAllUsers(): List<User>
fun getComment(quoteId : Int) : List<Comment>
fun getUserById(id: Int): User?
suspend fun getUserById(id: Int): User?
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 getAllQuote(): List<Quote>
fun getSomeQuotes(nb: Int, page: Int) : MutableList<Quote>

@ -1,89 +1,162 @@
package com.example.what_the_fantasy.data.services
import com.example.what_the_fantasy.data.local.UserStub.users
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.data.retrofit.UserUpdateRequest
//import com.example.what_the_fantasy.data.model.Comment
//import com.example.what_the_fantasy.data.model.Favorite
//import com.example.what_the_fantasy.data.model.Quote
//import com.example.what_the_fantasy.data.model.User
////import com.example.what_the_fantasy.ui.navigations.Destination
//class ServicesAPI : IServices {
// override fun EditUsername(username: String, index : Int): Boolean {
// TODO("Not yet implemented")
// }
//
// override fun EditEmail(email: String, index : Int): Boolean {
// TODO("Not yet implemented")
// }
//
// override fun EditPasswd(passwd: String, index : Int) {
// TODO("Not yet implemented")
// }
//
// override fun EditImage(imageURL: String, index : Int) {
// TODO("Not yet implemented")
// }
//
// override fun ChangeLangage(user: User) {
// TODO("Not yet implemented")
// }
//
// override fun AddFav(userId: Int, QuoteId: Int) {
// TODO("Not yet implemented")
// }
//
// override fun SupFav(userId: Int, QuoteId: Int) {
// TODO("Not yet implemented")
// }
//
// override fun AddComment(content: String) {
// TODO("Not yet implemented")
// }
//
// override fun CreateUser(username: String, email: String, passwd: String, services: IServices) : Boolean {
// TODO("Not yet implemented")
// }
//
// override fun getFavorite(user: User): List<Quote> {
// TODO("Not yet implemented")
// }
//
// override fun SearchQuote(quote: String) {
// TODO("Not yet implemented")
// }
//
// override fun getQuote(id: Int): Quote? {
// TODO("Not yet implemented")
// }
//
// override fun isFavorite(id: Int, user: User): Boolean {
// TODO("Not yet implemented")
// }
//
// override fun getAllFavorite(): List<Favorite> {
// TODO("Not yet implemented")
// }
//
// override fun getAllQuote(): List<Quote> {
// TODO("Not yet implemented")
// }
//
// override fun getSomeQuotes(nb: Int, page: Int): MutableList<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 fun getUserById(id: Int): User? {
// TODO("Not yet implemented")
// }
//
// override fun search(type : String ,search:String ,indexCount: Int): List<Quote>{
// TODO("Not yet implemented")
// }
//}
class ServicesAPI : IServices {
override suspend fun validLogin(
username: String,
passwd: String,
navController: (Int) -> Unit,
initialierCurrentUser: (Int) -> Unit
): Boolean {
try {
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
//val hashPassWd = hashPassword(passwd)// hache mot de passe demandé
if (passwd == hashedPasswordAPI) { // on compare les deux mots de passe
navController(index)
initialierCurrentUser(index)
return true
}
else {
return false
}
} catch (e: Exception) {
return false
}
}
override suspend fun EditUsername(username: String, index: Int): Boolean {
try {
val responseOldUser = RetrofitInstance.api.getUserById(index)
val request = UserUpdateRequest(username,
responseOldUser.email,
responseOldUser.password,
responseOldUser.langage,
responseOldUser.imgUrl)
return false
}catch (e: Exception) {
return false
}
}
override suspend fun EditEmail(email: String, index: Int): Boolean {
try {
val responseOldUser = RetrofitInstance.api.getUserById(index)
val request = UserUpdateRequest(responseOldUser.username,
email,
responseOldUser.password,
responseOldUser.langage,
responseOldUser.imgUrl)
return false
}catch (e: Exception) {
return false
}
}
override suspend fun EditPasswd(passwd: String, index: Int) {
try {
val responseOldUser = RetrofitInstance.api.getUserById(index)
val request = UserUpdateRequest(responseOldUser.username,
responseOldUser.email,
passwd,
responseOldUser.langage,
responseOldUser.imgUrl)
}catch (_: Exception) { }
}
override fun EditImage(index: Int): String {
TODO("Not yet implemented")
}
override fun ChangeLangage(index: Int): SrcLanguage {
TODO("Not yet implemented")
}
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 fun CreateUser(username: String, email: String, passwd: String): Boolean {
TODO("Not yet implemented")
}
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 fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
TODO("Not yet implemented")
}
override fun search(type: String, search: String, indexCount: Int): List<Quote> {
TODO("Not yet implemented")
}
}

@ -18,7 +18,7 @@ class ServicesStub : IServices {
val logsUser = LogsUsers() //gestion des logs pour les utilisateurs
override fun validLogin(username : String,
override suspend fun validLogin(username : String,
passwd : String,
navController: (Int) -> Unit,
initialierCurrentUser : (Int) ->Unit): Boolean{
@ -36,7 +36,7 @@ class ServicesStub : IServices {
}
override fun EditUsername(username: String, index : Int) : Boolean{
override suspend fun EditUsername(username: String, index : Int) : Boolean{
val user = getUserById(index)
if(!isUsernameExist(username)){
@ -49,7 +49,7 @@ class ServicesStub : IServices {
return false
}
override fun EditEmail(email: String,index : Int) : Boolean {
override suspend fun EditEmail(email: String, index : Int) : Boolean {
val user = getUserById(index)
if(!isEmailExist(email)){
@ -61,7 +61,7 @@ class ServicesStub : IServices {
return false
}
override fun EditPasswd(passwd: String,index : Int) {
override suspend fun EditPasswd(passwd: String, index : Int) {
val user = getUserById(index)
val passwordhash = hashPassword(passwd)
user?.password = passwordhash
@ -131,7 +131,7 @@ class ServicesStub : IServices {
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 })
}
@ -151,7 +151,7 @@ class ServicesStub : IServices {
return quotes.subList(fromIndex, toIndex).toMutableList()
}
override fun isFavorite(idQuote: Int, idUser: Int): Boolean {
override suspend fun isFavorite(idQuote: Int, idUser: Int): Boolean {
val user = getUserById(idUser) ?: return false
val quote = getFavorite(user)
return quote.find{ it.id == idQuote } != null

@ -8,6 +8,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.NavHost
@ -21,6 +22,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.SearchViewModel
import com.example.what_the_fantasy.ui.viewModels.SignInUserViewModel
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
@Serializable
@ -100,6 +102,7 @@ fun AppNavigator() {
NavHost(navController, startDestination = Login) {
composable<Login> {
val coroutineScope = rememberCoroutineScope()
LoginPage(
navControllerSignUp = { navController.navigate(SignUp) },
navControllerProfil = { userIndex ->
@ -109,7 +112,11 @@ fun AppNavigator() {
},
authUserVM = authUserVM,
authState = authState,
initialierCurrentUser ={currentUserVM.initialiseCurrentUser(it)}
initialierCurrentUser ={
coroutineScope.launch {
currentUserVM.initialiseCurrentUser(it)
}
}
)
}

@ -33,9 +33,10 @@ fun FavoritePage(
currentUserVM : CurrentUserViewModel,
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)
NavBar(onFavorite = true,
@ -65,12 +66,12 @@ fun FavoritePage(
textAlign = TextAlign.Center
)
}
items(quotes) { quote ->
Column(Modifier.clickable { navQuote(quote.id) }) {
QuoteLittle(quote)
Spacer(modifier = Modifier.height(16.dp))
}
}
// items(quotes) { quote ->
// Column(Modifier.clickable { navQuote(quote.id) }) {
// QuoteLittle(quote)
// Spacer(modifier = Modifier.height(16.dp))
// }
// }
}
}
}

@ -21,6 +21,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -44,6 +45,7 @@ import com.example.what_the_fantasy.data.services.hashPassword
import com.example.what_the_fantasy.ui.components.VisibleIconPasswordComponent
import com.example.what_the_fantasy.ui.states.AuthUserState
import com.example.what_the_fantasy.ui.viewModels.AuthUserViewModel
import kotlinx.coroutines.launch
@Composable
fun LoginPage(navControllerSignUp: () -> Unit,
@ -139,9 +141,15 @@ fun PassWdTextField(textpasswdResId : Int, password : String, onValueChange: (St
fun ConnexionButtonLogin(authUserVM : AuthUserViewModel, username : String, passwd : String, titleResId : Int, size : Int, navController: (Int) -> Unit, initialierCurrentUser : (Int) -> Unit){
val title = stringResource(id = titleResId)
var showError by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
Button(
onClick = { showError = !authUserVM.validLogin(username, passwd, navController, initialierCurrentUser)
onClick = {
coroutineScope.launch {
val result = authUserVM.validLogin(username, passwd, navController, initialierCurrentUser)
showError = !result
}
},
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background),
modifier = Modifier
.fillMaxWidth(),

@ -33,6 +33,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -57,6 +58,7 @@ import com.example.what_the_fantasy.ui.components.TitlePageComponent
import com.example.what_the_fantasy.ui.components.VisibleIconPasswordComponent
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import kotlinx.coroutines.launch
@Composable
fun ProfilPage(navFavorite: () -> Unit,
@ -145,14 +147,16 @@ fun EditEmail(emailState: String, index: Int, currentUserVM: CurrentUserViewMode
var originalEmail by remember { mutableStateOf(emailState) }
var isEditingEmail by remember { mutableStateOf(false) }
var emailError by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
fun onDoneEditing() {
coroutineScope.launch {
if (email != originalEmail) {
isEditingEmail = !currentUserVM.editEmail(email, index)
} else {
isEditingEmail = false
}
}
}
if (isEditingEmail) {
EmailEditingField(
@ -235,14 +239,17 @@ fun EditUsername(usernameState: String, index: Int, currentUserVM: CurrentUserVi
var username by remember { mutableStateOf(usernameState) }
var originalUsername by remember { mutableStateOf(usernameState) }
var isEditingUsername by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
fun onDoneEditing() {
coroutineScope.launch {
if (username != originalUsername) {
isEditingUsername = !currentUserVM.editUsername(username, index)
} else {
isEditingUsername = false
}
}
}
if (isEditingUsername) {
UsernameEditingField(
@ -312,13 +319,15 @@ fun EditPasswd(index: Int, currentUserVM: CurrentUserViewModel) {
var confirmPassword by remember { mutableStateOf("") }
var passwordVisible 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
fun onDoneEditing() {
coroutineScope.launch {
// Appeler EditPasswd pour mettre à jour le mot de passe de l'utilisateur
currentUserVM.editPassword(newPassword, index)
isEditingPassword = false
}
}
if (isEditingPassword) {
PasswordEditingFields(

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

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

@ -3,6 +3,7 @@ package com.example.what_the_fantasy.ui.viewModels
import android.util.Log
import androidx.lifecycle.ViewModel
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.data.services.ServicesAPI
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.states.CurrentUserState
import kotlinx.coroutines.flow.MutableStateFlow
@ -11,12 +12,13 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
class CurrentUserViewModel : ViewModel(){
private val services = ServicesStub() // faire repository qui gère les services Stub et API
private val services = ServicesStub()
//private val services = ServicesAPI() // faire repository qui gère les services Stub et API
private val _currentUserState = MutableStateFlow(CurrentUserState())
var currentUserState : StateFlow<CurrentUserState> = _currentUserState.asStateFlow()
fun initialiseCurrentUser(index : Int){
suspend fun initialiseCurrentUser(index : Int){
services.getUserById(index)?.let {
setId(it.id)
setUsername(it.username)
@ -25,7 +27,6 @@ class CurrentUserViewModel : ViewModel(){
setLangue(it.langage)
setImage(it.imgUrl)
}
}
fun clearCurrentUser(){
@ -59,19 +60,19 @@ class CurrentUserViewModel : ViewModel(){
fun editUsername(username : String, index : Int) : Boolean{
suspend fun editUsername(username : String, index : Int) : Boolean{
_currentUserState.update {it.copy(username = username)}
return services.EditUsername(username, index)
}
fun editEmail(email : String, index : Int) : Boolean{
suspend fun editEmail(email : String, index : Int) : Boolean{
_currentUserState.update {
it.copy(email = email)
}
return services.EditEmail(email, index)
}
fun editPassword(password : String, index : Int){
suspend fun editPassword(password : String, index : Int){
services.EditPasswd(password, index)
}

@ -3,6 +3,8 @@ agp = "8.6.0"
bcrypt = "0.4"
coilCompose = "2.2.1"
coilComposeVersion = "1.4.0"
converterGson = "2.9.0"
kotlin = "1.9.0"
coreKtx = "1.10.1"
junit = "4.13.2"
@ -15,12 +17,15 @@ navigationCompose = "2.8.6"
navigationCommonAndroid = "2.9.0-alpha05"
engageCore = "1.5.6"
lifecycle = "2.8.0"
retrofit = "2.9.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
bcrypt = { module = "org.mindrot:jbcrypt", version.ref = "bcrypt" }
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" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
@ -40,6 +45,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-runtime-ktx ={ group = "androidx.lifecycle", name ="lifecycle-viewmodel-ktx", version.ref ="lifecycle"}
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

Loading…
Cancel
Save