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 { object FavoriteStub {
val favorites: MutableList<Favorite> = mutableListOf( 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[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[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 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( val allQuestions: List<Question> = listOf(
question1, question2, question3, question4, question5, question6, question7, question8, question9, question10 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 { object QuoteStub {
val quotes: MutableList<Quote> = mutableListOf( 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(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(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), 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(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(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(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 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) { enum class SrcType (val value: String) {
Movie("@string/movie"), Movie("movie" ),
VideoGame("@string/videoGame"), VideoGame("videoGame"),
Series("@string/series"), Series("series"),
} }

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

@ -1,15 +1,17 @@
package com.example.what_the_fantasy.data.services 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.Favorite
import com.example.what_the_fantasy.data.model.User //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 { //class ServicesAPI : IServices {
// override fun EditUsername(username: String, index : Int) : Boolean { // override fun EditUsername(username: String, index : Int): Boolean {
// TODO("Not yet implemented") // TODO("Not yet implemented")
// } // }
// //
// override fun EditEmail(email: String, index : Int) : Boolean { // override fun EditEmail(email: String, index : Int): Boolean {
// TODO("Not yet implemented") // TODO("Not yet implemented")
// } // }
// //
@ -25,10 +27,26 @@ import com.example.what_the_fantasy.data.model.User
// TODO("Not yet implemented") // 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 { // override fun CreateUser(username: String, email: String, passwd: String, services: IServices) : Boolean {
// TODO("Not yet implemented") // TODO("Not yet implemented")
// } // }
// //
// override fun getFavorite(user: User): List<Quote> {
// TODO("Not yet implemented")
// }
//
// override fun SearchQuote(quote: String) { // override fun SearchQuote(quote: String) {
// TODO("Not yet implemented") // TODO("Not yet implemented")
// } // }
@ -37,19 +55,19 @@ import com.example.what_the_fantasy.data.model.User
// TODO("Not yet implemented") // TODO("Not yet implemented")
// } // }
// //
// override fun isFavorite(id: Int): Boolean { // override fun isFavorite(id: Int, user: User): Boolean {
// TODO("Not yet implemented") // TODO("Not yet implemented")
// } // }
// //
// override fun getAllFavorite(): List<Favorite> { // override fun getAllFavorite(): List<Favorite> {
// TODO("Not yet implemented") // TODO("Not yet implemented")
// } // }
//
// override fun getAllQuote(): List<Quote> { // override fun getAllQuote(): List<Quote> {
// TODO("Not yet implemented") // TODO("Not yet implemented")
// } // }
// //
// override fun getFavorite(user: User): Favorite { // override fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
// TODO("Not yet implemented") // TODO("Not yet implemented")
// } // }
// //
@ -57,8 +75,15 @@ import com.example.what_the_fantasy.data.model.User
// TODO("Not yet implemented") // TODO("Not yet implemented")
// } // }
// //
// override fun getComment(quoteId: Int): List<Comment> {
// TODO("Not yet implemented")
// }
//
// override fun getUserById(id: Int): User? { // override fun getUserById(id: Int): User? {
// TODO("Not yet implemented") // 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 package com.example.what_the_fantasy.data.services
import android.annotation.SuppressLint 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.local.UserStub.users
import com.example.what_the_fantasy.data.model.User import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.Logs.LogsUsers 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.ImageStub.allImages
import com.example.what_the_fantasy.data.local.QuoteStub.quotes 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.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.Quote
import com.example.what_the_fantasy.data.model.SrcLanguage import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.ui.components.hashPassword import com.example.what_the_fantasy.ui.components.hashPassword
@ -85,6 +89,21 @@ class ServicesStub : IServices {
return getAllUsers()[index].langage 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 { override fun CreateUser(username: String, email: String, passwd: String) : Boolean {
val date =dateDuJour() val date =dateDuJour()
val passwordhash = hashPassword(passwd) val passwordhash = hashPassword(passwd)
@ -113,6 +132,8 @@ class ServicesStub : IServices {
override fun getAllQuote(): List<Quote> = quotes override fun getAllQuote(): List<Quote> = quotes
override fun getAllUsers(): List<User> = users override fun getAllUsers(): List<User> = users
override fun getComment(quoteId: Int): List<Comment> = comments
override fun getUserById(id: Int): User? { override fun getUserById(id: Int): User? {
return (users.find { it.id == id }) return (users.find { it.id == id })
} }
@ -122,11 +143,20 @@ class ServicesStub : IServices {
} }
override fun getQuote(id: Int): Quote? { 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 { override fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
TODO("Not yet implemented") 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 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.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonColors import androidx.compose.material3.IconButtonColors
import androidx.compose.material3.IconToggleButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBar
import androidx.compose.runtime.Composable 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.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.rememberAsyncImagePainter import coil.compose.rememberAsyncImagePainter
@ -49,10 +51,11 @@ fun NavBar(onProfile : Boolean = false,
onQuiz : Boolean = false, onQuiz : Boolean = false,
currentUserVM : CurrentUserViewModel, currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState, currentUserState : CurrentUserState,
navControllerProfil: (Int) -> Unit, navControllerProfil: () -> Unit = {},
navControllerFavorite:(Int) -> Unit, navControllerFavorite:() -> Unit= {},
navControllerAccueil: (Int) -> Unit, navControllerAccueil: () -> Unit= {},
navControllerQuiz: (Int) -> Unit, navControllerQuiz: () -> Unit= {},
navControllerSearch: () -> Unit = {},
content : @Composable ()-> Unit ) { content : @Composable ()-> Unit ) {
var theme by remember { mutableStateOf(true) } var theme by remember { mutableStateOf(true) }
@ -71,26 +74,17 @@ fun NavBar(onProfile : Boolean = false,
Arrangement.SpaceBetween, Arrangement.SpaceBetween,
verticalAlignment = Alignment.Bottom 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() content()
} }
@ -104,20 +98,20 @@ fun NavBar(onProfile : Boolean = false,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
ButtonIconPainterInt(painterResource( ButtonIconPainter(painterResource(
if(onFavorite)R.drawable.favorite_button_full if(onFavorite)R.drawable.favorite_button_full
else R.drawable.favorite_button_empty 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 if(onAccueil)R.drawable.home_button_full
else R.drawable.home_button_empty 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 if(onQuiz)R.drawable.quiz_button_full
else R.drawable.quiz_button_empty 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 @Composable
fun ButtonIconVectorInt(img : String, name : String, nav : (Int)->Unit ,index: Int,onPage : Boolean){ fun ButtonIconVectorInt(img : String, name : String, nav : ()->Unit ,onPage : Boolean){
IconButton(onClick = {nav(index)}, IconButton(onClick = {nav()},
enabled = !onPage, enabled = !onPage,
colors = IconButtonColors(Color.Transparent, MaterialTheme.colorScheme.onBackground,//couleur quand il n'est pas selectionné colors = IconButtonColors(Color.Transparent, MaterialTheme.colorScheme.onBackground,//couleur quand il n'est pas selectionné
Color.Transparent, MaterialTheme.colorScheme.primary),//couleur quand il est 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 @Composable
fun ButtonIconPainterInt(img : Painter, name : String, nav : (Int)->Unit,index: Int,onPage : Boolean){ fun ButtonIconPainter(img : Painter, name : String, nav : ()->Unit,onPage : Boolean){
IconButton(onClick = {nav(index)}, IconButton(onClick = {nav()},
enabled = !onPage, enabled = !onPage,
colors = IconButtonColors(Color.Transparent,MaterialTheme.colorScheme.onBackground,//couleur quand il n'est pas selectionné colors = IconButtonColors(Color.Transparent,MaterialTheme.colorScheme.onBackground,//couleur quand il n'est pas selectionné
Color.Transparent, MaterialTheme.colorScheme.primary),//couleur quand il est 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, Icon(img,
contentDescription = name, contentDescription = name,
modifier = Modifier 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) data class QuizEnd(val userIndex: Int, val idQuiz: Int, val pts: Int)
@Serializable @Serializable
data class OneQuote(val quoteId: Int, val userIndex: Int) data class QuizRandom(val userIndex: Int)
@Serializable @Serializable
data class Quote(val quoteId: Int, val userIndex: Int) data class OneQuote(val quoteId: Int, val userIndex: Int)
@Serializable @Serializable
data object Search data class Search(val userIndex: Int,val type : String = "contenue", val search: String = "")
@Serializable @Serializable
data object SignUp data object SignUp
@ -116,6 +116,7 @@ fun AppNavigator() {
) )
) )
}, },
navSearch = { navController.navigate(Search(currentUserState.id))},
services = services, services = services,
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
@ -135,6 +136,7 @@ fun AppNavigator() {
) )
) )
}, },
navSearch = { navController.navigate(Search(currentUserState.id))},
services = services, services = services,
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
@ -154,6 +156,7 @@ fun AppNavigator() {
}, },
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
navSearch = { navController.navigate(Search(profil.userIndex))},
) )
} }
composable<OneQuote> { composable<OneQuote> {
@ -167,9 +170,25 @@ fun AppNavigator() {
service = services, service = services,
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
navSearch = { navController.navigate(Search(currentUserState.id))}
) )
} }
composable<Search> { SearchPage() } 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<SignUp> { composable<SignUp> {
SignUpPage( SignUpPage(
navControllerLogin = { navControllerLogin = {
@ -187,9 +206,7 @@ fun AppNavigator() {
navAccueil = { navController.navigate(Accueil(currentUserState.id)) }, navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(currentUserState.id)) }, navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(currentUserState.id)) }, navProfil = { navController.navigate(Profil(currentUserState.id)) },
navControllerQuiz = { idQuiz -> navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
navController.navigate(Quiz(currentUserState.id, idQuiz))
},
navRecap = { quoteContent, character, source -> navRecap = { quoteContent, character, source ->
navController.navigate( navController.navigate(
RecapSubmit( RecapSubmit(
@ -213,6 +230,8 @@ fun AppNavigator() {
navAccueil = { navController.navigate(Accueil(currentUserState.id)) }, navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(currentUserState.id)) }, navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(currentUserState.id)) }, navProfil = { navController.navigate(Profil(currentUserState.id)) },
navSearch = { navController.navigate(Search(currentUserState.id))},
navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
) )
@ -226,9 +245,11 @@ fun AppNavigator() {
navAccueil = { navController.navigate(Accueil(currentUserState.id)) }, navAccueil = { navController.navigate(Accueil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(currentUserState.id)) }, navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(currentUserState.id)) }, navProfil = { navController.navigate(Profil(currentUserState.id)) },
navSearch = { navController.navigate(Search(currentUserState.id))},
navControllerQuiz = { idQuiz -> navControllerQuiz = { idQuiz ->
navController.navigate(Quiz(currentUserState.id, idQuiz)) navController.navigate(Quiz(currentUserState.id, idQuiz))
}, },
navControllerRandomQuiz = { navController.navigate(QuizRandom(currentUserState.id)) }
) )
} }
@ -242,6 +263,7 @@ fun AppNavigator() {
navControllerQuizEnd = { idQuiz, pts -> navControllerQuizEnd = { idQuiz, pts ->
navController.navigate(QuizEnd(currentUserState.id, idQuiz, pts)) navController.navigate(QuizEnd(currentUserState.id, idQuiz, pts))
}, },
navSearch = { navController.navigate(Search(currentUserState.id))},
idQuiz = quiz.idQuiz, idQuiz = quiz.idQuiz,
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
@ -256,6 +278,23 @@ fun AppNavigator() {
navFavorite = { navController.navigate(Favorite(currentUserState.id)) }, navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
navProfil = { navController.navigate(Profil(currentUserState.id)) }, navProfil = { navController.navigate(Profil(currentUserState.id)) },
navQuiz = { navController.navigate(QuizMenu(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, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
) )

@ -5,58 +5,91 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.R import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.local.DailyQuoteStub import com.example.what_the_fantasy.data.local.DailyQuoteStub
import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.services.IServices import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.QuoteLittle import com.example.what_the_fantasy.ui.components.QuoteLittle
import com.example.what_the_fantasy.ui.states.CurrentUserState import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import com.example.what_the_fantasy.ui.theme.colorBackground
import kotlinx.coroutines.delay
@Composable @Composable
fun AccueilPage( fun AccueilPage(
navFavorite: (Int) -> Unit, navFavorite: () -> Unit,
navQuiz: (Int) -> Unit, navQuiz: () -> Unit,
navProfil: (Int) -> Unit, navProfil: () -> Unit,
navQuote: (Int) -> Unit, navQuote: (Int) -> Unit,
navSearch: () -> Unit,
services: IServices, services: IServices,
currentUserVM : CurrentUserViewModel, currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState, currentUserState : CurrentUserState,
) { ) {
var itemCount by remember { mutableIntStateOf(15) }
val dailyQuote = DailyQuoteStub.dailyQuote val dailyQuote = DailyQuoteStub.dailyQuote
val quotes = services.getAllQuote().take(itemCount)
val titleDalyQuote = stringResource(R.string.TitleHomeDailyQuote) val titleDalyQuote = stringResource(R.string.TitleHomeDailyQuote)
val titleSuggestion = stringResource(R.string.TitleHomeSuggestion) val titleSuggestion = stringResource(R.string.TitleHomeSuggestion)
val page = remember { mutableIntStateOf(1) }
val 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( NavBar(
onAccueil = true, onAccueil = true,
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = { },
navControllerProfil = navProfil, navControllerProfil = navProfil,
navControllerQuiz = navQuiz navControllerQuiz = navQuiz,
navControllerSearch = navSearch
) { ) {
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background(MaterialTheme.colorScheme.background) .background(MaterialTheme.colorScheme.background)
) { ) {
LazyColumn(modifier = Modifier.weight(1f)) { LazyColumn(modifier = Modifier.weight(1f), state = state) {
item{ item {
Column { Column(Modifier.clickable { navQuote(dailyQuote.id) }) {
Text( Text(
text = titleDalyQuote, text = titleDalyQuote,
color = MaterialTheme.colorScheme.onBackground, color = MaterialTheme.colorScheme.onBackground,
@ -66,9 +99,9 @@ fun AccueilPage(
.padding(16.dp), .padding(16.dp),
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
QuoteLittle(dailyQuote) QuoteLittle(dailyQuote)
} }
Text( Text(
text = titleSuggestion, text = titleSuggestion,
color = MaterialTheme.colorScheme.onBackground, color = MaterialTheme.colorScheme.onBackground,
@ -79,21 +112,18 @@ fun AccueilPage(
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
} }
items(quotes) { quote ->
Column(Modifier.clickable {navQuote(quote.id)} items(quotes) { quote ->
) { if (quote.language == currentUserState.langage) {
if(quote.language == currentUserState.langage){ Column(Modifier.clickable { navQuote(quote.id ) }) {
QuoteLittle(quote) QuoteLittle(quote)
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
} }
} }
} }
if (itemCount < quotes.size) {
item { item {
LaunchedEffect(itemCount) { if (lastItem?.index == quotes.size) {
itemCount += 15
}
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -102,6 +132,15 @@ fun AccueilPage(
) { ) {
CircularProgressIndicator() 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 @Composable
fun FavoritePage( fun FavoritePage(
navAccueil: (Int) -> Unit, navAccueil: () -> Unit,
navQuiz: (Int) -> Unit, navQuiz: () -> Unit,
navProfil: (Int) -> Unit, navProfil: () -> Unit,
navQuote: (Int) -> Unit, navQuote: (Int) -> Unit,
navSearch: () -> Unit,
services: IServices, services: IServices,
currentUserVM : CurrentUserViewModel, currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState, currentUserState : CurrentUserState,
@ -46,7 +47,8 @@ fun FavoritePage(
navControllerFavorite = { }, navControllerFavorite = { },
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,
navControllerQuiz = navQuiz navControllerQuiz = navQuiz,
navControllerSearch = navSearch
) { ) {
Box( Box(
modifier = Modifier modifier = Modifier

@ -1,5 +1,6 @@
package com.example.what_the_fantasy.ui.screens package com.example.what_the_fantasy.ui.screens
import android.util.Log
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -88,8 +89,6 @@ fun LoginPage(navControllerSignUp: () -> Unit,
} }
@Composable @Composable
fun IdentifiantTextField(textIdentifiantResId : Int, username : String, onValueChange: (String) -> Unit ) : String{ fun IdentifiantTextField(textIdentifiantResId : Int, username : String, onValueChange: (String) -> Unit ) : String{
val textIdentifiant = stringResource(id = textIdentifiantResId) val textIdentifiant = stringResource(id = textIdentifiantResId)
@ -103,6 +102,7 @@ fun IdentifiantTextField(textIdentifiantResId : Int, username : String, onValueC
.fillMaxWidth() .fillMaxWidth()
.padding(top = 8.dp), .padding(top = 8.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
maxLines = 1,
shape = RoundedCornerShape(16.dp) shape = RoundedCornerShape(16.dp)
) )
} }
@ -123,6 +123,7 @@ fun PassWdTextField(textpasswdResId : Int, password : String, onValueChange: (St
.fillMaxWidth() .fillMaxWidth()
.padding(top = 8.dp), .padding(top = 8.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
maxLines = 1,
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = { trailingIcon = {
IconButton(onClick = { passwordVisible = !passwordVisible }) { 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 @Composable
fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navController: () -> Unit) { 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 import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable @Composable
fun ProfilPage(navFavorite: (Int) -> Unit, fun ProfilPage(navFavorite: () -> Unit,
navAccueil: (Int) -> Unit, navAccueil: () -> Unit,
navQuiz: (Int) -> Unit, navQuiz: () -> Unit,
navUnLog: () -> Unit, navUnLog: () -> Unit,
navSubmitQuote: () -> Unit, navSubmitQuote: () -> Unit,
navSearch: () -> Unit,
currentUserVM : CurrentUserViewModel, currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState, currentUserState : CurrentUserState,
) { ) {
@ -71,8 +72,8 @@ fun ProfilPage(navFavorite: (Int) -> Unit,
currentUserState = currentUserState, currentUserState = currentUserState,
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = {}, navControllerQuiz = navQuiz,
navControllerQuiz = navQuiz navControllerSearch = navSearch
) { ) {
Box( Box(
@ -91,9 +92,9 @@ fun ProfilPage(navFavorite: (Int) -> Unit,
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
// Titre // Titre
TitlePageComponent(R.string.titleProfile, Color.White) TitlePageComponent(R.string.titleProfile, MaterialTheme.colorScheme.onBackground)
SpaceHeightComponent(16) SpaceHeightComponent(16)
// Image de profil // Image de profil
ImageProfil(currentUserState.imagePath, 120) ImageProfil(currentUserState.imagePath, 120)
@ -109,11 +110,11 @@ fun ProfilPage(navFavorite: (Int) -> Unit,
SpaceHeightComponent(16) SpaceHeightComponent(16)
// Bouton // 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) 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) 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 = "*****", text = "*****",
fontSize = 18.sp, fontSize = 18.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onPrimary color = MaterialTheme.colorScheme.primary
) )
Icon( Icon(
imageVector = Icons.Default.Edit, imageVector = Icons.Default.Edit,
contentDescription = "Modifier", contentDescription = "Modifier",
tint = MaterialTheme.colorScheme.onPrimary, tint =MaterialTheme.colorScheme.primary,
modifier = Modifier.size(16.dp).padding(start = 8.dp) modifier = Modifier.size(16.dp).padding(start = 8.dp)
) )
} }
} }
@Composable @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 text = stringResource(id = textResId)
val logsUser = LogsUsers() //gestion des logs pour les utilisateurs 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") logsUser.unlogInformationUserConnect("UserUnLog")
}, },
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background), colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
) { ) {
Text(text, fontSize = size.sp, color = MaterialTheme.colorScheme.primary) Text(text, fontSize = size.sp, color = colorTexte)
} }
} }
@Composable @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) val text = stringResource(id = textResId)
Button( Button(
@ -475,12 +476,12 @@ fun ButtonLanguage(textResId : Int, size :Int, colorButton : Color, currentUserV
colors = ButtonDefaults.buttonColors(containerColor = colorButton), colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
) { ) {
Text("${text} (${currentUserState.langage})", fontSize = size.sp, color = MaterialTheme.colorScheme.primary) Text("${text} (${currentUserState.langage})", fontSize = size.sp, color = colorTexte)
} }
} }
@Composable @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) val text = stringResource(id = textResId)
Button( Button(
@ -490,6 +491,6 @@ fun ButtonProfile(textResId : Int, size :Int, colorButton : Color,navController:
colors = ButtonDefaults.buttonColors(containerColor = colorButton), colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(), 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.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.material3.MaterialTheme
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle 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.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp 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.data.local.QuizStub
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.states.CurrentUserState import com.example.what_the_fantasy.ui.states.CurrentUserState
@ -30,10 +32,11 @@ val gradient = Brush.linearGradient(
fun QuizEndPage( fun QuizEndPage(
idQuiz: Int, idQuiz: Int,
points: Int, points: Int,
navFavorite: (Int) -> Unit, navFavorite: () -> Unit,
navAccueil: (Int) -> Unit, navAccueil: () -> Unit,
navProfil:(Int) -> Unit, navProfil:() -> Unit,
navQuiz: (Int) -> Unit, navQuiz: () -> Unit,
navSearch: () -> Unit,
currentUserVM : CurrentUserViewModel, currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState, currentUserState : CurrentUserState,
) { ) {
@ -43,7 +46,9 @@ fun QuizEndPage(
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,
navControllerQuiz = navQuiz) { navControllerQuiz = navQuiz,
navControllerSearch = navSearch
) {
Column( Column(
modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B)) modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B))
) { ) {
@ -68,16 +73,16 @@ fun QuizEndPage(
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
Column( Column(
modifier = Modifier modifier = Modifier
.background(brush = gradient, shape = RoundedCornerShape(20.dp)) .background(color = MaterialTheme.colorScheme.onPrimary, shape = RoundedCornerShape(20.dp))
.padding(30.dp) .padding(30.dp)
.fillMaxSize(), .fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly verticalArrangement = Arrangement.SpaceEvenly
) { ) {
val quiz = QuizStub.getQuizById(idQuiz) val quizName = if (idQuiz == -1) "Random Quiz" else QuizStub.getQuizById(idQuiz)?.name ?: "Quiz Inconnu"
val nbQuestions = quiz?.questions?.size
Text( Text(
text = "${quiz?.name}", text = quizName,
color = Color.White, color = Color.White,
style = TextStyle( style = TextStyle(
fontSize = 25.sp, fontSize = 25.sp,
@ -85,6 +90,7 @@ fun QuizEndPage(
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
) )
val nbQuestions = 10
Text( Text(
text = "Nombres de Questions : $nbQuestions", text = "Nombres de Questions : $nbQuestions",
color = Color.White, color = Color.White,

@ -3,6 +3,7 @@ package com.example.what_the_fantasy.ui.screens
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row 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.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
@ -38,10 +40,12 @@ import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
fun QuizMenu( fun QuizMenu(
currentUserVM : CurrentUserViewModel, currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState, currentUserState : CurrentUserState,
navFavorite: (Int) -> Unit, navFavorite: () -> Unit,
navAccueil: (Int) -> Unit, navAccueil: () -> Unit,
navProfil:(Int) -> Unit, navProfil:() -> Unit,
navControllerQuiz: (Int) -> Unit, navControllerQuiz: (Int) -> Unit,
navSearch: () -> Unit,
navControllerRandomQuiz:() -> Unit
) { ) {
NavBar(onQuiz = true, NavBar(onQuiz = true,
@ -50,16 +54,19 @@ fun QuizMenu(
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,
navControllerQuiz = { } navControllerSearch = navSearch
) { ) {
Column( Row(
modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background) modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
.horizontalScroll(state = rememberScrollState())
) { ) {
// Contenu princiapl // Contenu princiapl
Column( Column(
modifier = Modifier modifier = Modifier
.weight(0.9f) .width(400.dp)
.fillMaxSize() .fillMaxSize()
.padding(20.dp), .padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
@ -76,7 +83,7 @@ fun QuizMenu(
Spacer(Modifier.height(20.dp)) Spacer(Modifier.height(20.dp))
Column( Column(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colorScheme.onPrimary, shape = RoundedCornerShape(20.dp)) .background(MaterialTheme.colorScheme.primary, shape = RoundedCornerShape(20.dp))
.fillMaxSize() .fillMaxSize()
.padding(vertical = 30.dp) .padding(vertical = 30.dp)
.verticalScroll(rememberScrollState()), .verticalScroll(rememberScrollState()),
@ -115,7 +122,7 @@ fun QuizMenu(
fontSize = 17.sp, fontSize = 17.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
textAlign = TextAlign.Center, 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( fun QuizPage(
currentUserVM : CurrentUserViewModel, currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState, currentUserState : CurrentUserState,
navFavorite: (Int) -> Unit, navFavorite: () -> Unit,
navAccueil: (Int) -> Unit, navAccueil: () -> Unit,
navProfil:(Int) -> Unit, navProfil:() -> Unit,
navQuiz: (Int) -> Unit, navQuiz: () -> Unit,
navSearch: () -> Unit,
navControllerQuizEnd: (Int, Int) -> Unit, navControllerQuizEnd: (Int, Int) -> Unit,
@ -65,7 +66,8 @@ fun QuizPage(
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,
navControllerQuiz = navQuiz navControllerQuiz = navQuiz,
navControllerSearch = navSearch
){ ){
Column ( Column (
modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B)) 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.Context
import android.content.Intent 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.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size 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.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons 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.Favorite
import androidx.compose.material.icons.filled.FavoriteBorder import androidx.compose.material.icons.filled.FavoriteBorder
import androidx.compose.material.icons.filled.MailOutline import androidx.compose.material.icons.filled.MailOutline
import androidx.compose.material.icons.filled.Share import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable 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.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
@ -33,6 +55,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.R import com.example.what_the_fantasy.R
import coil.compose.AsyncImage 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.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.states.CurrentUserState 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.theme.whiteBackcgroundText
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
var isCommentVisible by mutableStateOf(false)
@Composable @Composable
fun QuotePage( fun QuotePage(
quoteId : Int, quoteId : Int,
service : IServices, service : IServices,
navAccueil: (Int) -> Unit, navAccueil: () -> Unit,
navFavorite:(Int) -> Unit, navFavorite:() -> Unit,
navQuiz: (Int) -> Unit, navQuiz: () -> Unit,
navProfil:(Int) -> Unit, navProfil:() -> Unit,
navSearch: () -> Unit,
currentUserVM : CurrentUserViewModel, 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 context = LocalContext.current
val user = service.getUserById(currentUserState.id) ?: return
val favorite by remember { mutableStateOf(service.isFavorite(id = quoteId, user = user)) }
NavBar(onProfile = true, NavBar(onProfile = true,
currentUserVM = currentUserVM, currentUserVM = currentUserVM,
currentUserState = currentUserState, currentUserState = currentUserState,
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,
navControllerQuiz = navQuiz navControllerQuiz = navQuiz,
navControllerSearch = navSearch
) { ) {
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background(colorBackground), .background(MaterialTheme.colorScheme.background),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
Column(modifier = Modifier Column(modifier = Modifier
.padding(15.dp) .padding(15.dp)
.drawBehind { .background(
drawRoundRect( color = MaterialTheme.colorScheme.primary,
gradienBox, shape = RoundedCornerShape(15.dp)
cornerRadius = CornerRadius(15.dp.toPx()), )
)
}
) { ) {
Row(modifier = Modifier.padding(15.dp)) { Row(modifier = Modifier.padding(15.dp)) {
ImageQuote( ImageQuote(
@ -86,12 +115,11 @@ fun QuotePage(
Column { Column {
FunctionalIcon( FunctionalIcon(
// --/!\-- a modifier --/!\-- isFavorite = favorite,
// isFavorite = service.isFavorite(id) userId = currentUserState.id,
// --------------------------
true,
id = quoteId, id = quoteId,
context = context context = context,
service = service
) )
QuoteText( QuoteText(
text = '"' + quote.content + '"' 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), modifier = Modifier.padding(start = 10.dp, top = 15.dp),
fontWeight = FontWeight(1000), fontWeight = FontWeight(1000),
fontSize = 20.sp, fontSize = 20.sp,
color = iconText color = MaterialTheme.colorScheme.onPrimary
) )
} }
@ -150,7 +196,7 @@ fun ImageQuote(imageUrl : String){
} }
@Composable @Composable
fun FunctionalIcon(isFavorite: Boolean, id : Int, context : Context){ fun FunctionalIcon(isFavorite: Boolean, userId : Int, id : Int, context : Context, service: IServices){
Row(modifier = Modifier Row(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
) { ) {
@ -160,13 +206,13 @@ fun FunctionalIcon(isFavorite: Boolean, id : Int, context : Context){
val sendIntent = Intent().apply { val sendIntent = Intent().apply {
action = Intent.ACTION_SEND action = Intent.ACTION_SEND
// lien a changer quand le site sra deployer // 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" type = "text/plain"
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) // Ajout pour compatibilité addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
} }
val shareIntent = Intent.createChooser(sendIntent, null) 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) context.startActivity(shareIntent)
}, },
@ -175,42 +221,44 @@ fun FunctionalIcon(isFavorite: Boolean, id : Int, context : Context){
Icon( Icon(
Icons.Default.Share, Icons.Default.Share,
contentDescription = stringResource(R.string.share), contentDescription = stringResource(R.string.share),
tint = iconText, tint = MaterialTheme.colorScheme.onPrimary,
) )
} }
IconButton( IconButton(
onClick = { }, //Go to comment onClick = {
isCommentVisible = !isCommentVisible
},
modifier = Modifier.padding(start = 20.dp) modifier = Modifier.padding(start = 20.dp)
){ ){
Icon( Icon(
Icons.Default.MailOutline, Icons.Default.MailOutline,
contentDescription = stringResource(R.string.comment), contentDescription = stringResource(R.string.comment),
tint = iconText, tint = MaterialTheme.colorScheme.onPrimary,
) )
} }
if(isFavorite){ if(isFavorite){
IconButton( IconButton(
onClick = { }, //Go to comment onClick = { service.SupFav(userId = userId, QuoteId = id)}, //sup fav
modifier = Modifier.padding(start = 20.dp) modifier = Modifier.padding(start = 20.dp)
){ ){
Icon( Icon(
Icons.Default.Favorite, Icons.Default.Favorite,
contentDescription = stringResource(R.string.favorite), contentDescription = stringResource(R.string.favorite),
tint = likeIcon, tint = MaterialTheme.colorScheme.onPrimary,
) )
} }
} }
else{ else{
IconButton( IconButton(
onClick = { }, //Go to comment onClick = { service.AddFav(userId = userId, QuoteId = id)}, //add fav
modifier = Modifier.padding(start = 50.dp) modifier = Modifier.padding(start = 50.dp)
){ ){
Icon( Icon(
Icons.Default.FavoriteBorder, Icons.Default.FavoriteBorder,
contentDescription = stringResource(R.string.favorite), 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), text = stringResource(id = nameId),
fontSize = 18.sp, fontSize = 18.sp,
fontWeight = FontWeight(500), fontWeight = FontWeight(500),
color = iconText color = MaterialTheme.colorScheme.onPrimary
) )
Text( Text(
text = text, text = text,
color = whiteBackcgroundText, color = MaterialTheme.colorScheme.onBackground,
fontSize = 16.sp, fontSize = 16.sp,
fontWeight = FontWeight(400), fontWeight = FontWeight(400),
modifier = Modifier modifier = Modifier
.drawBehind { .background(
drawRoundRect( color = MaterialTheme.colorScheme.background,
Color(255,255,255), shape = RoundedCornerShape(15.dp)
cornerRadius = CornerRadius(15.dp.toPx()) )
) .padding(5.dp)
}
.padding(5.dp),
) )
} }
} }
@ -248,11 +294,103 @@ fun InfoQuoteText(nameId : Int, text : String){
fun LikeInfo(likes : Int){ fun LikeInfo(likes : Int){
Text( Text(
text = likes.toString(), text = likes.toString(),
color = iconText color = MaterialTheme.colorScheme.onPrimary
) )
Icon( Icon(
Icons.Default.Favorite, Icons.Default.Favorite,
contentDescription = stringResource(R.string.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.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -45,9 +46,11 @@ import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
@Composable @Composable
fun RecapSubmitPage( fun RecapSubmitPage(
navFavorite: (Int) -> Unit, navFavorite: () -> Unit,
navAccueil: (Int) -> Unit, navAccueil: () -> Unit,
navProfil:(Int) -> Unit, navProfil:() -> Unit,
navSearch: () -> Unit,
navQuiz : () -> Unit,
quoteContent : String, quoteContent : String,
character: String, character: String,
source: String, source: String,
@ -60,11 +63,14 @@ fun RecapSubmitPage(
navControllerFavorite = navFavorite, navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil, navControllerAccueil = navAccueil,
navControllerProfil = navProfil, navControllerProfil = navProfil,
navControllerQuiz = { } navControllerQuiz = navQuiz,
navControllerSearch = navSearch
) { ) {
Column( Column(
modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B)) modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
) { ) {
// Contenu princiapl // Contenu princiapl
Column( Column(
@ -76,7 +82,7 @@ fun RecapSubmitPage(
) { ) {
Text( Text(
text = "▶ Recap de la citation ◀", text = "▶ Recap de la citation ◀",
color = Color.White, color = MaterialTheme.colorScheme.onBackground,
style = TextStyle( style = TextStyle(
fontSize = 25.sp, fontSize = 25.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
@ -137,7 +143,7 @@ fun QuoteText2(text: String ){
modifier = Modifier.padding(start = 10.dp, top = 15.dp), modifier = Modifier.padding(start = 10.dp, top = 15.dp),
fontWeight = FontWeight(1000), fontWeight = FontWeight(1000),
fontSize = 20.sp, fontSize = 20.sp,
color = Color.White color = MaterialTheme.colorScheme.background
) )
} }

@ -1,8 +1,179 @@
package com.example.what_the_fantasy.ui.screens 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.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 @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( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background(colorBackground) .background(MaterialTheme.colorScheme.background)
.verticalScroll(rememberScrollState()), .verticalScroll(rememberScrollState()),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
){ ){
@ -66,12 +66,12 @@ fun SignUpPage(navControllerLogin: () -> Unit, signInUserVM :SignInUserViewModel
.fillMaxWidth(0.9f) .fillMaxWidth(0.9f)
.padding(20.dp) .padding(20.dp)
.clip(RoundedCornerShape(16.dp)) .clip(RoundedCornerShape(16.dp))
.background(gradienBox) .background(MaterialTheme.colorScheme.onPrimary)
.padding(20.dp), .padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally 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 IdentifiantTextFieldSign(R.string.IdentifiantLogin,signInState.username){ // Username
signInUserVM.setUsername(it) signInUserVM.setUsername(it)

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

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

@ -13,6 +13,7 @@
<string name="favorite">Favoris</string> <string name="favorite">Favoris</string>
<string name="like">Likes</string> <string name="like">Likes</string>
<string name="profilePict">Image de profil</string> <string name="profilePict">Image de profil</string>
<string name="send">Envoyer</string>
//Page Login //Page Login
<string name="titleLogin">Connexion au compte</string> <string name="titleLogin">Connexion au compte</string>
@ -68,4 +69,16 @@
<string name="timeCode">Time Code</string> <string name="timeCode">Time Code</string>
<string name="year">Année</string> <string name="year">Année</string>
<string name="ErrorSubmitQuote">Champs Invalides</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> </resources>

@ -8,10 +8,11 @@
<string name="charac">Character</string> <string name="charac">Character</string>
<string name="source">Source</string> <string name="source">Source</string>
<string name="share">Share</string> <string name="share">Share</string>
<string name="comment">comment</string> <string name="comment">Comment</string>
<string name="favorite">favorite</string> <string name="favorite">Favorite</string>
<string name="like">likes</string> <string name="like">Likes</string>
<string name="profilePict">Profile picture</string> <string name="profilePict">Profile picture</string>
<string name="send">Send</string>
//Page Login //Page Login
<string name="titleLogin">Account login</string> <string name="titleLogin">Account login</string>
@ -64,4 +65,16 @@
<string name="timeCode">Time Code</string> <string name="timeCode">Time Code</string>
<string name="year">Year</string> <string name="year">Year</string>
<string name="ErrorSubmitQuote"> Invalid Fields </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> </resources>
Loading…
Cancel
Save