Merge avec master

pull/51/head
Leni BEAULATON 3 weeks ago
commit daf45f2fd2

@ -0,0 +1,39 @@
package com.example.what_the_fantasy.data.local
import com.example.what_the_fantasy.data.model.Comment
import com.example.what_the_fantasy.data.model.User
object CommentStub {
val comments: MutableList<Comment> = mutableListOf(
Comment("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Trop bien","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("encore un Test","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Je suis la ","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("J'en ai rien a foutre de la citation","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Android c'est bien","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("je sais plus quoi mettre donc ca va être le bordel","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Et un test de plus","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("La bombe à été activer","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("J'aime pas les *****","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Test","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Trop bien","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("encore un Test","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Je suis la ","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("J'en ai rien a foutre de la citation","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Android c'est bien","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("je sais plus quoi mettre donc ca va être le bordel","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Et un test de plus","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("La bombe à été activer","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("J'aime pas les *****","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Test","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Trop bien","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("encore un Test","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Je suis la ","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("J'en ai rien a foutre de la citation","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Android c'est bien","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("je sais plus quoi mettre donc ca va être le bordel","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("Et un test de plus","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("La bombe à été activer","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
Comment("J'aime pas les *****","Dev","21-12-2005", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"),
)
}

@ -6,7 +6,7 @@ import com.example.what_the_fantasy.data.model.Favorite
object FavoriteStub {
val favorites: MutableList<Favorite> = mutableListOf(
Favorite(users[0], mutableListOf(quotes[0], quotes[0], quotes[0])), // Aragorn123 aime ces citations
Favorite(users[0], mutableListOf(quotes[0], quotes[1], quotes[12])), // Aragorn123 aime ces citations
Favorite(users[1], mutableListOf(quotes[5], quotes[6], quotes[7])), // Legolas456 aime ces citations
Favorite(users[2], mutableListOf(quotes[8], quotes[9], quotes[10])), // Gandalf789 aime ces citations
Favorite(users[3], mutableListOf(quotes[11], quotes[12], quotes[13])), // FrodoBaggins aime ces citations

@ -97,4 +97,6 @@ object QuestionStub {
val allQuestions: List<Question> = listOf(
question1, question2, question3, question4, question5, question6, question7, question8, question9, question10
)
val shuffleRandomQuestions: List<Question> = allQuestions.shuffled().take(10)
}

@ -7,7 +7,7 @@ import com.example.what_the_fantasy.data.model.SrcType
object QuoteStub {
val quotes: MutableList<Quote> = mutableListOf(
Quote(1,"All we have to decide is what to do with the time that is given us.",466,SrcLanguage.vo,CharacterStub.gandalf.name,"The Lord of the Rings: The Fellowship of the Ring",CharacterStub.gandalf.imgUrl,SrcType.Movie,2000),
Quote(1, "All we have to decide is what to do with the time that is given us.", 466, SrcLanguage.vo, CharacterStub.gandalf.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.gandalf.imgUrl, SrcType.Movie, 2000),
Quote(2, "A wizard is never late, nor is he early, he arrives precisely when he means to.", 467, SrcLanguage.vo, CharacterStub.gandalf.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.gandalf.imgUrl, SrcType.Movie, 2000),
Quote(3, "Even the smallest person can change the course of the future.", 466, SrcLanguage.vo, CharacterStub.galadriel.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.galadriel.imgUrl, SrcType.Movie, 2000),
Quote(4, "I would rather share one lifetime with you than face all the ages of this world alone.", 120, SrcLanguage.vo, CharacterStub.arwen.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.arwen.imgUrl, SrcType.Movie, 2000),
@ -26,6 +26,47 @@ object QuoteStub {
Quote(17, "Le courage n'est pas l'absence de peur, mais la capacité de vaincre ce qui fait peur.", 300, SrcLanguage.vf, CharacterStub.boromir.name, "Nelson Mandela", CharacterStub.boromir.imgUrl, SrcType.Movie, 2000),
Quote(18, "La folie, c'est de faire toujours la même chose et de s'attendre à un résultat différent.", 400, SrcLanguage.vf, CharacterStub.eowyn.name, "Albert Einstein", CharacterStub.eowyn.imgUrl, SrcType.Movie, 2000),
Quote(19, "Le bonheur n'est pas quelque chose de tout fait. Il vient de vos propres actions.", 500, SrcLanguage.vo, CharacterStub.saruman.name, "Dalaï Lama", CharacterStub.saruman.imgUrl, SrcType.Movie, 2000),
Quote(20, "La vie est un mystère qu'il faut vivre, et non un problème à résoudre.", 600, SrcLanguage.vo, CharacterStub.samwiseGamgee.name, "Gandhi", CharacterStub.samwiseGamgee.imgUrl, SrcType.Movie, 2000)
Quote(20, "La vie est un mystère qu'il faut vivre, et non un problème à résoudre.", 600, SrcLanguage.vo, CharacterStub.samwiseGamgee.name, "Gandhi", CharacterStub.samwiseGamgee.imgUrl, SrcType.Movie, 2000),
Quote(21, "All we have to decide is what to do with the time that is given us.", 466, SrcLanguage.vf, CharacterStub.gandalf.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.gandalf.imgUrl, SrcType.Movie, 2000),
Quote(22, "A wizard is never late, nor is he early, he arrives precisely when he means to.", 467, SrcLanguage.vf, CharacterStub.gandalf.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.gandalf.imgUrl, SrcType.Movie, 2000),
Quote(23, "Even the smallest person can change the course of the future.", 466, SrcLanguage.vf, CharacterStub.galadriel.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.galadriel.imgUrl, SrcType.Movie, 2000),
Quote(24, "I would rather share one lifetime with you than face all the ages of this world alone.", 120, SrcLanguage.vf, CharacterStub.arwen.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.arwen.imgUrl, SrcType.Movie, 2000),
Quote(25, "Faithless is he that says farewell when the road darkens.", 150, SrcLanguage.vf, CharacterStub.gimli.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.gimli.imgUrl, SrcType.Movie, 2000),
Quote(26, "It's a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there's no knowing where you might be swept off to.", 200, SrcLanguage.vf, CharacterStub.frodoBaggins.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.frodoBaggins.imgUrl, SrcType.Movie, 2000),
Quote(27, "I am no man.", 300, SrcLanguage.vf, CharacterStub.eowyn.name, "The Lord of the Rings: The Return of the King", CharacterStub.eowyn.imgUrl, SrcType.Movie, 2000),
Quote(28, "The world is changed. I feel it in the water. I feel it in the earth. I smell it in the air.", 400, SrcLanguage.vf, CharacterStub.treebeard.name, "The Lord of the Rings: The Two Towers", CharacterStub.treebeard.imgUrl, SrcType.Movie, 2000),
Quote(29, "We wants it, we needs it. Must have the precious.", 500, SrcLanguage.vf, CharacterStub.gollum.name, "The Lord of the Rings: The Two Towers", CharacterStub.gollum.imgUrl, SrcType.Movie, 2000),
Quote(30, "The board is set, the pieces are moving. We come to it at last, the great battle of our time.", 600, SrcLanguage.vf, CharacterStub.gandalf.name, "The Lord of the Rings: The Return of the King", CharacterStub.gandalf.imgUrl, SrcType.Movie, 2000),
Quote(31, "Un grand pouvoir implique de grandes responsabilités.", 466, SrcLanguage.vo, CharacterStub.aragorn.name, "Spider-Man", CharacterStub.aragorn.imgUrl, SrcType.Series, 2000),
Quote(32, "Que la Force soit avec toi.", 467, SrcLanguage.vo, CharacterStub.legolas.name, "Star Wars", CharacterStub.legolas.imgUrl, SrcType.Movie, 2000),
Quote(33, "La magie est partout. Il suffit de savoir où la trouver.", 466, SrcLanguage.vo, CharacterStub.gandalf.name, "Harry Potter", CharacterStub.gandalf.imgUrl, SrcType.Movie, 2000),
Quote(34, "Le monde est plein de choses magiques, patientant que nos sens s'aiguisent.", 120, SrcLanguage.vo, CharacterStub.frodoBaggins.name, "Le Seigneur des Anneaux", CharacterStub.frodoBaggins.imgUrl, SrcType.Movie, 2000),
Quote(35, "La peur mène à la colère, la colère mène à la haine, la haine mène à la souffrance.", 150, SrcLanguage.vo, CharacterStub.gimli.name, "Star Wars", CharacterStub.gimli.imgUrl, SrcType.Movie, 2000),
Quote(36, "La vie est une aventure audacieuse ou rien du tout.", 200, SrcLanguage.vo, CharacterStub.galadriel.name, "Helen Keller", CharacterStub.galadriel.imgUrl, SrcType.Movie, 2000),
Quote(37, "Le courage n'est pas l'absence de peur, mais la capacité de vaincre ce qui fait peur.", 300, SrcLanguage.vo, CharacterStub.boromir.name, "Nelson Mandela", CharacterStub.boromir.imgUrl, SrcType.Movie, 2000),
Quote(38, "La folie, c'est de faire toujours la même chose et de s'attendre à un résultat différent.", 400, SrcLanguage.vo, CharacterStub.eowyn.name, "Albert Einstein", CharacterStub.eowyn.imgUrl, SrcType.Movie, 2000),
Quote(39, "Le bonheur n'est pas quelque chose de tout fait. Il vient de vos propres actions.", 500, SrcLanguage.vf, CharacterStub.saruman.name, "Dalaï Lama", CharacterStub.saruman.imgUrl, SrcType.Movie, 2000),
Quote(40, "La vie est un mystère qu'il faut vivre, et non un problème à résoudre.", 600, SrcLanguage.vf, CharacterStub.samwiseGamgee.name, "Gandhi", CharacterStub.samwiseGamgee.imgUrl, SrcType.Movie, 2000),
Quote(41, "All we have to decide is what to do with the time that is given us.", 466, SrcLanguage.vo, CharacterStub.gandalf.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.gandalf.imgUrl, SrcType.Movie, 2000),
Quote(42, "A wizard is never late, nor is he early, he arrives precisely when he means to.", 467, SrcLanguage.vo, CharacterStub.gandalf.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.gandalf.imgUrl, SrcType.Movie, 2000),
Quote(43, "Even the smallest person can change the course of the future.", 466, SrcLanguage.vo, CharacterStub.galadriel.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.galadriel.imgUrl, SrcType.Movie, 2000),
Quote(44, "I would rather share one lifetime with you than face all the ages of this world alone.", 120, SrcLanguage.vo, CharacterStub.arwen.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.arwen.imgUrl, SrcType.Movie, 2000),
Quote(45, "Faithless is he that says farewell when the road darkens.", 150, SrcLanguage.vo, CharacterStub.gimli.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.gimli.imgUrl, SrcType.Movie, 2000),
Quote(46, "It's a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there's no knowing where you might be swept off to.", 200, SrcLanguage.vo, CharacterStub.frodoBaggins.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.frodoBaggins.imgUrl, SrcType.Movie, 2000),
Quote(47, "I am no man.", 300, SrcLanguage.vo, CharacterStub.eowyn.name, "The Lord of the Rings: The Return of the King", CharacterStub.eowyn.imgUrl, SrcType.Movie, 2000),
Quote(48, "The world is changed. I feel it in the water. I feel it in the earth. I smell it in the air.", 400, SrcLanguage.vo, CharacterStub.treebeard.name, "The Lord of the Rings: The Two Towers", CharacterStub.treebeard.imgUrl, SrcType.Movie, 2000),
Quote(49, "We wants it, we needs it. Must have the precious.", 500, SrcLanguage.vo, CharacterStub.gollum.name, "The Lord of the Rings: The Two Towers", CharacterStub.gollum.imgUrl, SrcType.Movie, 2000),
Quote(50, "The board is set, the pieces are moving. We come to it at last, the great battle of our time.", 600, SrcLanguage.vo, CharacterStub.gandalf.name, "The Lord of the Rings: The Return of the King", CharacterStub.gandalf.imgUrl, SrcType.Movie, 2000),
Quote(51, "Un grand pouvoir implique de grandes responsabilités.", 466, SrcLanguage.vf, CharacterStub.aragorn.name, "Spider-Man", CharacterStub.aragorn.imgUrl, SrcType.Series, 2000),
Quote(52, "Que la Force soit avec toi.", 467, SrcLanguage.vf, CharacterStub.legolas.name, "Star Wars", CharacterStub.legolas.imgUrl, SrcType.Movie, 2000),
Quote(53, "La magie est partout. Il suffit de savoir où la trouver.", 466, SrcLanguage.vf, CharacterStub.gandalf.name, "Harry Potter", CharacterStub.gandalf.imgUrl, SrcType.Movie, 2000),
Quote(54, "Le monde est plein de choses magiques, patientant que nos sens s'aiguisent.", 120, SrcLanguage.vf, CharacterStub.frodoBaggins.name, "Le Seigneur des Anneaux", CharacterStub.frodoBaggins.imgUrl, SrcType.Movie, 2000),
Quote(55, "La peur mène à la colère, la colère mène à la haine, la haine mène à la souffrance.", 150, SrcLanguage.vf, CharacterStub.gimli.name, "Star Wars", CharacterStub.gimli.imgUrl, SrcType.Movie, 2000),
Quote(56, "La vie est une aventure audacieuse ou rien du tout.", 200, SrcLanguage.vf, CharacterStub.galadriel.name, "Helen Keller", CharacterStub.galadriel.imgUrl, SrcType.Movie, 2000),
Quote(57, "Le courage n'est pas l'absence de peur, mais la capacité de vaincre ce qui fait peur.", 300, SrcLanguage.vf, CharacterStub.boromir.name, "Nelson Mandela", CharacterStub.boromir.imgUrl, SrcType.Movie, 2000),
Quote(58, "La folie, c'est de faire toujours la même chose et de s'attendre à un résultat différent.", 400, SrcLanguage.vf, CharacterStub.eowyn.name, "Albert Einstein", CharacterStub.eowyn.imgUrl, SrcType.Movie, 2000),
Quote(59, "Le bonheur n'est pas quelque chose de tout fait. Il vient de vos propres actions.", 500, SrcLanguage.vo, CharacterStub.saruman.name, "Dalaï Lama", CharacterStub.saruman.imgUrl, SrcType.Movie, 2000),
Quote(60, "La vie est un mystère qu'il faut vivre, et non un problème à résoudre.", 600, SrcLanguage.vo, CharacterStub.samwiseGamgee.name, "Gandhi", CharacterStub.samwiseGamgee.imgUrl, SrcType.Movie, 2000)
)
}

@ -0,0 +1,8 @@
package com.example.what_the_fantasy.data.model
data class Comment(
val content : String,
val user : String,
val date : String,
val img : String
)

@ -1,7 +1,10 @@
package com.example.what_the_fantasy.data.model
import androidx.compose.ui.res.stringResource
import com.example.what_the_fantasy.R
enum class SrcType (val value: String) {
Movie("@string/movie"),
VideoGame("@string/videoGame"),
Series("@string/series"),
Movie("movie" ),
VideoGame("videoGame"),
Series("series"),
}

@ -1,6 +1,7 @@
package com.example.what_the_fantasy.data.services
import com.example.what_the_fantasy.data.model.Favorite
import com.example.what_the_fantasy.data.model.Comment
import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.data.model.User
@ -20,17 +21,23 @@ interface IServices {
fun EditImage(imageURL : String, index : Int)
fun ChangeLangage(index : Int): SrcLanguage
fun AddFav(userId: Int, QuoteId : Int)
fun SupFav(userId: Int, QuoteId : Int)
fun AddComment(content : String)
fun CreateUser(username : String, email : String, passwd : String) : Boolean
fun getFavorite(user: User): List<Quote>
fun getAllUsers(): List<User>
fun getComment(quoteId : Int) : List<Comment>
fun getUserById(id: Int): User?
fun SearchQuote(quote : String)
fun getQuote( id : Int): Quote?
fun isFavorite(id : Int): Boolean
fun isFavorite(id : Int, user: User): Boolean
fun getAllFavorite(): List<Favorite>
fun getAllQuote(): List<Quote>
fun getSomeQuotes(nb: Int, page: Int) : MutableList<Quote>
fun search(type : String ,search:String ,indexCount: Int): List<Quote>
}

@ -1,15 +1,17 @@
package com.example.what_the_fantasy.data.services
import com.example.what_the_fantasy.data.model.Favorite
import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.model.User
//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 {
// override fun EditUsername(username: String, index : Int): Boolean {
// TODO("Not yet implemented")
// }
//
// override fun EditEmail(email: String, index : Int) : Boolean {
// override fun EditEmail(email: String, index : Int): Boolean {
// TODO("Not yet implemented")
// }
//
@ -25,10 +27,26 @@ import com.example.what_the_fantasy.data.model.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")
// }
@ -37,19 +55,19 @@ import com.example.what_the_fantasy.data.model.User
// TODO("Not yet implemented")
// }
//
// override fun isFavorite(id: Int): Boolean {
// 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 getFavorite(user: User): Favorite {
// override fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
// TODO("Not yet implemented")
// }
//
@ -57,8 +75,15 @@ import com.example.what_the_fantasy.data.model.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")
// }
//}

@ -1,6 +1,7 @@
package com.example.what_the_fantasy.data.services
import android.annotation.SuppressLint
import android.util.Log
import com.example.what_the_fantasy.data.local.UserStub.users
import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.Logs.LogsUsers
@ -8,6 +9,9 @@ import com.example.what_the_fantasy.data.local.FavoriteStub.favorites
import com.example.what_the_fantasy.data.local.ImageStub.allImages
import com.example.what_the_fantasy.data.local.QuoteStub.quotes
import com.example.what_the_fantasy.data.model.Favorite
import com.example.what_the_fantasy.data.local.CommentStub.comments
import com.example.what_the_fantasy.data.local.QuoteStub
import com.example.what_the_fantasy.data.model.Comment
import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.ui.components.hashPassword
@ -85,6 +89,21 @@ class ServicesStub : IServices {
return getAllUsers()[index].langage
}
override fun AddFav(userId: Int, QuoteId: Int) {
return
}
override fun SupFav(userId: Int, QuoteId: Int) {
return
}
override fun AddComment(content: String) {
return
TODO("Not yet implemented")
//comments.add(Comment(content = content,))
}
override fun CreateUser(username: String, email: String, passwd: String) : Boolean {
val date =dateDuJour()
val passwordhash = hashPassword(passwd)
@ -113,6 +132,8 @@ class ServicesStub : IServices {
override fun getAllQuote(): List<Quote> = quotes
override fun getAllUsers(): List<User> = users
override fun getComment(quoteId: Int): List<Comment> = comments
override fun getUserById(id: Int): User? {
return (users.find { it.id == id })
}
@ -122,11 +143,20 @@ class ServicesStub : IServices {
}
override fun getQuote(id: Int): Quote? {
return (quotes.find { it.id == id+1 })
return (quotes.find { it.id == id })
}
override fun isFavorite(id: Int): Boolean {
TODO("Not yet implemented")
override fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
val fromIndex = (page - 1) * nb
val toIndex = minOf(page * nb, quotes.size)
if (fromIndex >= quotes.size) return mutableListOf()
return quotes.subList(fromIndex, toIndex).toMutableList()
}
override fun isFavorite(id: Int, user: User): Boolean {
var quote = getFavorite(user)
return quote.find{ it.id == id } != null
}
@ -170,4 +200,22 @@ class ServicesStub : IServices {
}
return false
}
override fun search(type : String ,search:String ,indexCount: Int): List<Quote> {
return (getAllQuote().filter {
when (type) {
"personnage" -> {
it.character.uppercase().contains(search.uppercase())
}
"titre" -> {
it.source.uppercase().contains(search.uppercase())
}
else -> {
it.content.uppercase().contains(search.uppercase())
}
}
}.take(indexCount))
}
}

@ -21,6 +21,7 @@ import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonColors
import androidx.compose.material3.IconToggleButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.runtime.Composable
@ -34,6 +35,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.rememberAsyncImagePainter
@ -49,10 +51,11 @@ fun NavBar(onProfile : Boolean = false,
onQuiz : Boolean = false,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
navControllerProfil: (Int) -> Unit,
navControllerFavorite:(Int) -> Unit,
navControllerAccueil: (Int) -> Unit,
navControllerQuiz: (Int) -> Unit,
navControllerProfil: () -> Unit = {},
navControllerFavorite:() -> Unit= {},
navControllerAccueil: () -> Unit= {},
navControllerQuiz: () -> Unit= {},
navControllerSearch: () -> Unit = {},
content : @Composable ()-> Unit ) {
var theme by remember { mutableStateOf(true) }
@ -71,26 +74,17 @@ fun NavBar(onProfile : Boolean = false,
Arrangement.SpaceBetween,
verticalAlignment = Alignment.Bottom
) {
ButtonIconVectorInt(currentUserState.imagePath,"Profile",navControllerProfil,currentUserState.id,onProfile)
ButtonIconVectorInt(currentUserState.imagePath,"Profile",navControllerProfil,onProfile)
ButtonIconVector(Icons.Rounded.Search,stringResource(R.string.NavSearch),navControllerSearch,false)
IconButton(onClick = { theme=!theme},
modifier = Modifier.size(60.dp)
.clip(RoundedCornerShape(0))
) {
Icon(painterResource(
if(theme)R.drawable.dark_mode_toggle_icon
else R.drawable.light_mode_toggle_icon),
contentDescription = "Dark mode",
modifier = Modifier.fillMaxSize(),
tint = MaterialTheme.colorScheme.primary
)
}
}
}
Box(modifier = Modifier.background(Color.Black).fillMaxHeight(0.90f)){
Box(modifier = Modifier
.background(Color.Black)
.fillMaxHeight(0.90f)){
content()
}
@ -104,20 +98,20 @@ fun NavBar(onProfile : Boolean = false,
verticalAlignment = Alignment.CenterVertically
) {
ButtonIconPainterInt(painterResource(
ButtonIconPainter(painterResource(
if(onFavorite)R.drawable.favorite_button_full
else R.drawable.favorite_button_empty
),"Favorite",navControllerFavorite,currentUserState.id,onFavorite)
), stringResource(R.string.NavFavorite) ,navControllerFavorite,onFavorite)
ButtonIconPainterInt(painterResource(
ButtonIconPainter(painterResource(
if(onAccueil)R.drawable.home_button_full
else R.drawable.home_button_empty
),"Accueil",navControllerAccueil,currentUserState.id,onAccueil)
),stringResource(R.string.NavHome),navControllerAccueil,onAccueil)
ButtonIconPainterInt(painterResource(
ButtonIconPainter(painterResource(
if(onQuiz)R.drawable.quiz_button_full
else R.drawable.quiz_button_empty
),"Quiz",navControllerQuiz,currentUserState.id,onQuiz)
),stringResource(R.string.NavQuiz),navControllerQuiz,onQuiz)
}
}
@ -125,8 +119,8 @@ fun NavBar(onProfile : Boolean = false,
}
@Composable
fun ButtonIconVectorInt(img : String, name : String, nav : (Int)->Unit ,index: Int,onPage : Boolean){
IconButton(onClick = {nav(index)},
fun ButtonIconVectorInt(img : String, name : String, nav : ()->Unit ,onPage : Boolean){
IconButton(onClick = {nav()},
enabled = !onPage,
colors = IconButtonColors(Color.Transparent, MaterialTheme.colorScheme.onBackground,//couleur quand il n'est pas selectionné
Color.Transparent, MaterialTheme.colorScheme.primary),//couleur quand il est selectionné
@ -143,11 +137,28 @@ fun ButtonIconVectorInt(img : String, name : String, nav : (Int)->Unit ,index: I
)
}
}
@Composable
fun ButtonIconVector(img : ImageVector, name : String, nav : ()->Unit ,onPage : Boolean){
IconButton(onClick = {nav()},
enabled = !onPage,
colors = IconButtonColors(Color.Transparent, MaterialTheme.colorScheme.onBackground,//couleur quand il n'est pas selectionné
Color.Transparent, MaterialTheme.colorScheme.primary),//couleur quand il est selectionné
modifier = Modifier
.size(60.dp)
) {
Image(img,
contentDescription = name,
modifier = Modifier
.fillMaxSize()
.clip(CircleShape) // Pour rendre l'image circulaire
)
}
}
@Composable
fun ButtonIconPainterInt(img : Painter, name : String, nav : (Int)->Unit,index: Int,onPage : Boolean){
IconButton(onClick = {nav(index)},
fun ButtonIconPainter(img : Painter, name : String, nav : ()->Unit,onPage : Boolean){
IconButton(onClick = {nav()},
enabled = !onPage,
colors = IconButtonColors(Color.Transparent,MaterialTheme.colorScheme.onBackground,//couleur quand il n'est pas selectionné
Color.Transparent, MaterialTheme.colorScheme.primary),//couleur quand il est selectionné
@ -157,7 +168,7 @@ fun ButtonIconPainterInt(img : Painter, name : String, nav : (Int)->Unit,index:
Icon(img,
contentDescription = name,
modifier = Modifier
.fillMaxSize()
.size(50.dp)
)
}
}

@ -43,13 +43,13 @@ data class Quiz(val userIndex: Int, val idQuiz: Int)
data class QuizEnd(val userIndex: Int, val idQuiz: Int, val pts: Int)
@Serializable
data class OneQuote(val quoteId: Int, val userIndex: Int)
data class QuizRandom(val userIndex: Int)
@Serializable
data class Quote(val quoteId: Int, val userIndex: Int)
data class OneQuote(val quoteId: Int, val userIndex: Int)
@Serializable
data object Search
data class Search(val userIndex: Int,val type : String = "contenue", val search: String = "")
@Serializable
data object SignUp
@ -116,6 +116,7 @@ fun AppNavigator() {
)
)
},
navSearch = { navController.navigate(Search(currentUserState.id))},
services = services,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
@ -135,6 +136,7 @@ fun AppNavigator() {
)
)
},
navSearch = { navController.navigate(Search(currentUserState.id))},
services = services,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
@ -154,6 +156,7 @@ fun AppNavigator() {
},
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navSearch = { navController.navigate(Search(profil.userIndex))},
)
}
composable<OneQuote> {
@ -167,9 +170,25 @@ fun AppNavigator() {
service = services,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navSearch = { navController.navigate(Search(currentUserState.id))}
)
}
composable<Search> {
val search: Search = it.toRoute()
SearchPage(
navAccueil = { navController.navigate(Accueil(search.userIndex)) },
navFavorite = { navController.navigate(Favorite(search.userIndex)) },
navQuiz = { navController.navigate(QuizMenu(search.userIndex)) },
navProfil = { navController.navigate(Profil(search.userIndex)) },
navQuote = { quoteId -> navController.navigate(OneQuote(quoteId,search.userIndex)) },
navSearch = {type,newSearch -> navController.navigate(Search(search.userIndex,type,newSearch))},
services = services,
type = search.type,
search = search.search,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
)
}
composable<Search> { SearchPage() }
composable<SignUp> {
SignUpPage(
navControllerLogin = {
@ -187,9 +206,7 @@ fun AppNavigator() {
navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(currentUserState.id)) },
navControllerQuiz = { idQuiz ->
navController.navigate(Quiz(currentUserState.id, idQuiz))
},
navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
navRecap = { quoteContent, character, source ->
navController.navigate(
RecapSubmit(
@ -213,6 +230,8 @@ fun AppNavigator() {
navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(currentUserState.id)) },
navSearch = { navController.navigate(Search(currentUserState.id))},
navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
currentUserVM = currentUserVM,
currentUserState = currentUserState,
)
@ -226,9 +245,11 @@ fun AppNavigator() {
navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(currentUserState.id)) },
navSearch = { navController.navigate(Search(currentUserState.id))},
navControllerQuiz = { idQuiz ->
navController.navigate(Quiz(currentUserState.id, idQuiz))
},
navControllerRandomQuiz = { navController.navigate(QuizRandom(currentUserState.id)) }
)
}
@ -242,6 +263,7 @@ fun AppNavigator() {
navControllerQuizEnd = { idQuiz, pts ->
navController.navigate(QuizEnd(currentUserState.id, idQuiz, pts))
},
navSearch = { navController.navigate(Search(currentUserState.id))},
idQuiz = quiz.idQuiz,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
@ -256,6 +278,23 @@ fun AppNavigator() {
navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(currentUserState.id)) },
navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
navSearch = { navController.navigate(Search(currentUserState.id))},
currentUserVM = currentUserVM,
currentUserState = currentUserState,
)
}
composable<QuizRandom> {
val quizRandom: QuizRandom = it.toRoute()
QuizRandom(
navAccueil = { navController.navigate(Accueil(quizRandom.userIndex)) },
navFavorite = { navController.navigate(Favorite(quizRandom.userIndex)) },
navProfil = { navController.navigate(Profil(quizRandom.userIndex)) },
navQuiz = { navController.navigate(QuizMenu(quizRandom.userIndex)) },
navSearch = { navController.navigate(Search(quizRandom.userIndex)) },
navControllerQuizEnd = { idQuiz, pts ->
navController.navigate(QuizEnd(quizRandom.userIndex, idQuiz, pts))
},
currentUserVM = currentUserVM,
currentUserState = currentUserState,
)

@ -5,58 +5,91 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.R
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.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.QuoteLittle
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import com.example.what_the_fantasy.ui.theme.colorBackground
import kotlinx.coroutines.delay
@Composable
fun AccueilPage(
navFavorite: (Int) -> Unit,
navQuiz: (Int) -> Unit,
navProfil: (Int) -> Unit,
navFavorite: () -> Unit,
navQuiz: () -> Unit,
navProfil: () -> Unit,
navQuote: (Int) -> Unit,
navSearch: () -> Unit,
services: IServices,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) {
var itemCount by remember { mutableIntStateOf(15) }
) {
val dailyQuote = DailyQuoteStub.dailyQuote
val quotes = services.getAllQuote().take(itemCount)
val titleDalyQuote = stringResource(R.string.TitleHomeDailyQuote)
val titleSuggestion = stringResource(R.string.TitleHomeSuggestion)
val page = remember { mutableIntStateOf(1) }
val quotes = remember { mutableStateListOf<Quote>() }
val state = rememberLazyListState()
val layoutInfo = remember { derivedStateOf { state.layoutInfo } }
val isLoading = remember { mutableStateOf(false) }
val visibleItemsInfo = layoutInfo.value.visibleItemsInfo
val fullyVisibleItemsInfo = visibleItemsInfo.toMutableList()
val lastItem = if (fullyVisibleItemsInfo.isNotEmpty()) fullyVisibleItemsInfo.last() else null
LaunchedEffect(page.intValue) {
if (!isLoading.value) {
isLoading.value = true
delay(500)
val newQuotes = services.getSomeQuotes(15, page.intValue)
val uniqueQuotes = newQuotes.filterNot { new -> quotes.any { it.id == new.id } }
if (uniqueQuotes.isNotEmpty()) {
quotes.addAll(uniqueQuotes)
} else {
println("Aucune nouvelle quote à la page ${page.intValue}, stop pagination.")
}
isLoading.value = false
}
}
NavBar(
onAccueil = true,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navControllerFavorite = navFavorite,
navControllerAccueil = { },
navControllerProfil = navProfil,
navControllerQuiz = navQuiz
navControllerQuiz = navQuiz,
navControllerSearch = navSearch
) {
Column(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
) {
LazyColumn(modifier = Modifier.weight(1f)) {
item{
Column {
LazyColumn(modifier = Modifier.weight(1f), state = state) {
item {
Column(Modifier.clickable { navQuote(dailyQuote.id) }) {
Text(
text = titleDalyQuote,
color = MaterialTheme.colorScheme.onBackground,
@ -66,9 +99,9 @@ fun AccueilPage(
.padding(16.dp),
textAlign = TextAlign.Center
)
QuoteLittle(dailyQuote)
}
Text(
text = titleSuggestion,
color = MaterialTheme.colorScheme.onBackground,
@ -79,21 +112,18 @@ fun AccueilPage(
textAlign = TextAlign.Center
)
}
items(quotes) { quote ->
Column(Modifier.clickable {navQuote(quote.id)}
) {
if(quote.language == currentUserState.langage){
items(quotes) { quote ->
if (quote.language == currentUserState.langage) {
Column(Modifier.clickable { navQuote(quote.id ) }) {
QuoteLittle(quote)
Spacer(modifier = Modifier.height(16.dp))
}
}
}
if (itemCount < quotes.size) {
item {
LaunchedEffect(itemCount) {
itemCount += 15
}
if (lastItem?.index == quotes.size) {
Box(
modifier = Modifier
.fillMaxWidth()
@ -102,6 +132,15 @@ fun AccueilPage(
) {
CircularProgressIndicator()
}
} else {
LaunchedEffect(remember { derivedStateOf { state.firstVisibleItemIndex } }, remember { derivedStateOf { state.layoutInfo } }.value.totalItemsCount) {
if (!isLoading.value && state.layoutInfo.visibleItemsInfo.isNotEmpty()) {
val lastVisibleItem = state.layoutInfo.visibleItemsInfo.last()
if (lastVisibleItem.index >= state.layoutInfo.totalItemsCount - 1) {
page.intValue++
}
}
}
}
}
}

@ -27,10 +27,11 @@ import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable
fun FavoritePage(
navAccueil: (Int) -> Unit,
navQuiz: (Int) -> Unit,
navProfil: (Int) -> Unit,
navAccueil: () -> Unit,
navQuiz: () -> Unit,
navProfil: () -> Unit,
navQuote: (Int) -> Unit,
navSearch: () -> Unit,
services: IServices,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
@ -46,7 +47,8 @@ fun FavoritePage(
navControllerFavorite = { },
navControllerAccueil = navAccueil,
navControllerProfil = navProfil,
navControllerQuiz = navQuiz
navControllerQuiz = navQuiz,
navControllerSearch = navSearch
) {
Box(
modifier = Modifier

@ -1,5 +1,6 @@
package com.example.what_the_fantasy.ui.screens
import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
@ -88,8 +89,6 @@ fun LoginPage(navControllerSignUp: () -> Unit,
}
@Composable
fun IdentifiantTextField(textIdentifiantResId : Int, username : String, onValueChange: (String) -> Unit ) : String{
val textIdentifiant = stringResource(id = textIdentifiantResId)
@ -103,6 +102,7 @@ fun IdentifiantTextField(textIdentifiantResId : Int, username : String, onValueC
.fillMaxWidth()
.padding(top = 8.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
maxLines = 1,
shape = RoundedCornerShape(16.dp)
)
}
@ -123,6 +123,7 @@ fun PassWdTextField(textpasswdResId : Int, password : String, onValueChange: (St
.fillMaxWidth()
.padding(top = 8.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
maxLines = 1,
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = {
IconButton(onClick = { passwordVisible = !passwordVisible }) {
@ -156,19 +157,6 @@ fun ConnexionButtonLogin(authUserVM : AuthUserViewModel, username : String, pass
}
fun validLogin(username : String, passwd : String, users : List<User>, navController: (Int) -> Unit): Boolean {
val logsUser = LogsUsers() //gestion des logs pour les utilisateurs
users.forEachIndexed { index, user ->
val hashPassWd = hashPassword(passwd)
if (user.username == username && user.password == hashPassWd) {
navController(index)
logsUser.logInformationUserConnect(user, "UserConnect")
return true
}
}
return false
}
@Composable
fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: () -> Unit) {

@ -57,11 +57,12 @@ import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable
fun ProfilPage(navFavorite: (Int) -> Unit,
navAccueil: (Int) -> Unit,
navQuiz: (Int) -> Unit,
fun ProfilPage(navFavorite: () -> Unit,
navAccueil: () -> Unit,
navQuiz: () -> Unit,
navUnLog: () -> Unit,
navSubmitQuote: () -> Unit,
navSearch: () -> Unit,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) {
@ -71,8 +72,8 @@ fun ProfilPage(navFavorite: (Int) -> Unit,
currentUserState = currentUserState,
navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil,
navControllerProfil = {},
navControllerQuiz = navQuiz
navControllerQuiz = navQuiz,
navControllerSearch = navSearch
) {
Box(
@ -92,7 +93,7 @@ fun ProfilPage(navFavorite: (Int) -> Unit,
) {
// Titre
TitlePageComponent(R.string.titleProfile, Color.White)
TitlePageComponent(R.string.titleProfile, MaterialTheme.colorScheme.onBackground)
SpaceHeightComponent(16)
// Image de profil
@ -109,11 +110,11 @@ fun ProfilPage(navFavorite: (Int) -> Unit,
SpaceHeightComponent(16)
// Bouton
ButtonProfile(R.string.ButtonAddQuoteprofile, 18, MaterialTheme.colorScheme.background,navSubmitQuote) // Pas encore de navigation definie
ButtonProfile(R.string.ButtonAddQuoteprofile, 18, MaterialTheme.colorScheme.primary,MaterialTheme.colorScheme.background,navSubmitQuote) // Pas encore de navigation definie
SpaceHeightComponent(16)
ButtonLanguage(R.string.ButtonLanguageprofile, 18, MaterialTheme.colorScheme.background,currentUserVM, currentUserState)
ButtonLanguage(R.string.ButtonLanguageprofile, 18, MaterialTheme.colorScheme.primary,MaterialTheme.colorScheme.background,currentUserVM, currentUserState)
SpaceHeightComponent(16)
ButtonUnLog(R.string.ButtonUnlogprofile, 18, navUnLog,currentUserVM)
ButtonUnLog(R.string.ButtonUnlogprofile, 18,MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.background, navUnLog,currentUserVM)
@ -434,19 +435,19 @@ fun DisplayPassword(onEdit: () -> Unit) {
text = "*****",
fontSize = 18.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onPrimary
color = MaterialTheme.colorScheme.primary
)
Icon(
imageVector = Icons.Default.Edit,
contentDescription = "Modifier",
tint = MaterialTheme.colorScheme.onPrimary,
tint =MaterialTheme.colorScheme.primary,
modifier = Modifier.size(16.dp).padding(start = 8.dp)
)
}
}
@Composable
fun ButtonUnLog(textResId : Int, size :Int,navController: () -> Unit, currentUserVM: CurrentUserViewModel){
fun ButtonUnLog(textResId : Int, size :Int, colorTexte : Color,colorButton : Color, navController: () -> Unit, currentUserVM: CurrentUserViewModel){
val text = stringResource(id = textResId)
val logsUser = LogsUsers() //gestion des logs pour les utilisateurs
@ -457,15 +458,15 @@ fun ButtonUnLog(textResId : Int, size :Int,navController: () -> Unit, currentUse
logsUser.unlogInformationUserConnect("UserUnLog")
},
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background),
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(),
) {
Text(text, fontSize = size.sp, color = MaterialTheme.colorScheme.primary)
Text(text, fontSize = size.sp, color = colorTexte)
}
}
@Composable
fun ButtonLanguage(textResId : Int, size :Int, 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)
Button(
@ -475,12 +476,12 @@ fun ButtonLanguage(textResId : Int, size :Int, colorButton : Color, currentUserV
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(),
) {
Text("${text} (${currentUserState.langage})", fontSize = size.sp, color = MaterialTheme.colorScheme.primary)
Text("${text} (${currentUserState.langage})", fontSize = size.sp, color = colorTexte)
}
}
@Composable
fun ButtonProfile(textResId : Int, size :Int, colorButton : Color,navController: () -> Unit){
fun ButtonProfile(textResId : Int, size :Int,colorTexte : Color, colorButton : Color,navController: () -> Unit){
val text = stringResource(id = textResId)
Button(
@ -490,6 +491,6 @@ fun ButtonProfile(textResId : Int, size :Int, colorButton : Color,navController:
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(),
) {
Text(text, fontSize = size.sp, color = MaterialTheme.colorScheme.primary)
Text(text, fontSize = size.sp, color = colorTexte)
}
}

@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.material3.MaterialTheme
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
@ -15,6 +16,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.data.local.QuestionStub
import com.example.what_the_fantasy.data.local.QuizStub
import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.states.CurrentUserState
@ -30,10 +32,11 @@ val gradient = Brush.linearGradient(
fun QuizEndPage(
idQuiz: Int,
points: Int,
navFavorite: (Int) -> Unit,
navAccueil: (Int) -> Unit,
navProfil:(Int) -> Unit,
navQuiz: (Int) -> Unit,
navFavorite: () -> Unit,
navAccueil: () -> Unit,
navProfil:() -> Unit,
navQuiz: () -> Unit,
navSearch: () -> Unit,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) {
@ -43,7 +46,9 @@ fun QuizEndPage(
navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil,
navControllerProfil = navProfil,
navControllerQuiz = navQuiz) {
navControllerQuiz = navQuiz,
navControllerSearch = navSearch
) {
Column(
modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B))
) {
@ -68,16 +73,16 @@ fun QuizEndPage(
Spacer(modifier = Modifier.height(16.dp))
Column(
modifier = Modifier
.background(brush = gradient, shape = RoundedCornerShape(20.dp))
.background(color = MaterialTheme.colorScheme.onPrimary, shape = RoundedCornerShape(20.dp))
.padding(30.dp)
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly
) {
val quiz = QuizStub.getQuizById(idQuiz)
val nbQuestions = quiz?.questions?.size
val quizName = if (idQuiz == -1) "Random Quiz" else QuizStub.getQuizById(idQuiz)?.name ?: "Quiz Inconnu"
Text(
text = "${quiz?.name}",
text = quizName,
color = Color.White,
style = TextStyle(
fontSize = 25.sp,
@ -85,6 +90,7 @@ fun QuizEndPage(
textAlign = TextAlign.Center
)
)
val nbQuestions = 10
Text(
text = "Nombres de Questions : $nbQuestions",
color = Color.White,

@ -3,6 +3,7 @@ package com.example.what_the_fantasy.ui.screens
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@ -12,6 +13,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
@ -38,10 +40,12 @@ import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
fun QuizMenu(
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
navFavorite: (Int) -> Unit,
navAccueil: (Int) -> Unit,
navProfil:(Int) -> Unit,
navFavorite: () -> Unit,
navAccueil: () -> Unit,
navProfil:() -> Unit,
navControllerQuiz: (Int) -> Unit,
navSearch: () -> Unit,
navControllerRandomQuiz:() -> Unit
) {
NavBar(onQuiz = true,
@ -50,16 +54,19 @@ fun QuizMenu(
navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil,
navControllerProfil = navProfil,
navControllerQuiz = { }
navControllerSearch = navSearch
) {
Column(
modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)
Row(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
.horizontalScroll(state = rememberScrollState())
) {
// Contenu princiapl
Column(
modifier = Modifier
.weight(0.9f)
.width(400.dp)
.fillMaxSize()
.padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally
@ -76,7 +83,7 @@ fun QuizMenu(
Spacer(Modifier.height(20.dp))
Column(
modifier = Modifier
.background(MaterialTheme.colorScheme.onPrimary, shape = RoundedCornerShape(20.dp))
.background(MaterialTheme.colorScheme.primary, shape = RoundedCornerShape(20.dp))
.fillMaxSize()
.padding(vertical = 30.dp)
.verticalScroll(rememberScrollState()),
@ -115,7 +122,7 @@ fun QuizMenu(
fontSize = 17.sp,
fontWeight = FontWeight.Medium,
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.primary
color = MaterialTheme.colorScheme.onPrimary
)
)
}
@ -125,6 +132,66 @@ fun QuizMenu(
}
}
}
Column(
modifier = Modifier
.width(400.dp)
.fillMaxSize()
.padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "▶ Mini-Jeux ◀",
color = MaterialTheme.colorScheme.onBackground,
style = TextStyle(
fontSize = 25.sp,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center
)
)
Spacer(Modifier.height(20.dp))
Column(
modifier = Modifier
.background(MaterialTheme.colorScheme.onPrimary, shape = RoundedCornerShape(20.dp))
.fillMaxSize()
.padding(vertical = 30.dp)
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally
) {
val context = LocalContext.current
val imageResId = context.resources.getIdentifier(
"quiz",
"drawable",
context.packageName
)
Column(
modifier = Modifier
.size(width = 150.dp, height = 145.dp)
.clickable { navControllerRandomQuiz() },
) {
Image(
painter = painterResource(id = imageResId),
contentDescription = "Random Quiz",
modifier = Modifier
.size(width = 150.dp, height = 100.dp)
.clip(shape = RoundedCornerShape(20.dp)),
contentScale = ContentScale.Crop
)
Spacer(Modifier.height(10.dp))
Text(
text = "Random Quiz",
style = TextStyle(
fontSize = 17.sp,
fontWeight = FontWeight.Medium,
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.primary
)
)
}
}
}
}
}
}

@ -26,10 +26,11 @@ import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
fun QuizPage(
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
navFavorite: (Int) -> Unit,
navAccueil: (Int) -> Unit,
navProfil:(Int) -> Unit,
navQuiz: (Int) -> Unit,
navFavorite: () -> Unit,
navAccueil: () -> Unit,
navProfil:() -> Unit,
navQuiz: () -> Unit,
navSearch: () -> Unit,
navControllerQuizEnd: (Int, Int) -> Unit,
@ -65,7 +66,8 @@ fun QuizPage(
navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil,
navControllerProfil = navProfil,
navControllerQuiz = navQuiz
navControllerQuiz = navQuiz,
navControllerSearch = navSearch
){
Column (
modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B))

@ -0,0 +1,165 @@
package com.example.what_the_fantasy.ui.screens
import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.data.local.QuestionStub
import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable
fun QuizRandom(
navFavorite: () -> Unit,
navAccueil: () -> Unit,
navProfil:() -> Unit,
navQuiz: () -> Unit,
navSearch: () -> Unit,
navControllerQuizEnd: (Int, Int) -> Unit,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) {
val questions = QuestionStub.shuffleRandomQuestions
var idCurrentQuestion by remember { mutableIntStateOf(0) }
var pts by remember { mutableIntStateOf(0) }
var lifes by remember { mutableIntStateOf(3) }
val gradient = Brush.linearGradient(
colors = listOf(MaterialTheme.colorScheme.onPrimary, MaterialTheme.colorScheme.onPrimary),
start = Offset(0f, 1000f),
end = Offset(1000f, 0f)
)
fun onAnswerSelected(answer: String) {
val currentQuestion = questions[idCurrentQuestion]
val correctAnswer = mapOf(
"A" to currentQuestion.ansA,
"B" to currentQuestion.ansB,
"C" to currentQuestion.ansC,
"D" to currentQuestion.ansD
)[currentQuestion.correctAns]
if (answer == correctAnswer) pts++
else {
lifes -= 1
Log.d("Quiz Debug", "Lifes -1 :, $lifes")
}
if (idCurrentQuestion < questions.size - 1 && lifes > 0) idCurrentQuestion++
else {
navControllerQuizEnd(-1, pts)
Log.d("Quiz Debug", "Game over lifes : $lifes")
} // Retour menu
}
NavBar(
navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil,
navControllerProfil = navProfil,
navControllerQuiz = navQuiz,
navControllerSearch = navSearch,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
){
Column (
modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B))
) {
// Contenu princiapl
Column(
modifier = Modifier
.weight(0.8f)
.fillMaxWidth()
.padding(horizontal = 50.dp, vertical = 20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
val question = questions[idCurrentQuestion]
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
if (questions != null) {
Text(
text = "▶ Random Quiz ◀",
color = Color.White,
style = TextStyle(
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center
)
)
}
Spacer(Modifier.height(20.dp))
Column(
modifier = Modifier
.background(brush = gradient, shape = RoundedCornerShape(20.dp))
.height(800.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
"Question ${idCurrentQuestion + 1}",
color = Color.White,
fontSize = 18.sp,
modifier = Modifier
.padding(top = 20.dp)
.weight(0.1f),
style = TextStyle(
fontSize = 25.sp,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center
)
)
Text(
question.question,
color = Color.White,
fontSize = 15.sp,
modifier = Modifier
.padding(horizontal = 25.dp)
.weight(0.1f),
textAlign = TextAlign.Center
)
Column(
modifier = Modifier
.weight(0.7f)
.fillMaxHeight()
.padding(vertical = 30.dp),
verticalArrangement = Arrangement.SpaceBetween
) {
listOf(
question.ansA,
question.ansB,
question.ansC,
question.ansD
).forEach { answer ->
Box(
modifier = Modifier
.width(220.dp)
.height(50.dp)
.background(Color.White, shape = RoundedCornerShape(16.dp))
.clickable { onAnswerSelected(answer) }
.padding(horizontal = 8.dp),
contentAlignment = Alignment.Center
) {
Text(answer, color = Color.Black, fontSize = 18.sp)
}
}
}
}
}
}
}
}
}

@ -2,24 +2,46 @@ package com.example.what_the_fantasy.ui.screens
import android.content.Context
import android.content.Intent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.automirrored.filled.Send
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.FavoriteBorder
import androidx.compose.material.icons.filled.MailOutline
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -33,6 +55,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.R
import coil.compose.AsyncImage
import com.example.what_the_fantasy.data.model.Comment
import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.states.CurrentUserState
@ -43,41 +66,47 @@ import com.example.what_the_fantasy.ui.theme.likeIcon
import com.example.what_the_fantasy.ui.theme.whiteBackcgroundText
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
var isCommentVisible by mutableStateOf(false)
@Composable
fun QuotePage(
quoteId : Int,
service : IServices,
navAccueil: (Int) -> Unit,
navFavorite:(Int) -> Unit,
navQuiz: (Int) -> Unit,
navProfil:(Int) -> Unit,
navAccueil: () -> Unit,
navFavorite:() -> Unit,
navQuiz: () -> Unit,
navProfil:() -> Unit,
navSearch: () -> Unit,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,)
currentUserState : CurrentUserState,
)
{
var quote = service.getQuote(quoteId) ?: return
// utiliser ViewModel
val quote = service.getQuote(quoteId) ?: return
val context = LocalContext.current
val user = service.getUserById(currentUserState.id) ?: return
val favorite by remember { mutableStateOf(service.isFavorite(id = quoteId, user = user)) }
NavBar(onProfile = true,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil,
navControllerProfil = navProfil,
navControllerQuiz = navQuiz
navControllerQuiz = navQuiz,
navControllerSearch = navSearch
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(colorBackground),
.background(MaterialTheme.colorScheme.background),
contentAlignment = Alignment.Center
) {
Column(modifier = Modifier
.padding(15.dp)
.drawBehind {
drawRoundRect(
gradienBox,
cornerRadius = CornerRadius(15.dp.toPx()),
.background(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(15.dp)
)
}
) {
Row(modifier = Modifier.padding(15.dp)) {
ImageQuote(
@ -86,12 +115,11 @@ fun QuotePage(
Column {
FunctionalIcon(
// --/!\-- a modifier --/!\--
// isFavorite = service.isFavorite(id)
// --------------------------
true,
isFavorite = favorite,
userId = currentUserState.id,
id = quoteId,
context = context
context = context,
service = service
)
QuoteText(
text = '"' + quote.content + '"'
@ -122,6 +150,24 @@ fun QuotePage(
}
}
}
AnimatedVisibility(
visible = isCommentVisible,
enter = expandVertically(
expandFrom = Alignment.CenterVertically
) + fadeIn(
initialAlpha = 0.3f
) + slideInVertically(
initialOffsetY = { -40 }
),
exit = slideOutVertically() + shrinkVertically() + fadeOut()
) {
Box(modifier = Modifier.fillMaxWidth().background(MaterialTheme.colorScheme.primary).fillMaxSize()){
Column {
AddComment(currentUserState.id, service)
LstComment(service.getComment(quoteId))
}
}
}
}
}
@ -134,7 +180,7 @@ fun QuoteText(text: String ){
modifier = Modifier.padding(start = 10.dp, top = 15.dp),
fontWeight = FontWeight(1000),
fontSize = 20.sp,
color = iconText
color = MaterialTheme.colorScheme.onPrimary
)
}
@ -150,7 +196,7 @@ fun ImageQuote(imageUrl : String){
}
@Composable
fun FunctionalIcon(isFavorite: Boolean, id : Int, context : Context){
fun FunctionalIcon(isFavorite: Boolean, userId : Int, id : Int, context : Context, service: IServices){
Row(modifier = Modifier
.fillMaxWidth()
) {
@ -160,13 +206,13 @@ fun FunctionalIcon(isFavorite: Boolean, id : Int, context : Context){
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
// lien a changer quand le site sra deployer
putExtra(Intent.EXTRA_TEXT, "http://wfWebsite/quote/" + id.toString() )
putExtra(Intent.EXTRA_TEXT, "http://wfWebsite/quote/$id")
type = "text/plain"
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) // Ajout pour compatibilité
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
val shareIntent = Intent.createChooser(sendIntent, null)
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) // Ajout aussi ici
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(shareIntent)
},
@ -175,42 +221,44 @@ fun FunctionalIcon(isFavorite: Boolean, id : Int, context : Context){
Icon(
Icons.Default.Share,
contentDescription = stringResource(R.string.share),
tint = iconText,
tint = MaterialTheme.colorScheme.onPrimary,
)
}
IconButton(
onClick = { }, //Go to comment
onClick = {
isCommentVisible = !isCommentVisible
},
modifier = Modifier.padding(start = 20.dp)
){
Icon(
Icons.Default.MailOutline,
contentDescription = stringResource(R.string.comment),
tint = iconText,
tint = MaterialTheme.colorScheme.onPrimary,
)
}
if(isFavorite){
IconButton(
onClick = { }, //Go to comment
onClick = { service.SupFav(userId = userId, QuoteId = id)}, //sup fav
modifier = Modifier.padding(start = 20.dp)
){
Icon(
Icons.Default.Favorite,
contentDescription = stringResource(R.string.favorite),
tint = likeIcon,
tint = MaterialTheme.colorScheme.onPrimary,
)
}
}
else{
IconButton(
onClick = { }, //Go to comment
onClick = { service.AddFav(userId = userId, QuoteId = id)}, //add fav
modifier = Modifier.padding(start = 50.dp)
){
Icon(
Icons.Default.FavoriteBorder,
contentDescription = stringResource(R.string.favorite),
tint = iconText
tint = MaterialTheme.colorScheme.onPrimary
)
}
}
@ -224,22 +272,20 @@ fun InfoQuoteText(nameId : Int, text : String){
text = stringResource(id = nameId),
fontSize = 18.sp,
fontWeight = FontWeight(500),
color = iconText
color = MaterialTheme.colorScheme.onPrimary
)
Text(
text = text,
color = whiteBackcgroundText,
color = MaterialTheme.colorScheme.onBackground,
fontSize = 16.sp,
fontWeight = FontWeight(400),
modifier = Modifier
.drawBehind {
drawRoundRect(
Color(255,255,255),
cornerRadius = CornerRadius(15.dp.toPx())
.background(
color = MaterialTheme.colorScheme.background,
shape = RoundedCornerShape(15.dp)
)
}
.padding(5.dp),
.padding(5.dp)
)
}
}
@ -248,11 +294,103 @@ fun InfoQuoteText(nameId : Int, text : String){
fun LikeInfo(likes : Int){
Text(
text = likes.toString(),
color = iconText
color = MaterialTheme.colorScheme.onPrimary
)
Icon(
Icons.Default.Favorite,
contentDescription = stringResource(R.string.favorite),
tint = iconText,
tint = MaterialTheme.colorScheme.onPrimary,
)
}
@Composable
fun AddComment(userId: Int, service: IServices) {
var text by remember { mutableStateOf("") }
Row(
modifier = Modifier
.padding(15.dp)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
IconButton(
onClick = { isCommentVisible = !isCommentVisible }
) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = stringResource(R.string.send),
tint = MaterialTheme.colorScheme.onPrimary
)
}
TextField(
value = text,
onValueChange = { text = it },
label = { Text(stringResource(R.string.comment)) },
modifier = Modifier
.weight(1f)
.padding(horizontal = 8.dp),
shape = RoundedCornerShape(20.dp),
colors = TextFieldDefaults.colors(
focusedContainerColor = MaterialTheme.colorScheme.onPrimary,
unfocusedContainerColor = MaterialTheme.colorScheme.onPrimary,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
focusedLabelColor = MaterialTheme.colorScheme.primary,
unfocusedLabelColor = MaterialTheme.colorScheme.primary
),
trailingIcon = {
IconButton(
onClick = { isCommentVisible = !isCommentVisible }
) {
Icon(
imageVector = Icons.AutoMirrored.Filled.Send,
contentDescription = "Retour",
tint = MaterialTheme.colorScheme.primary
)
}
}
)
}
}
@Composable
fun LstComment(lst: List<Comment>) {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.padding(10.dp)
) {
items(lst) {
Column(
modifier = Modifier
.fillMaxWidth()
.background(
color = MaterialTheme.colorScheme.onPrimary,
shape = RoundedCornerShape(15.dp)
)
.padding(12.dp)
) {
Row(verticalAlignment = Alignment.CenterVertically) {
AsyncImage(
model = it.img,
contentDescription = stringResource(R.string.profilePict),
modifier = Modifier
.size(50.dp)
.clip(RoundedCornerShape(50))
)
Text(
text = "${it.user}${it.date}",
color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.padding(start = 12.dp),
fontWeight = FontWeight.Bold,
fontSize = 14.sp
)
}
Text(
text = it.content,
color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.padding(top = 10.dp, start = 8.dp, end = 8.dp),
fontSize = 14.sp
)
}
}
}
}

@ -31,6 +31,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -45,9 +46,11 @@ import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable
fun RecapSubmitPage(
navFavorite: (Int) -> Unit,
navAccueil: (Int) -> Unit,
navProfil:(Int) -> Unit,
navFavorite: () -> Unit,
navAccueil: () -> Unit,
navProfil:() -> Unit,
navSearch: () -> Unit,
navQuiz : () -> Unit,
quoteContent : String,
character: String,
source: String,
@ -60,11 +63,14 @@ fun RecapSubmitPage(
navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil,
navControllerProfil = navProfil,
navControllerQuiz = { }
navControllerQuiz = navQuiz,
navControllerSearch = navSearch
) {
Column(
modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B))
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
) {
// Contenu princiapl
Column(
@ -76,7 +82,7 @@ fun RecapSubmitPage(
) {
Text(
text = "▶ Recap de la citation ◀",
color = Color.White,
color = MaterialTheme.colorScheme.onBackground,
style = TextStyle(
fontSize = 25.sp,
fontWeight = FontWeight.Bold,
@ -137,7 +143,7 @@ fun QuoteText2(text: String ){
modifier = Modifier.padding(start = 10.dp, top = 15.dp),
fontWeight = FontWeight(1000),
fontSize = 20.sp,
color = Color.White
color = MaterialTheme.colorScheme.background
)
}

@ -1,8 +1,179 @@
package com.example.what_the_fantasy.ui.screens
import androidx.compose.runtime.Composable
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Search
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.QuoteLittle
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import kotlinx.coroutines.delay
@Composable
fun SearchPage() {
fun SearchPage(
navFavorite: () -> Unit,
navAccueil: () -> Unit,
navProfil: () -> Unit,
navQuiz: () -> Unit,
navQuote: (Int) -> Unit,
navSearch: (String, String) -> Unit,
services: IServices,
type: String,
search: String,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) {
var newSearch by remember { mutableStateOf(search) }
val filtre = listOf("contenue", "personnage", "titre")
val (newFiltre, onFiltreSelected) = remember { mutableStateOf(type) }
val page = remember { mutableStateOf(1) }
val quotes = remember { mutableStateListOf<Quote>() }
val isLoading = remember { mutableStateOf(false) }
val state = rememberLazyListState()
LaunchedEffect(page.value, type, search) {
if (!isLoading.value) {
isLoading.value = true
delay(500)
val newQuotes = services.search(type, search, page.value * 15)
val uniqueQuotes = newQuotes.filterNot { new -> quotes.any { it.id == new.id } }
if (uniqueQuotes.isNotEmpty()) {
quotes.addAll(uniqueQuotes)
}
isLoading.value = false
}
}
NavBar(
onAccueil = true,
navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil,
navControllerProfil = navProfil,
navControllerQuiz = navQuiz,
navControllerSearch = { navSearch("contenue", "") },
currentUserVM = currentUserVM,
currentUserState = currentUserState,
) {
Column(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
) {
Text(
text = "" + stringResource(R.string.TitleSearch) + "",
color = MaterialTheme.colorScheme.onBackground,
fontSize = 24.sp,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
textAlign = TextAlign.Center
)
Column(horizontalAlignment = Alignment.CenterHorizontally) {
OutlinedTextField(
value = newSearch,
onValueChange = { newSearch = it },
textStyle = TextStyle(color = MaterialTheme.colorScheme.onBackground),
modifier = Modifier
.padding(top = 2.dp)
.fillMaxWidth()
.height(50.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
maxLines = 1,
shape = CircleShape,
trailingIcon = {
IconButton(
onClick = { navSearch(newFiltre, newSearch) },
modifier = Modifier
.size(50.dp)
.clip(CircleShape)
) {
Icon(
Icons.Rounded.Search,
contentDescription = stringResource(R.string.TitleSearch),
Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.primary, CircleShape)
)
}
}
)
Row(horizontalArrangement = Arrangement.SpaceAround) {
filtre.forEach { typeItem ->
Row(
Modifier
.height(56.dp)
.selectable(
selected = (typeItem == newFiltre),
onClick = { onFiltreSelected(typeItem) },
role = Role.RadioButton
)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = (typeItem == newFiltre),
onClick = null
)
Text(
text = typeItem,
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier.padding(start = 16.dp),
color = MaterialTheme.colorScheme.onBackground
)
}
}
}
}
LazyColumn(
modifier = Modifier.weight(1f),
state = state
) {
items(quotes) { quote ->
Column(Modifier.clickable { navQuote(quote.id) }) {
QuoteLittle(quote)
}
}
item {
if (state.layoutInfo.visibleItemsInfo.lastOrNull()?.index == quotes.size - 1 && !isLoading.value) {
LaunchedEffect(Unit) {
page.value++
}
Box(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
}
}
}
}
}
}

@ -57,7 +57,7 @@ fun SignUpPage(navControllerLogin: () -> Unit, signInUserVM :SignInUserViewModel
Box(
modifier = Modifier
.fillMaxSize()
.background(colorBackground)
.background(MaterialTheme.colorScheme.background)
.verticalScroll(rememberScrollState()),
contentAlignment = Alignment.Center
){
@ -66,12 +66,12 @@ fun SignUpPage(navControllerLogin: () -> Unit, signInUserVM :SignInUserViewModel
.fillMaxWidth(0.9f)
.padding(20.dp)
.clip(RoundedCornerShape(16.dp))
.background(gradienBox)
.background(MaterialTheme.colorScheme.onPrimary)
.padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
TitlePageComponent(R.string.titleSignUp,Color.White) // Page Title
TitlePageComponent(R.string.titleSignUp,MaterialTheme.colorScheme.onBackground) // Page Title
IdentifiantTextFieldSign(R.string.IdentifiantLogin,signInState.username){ // Username
signInUserVM.setUsername(it)

@ -14,6 +14,7 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@ -41,10 +42,10 @@ import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable
fun SubmitQuotePage(
navFavorite: (Int) -> Unit,
navAccueil: (Int) -> Unit,
navProfil:(Int) -> Unit,
navControllerQuiz: (Int) -> Unit,
navFavorite: () -> Unit,
navAccueil: () -> Unit,
navProfil:() -> Unit,
navQuiz: () -> Unit,
navRecap: (String, String, String) -> Unit,
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
@ -55,12 +56,12 @@ fun SubmitQuotePage(
navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil,
navControllerProfil = navProfil,
navControllerQuiz = navControllerQuiz
navControllerQuiz = navQuiz
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(colorBackground)
.background(MaterialTheme.colorScheme.background)
.verticalScroll(rememberScrollState()),
contentAlignment = Alignment.Center
){
@ -69,11 +70,11 @@ fun SubmitQuotePage(
.fillMaxWidth(0.9f)
.padding(20.dp)
.clip(RoundedCornerShape(16.dp))
.background(gradienBox)
.background(MaterialTheme.colorScheme.onPrimary)
.padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
TitlePageComponent(R.string.titleSubmitQuote, Color.White)
TitlePageComponent(R.string.titleSubmitQuote, MaterialTheme.colorScheme.onBackground)
SpaceHeightComponent(20)
SubmitQuoteButton(
quoteTextField(R.string.quote),
@ -83,12 +84,12 @@ fun SubmitQuotePage(
yearTextField(R.string.year),
R.string.titleButtonSubmit,
18,
Color.White,
Color.Black,
MaterialTheme.colorScheme.background,
MaterialTheme.colorScheme.onBackground,
navRecap
)
SpaceHeightComponent(20)
BackButton(R.string.titleButtonBack, 12, Color.White,navProfil, currentUserState.id)
BackButton(R.string.titleButtonBack, 12, Color.White,navProfil)
}
}
}
@ -103,7 +104,7 @@ fun quoteTextField(textQuoteResId : Int) : String{
OutlinedTextField(
value = quote,
onValueChange = { quote = it },
label = { Text(textQuote, color = Color.White) },
label = { Text(textQuote, color = MaterialTheme.colorScheme.onBackground) },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
@ -123,7 +124,7 @@ fun characterTextField(textCharacterResId : Int) : String{
OutlinedTextField(
value = character,
onValueChange = { character = it },
label = { Text(textCharacter, color = Color.White) },
label = { Text(textCharacter, color = MaterialTheme.colorScheme.onBackground) },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
@ -142,7 +143,7 @@ fun sourceTextField(textSourceResId : Int) : String{
OutlinedTextField(
value = source,
onValueChange = { source = it },
label = { Text(textSource, color = Color.White) },
label = { Text(textSource, color = MaterialTheme.colorScheme.onBackground) },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
@ -162,7 +163,7 @@ fun timeCodeTextField(textTimeCodeResId : Int) : String{
OutlinedTextField(
value = timeCode,
onValueChange = { timeCode = it },
label = { Text(textTimeCode, color = Color.White) },
label = { Text(textTimeCode, color = MaterialTheme.colorScheme.onBackground) },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
@ -182,7 +183,7 @@ fun yearTextField(textYearResId : Int) : String{
OutlinedTextField(
value = year,
onValueChange = { year = it },
label = { Text(textYear, color = Color.White) },
label = { Text(textYear, color = MaterialTheme.colorScheme.onBackground) },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
@ -245,22 +246,22 @@ fun validSubmitQuote(quote : String, character : String, source: String, timeCod
val invalidRegex = """^[a-zA-Z0-9]*$""".toRegex()
val isNotBlank = quote.isNotBlank() && quote.matches(quoteRegex) && !quote.matches(invalidRegex) && quote.length in 3..100 &&
character.isNotBlank() && character.matches(characterRegex) && character.length in 3..50 && !character.matches(invalidRegex) &&
source.isNotBlank() && source.matches(movieTitleRegex) && source.length in 3..50 && !source.matches(invalidRegex) &&
character.isNotBlank() && character.matches(characterRegex) && character.length in 3..50 && /*!character.matches(invalidRegex) &&*/
source.isNotBlank() && source.matches(movieTitleRegex) && source.length in 3..50 && /*!source.matches(invalidRegex) &&*/
timeCode.isNotBlank() && timeCode.matches(timeCodeRegex) &&
year.isNotBlank() && year.all { it.isDigit() } && year.length == 4 && year.toInt() in 1900..2025
return isNotBlank
}
@Composable
fun BackButton(titleResId : Int, size : Int, color : Color, navController: (Int) -> Unit, user: Int) {
fun BackButton(titleResId : Int, size : Int, color : Color, navController: () -> Unit) {
val title = stringResource(id = titleResId)
Text(
text = title,
fontSize = size.sp,
color = color,
modifier = Modifier.clickable {
navController(user)
navController()
}
)
}

@ -1,5 +1,6 @@
package com.example.what_the_fantasy.ui.viewModels
import android.util.Log
import androidx.lifecycle.ViewModel
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.states.AuthUserState

@ -13,6 +13,7 @@
<string name="favorite">Favoris</string>
<string name="like">Likes</string>
<string name="profilePict">Image de profil</string>
<string name="send">Envoyer</string>
//Page Login
<string name="titleLogin">Connexion au compte</string>
@ -68,4 +69,16 @@
<string name="timeCode">Time Code</string>
<string name="year">Année</string>
<string name="ErrorSubmitQuote">Champs Invalides</string>
//NavBar
<string name="NavFavorite">Favoris</string>
<string name="NavProfile">Profile</string>
<string name="NavHome">Accueil</string>
<string name="NavQuiz">Quiz</string>
<string name="NavSearch">Recherche</string>
//Page Search
<string name="TitleSearch">Recherche</string>
</resources>

@ -8,10 +8,11 @@
<string name="charac">Character</string>
<string name="source">Source</string>
<string name="share">Share</string>
<string name="comment">comment</string>
<string name="favorite">favorite</string>
<string name="like">likes</string>
<string name="comment">Comment</string>
<string name="favorite">Favorite</string>
<string name="like">Likes</string>
<string name="profilePict">Profile picture</string>
<string name="send">Send</string>
//Page Login
<string name="titleLogin">Account login</string>
@ -64,4 +65,16 @@
<string name="timeCode">Time Code</string>
<string name="year">Year</string>
<string name="ErrorSubmitQuote"> Invalid Fields </string>
//NavBar
<string name="NavFavorite">Favorite</string>
<string name="NavProfile">Profile</string>
<string name="NavHome">Home</string>
<string name="NavQuiz">Quiz</string>
<string name="NavSearch">Search</string>
//Page Search
<string name="TitleSearch">Search</string>
</resources>
Loading…
Cancel
Save