Finition du merge entre Search et master avec une mise en cohérence du style

SearchPage
brongniart 4 weeks ago
commit 9d8738e398

@ -4,13 +4,25 @@ import android.util.Log
import com.example.what_the_fantasy.data.model.User
class LogsUsers{
fun logDebugDisplayUsers(users : List<User>, titleLog : String){
fun logDebugAllUsers(users : List<User>, titleLog : String){
for(user in users){
Log.e(titleLog, "User created: ${user.username} => ${user.email} => ${user.imgUrl} => ${user.language}")
Log.e(titleLog, "User created: ${user.username} => ${user.email} => ${user.imgUrl} => ${user.langage}")
}
}
fun logDebugDisplayUser(user : User, titleLog : String){
Log.e(titleLog, "User created: ${user.username} => ${user.email}")
fun logDebugUserEmail(user : User?, titleLog : String){
Log.e(titleLog, "User created: ${user?.username} => ${user?.email}")
}
fun logDebugUserLangage(user : User?, titleLog : String){
Log.e(titleLog, "User Change: ${user?.username} => ${user?.langage}")
}
fun logInformationUserConnect(user : User?, titleLog : String){
Log.e(titleLog, "${user?.username} logged in")
}
fun unlogInformationUserConnect(titleLog : String){
Log.e(titleLog, "Logged out")
}
}

@ -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"),
)
}

@ -1,27 +1,21 @@
package com.example.what_the_fantasy.data.local
import com.example.what_the_fantasy.data.local.QuoteStub.quotes
import com.example.what_the_fantasy.data.local.UserStub.users
import com.example.what_the_fantasy.data.model.Favorite
import com.example.what_the_fantasy.data.model.Quote
object FavoriteStub {
val favorites: MutableList<Favorite> = mutableListOf(
Favorite(UserStub.users[0], QuoteStub.quote1),
Favorite(UserStub.users[1], QuoteStub.quote12),
Favorite(UserStub.users[2], QuoteStub.quote13),
Favorite(UserStub.users[3], QuoteStub.quote6),
Favorite(UserStub.users[4], QuoteStub.quote5),
Favorite(UserStub.users[5], QuoteStub.quote3),
Favorite(UserStub.users[6], QuoteStub.quote17),
Favorite(UserStub.users[7], QuoteStub.quote7),
Favorite(UserStub.users[8], QuoteStub.quote19),
Favorite(UserStub.users[9], QuoteStub.quote20),
Favorite(UserStub.users[10], QuoteStub.quote11)
Favorite(users[0], mutableListOf(quotes[0], quotes[1], quotes[12])), // Aragorn123 aime ces citations
Favorite(users[1], mutableListOf(quotes[5], quotes[6], quotes[7])), // Legolas456 aime ces citations
Favorite(users[2], mutableListOf(quotes[8], quotes[9], quotes[10])), // Gandalf789 aime ces citations
Favorite(users[3], mutableListOf(quotes[11], quotes[12], quotes[13])), // FrodoBaggins aime ces citations
Favorite(users[4], mutableListOf(quotes[14], quotes[15], quotes[16])), // Gimli999 aime ces citations
Favorite(users[5], mutableListOf(quotes[17], quotes[18], quotes[19])), // Galadriel321 aime ces citations
Favorite(users[6], mutableListOf(quotes[17], quotes[2], quotes[7])), // Boromir654 aime ces citations
Favorite(users[7], mutableListOf(quotes[3], quotes[4], quotes[10])), // Eowyn777 aime ces citations
Favorite(users[8], mutableListOf(quotes[6], quotes[8], quotes[9])), // Saruman888 aime ces citations
Favorite(users[9], mutableListOf(quotes[5], quotes[13], quotes[15])), // Faramir222 aime ces citations
Favorite(users[10], mutableListOf(quotes[12], quotes[17], quotes[16])) // dev aime ces citations
)
fun getFavoritesByUser(userId: Int): List<Quote> {
return favorites
.filter { it.user.id == userId }
.map { it.quote }
}
}

@ -6,229 +6,26 @@ import com.example.what_the_fantasy.data.model.SrcType
object QuoteStub {
val quote1 = Quote(
id = 1,
content = "All we have to decide is what to do with the time that is given us.",
likes = 466,
language = SrcLanguage.vo,
character = CharacterStub.gandalf.name,
source = "The Lord of the Rings: The Fellowship of the Ring",
date = 2000,
type = SrcType.Movie,
imgUrl = CharacterStub.gandalf.imgUrl
)
val quote2 = Quote(
id = 2,
content = "A wizard is never late, nor is he early, he arrives precisely when he means to.",
likes = 467,
language = SrcLanguage.vo,
character = CharacterStub.gandalf.name,
source = "The Lord of the Rings: The Fellowship of the Ring",
imgUrl = CharacterStub.gandalf.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote3 = Quote(
id = 3,
content = "Even the smallest person can change the course of the future.",
likes = 466,
language = SrcLanguage.vo,
character = CharacterStub.galadriel.name,
source = "The Lord of the Rings: The Fellowship of the Ring",
imgUrl = CharacterStub.galadriel.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote4 = Quote(
id = 4,
content = "I would rather share one lifetime with you than face all the ages of this world alone.",
likes = 120,
language = SrcLanguage.vo,
character = CharacterStub.arwen.name,
source = "The Lord of the Rings: The Fellowship of the Ring",
imgUrl = CharacterStub.arwen.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote5 = Quote(
id = 5,
content = "Faithless is he that says farewell when the road darkens.",
likes = 150,
language = SrcLanguage.vo,
character = CharacterStub.gimli.name,
source = "The Lord of the Rings: The Fellowship of the Ring",
imgUrl = CharacterStub.gimli.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote6 = Quote(
id = 6,
content = "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.",
likes = 200,
language = SrcLanguage.vo,
character = CharacterStub.frodoBaggins.name,
source = "The Lord of the Rings: The Fellowship of the Ring",
imgUrl = CharacterStub.frodoBaggins.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote7 = Quote(
id = 7,
content = "I am no man.",
likes = 300,
language = SrcLanguage.vo,
character = CharacterStub.eowyn.name,
source = "The Lord of the Rings: The Return of the King",
imgUrl = CharacterStub.eowyn.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote8 = Quote(
id = 8,
content = "The world is changed. I feel it in the water. I feel it in the earth. I smell it in the air.",
likes = 400,
language = SrcLanguage.vo,
character = CharacterStub.treebeard.name,
source = "The Lord of the Rings: The Two Towers",
imgUrl = CharacterStub.treebeard.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote9 = Quote(
id = 9,
content = "We wants it, we needs it. Must have the precious.",
likes = 500,
language = SrcLanguage.vo,
character = CharacterStub.gollum.name,
source = "The Lord of the Rings: The Two Towers",
imgUrl = CharacterStub.gollum.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote10 = Quote(
id = 10,
content = "The board is set, the pieces are moving. We come to it at last, the great battle of our time.",
likes = 600,
language = SrcLanguage.vo,
character = CharacterStub.gandalf.name,
source = "The Lord of the Rings: The Return of the King",
imgUrl = CharacterStub.gandalf.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote11 = Quote(
id = 11,
content = "Un grand pouvoir implique de grandes responsabilités.",
likes = 466,
language = SrcLanguage.fr,
character = CharacterStub.aragorn.name,
source = "Spider-Man",
imgUrl = CharacterStub.aragorn.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote12 = Quote(
id = 12,
content = "Que la Force soit avec toi.",
likes = 467,
language = SrcLanguage.fr,
character = CharacterStub.legolas.name,
source = "Star Wars",
imgUrl = CharacterStub.legolas.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote13 = Quote(
id = 13,
content = "La magie est partout. Il suffit de savoir où la trouver.",
likes = 466,
language = SrcLanguage.fr,
character = CharacterStub.gandalf.name,
source = "Harry Potter",
imgUrl = CharacterStub.gandalf.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote14 = Quote(
id = 14,
content = "Le monde est plein de choses magiques, patientant que nos sens s'aiguisent.",
likes = 120,
language = SrcLanguage.fr,
character = CharacterStub.frodoBaggins.name,
source = "Le Seigneur des Anneaux",
imgUrl = CharacterStub.frodoBaggins.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote15 = Quote(
id = 15,
content = "La peur mène à la colère, la colère mène à la haine, la haine mène à la souffrance.",
likes = 150,
language = SrcLanguage.fr,
character = CharacterStub.gimli.name,
source = "Star Wars",
imgUrl = CharacterStub.gimli.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote16 = Quote(
id = 16,
content = "La vie est une aventure audacieuse ou rien du tout.",
likes = 200,
language = SrcLanguage.fr,
character = CharacterStub.galadriel.name,
source = "Helen Keller",
imgUrl = CharacterStub.galadriel.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote17 = Quote(
id = 17,
content = "Le courage n'est pas l'absence de peur, mais la capacité de vaincre ce qui fait peur.",
likes = 300,
language = SrcLanguage.fr,
character = CharacterStub.boromir.name,
source = "Nelson Mandela",
imgUrl = CharacterStub.boromir.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote18 = Quote(
id = 18,
content = "La folie, c'est de faire toujours la même chose et de s'attendre à un résultat différent.",
likes = 400,
language = SrcLanguage.fr,
character = CharacterStub.eowyn.name,
source = "Albert Einstein",
imgUrl = CharacterStub.eowyn.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote19 = Quote(
id = 19,
content = "Le bonheur n'est pas quelque chose de tout fait. Il vient de vos propres actions.",
likes = 500,
language = SrcLanguage.fr,
character = CharacterStub.saruman.name,
source = "Dalaï Lama",
imgUrl = CharacterStub.saruman.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val quote20 = Quote(
id = 20,
content = "La vie est un mystère qu'il faut vivre, et non un problème à résoudre.",
likes = 600,
language = SrcLanguage.fr,
character = CharacterStub.samwiseGamgee.name,
source = "Gandhi",
imgUrl = CharacterStub.samwiseGamgee.imgUrl,
date = 2000,
type = SrcType.Movie,
)
val allQuotes: List<Quote> = listOf(
quote1, quote2, quote3, quote4, quote5, quote6, quote7, quote8, quote9, quote10,
quote11, quote12, quote13, quote14, quote15, quote16, quote17, quote18, quote19, quote20
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(2, "A wizard is never late, nor is he early, he arrives precisely when he means to.", 467, SrcLanguage.vo, CharacterStub.gandalf.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.gandalf.imgUrl, SrcType.Movie, 2000),
Quote(3, "Even the smallest person can change the course of the future.", 466, SrcLanguage.vo, CharacterStub.galadriel.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.galadriel.imgUrl, SrcType.Movie, 2000),
Quote(4, "I would rather share one lifetime with you than face all the ages of this world alone.", 120, SrcLanguage.vo, CharacterStub.arwen.name, "The Lord of the Rings: The Fellowship of the Ring", CharacterStub.arwen.imgUrl, SrcType.Movie, 2000),
Quote(5, "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(6, "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(7, "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(8, "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(9, "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(10, "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(11, "Un grand pouvoir implique de grandes responsabilités.", 466, SrcLanguage.vf, CharacterStub.aragorn.name, "Spider-Man", CharacterStub.aragorn.imgUrl, SrcType.Series, 2000),
Quote(12, "Que la Force soit avec toi.", 467, SrcLanguage.vf, CharacterStub.legolas.name, "Star Wars", CharacterStub.legolas.imgUrl, SrcType.Movie, 2000),
Quote(13, "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(14, "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(15, "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(16, "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(17, "Le courage n'est pas l'absence de peur, mais la capacité de vaincre ce qui fait peur.", 300, SrcLanguage.vf, CharacterStub.boromir.name, "Nelson Mandela", CharacterStub.boromir.imgUrl, SrcType.Movie, 2000),
Quote(18, "La folie, c'est de faire toujours la même chose et de s'attendre à un résultat différent.", 400, SrcLanguage.vf, CharacterStub.eowyn.name, "Albert Einstein", CharacterStub.eowyn.imgUrl, SrcType.Movie, 2000),
Quote(19, "Le bonheur n'est pas quelque chose de tout fait. Il vient de vos propres actions.", 500, SrcLanguage.vo, CharacterStub.saruman.name, "Dalaï Lama", CharacterStub.saruman.imgUrl, SrcType.Movie, 2000),
Quote(20, "La vie est un mystère qu'il faut vivre, et non un problème à résoudre.", 600, SrcLanguage.vo, CharacterStub.samwiseGamgee.name, "Gandhi", CharacterStub.samwiseGamgee.imgUrl, SrcType.Movie, 2000)
)
}

@ -6,18 +6,16 @@ import com.example.what_the_fantasy.data.model.User
object UserStub {
//LE MOT DE PASSE POUR TOUS LES UTILISATEURS EST : 1234
val users: MutableList<User> = mutableListOf(
User(1, "Aragorn123", "aragorn@example.com", "2022-01-15", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-fantaisie_1045-185.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.fr), //1234
User(2, "Legolas456", "legolas@example.com", "2021-05-23", "https://img.freepik.com/vecteurs-libre/personnage-elfe-fantaisie_1045-186.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.fr),//1234
User(3, "Gandalf789", "gandalf@example.com", "2020-09-10", "https://img.freepik.com/vecteurs-libre/personnage-magicien-fantaisie_1045-187.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.fr),//1234
User(4, "FrodoBaggins", "frodo@example.com", "2023-03-18", "https://img.freepik.com/vecteurs-libre/personnage-hobbit-fantaisie_1045-188.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.fr),//1234
User(1, "Aragorn123", "aragorn@example.com", "2022-01-15", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-fantaisie_1045-185.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vf), //1234
User(2, "Legolas456", "legolas@example.com", "2021-05-23", "https://img.freepik.com/vecteurs-libre/personnage-elfe-fantaisie_1045-186.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vf),//1234
User(3, "Gandalf789", "gandalf@example.com", "2020-09-10", "https://img.freepik.com/vecteurs-libre/personnage-magicien-fantaisie_1045-187.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vf),//1234
User(4, "FrodoBaggins", "frodo@example.com", "2023-03-18", "https://img.freepik.com/vecteurs-libre/personnage-hobbit-fantaisie_1045-188.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vf),//1234
User(5, "Gimli999", "gimli@example.com", "2022-07-04", "https://img.freepik.com/vecteurs-libre/personnage-nain-fantaisie_1045-189.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234
User(6, "Galadriel321", "galadriel@example.com", "2021-11-30", "https://img.freepik.com/vecteurs-libre/personnage-elfe-femme-fantaisie_1045-190.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234
User(7, "Boromir654", "boromir@example.com", "2023-06-22", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-191.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234
User(8, "Eowyn777", "eowyn@example.com", "2022-04-11", "https://img.freepik.com/vecteurs-libre/personnage-guerriere-femme-fantaisie_1045-192.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234
User(9, "Saruman888", "saruman@example.com", "2021-08-15", "https://img.freepik.com/vecteurs-libre/personnage-magicien-malefique-fantaisie_1045-193.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234
User(10, "Faramir222", "faramir@example.com", "2023-02-08", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo),//1234
User(11, "dev", "testeur@example.com", "2023-02-08", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.fr)//1234
User(11, "dev", "testeur@example.com", "2023-02-08", "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg", "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", SrcLanguage.vo)//1234
)
}

@ -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
)

@ -2,5 +2,5 @@ package com.example.what_the_fantasy.data.model
class Favorite (
val user: User,
val quote: Quote
val quote: List<Quote>
)

@ -1,6 +1,6 @@
package com.example.what_the_fantasy.data.model
enum class SrcLanguage {
fr,
vf,
vo
}

@ -7,5 +7,5 @@ class User(
var date:String,
val imgUrl: String,
var password: String,
val language : SrcLanguage
var langage : SrcLanguage
)

@ -1,27 +1,33 @@
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.User
interface IServices {
fun EditUsername(username : String, index : Int)
fun EditEmail(email : String, index : Int)
fun EditUsername(username : String, index : Int) : Boolean
fun EditEmail(email : String, index : Int) : Boolean
fun EditPasswd(passwd : String, index : Int)
fun EditImage(imageURL : String, index : Int)
fun ChangeLangage(user: User)
fun AddFav(userId: Int, QuoteId : Int)
fun SupFav(userId: Int, QuoteId : Int)
fun AddComment(content : String)
fun CreateUser(username : String, email : String, passwd : String, services : IServices) : Boolean
fun getFavorite(username: String)
fun getFavorite(user: User): List<Quote>
fun getAllUsers(): List<User>
fun getComment(quoteId : Int) : List<Comment>
fun getUserById(id: Int): User?
fun SearchQuote(quote : String)
fun getQuote( id : Int): Quote?
fun isFavorite(id : Int): Boolean
fun isFavorite(id : Int, user: User): Boolean
fun getAllFavorite(): List<Favorite>
fun getAllQuote(): List<Quote>
fun search(type : String ,search:String ,indexCount: Int): List<Quote>
}

@ -1,14 +1,17 @@
package com.example.what_the_fantasy.data.services
import com.example.what_the_fantasy.data.model.Comment
import com.example.what_the_fantasy.data.model.Favorite
import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.model.User
//import com.example.what_the_fantasy.ui.navigations.Destination
class ServicesAPI : IServices {
override fun EditUsername(username: String, index : Int) {
override fun EditUsername(username: String, index : Int): Boolean {
TODO("Not yet implemented")
}
override fun EditEmail(email: String, index : Int) {
override fun EditEmail(email: String, index : Int): Boolean {
TODO("Not yet implemented")
}
@ -20,10 +23,30 @@ class ServicesAPI : IServices {
TODO("Not yet implemented")
}
override fun ChangeLangage(user: User) {
TODO("Not yet implemented")
}
override fun AddFav(userId: Int, QuoteId: Int) {
TODO("Not yet implemented")
}
override fun SupFav(userId: Int, QuoteId: Int) {
TODO("Not yet implemented")
}
override fun AddComment(content: String) {
TODO("Not yet implemented")
}
override fun CreateUser(username: String, email: String, passwd: String, services: IServices) : Boolean {
TODO("Not yet implemented")
}
override fun getFavorite(user: User): List<Quote> {
TODO("Not yet implemented")
}
override fun SearchQuote(quote: String) {
TODO("Not yet implemented")
}
@ -32,11 +55,15 @@ class ServicesAPI : IServices {
TODO("Not yet implemented")
}
override fun isFavorite(id: Int): Boolean {
override fun isFavorite(id: Int, user: User): Boolean {
TODO("Not yet implemented")
}
override fun getAllFavorite(): List<Favorite> {
TODO("Not yet implemented")
}
override fun getFavorite(username: String) {
override fun getAllQuote(): List<Quote> {
TODO("Not yet implemented")
}
@ -44,6 +71,10 @@ class ServicesAPI : IServices {
TODO("Not yet implemented")
}
override fun getComment(quoteId: Int): List<Comment> {
TODO("Not yet implemented")
}
override fun getUserById(id: Int): User? {
TODO("Not yet implemented")
}

@ -5,7 +5,12 @@ import android.util.Log
import com.example.what_the_fantasy.data.local.UserStub.users
import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.Logs.LogsUsers
import com.example.what_the_fantasy.data.local.FavoriteStub.favorites
import com.example.what_the_fantasy.data.local.QuoteStub.quotes
import com.example.what_the_fantasy.data.model.Favorite
import com.example.what_the_fantasy.data.local.CommentStub.comments
import com.example.what_the_fantasy.data.local.QuoteStub
import com.example.what_the_fantasy.data.model.Comment
import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.ui.components.hashPassword
@ -14,20 +19,29 @@ import java.time.LocalDate
class ServicesStub : IServices {
val logsUser = LogsUsers() //gestion des logs pour les utilisateurs
override fun EditUsername(username: String, index : Int) {
override fun EditUsername(username: String, index : Int) : Boolean{
val user = getUserById(index)
if(!isUsernameExist(username)){
user?.username = username
return true
}
//Afficher tous les users
logsUser.logDebugDisplayUsers(getAllUsers(), "UsernameUpdate")
logsUser.logDebugUserEmail(user, "UsernameUpdate")
return false
}
override fun EditEmail(email: String,index : Int) {
override fun EditEmail(email: String,index : Int) : Boolean {
val user = getUserById(index)
user?.email = email
if(!isEmailExist(email)){
user?.email = email
return true
}
//Afficher tous les users
logsUser.logDebugDisplayUsers(getAllUsers(), "EmailUpdate")
logsUser.logDebugAllUsers(getAllUsers(), "EmailUpdate")
return false
}
override fun EditPasswd(passwd: String,index : Int) {
@ -36,34 +50,67 @@ class ServicesStub : IServices {
user?.password = passwordhash
//Afficher tous les users en log
logsUser.logDebugDisplayUsers(getAllUsers(), "PasswordUpdate")
logsUser.logDebugAllUsers(getAllUsers(), "PasswordUpdate")
}
override fun EditImage(imageURL: String,index : Int) {
TODO("Not yet implemented")
}
override fun ChangeLangage(user: User) {
if(user.langage == SrcLanguage.vo){
user.langage = SrcLanguage.vf
}
else{
user.langage = SrcLanguage.vo
}
logsUser.logDebugUserLangage(user, "ChangeLangue")
}
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, services : IServices) : Boolean {
val date =dateDuJour()
val passwordhash = hashPassword(passwd)
val userStub = services.getAllUsers()
val nbUser = userStub.size
for (user in userStub) {
if (user.username == username) {
return false
}
}
if(!isUsernameExist(username) && !isEmailExist(email)){
val user = User(nbUser+1,username, email, date,randomImage(userStub), passwordhash, SrcLanguage.vo)
users.add(user)//ajout au stub
//Afficher tous les users
logsUser.logDebugDisplayUsers(users, "CreateUser")
logsUser.logDebugAllUsers(users, "CreateUser")
return true
}
return false
}
override fun getFavorite(user: User): List<Quote> {
val favorite = favorites
return favorite[user.id-1].quote
//return emptyList()
}
override fun getAllFavorite(): List<Favorite> = favorites
override fun getAllQuote(): List<Quote> = quotes
override fun getAllUsers(): List<User> = users
override fun getComment(quoteId: Int): List<Comment> = comments
override fun getUserById(id: Int): User? {
return (users.find { it.id == id+1 })
}
@ -73,16 +120,15 @@ class ServicesStub : IServices {
}
override fun getQuote(id: Int): Quote? {
return (QuoteStub.allQuotes.find { it.id == id })
return (quotes.find { it.id == id })
}
override fun isFavorite(id: Int): Boolean {
TODO("Not yet implemented")
override fun isFavorite(id: Int, user: User): Boolean {
var quote = getFavorite(user)
return quote.find{ it.id == id } != null
}
override fun getFavorite(username: String) {
TODO("Not yet implemented")
}
//------------------------------------------------------
@ -96,8 +142,28 @@ class ServicesStub : IServices {
return "https://img.freepik.com/vecteurs-libre/personnage-guerrier-homme-fantaisie_1045-194.jpg?size=338&ext=jpg"
}
fun isUsernameExist(username : String) : Boolean{
val userStub = getAllUsers()
for (user in userStub) {
if (user.username == username) {
return true
}
}
return false
}
fun isEmailExist(email : String) : Boolean{
val userStub = getAllUsers()
for (user in userStub) {
if (user.email == email) {
return true
}
}
return false
}
override fun search(type : String ,search:String ,indexCount: Int): List<Quote> {
return (QuoteStub.allQuotes.filter {
return (getAllQuote().filter {
when (type) {
"personnage" -> {
it.character.uppercase().contains(search.uppercase())

@ -20,3 +20,14 @@ fun ErrorMessageProfileComponent(titleResId : Int) {
modifier = Modifier.padding(top = 4.dp)
)
}
@Composable
fun ErrorMessageSubmitQuoteComponent(titleResId: Int) {
val textError = stringResource(id = titleResId)
Text(
text = textError,
color = Color.Red,
fontSize = 12.sp,
modifier = Modifier.padding(top = 4.dp)
)
}

@ -19,6 +19,7 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonColors
import androidx.compose.material3.IconToggleButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@ -56,7 +57,7 @@ fun NavBar(onProfile : Boolean = false ,
NavigationBar(
modifier = Modifier
.fillMaxWidth(),
containerColor = colorNavBar
containerColor = MaterialTheme.colorScheme.onPrimary
) {
Row(
modifier = Modifier
@ -66,26 +67,9 @@ fun NavBar(onProfile : Boolean = false ,
) {
ButtonIconVector(Icons.Rounded.AccountCircle,stringResource(R.string.NavProfile),navControllerProfil,onProfile)
Row{
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 = Color.White
)
}
}
}
}
@ -97,7 +81,7 @@ fun NavBar(onProfile : Boolean = false ,
BottomAppBar (modifier = Modifier
.fillMaxSize(),
containerColor = colorNavBar
containerColor = MaterialTheme.colorScheme.onPrimary
) {
Row(modifier = Modifier
.fillMaxSize(),
@ -129,8 +113,8 @@ fun NavBar(onProfile : Boolean = false ,
fun ButtonIconVector(img : ImageVector, name : String, nav : ()->Unit,onPage : Boolean){
IconButton(onClick = {nav()},
enabled = !onPage,
colors = IconButtonColors(Color.Transparent, colorButtonNav,//couleur quand il n'est pas selectionné
Color.Transparent, colorButtonNavSelected),//couleur quand il est 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é
modifier = Modifier
.size(60.dp)
) {
@ -147,15 +131,15 @@ fun ButtonIconVector(img : ImageVector, name : String, nav : ()->Unit,onPage : B
fun ButtonIconPainter(img : Painter, name : String, nav : ()->Unit,onPage : Boolean){
IconButton(onClick = {nav()},
enabled = !onPage,
colors = IconButtonColors(Color.Transparent,colorButtonNav,//couleur quand il n'est pas selectionné
Color.Transparent, colorButtonNavSelected),//couleur quand il est 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é
modifier = Modifier
.size(60.dp)
) {
Icon(img,
contentDescription = name,
modifier = Modifier
.fillMaxSize()
.size(50.dp)
)
}
}

@ -10,29 +10,33 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.rememberAsyncImagePainter
import coil.compose.rememberImagePainter
import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.ui.theme.colorBackground
import com.example.what_the_fantasy.ui.theme.gradienBox
@Composable
fun QuoteLittle(quote: Quote, modifier: Modifier = Modifier) {
val Character = stringResource(R.string.CharacterQuote)
Row(
modifier = modifier
.fillMaxWidth()
.padding(8.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorBackground)
.background(MaterialTheme.colorScheme.background)
) {
Image(
painter = rememberAsyncImagePainter(quote.imgUrl),
@ -60,12 +64,12 @@ fun QuoteLittle(quote: Quote, modifier: Modifier = Modifier) {
bottomEnd = 12.dp
)
)
.background(gradienBox)
.background(MaterialTheme.colorScheme.primary)
.padding(12.dp)
) {
Text(
text = quote.content,
color = Color.White,
color = MaterialTheme.colorScheme.onPrimary,
fontSize = 16.sp,
maxLines = 2,
overflow = TextOverflow.Ellipsis
@ -73,15 +77,15 @@ fun QuoteLittle(quote: Quote, modifier: Modifier = Modifier) {
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Film : ${quote.source}",
color = Color.White,
text = "${quote.type} : ${quote.source}",
color = MaterialTheme.colorScheme.onPrimary,
fontSize = 12.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
Text(
text = "Personnage : ${quote.character}",
color = Color.White,
text = "${Character}: ${quote.character}",
color = MaterialTheme.colorScheme.onPrimary,
fontSize = 12.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis

@ -3,6 +3,7 @@ package com.example.what_the_fantasy.ui.navigations
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@ -46,7 +47,14 @@ data class Search(val userIndex: Int,val type : String = "contenue", val search:
data object SignUp
@Serializable
data object SubmitQuote
data class SubmitQuote(val userIndex: Int)
@Serializable
data class RecapSubmit(val userIndex: Int,
val quoteContent : String,
val character : String,
val source : String)
@Composable
fun AppNavigator() {
@ -55,7 +63,7 @@ fun AppNavigator() {
Scaffold(
modifier = Modifier.fillMaxSize(),
containerColor = colorNavBar
containerColor = MaterialTheme.colorScheme.onPrimary
) { paddingValues ->
Box(modifier = Modifier.padding(paddingValues)) {
NavHost(navController, startDestination = Login) {
@ -73,11 +81,13 @@ fun AppNavigator() {
composable<Accueil> {
val accueil: Accueil = it.toRoute()
AccueilPage(
index = accueil.userIndex,
navFavorite = { navController.navigate(Favorite(accueil.userIndex)) },
navQuiz = { navController.navigate(QuizMenu(accueil.userIndex)) },
navProfil = { navController.navigate(Profil(accueil.userIndex)) },
navQuote = { quoteId -> navController.navigate(OneQuote(quoteId,accueil.userIndex)) },
navSearch = { navController.navigate(Search(accueil.userIndex))}
navSearch = { navController.navigate(Search(accueil.userIndex))},
services = services
)
}
composable<Favorite> {
@ -99,6 +109,7 @@ fun AppNavigator() {
navFavorite = { navController.navigate(Favorite(profil.userIndex)) },
navAccueil = { navController.navigate(Accueil(profil.userIndex)) },
navQuiz = { navController.navigate(QuizMenu(profil.userIndex)) },
navSubmitQuote = { navController.navigate(SubmitQuote(profil.userIndex)) },
navUnLog = {
navController.navigate(Login) {
popUpTo(profil) { inclusive = true }
@ -112,12 +123,13 @@ fun AppNavigator() {
val quote: OneQuote = it.toRoute()
QuotePage(
quoteId = quote.quoteId,
service = services,
index = quote.userIndex,
navAccueil = { navController.navigate(Accueil(quote.userIndex)) },
navQuiz = { navController.navigate(QuizMenu(quote.userIndex)) },
navProfil = { navController.navigate(Profil(quote.userIndex)) },
navFavorite = { navController.navigate(Favorite(quote.userIndex)) },
navSearch = { navController.navigate(Search(quote.userIndex))},
service = services
navSearch = { navController.navigate(Search(quote.userIndex))}
)
}
composable<Search> {
@ -144,7 +156,40 @@ fun AppNavigator() {
services = services
)
}
composable<SubmitQuote> { SubmitQuotePage() }
composable<SubmitQuote> {
val submitQuote: SubmitQuote = it.toRoute()
SubmitQuotePage(
navAccueil = { navController.navigate(Accueil(submitQuote.userIndex)) },
navFavorite = { navController.navigate(Favorite(submitQuote.userIndex)) },
navProfil = { navController.navigate(Profil(submitQuote.userIndex)) },
navQuiz = { navController.navigate(QuizMenu(submitQuote.userIndex)) },
navRecap = { quoteContent, character, source ->
navController.navigate(
RecapSubmit(
submitQuote.userIndex,
quoteContent,
character,
source
)
)
}
)
}
composable<RecapSubmit> {
val recapSubmit: RecapSubmit = it.toRoute()
RecapSubmitPage(
index = recapSubmit.userIndex,
quoteContent = recapSubmit.quoteContent,
character = recapSubmit.character,
source = recapSubmit.source,
navAccueil = { navController.navigate(Accueil(recapSubmit.userIndex)) },
navFavorite = { navController.navigate(Favorite(recapSubmit.userIndex)) },
navProfil = { navController.navigate(Profil(recapSubmit.userIndex)) },
navSearch = { navController.navigate(Search(recapSubmit.userIndex))},
navQuiz = { navController.navigate(QuizMenu(recapSubmit.userIndex)) }
)
}
composable<QuizMenu> {
val quizMenu: QuizMenu = it.toRoute()
QuizMenu(
@ -187,3 +232,4 @@ fun AppNavigator() {
}
}
}

@ -5,34 +5,41 @@ 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.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.local.DailyQuoteStub
import com.example.what_the_fantasy.data.local.QuoteStub
import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.QuoteLittle
import com.example.what_the_fantasy.ui.theme.colorBackground
@Composable
fun AccueilPage(
index: Int,
navFavorite: () -> Unit,
navQuiz: () -> Unit,
navProfil: () -> Unit,
navSearch: () -> Unit,
navQuote: (Int) -> Unit
navQuote: (Int) -> Unit,
services: IServices
) {
var itemCount by remember { mutableStateOf(15) }
val dailyQuote = DailyQuoteStub.dailyQuote
val quotes = QuoteStub.allQuotes.take(itemCount)
val quotes = services.getAllQuote().take(itemCount)
val user = services.getUserById(index) ?: return
val titleDalyQuote = stringResource(R.string.TitleHomeDailyQuote)
val titleSuggestion = stringResource(R.string.TitleHomeSuggestion)
NavBar(
onAccueil = true,
navControllerFavorite = navFavorite,
@ -43,14 +50,14 @@ fun AccueilPage(
Column(
modifier = Modifier
.fillMaxSize()
.background(colorBackground)
.background(MaterialTheme.colorScheme.background)
) {
LazyColumn(modifier = Modifier.weight(1f)) {
item{
Column {
Text(
text = "▶ Citation du jour ◀",
color = Color.White,
text = titleDalyQuote,
color = MaterialTheme.colorScheme.onBackground,
fontSize = 24.sp,
modifier = Modifier
.fillMaxWidth()
@ -65,8 +72,8 @@ fun AccueilPage(
}
Text(
text = "▶ Suggestions ◀",
color = Color.White,
text = titleSuggestion,
color = MaterialTheme.colorScheme.onBackground,
fontSize = 24.sp,
modifier = Modifier
.fillMaxWidth()
@ -75,12 +82,16 @@ fun AccueilPage(
)
}
items(quotes) { quote ->
Column(Modifier.clickable {navQuote(quote.id)}
) {
if(quote.language == user.langage){
QuoteLittle(quote)
Spacer(modifier = Modifier.height(16.dp))
}
}
}
if (itemCount < QuoteStub.allQuotes.size) {
if (itemCount < quotes.size) {
item {
LaunchedEffect(itemCount) {
itemCount += 15

@ -1,23 +1,26 @@
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.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.local.FavoriteStub
import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.QuoteLittle
import com.example.what_the_fantasy.ui.navigations.OneQuote
import com.example.what_the_fantasy.ui.theme.colorBackground
@Composable
@ -31,8 +34,10 @@ fun FavoritePage(
services: IServices
) {
val user = services.getUserById(index) ?: return
val quotes = FavoriteStub.getFavoritesByUser(user.id)
val quotes = services.getFavorite(user)
val TitlePage = stringResource(R.string.TitleFavorite)
NavBar(onFavorite = true,
navControllerAccueil = navAccueil,
navControllerProfil = navProfil,
@ -42,14 +47,14 @@ fun FavoritePage(
Box(
modifier = Modifier
.fillMaxSize()
.background(colorBackground),
.background(MaterialTheme.colorScheme.background),
contentAlignment = Alignment.TopCenter
){
) {
LazyColumn {
item{
item {
Text(
text = "▶ Favoris ◀",
color = Color.White,
text = TitlePage,
color = MaterialTheme.colorScheme.onBackground,
fontSize = 24.sp,
modifier = Modifier
.fillMaxWidth()
@ -58,8 +63,9 @@ fun FavoritePage(
)
}
items(quotes) { quote ->
Column (Modifier.clickable { navQuote( quote.id )} ){
Column(Modifier.clickable { navQuote(quote.id) }) {
QuoteLittle(quote)
Spacer(modifier = Modifier.height(16.dp))
}
}
}

@ -1,16 +1,12 @@
package com.example.what_the_fantasy.ui.screens
import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
@ -27,8 +23,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
@ -36,22 +30,16 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.example.what_the_fantasy.Logs.LogsUsers
import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.local.UserStub
import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent
import com.example.what_the_fantasy.ui.components.SpaceHeightComponent
import com.example.what_the_fantasy.ui.components.TitlePageComponent
import com.example.what_the_fantasy.ui.components.hashPassword
import com.example.what_the_fantasy.ui.theme.colorBackground
import com.example.what_the_fantasy.ui.theme.gradienBox
import java.security.MessageDigest
@Composable
fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: (Int) -> Unit, services : IServices) {
@ -60,7 +48,7 @@ fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: (Int) -> Uni
Box(
modifier = Modifier
.fillMaxSize()
.background(colorBackground),
.background(MaterialTheme.colorScheme.background),
contentAlignment = Alignment.Center
){
Column(
@ -68,16 +56,16 @@ fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: (Int) -> Uni
.fillMaxWidth(0.9f)
.padding(20.dp)
.clip(RoundedCornerShape(16.dp))
.background(gradienBox)
.background(MaterialTheme.colorScheme.onPrimary)
.padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
TitlePageComponent(R.string.titleLogin, Color.White)
TitlePageComponent(R.string.titleLogin, MaterialTheme.colorScheme.primary)
SpaceHeightComponent(20)
ConnexionButtonLogin(users,IdentifiantTextField(R.string.IdentifiantLogin), PassWdTextField(R.string.PasswdLogin), R.string.ButtonLogin,18, Color.White, Color.Black,navControllerProfil)
SpaceHeightComponent(16)
CreateAccountButton(R.string.ButtonCreateLogin,12, Color.White, navControllerSignUp)
CreateAccountButton(R.string.ButtonCreateLogin,12, MaterialTheme.colorScheme.primary, navControllerSignUp)
}
}
}
@ -88,7 +76,7 @@ fun LoginPage(navControllerSignUp: () -> Unit, navControllerProfil: (Int) -> Uni
@Composable
fun IdentifiantTextField(textIdentifiantResId : Int) : String{
val textIdentifiant = stringResource(id = textIdentifiantResId)
var identifiant by remember { mutableStateOf("") } // Stocke la valeur du champ
var identifiant by remember { mutableStateOf("") }
Column(modifier = Modifier.padding(top = 16.dp)) {
OutlinedTextField(
value = identifiant,
@ -99,7 +87,7 @@ fun IdentifiantTextField(textIdentifiantResId : Int) : String{
.padding(top = 8.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
maxLines = 1,
shape = RoundedCornerShape(16.dp) // Bords arrondis
shape = RoundedCornerShape(16.dp)
)
}
return identifiant;
@ -108,8 +96,8 @@ fun IdentifiantTextField(textIdentifiantResId : Int) : String{
@Composable
fun PassWdTextField(textpasswdResId : Int) : String{
val textpasswd = stringResource(id = textpasswdResId)
var passwd by remember { mutableStateOf("") } // Stocke la valeur du champ
var passwordVisible by remember { mutableStateOf(false) } // État pour afficher/masquer
var passwd by remember { mutableStateOf("") }
var passwordVisible by remember { mutableStateOf(false) }
Column(modifier = Modifier.padding(top = 10.dp, bottom = 30.dp)) {
OutlinedTextField(
value = passwd,
@ -125,7 +113,7 @@ fun PassWdTextField(textpasswdResId : Int) : String{
IconButton(onClick = { passwordVisible = !passwordVisible }) {
}
},
shape = RoundedCornerShape(16.dp) // Bords arrondis
shape = RoundedCornerShape(16.dp)
)
}
return passwd;
@ -139,11 +127,11 @@ fun ConnexionButtonLogin(userStub : List<User>, id : String, passwd : String, ti
Button(
onClick = { showError = !validLogin(id, passwd, userStub, navController)
},
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background),
modifier = Modifier
.fillMaxWidth(),
) {
Text(title, fontSize = size.sp, color = colorText)
Text(title, fontSize = size.sp, color = MaterialTheme.colorScheme.onBackground)
}
if(showError){
@ -153,12 +141,13 @@ fun ConnexionButtonLogin(userStub : List<User>, id : String, passwd : String, ti
fun validLogin(identifiant : 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 == identifiant && user.password == hashPassWd) {
navController(index) // Passer l'index à la fonction navController
navController(index)
logsUser.logInformationUserConnect(user, "UserConnect")
return true
}
}
@ -171,9 +160,9 @@ fun CreateAccountButton(titleResId : Int, size : Int, color : Color, navControll
Text(
text = title,
fontSize = size.sp,
color = color,
color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.clickable {
navController()// rediriger vers la page de création de compte
navController()
}
)
}

@ -1,15 +1,7 @@
package com.example.what_the_fantasy.ui.screens
import android.content.Context
import android.os.Bundle
import android.util.Patterns
import android.widget.ImageView
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -25,16 +17,14 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.rounded.Face
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@ -44,10 +34,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
@ -55,22 +42,17 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import coil.compose.AsyncImage
import com.example.what_the_fantasy.Logs.LogsUsers
import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.local.QuestionStub
import com.example.what_the_fantasy.data.local.UserStub
import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.data.services.IServices
//import com.example.what_the_fantasy.data.local.UserStub.users
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent
import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.SpaceHeightComponent
import com.example.what_the_fantasy.ui.components.TitlePageComponent
import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme
import com.example.what_the_fantasy.ui.theme.gradienBox
@Composable
@ -80,6 +62,7 @@ fun ProfilPage(index: Int,
navQuiz: () -> Unit,
navSearch: () -> Unit,
navUnLog: () -> Unit,
navSubmitQuote: () -> Unit,
services: IServices
) {
val user = services.getUserById(index) ?: return
@ -94,7 +77,7 @@ fun ProfilPage(index: Int,
Box(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFF100C1B)),
.background(MaterialTheme.colorScheme.background),
contentAlignment = Alignment.Center
) {
Column(
@ -102,13 +85,13 @@ fun ProfilPage(index: Int,
.fillMaxWidth(0.9f)
.padding(20.dp)
.clip(RoundedCornerShape(16.dp))
.background(gradienBox)
.background(MaterialTheme.colorScheme.onPrimary)
.padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
// Titre
TitlePageComponent(R.string.titleProfile, Color.White)
TitlePageComponent(R.string.titleProfile, MaterialTheme.colorScheme.onBackground)
SpaceHeightComponent(16)
// Image de profil
@ -125,11 +108,13 @@ fun ProfilPage(index: Int,
SpaceHeightComponent(16)
// Bouton
//ButtonProfile(R.string.ButtonAddQuoteprofile, 18, Color.Black, Color.White,navUnLog) // Pas encore de navigation definie
//SpaceHeightComponent(16)
ButtonProfile(R.string.ButtonLanguageprofile, 18, Color.Black, Color.White,navUnLog) // Pas encore de navigation definie
ButtonProfile(R.string.ButtonAddQuoteprofile, 18, MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.background,navSubmitQuote) // Pas encore de navigation definie
SpaceHeightComponent(16)
ButtonProfile(R.string.ButtonUnlogprofile, 18, Color.Black, Color.White, navUnLog)
ButtonLanguage(R.string.ButtonLanguageprofile, 18, MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.background,services, user)
SpaceHeightComponent(16)
ButtonUnLog(R.string.ButtonUnlogprofile, 18, MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.background,navUnLog)
}
}
@ -156,8 +141,8 @@ fun EditEmail(userEmail: String, index: Int, service: IServices) {
var emailError by remember { mutableStateOf(false) }
fun onDoneEditing() {
service.EditEmail(email, index)
isEditingEmail = false
isEditingEmail =!service.EditEmail(email, index)
}
if (isEditingEmail) {
@ -190,7 +175,7 @@ fun EmailEditingField(
value = email,
onValueChange = onEmailChange,
modifier = Modifier.fillMaxWidth(),
textStyle = TextStyle(color = Color.White, fontSize = 18.sp),
textStyle = TextStyle(color = MaterialTheme.colorScheme.primary, fontSize = 18.sp),
singleLine = true,
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Email,
@ -223,12 +208,12 @@ fun DisplayEmail(email: String, onEdit: () -> Unit) {
text = email,
fontSize = 18.sp,
fontWeight = FontWeight.Bold,
color = Color.White
color = MaterialTheme.colorScheme.primary
)
Icon(
imageVector = Icons.Default.Edit,
contentDescription = "Modifier",
tint = Color.White,
tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(16.dp).padding(start = 8.dp)
)
}
@ -242,8 +227,7 @@ fun EditUsername(userName: String, index: Int, service : IServices) {
var isEditingUsername by remember { mutableStateOf(false) }
fun onDoneEditing() {
service.EditUsername(username, index)
isEditingUsername = false
isEditingUsername= !service.EditUsername(username, index)
}
if (isEditingUsername) {
@ -267,7 +251,7 @@ fun UsernameEditingField(
value = username,
onValueChange = onUsernameChange,
modifier = Modifier.fillMaxWidth(),
textStyle = TextStyle(color = Color.White, fontSize = 18.sp),
textStyle = TextStyle(color = MaterialTheme.colorScheme.primary, fontSize = 18.sp),
singleLine = true,
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Done
@ -293,12 +277,12 @@ fun DisplayUsername(username: String, onEdit: () -> Unit) {
text = username,
fontSize = 18.sp,
fontWeight = FontWeight.Bold,
color = Color.White
color = MaterialTheme.colorScheme.primary
)
Icon(
imageVector = Icons.Default.Edit,
contentDescription = "Modifier",
tint = Color.White,
tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(16.dp).padding(start = 8.dp)
)
}
@ -404,7 +388,7 @@ fun PasswordTextField(
onValueChange = onValueChange,
label = { Text(label) },
modifier = Modifier.fillMaxWidth(),
textStyle = TextStyle(color = Color.White, fontSize = 18.sp),
textStyle = TextStyle(color = MaterialTheme.colorScheme.primary, fontSize = 18.sp),
singleLine = true,
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Password,
@ -427,13 +411,13 @@ fun PasswordTextField(
fun SaveButton(onClick: () -> Unit) {
Button(
onClick = onClick,
colors = ButtonDefaults.buttonColors(containerColor = Color.White),
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.onPrimary),
modifier = Modifier.fillMaxWidth()
) {
val text = stringResource(id = R.string.ButtonSaveprofile)
Text(text,
fontSize = 18.sp,
color = Color.Black)
color = MaterialTheme.colorScheme.primary)
}
}
@ -447,22 +431,58 @@ fun DisplayPassword(onEdit: () -> Unit) {
text = "*****",
fontSize = 18.sp,
fontWeight = FontWeight.Bold,
color = Color.White
color = MaterialTheme.colorScheme.primary
)
Icon(
imageVector = Icons.Default.Edit,
contentDescription = "Modifier",
tint = Color.White,
tint =MaterialTheme.colorScheme.primary,
modifier = Modifier.size(16.dp).padding(start = 8.dp)
)
}
}
@Composable
fun ButtonUnLog(textResId : Int, size :Int, colorTexte : Color, colorButton : Color,navController: () -> Unit){
val text = stringResource(id = textResId)
val logsUser = LogsUsers() //gestion des logs pour les utilisateurs
Button(
onClick = {
navController()
logsUser.unlogInformationUserConnect("UserUnLog")
},
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(),
) {
Text(text, fontSize = size.sp, color = colorTexte)
}
}
@Composable
fun ButtonLanguage(textResId : Int, size :Int, colorTexte : Color, colorButton : Color, service: IServices, user : User){
val text = stringResource(id = textResId)
val currentLangage = remember { mutableStateOf(user.langage) }
Button(
onClick = {
service.ChangeLangage(user)
currentLangage.value = user.langage
},
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(),
) {
Text("${text} (${currentLangage.value})", fontSize = size.sp, color = colorTexte)
}
}
@Composable
fun ButtonProfile(textResId : Int, size :Int, colorTexte : Color, colorButton : Color,navController: () -> Unit){
val text = stringResource(id = textResId)
Button(
onClick = { navController() },
onClick = {
navController()
},
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(),
) {

@ -1,15 +1,8 @@
package com.example.what_the_fantasy.ui.screens
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@ -17,14 +10,11 @@ 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.res.painterResource
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.R
import com.example.what_the_fantasy.data.local.QuestionStub
import com.example.what_the_fantasy.data.local.QuizStub
import com.example.what_the_fantasy.ui.components.NavBar

@ -2,16 +2,11 @@ package com.example.what_the_fantasy.ui.screens
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
@ -20,12 +15,12 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
@ -34,12 +29,9 @@ 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.R
import com.example.what_the_fantasy.data.local.QuizStub
import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar
@Composable
fun QuizMenu(
navFavorite: () -> Unit,
@ -56,7 +48,7 @@ fun QuizMenu(
) {
Column(
modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B))
modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)
) {
// Contenu princiapl
Column(
@ -68,7 +60,7 @@ fun QuizMenu(
) {
Text(
text = "▶ Menu des Quiz ◀",
color = Color.White,
color = MaterialTheme.colorScheme.onBackground,
style = TextStyle(
fontSize = 25.sp,
fontWeight = FontWeight.Bold,
@ -78,7 +70,7 @@ fun QuizMenu(
Spacer(Modifier.height(20.dp))
Column(
modifier = Modifier
.background(brush = gradient, shape = RoundedCornerShape(20.dp))
.background(MaterialTheme.colorScheme.onPrimary, shape = RoundedCornerShape(20.dp))
.fillMaxSize()
.padding(vertical = 30.dp)
.verticalScroll(rememberScrollState()),
@ -117,7 +109,7 @@ fun QuizMenu(
fontSize = 17.sp,
fontWeight = FontWeight.Medium,
textAlign = TextAlign.Center,
color = Color.White
color = MaterialTheme.colorScheme.primary
)
)
}

@ -1,11 +1,10 @@
package com.example.what_the_fantasy.ui.screens
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
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
@ -13,16 +12,12 @@ 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.res.painterResource
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.R
import com.example.what_the_fantasy.data.local.QuestionStub
import com.example.what_the_fantasy.data.local.QuizStub
import com.example.what_the_fantasy.ui.components.BackBar
import com.example.what_the_fantasy.ui.components.NavBar
@Composable
@ -43,7 +38,7 @@ fun QuizPage(
var pts by remember { mutableIntStateOf(0) }
val gradient = Brush.linearGradient(
colors = listOf(Color(0xFF7B1FA2), Color(0xFF311B92)),
colors = listOf(MaterialTheme.colorScheme.onPrimary, MaterialTheme.colorScheme.onPrimary),
start = Offset(0f, 1000f),
end = Offset(1000f, 0f)
)
@ -98,14 +93,17 @@ fun QuizPage(
Spacer(Modifier.height(20.dp))
Column(
modifier = Modifier
.background(brush = gradient, shape = RoundedCornerShape(20.dp)),
.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),
modifier = Modifier
.padding(top = 20.dp)
.weight(0.1f),
style = TextStyle(
fontSize = 25.sp,
fontWeight = FontWeight.Bold,
@ -115,12 +113,19 @@ fun QuizPage(
Text(
question.question,
color = Color.White,
fontSize = 22.sp,
modifier = Modifier.padding(40.dp)
fontSize = 15.sp,
modifier = Modifier
.padding(horizontal = 25.dp)
.weight(0.1f),
textAlign = TextAlign.Center
)
Column(
modifier = Modifier
.padding(top = 30.dp)
.weight(0.7f)
.fillMaxHeight()
.padding(vertical = 30.dp),
verticalArrangement = Arrangement.SpaceBetween
) {
listOf(
question.ansA,
@ -139,7 +144,6 @@ fun QuizPage(
) {
Text(answer, color = Color.Black, fontSize = 18.sp)
}
Spacer(modifier = Modifier.height(60.dp))
}
}
}

@ -2,24 +2,44 @@ package com.example.what_the_fantasy.ui.screens
import android.content.Context
import android.content.Intent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.automirrored.filled.Send
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.FavoriteBorder
import androidx.compose.material.icons.filled.MailOutline
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -33,6 +53,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.R
import coil.compose.AsyncImage
import com.example.what_the_fantasy.data.model.Comment
import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.theme.colorBackground
@ -41,18 +62,25 @@ import com.example.what_the_fantasy.ui.theme.iconText
import com.example.what_the_fantasy.ui.theme.likeIcon
import com.example.what_the_fantasy.ui.theme.whiteBackcgroundText
var isCommentVisible by mutableStateOf(false)
@Composable
fun QuotePage(
quoteId : Int,
service : IServices,
index : Int,
navAccueil: () -> Unit,
navFavorite:() -> Unit,
navQuiz: () -> Unit,
navSearch: () -> Unit,
navProfil:() -> Unit)
{
var quote = service.getQuote(quoteId) ?: return
// utiliser ViewModel
val quote = service.getQuote(quoteId) ?: return
val context = LocalContext.current
val user = service.getUserById(index) ?: return
val favorite by remember { mutableStateOf(service.isFavorite(id = quoteId, user = user)) }
NavBar(
navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil,
@ -63,17 +91,15 @@ fun QuotePage(
Box(
modifier = Modifier
.fillMaxSize()
.background(colorBackground),
.background(MaterialTheme.colorScheme.background),
contentAlignment = Alignment.Center
) {
Column(modifier = Modifier
.padding(15.dp)
.drawBehind {
drawRoundRect(
gradienBox,
cornerRadius = CornerRadius(15.dp.toPx()),
.background(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(15.dp)
)
}
) {
Row(modifier = Modifier.padding(15.dp)) {
ImageQuote(
@ -82,12 +108,11 @@ fun QuotePage(
Column {
FunctionalIcon(
// --/!\-- a modifier --/!\--
// isFavorite = service.isFavorite(id)
// --------------------------
true,
isFavorite = favorite,
userId = index,
id = quoteId,
context = context
context = context,
service = service
)
QuoteText(
text = '"' + quote.content + '"'
@ -118,6 +143,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(index, service)
LstComment(service.getComment(quoteId))
}
}
}
}
}
@ -130,7 +173,7 @@ fun QuoteText(text: String ){
modifier = Modifier.padding(start = 10.dp, top = 15.dp),
fontWeight = FontWeight(1000),
fontSize = 20.sp,
color = iconText
color = MaterialTheme.colorScheme.onPrimary
)
}
@ -146,7 +189,7 @@ fun ImageQuote(imageUrl : String){
}
@Composable
fun FunctionalIcon(isFavorite: Boolean, id : Int, context : Context){
fun FunctionalIcon(isFavorite: Boolean, userId : Int, id : Int, context : Context, service: IServices){
Row(modifier = Modifier
.fillMaxWidth()
) {
@ -156,13 +199,13 @@ fun FunctionalIcon(isFavorite: Boolean, id : Int, context : Context){
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
// lien a changer quand le site sra deployer
putExtra(Intent.EXTRA_TEXT, "http://wfWebsite/quote/" + id.toString() )
putExtra(Intent.EXTRA_TEXT, "http://wfWebsite/quote/$id")
type = "text/plain"
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) // Ajout pour compatibilité
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
val shareIntent = Intent.createChooser(sendIntent, null)
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) // Ajout aussi ici
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(shareIntent)
},
@ -171,42 +214,44 @@ fun FunctionalIcon(isFavorite: Boolean, id : Int, context : Context){
Icon(
Icons.Default.Share,
contentDescription = stringResource(R.string.share),
tint = iconText,
tint = MaterialTheme.colorScheme.onPrimary,
)
}
IconButton(
onClick = { }, //Go to comment
onClick = {
isCommentVisible = !isCommentVisible
},
modifier = Modifier.padding(start = 20.dp)
){
Icon(
Icons.Default.MailOutline,
contentDescription = stringResource(R.string.comment),
tint = iconText,
tint = MaterialTheme.colorScheme.onPrimary,
)
}
if(isFavorite){
IconButton(
onClick = { }, //Go to comment
onClick = { service.SupFav(userId = userId, QuoteId = id)}, //sup fav
modifier = Modifier.padding(start = 20.dp)
){
Icon(
Icons.Default.Favorite,
contentDescription = stringResource(R.string.favorite),
tint = likeIcon,
tint = MaterialTheme.colorScheme.onPrimary,
)
}
}
else{
IconButton(
onClick = { }, //Go to comment
onClick = { service.AddFav(userId = userId, QuoteId = id)}, //add fav
modifier = Modifier.padding(start = 50.dp)
){
Icon(
Icons.Default.FavoriteBorder,
contentDescription = stringResource(R.string.favorite),
tint = iconText
tint = MaterialTheme.colorScheme.onPrimary
)
}
}
@ -220,22 +265,20 @@ fun InfoQuoteText(nameId : Int, text : String){
text = stringResource(id = nameId),
fontSize = 18.sp,
fontWeight = FontWeight(500),
color = iconText
color = MaterialTheme.colorScheme.onPrimary
)
Text(
text = text,
color = whiteBackcgroundText,
color = MaterialTheme.colorScheme.onBackground,
fontSize = 16.sp,
fontWeight = FontWeight(400),
modifier = Modifier
.drawBehind {
drawRoundRect(
Color(255,255,255),
cornerRadius = CornerRadius(15.dp.toPx())
.background(
color = MaterialTheme.colorScheme.background,
shape = RoundedCornerShape(15.dp)
)
}
.padding(5.dp),
.padding(5.dp)
)
}
}
@ -244,11 +287,84 @@ fun InfoQuoteText(nameId : Int, text : String){
fun LikeInfo(likes : Int){
Text(
text = likes.toString(),
color = iconText
color = MaterialTheme.colorScheme.onPrimary
)
Icon(
Icons.Default.Favorite,
contentDescription = stringResource(R.string.favorite),
tint = iconText,
tint = MaterialTheme.colorScheme.onPrimary,
)
}
@Composable
fun AddComment(userId : Int, service: IServices){
var text by remember { mutableStateOf("") }
Row(modifier = Modifier.padding(bottom = 15.dp, top = 15.dp)){
IconButton(
onClick = { isCommentVisible = !isCommentVisible},
){
Icon(
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
.width(300.dp)
)
IconButton(
onClick = { service.AddComment(text)}, //send comment
){
Icon(
Icons.AutoMirrored.Filled.Send,
contentDescription = stringResource(R.string.send),
tint = MaterialTheme.colorScheme.onPrimary
)
}
}
}
@Composable
fun LstComment(lst : List<Comment>){
LazyColumn(
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
items(
items = lst,
) {
Column(
modifier = Modifier.padding(5.dp)
.fillMaxSize()
.background(
color = MaterialTheme.colorScheme.onPrimary,
shape = RoundedCornerShape(15.dp)
)
) {
Row {
AsyncImage(
model = it.img,
contentDescription = stringResource(R.string.profilePict),
modifier = Modifier
.size(50.dp)
.clip(RoundedCornerShape(50))
)
Text(
text = it.user + " " + it.date,
modifier = Modifier.padding(start = 15.dp)
)
}
Row {
Text(
text = it.content,
modifier = Modifier.padding(15.dp),
)
}
}
}
}
}

@ -0,0 +1,174 @@
package com.example.what_the_fantasy.ui.screens
import android.content.Context
import android.content.Intent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.FavoriteBorder
import androidx.compose.material.icons.filled.MailOutline
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.R
import coil.compose.AsyncImage
import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.theme.gradienBox
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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 com.example.what_the_fantasy.data.model.Character
@Composable
fun RecapSubmitPage(
index: Int,
navFavorite: () -> Unit,
navAccueil: () -> Unit,
navProfil:() -> Unit,
navQuiz: () -> Unit,
navSearch: () -> Unit,
quoteContent : String,
character: String,
source: String
) {
NavBar(
navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil,
navControllerProfil = navProfil,
navControllerQuiz = navQuiz,
navControllerSearch = navSearch
) {
Column(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
) {
// Contenu princiapl
Column(
modifier = Modifier
.weight(0.9f)
.fillMaxSize()
.padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "▶ Recap de la citation ◀",
color = MaterialTheme.colorScheme.onBackground,
style = TextStyle(
fontSize = 25.sp,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center
)
)
Spacer(Modifier.height(20.dp))
Column(
modifier = Modifier
.background(brush = gradient, shape = RoundedCornerShape(20.dp))
.fillMaxSize()
.padding(vertical = 30.dp)
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally
) {
Column(modifier = Modifier
.padding(15.dp)
.drawBehind {
drawRoundRect(
gradienBox,
cornerRadius = CornerRadius(15.dp.toPx()),
)
}
) {
Row(modifier = Modifier.padding(15.dp)) {
ImageQuote(
imageUrl = "https://img.freepik.com/vecteurs-libre/personnage-guerrier-fantaisie_1045-185.jpg?size=338&ext=jpg"
)
Column {
QuoteText(
text = '"' + quoteContent + '"'
)
}
}
Column(modifier = Modifier
.padding(15.dp)
.fillMaxWidth()
) {
InfoQuoteText(
nameId = R.string.source,
text = source
)
Text(
text = "Character : $character"
)
}
}
}
}
}
}
}
@Composable
fun QuoteText2(text: String ){
Text(
text = text,
modifier = Modifier.padding(start = 10.dp, top = 15.dp),
fontWeight = FontWeight(1000),
fontSize = 20.sp,
color = MaterialTheme.colorScheme.background
)
}
@Composable
fun ImageQuote2(imageUrl : String){
AsyncImage(
model = imageUrl,
contentDescription = "exemple",
modifier = Modifier
.size(150.dp)
.clip(RoundedCornerShape(15.dp))
)
}
@Composable
fun InfoQuoteText2(nameId : Int, text : String){
Column(modifier = Modifier.padding(bottom = 20.dp)){
Text(
text = text,
fontSize = 16.sp,
fontWeight = FontWeight(400),
modifier = Modifier
.drawBehind {
drawRoundRect(
Color(255,255,255),
cornerRadius = CornerRadius(15.dp.toPx())
)
}
.padding(5.dp),
)
}
}

@ -92,12 +92,12 @@ fun SearchPage(
Column(
modifier = Modifier
.fillMaxSize()
.background(colorBackground)
.background(MaterialTheme.colorScheme.background)
) {
Text(
text = ""+stringResource(R.string.TitleSearch)+"",
color = Color.White,
color = MaterialTheme.colorScheme.onBackground,
fontSize = 24.sp,
modifier = Modifier
.fillMaxWidth()
@ -109,7 +109,7 @@ fun SearchPage(
OutlinedTextField(
value = newSearch,
onValueChange = { newSearch = it },
textStyle = TextStyle(color = Color.White),
textStyle = TextStyle(color = MaterialTheme.colorScheme.onBackground),
modifier = Modifier
.padding(top = 2.dp)
.fillMaxWidth()
@ -127,7 +127,7 @@ fun SearchPage(
contentDescription = stringResource(R.string.TitleSearch),
Modifier
.fillMaxSize()
.background(Color.Magenta,CircleShape)
.background(MaterialTheme.colorScheme.primary,CircleShape)
)
}
}
@ -153,7 +153,7 @@ fun SearchPage(
text = type,
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier.padding(start = 16.dp),
color = Color.White
color = MaterialTheme.colorScheme.onBackground
)
}
}
@ -166,7 +166,7 @@ fun SearchPage(
QuoteLittle(quote)
}
}
if (itemCount < QuoteStub.allQuotes.size) {
if (itemCount < quotes.size) {
item {
LaunchedEffect(itemCount) {
itemCount += 15

@ -1,26 +1,23 @@
package com.example.what_the_fantasy.ui.screens
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@ -31,27 +28,20 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.SpaceHeightComponent
import com.example.what_the_fantasy.ui.components.TitlePageComponent
import com.example.what_the_fantasy.ui.theme.What_The_FantasyTheme
import com.example.what_the_fantasy.ui.theme.colorBackground
import com.example.what_the_fantasy.ui.theme.gradienBox
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent
import com.example.what_the_fantasy.ui.components.hashPassword
@Composable
fun SignUpPage(navControllerLogin: () -> Unit, services : IServices) {
@ -64,7 +54,8 @@ fun SignUpPage(navControllerLogin: () -> Unit, services : IServices) {
Box(
modifier = Modifier
.fillMaxSize()
.background(colorBackground),
.background(MaterialTheme.colorScheme.background)
.verticalScroll(rememberScrollState()),
contentAlignment = Alignment.Center
){
Column(
@ -72,20 +63,20 @@ fun SignUpPage(navControllerLogin: () -> Unit, services : IServices) {
.fillMaxWidth(0.9f)
.padding(20.dp)
.clip(RoundedCornerShape(16.dp))
.background(gradienBox)
.background(MaterialTheme.colorScheme.onPrimary)
.padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
TitlePageComponent(R.string.titleSignUp,Color.White)
TitlePageComponent(R.string.titleSignUp,MaterialTheme.colorScheme.onBackground)
IdentifiantTextFieldSign(R.string.IdentifiantLogin,identifiant = username,onValueChange = { username = it })
EmailTextFieldSign(R.string.EmailSignUp, email, onValueChange = { email = it })
PassWdTextFieldSign(R.string.PasswdLogin,password, onValueChange = { password = it },passwordVisible,onPasswordVisibilityChange = { passwordVisible = !passwordVisible })
PassWdConfirmTextFieldSign(R.string.ConfirmPassWdSignUp,confirmPassword,onValueChange = { confirmPassword = it },passwordVisible,onPasswordVisibilityChange = { passwordVisible = !passwordVisible })
SpaceHeightComponent(16)
ConnexionButtonSign(R.string.ButtonSignUp,18, Color.White, Color.Black, username, email, password, confirmPassword, services, navControllerLogin)
ConnexionButtonSign(R.string.ButtonSignUp,18, MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.onBackground, username, email, password, confirmPassword, services, navControllerLogin)
SpaceHeightComponent(16)
ReturnLogin(R.string.ButtonLogin,12, Color.White, navController = navControllerLogin)
ReturnLogin(R.string.ButtonLogin,12, MaterialTheme.colorScheme.primary, navController = navControllerLogin)
}
}
@ -204,17 +195,19 @@ fun ConnexionButtonSign(
var emailError by remember { mutableStateOf(false) }
var passwordError by remember { mutableStateOf(false) }
var passwordErrorEmpty by remember { mutableStateOf(false) }
var usernameErrorEmpty by remember { mutableStateOf(false) }
var usernameError by remember { mutableStateOf(false) }
var usernameErrorExist by remember { mutableStateOf(false) }
val invalidRegex = """^[a-zA-Z0-9]*$""".toRegex()
Button(
onClick = {
emailError = !isValidEmail(email)
passwordError = !arePasswordsMatching(password, confirmPassword)
usernameErrorEmpty = username.isBlank()
usernameError = username.isBlank() && !username.matches(invalidRegex)
passwordErrorEmpty = password.isBlank() || confirmPassword.isBlank()
if (!emailError && !passwordError && !usernameErrorEmpty && !passwordErrorEmpty) {
if (!emailError && !passwordError && !usernameError && !passwordErrorEmpty) {
usernameErrorExist = !service.CreateUser(username, email, password, service)
if(!usernameErrorExist){
navController() // retour à la page login
@ -228,8 +221,8 @@ fun ConnexionButtonSign(
}
// Afficher erreurs
if (usernameErrorEmpty) {
ErrorMessageProfileComponent(R.string.ErrorUserEmptySignUp)
if (usernameError) {
ErrorMessageProfileComponent(R.string.ErrorUserSignUp)
}
if (usernameErrorExist) {

@ -1,8 +1,262 @@
package com.example.what_the_fantasy.ui.screens
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
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.ui.components.ErrorMessageSubmitQuoteComponent
import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.SpaceHeightComponent
import com.example.what_the_fantasy.ui.components.TitlePageComponent
import com.example.what_the_fantasy.ui.theme.colorBackground
import com.example.what_the_fantasy.ui.theme.gradienBox
@Composable
fun SubmitQuotePage() {
fun SubmitQuotePage(
navFavorite: () -> Unit,
navAccueil: () -> Unit,
navProfil:() -> Unit,
navQuiz: () -> Unit,
navRecap: (String, String, String) -> Unit
) {
NavBar(
navControllerFavorite = navFavorite,
navControllerAccueil = navAccueil,
navControllerProfil = navProfil,
navControllerQuiz = navQuiz
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
.verticalScroll(rememberScrollState()),
contentAlignment = Alignment.Center
){
Column(
modifier = Modifier
.fillMaxWidth(0.9f)
.padding(20.dp)
.clip(RoundedCornerShape(16.dp))
.background(MaterialTheme.colorScheme.onPrimary)
.padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
TitlePageComponent(R.string.titleSubmitQuote, MaterialTheme.colorScheme.onBackground)
SpaceHeightComponent(20)
SubmitQuoteButton(
quoteTextField(R.string.quote),
characterTextField(R.string.character),
sourceTextField(R.string.source),
timeCodeTextField(R.string.timeCode),
yearTextField(R.string.year),
R.string.titleButtonSubmit,
18,
MaterialTheme.colorScheme.background,
MaterialTheme.colorScheme.onBackground,
navRecap
)
SpaceHeightComponent(20)
BackButton(R.string.titleButtonBack, 12, Color.White,navProfil)
}
}
}
}
@Composable
fun quoteTextField(textQuoteResId : Int) : String{
val textQuote = stringResource(id = textQuoteResId)
var quote by remember { mutableStateOf("") }
Column(modifier = Modifier.padding(top = 16.dp)) {
OutlinedTextField(
value = quote,
onValueChange = { quote = it },
label = { Text(textQuote, color = MaterialTheme.colorScheme.onBackground) },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
shape = RoundedCornerShape(16.dp)
)
}
return quote;
}
@Composable
fun characterTextField(textCharacterResId : Int) : String{
val textCharacter = stringResource(id = textCharacterResId)
var character by remember { mutableStateOf("") }
Column(modifier = Modifier.padding(top = 16.dp)) {
OutlinedTextField(
value = character,
onValueChange = { character = it },
label = { Text(textCharacter, color = MaterialTheme.colorScheme.onBackground) },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
shape = RoundedCornerShape(16.dp)
)
}
return character;
}
@Composable
fun sourceTextField(textSourceResId : Int) : String{
val textSource = stringResource(id = textSourceResId)
var source by remember { mutableStateOf("") }
Column(modifier = Modifier.padding(top = 16.dp)) {
OutlinedTextField(
value = source,
onValueChange = { source = it },
label = { Text(textSource, color = MaterialTheme.colorScheme.onBackground) },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
shape = RoundedCornerShape(16.dp)
)
}
return source;
}
@Composable
fun timeCodeTextField(textTimeCodeResId : Int) : String{
val textTimeCode = stringResource(id = textTimeCodeResId)
var timeCode by remember { mutableStateOf("") }
Column(modifier = Modifier.padding(top = 16.dp)) {
OutlinedTextField(
value = timeCode,
onValueChange = { timeCode = it },
label = { Text(textTimeCode, color = MaterialTheme.colorScheme.onBackground) },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
shape = RoundedCornerShape(16.dp)
)
}
return timeCode;
}
@Composable
fun yearTextField(textYearResId : Int) : String{
val textYear = stringResource(id = textYearResId)
var year by remember { mutableStateOf("") }
Column(modifier = Modifier.padding(top = 16.dp, bottom = 30.dp)) {
OutlinedTextField(
value = year,
onValueChange = { year = it },
label = { Text(textYear, color = MaterialTheme.colorScheme.onBackground) },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
shape = RoundedCornerShape(16.dp)
)
}
return year;
}
@Composable
fun SubmitQuoteButton(
quote: String,
character: String,
source: String,
timeCode: String,
year: String,
titleResId: Int,
size: Int,
colorButton: Color,
colorText: Color,
navRecap : (String, String, String) -> Unit
) {
val title = stringResource(id = titleResId)
var showError by remember { mutableStateOf(false) }
Button(
onClick = { showError = !goToRecap(quote, character, source, timeCode, year, navRecap) },
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(),
) {
Text(title, fontSize = size.sp, color = colorText)
}
if (showError) {
ErrorMessageSubmitQuoteComponent(R.string.ErrorSubmitQuote)
}
}
fun goToRecap(quote: String,
character: String,
source: String,
timeCode: String,
year: String,
navRecap : (String, String, String) -> Unit): Boolean {
if (validSubmitQuote(quote, character, source, timeCode, year)) {
navRecap(quote, character, source)
return true
}
return false
}
fun validSubmitQuote(quote : String, character : String, source: String, timeCode: String, year: String): Boolean{
val quoteRegex = """^[A-Za-zÀ-ÿ0-9\s\-\.,!?'"()]+$""".toRegex()
val timeCodeRegex = """^\d{1}:\d{2}:\d{2}$""".toRegex()
val movieTitleRegex = """^[A-Za-z0-9\s\-\(\):]+$""".toRegex()
val characterRegex = """^[A-Za-zÀ-ÿ\s\-']+$""".toRegex()
val invalidRegex = """^[a-zA-Z0-9]*$""".toRegex()
val isNotBlank = quote.isNotBlank() && quote.matches(quoteRegex) && !quote.matches(invalidRegex) && quote.length in 3..100 &&
character.isNotBlank() && character.matches(characterRegex) && character.length in 3..50 && /*!character.matches(invalidRegex) &&*/
source.isNotBlank() && source.matches(movieTitleRegex) && source.length in 3..50 && /*!source.matches(invalidRegex) &&*/
timeCode.isNotBlank() && timeCode.matches(timeCodeRegex) &&
year.isNotBlank() && year.all { it.isDigit() } && year.length == 4 && year.toInt() in 1900..2025
return isNotBlank
}
@Composable
fun BackButton(titleResId : Int, size : Int, color : Color, navController: () -> Unit) {
val title = stringResource(id = titleResId)
Text(
text = title,
fontSize = size.sp,
color = color,
modifier = Modifier.clickable {
navController()
}
)
}

@ -1,9 +1,14 @@
package com.example.what_the_fantasy.ui.theme
import android.content.Context
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import com.example.what_the_fantasy.R
import androidx.core.content.ContextCompat
fun Context.getColorFromRes(resId: Int): Color {
return Color(ContextCompat.getColor(this, resId))
}
val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
@ -22,6 +27,7 @@ val gradienBox = Brush.linearGradient(
)
val colorBackground = Color(0xFF100C1B)
val colorNavBar = Color.Black
val colorButtonNavSelected= Color(0xFFC8C8C8)

@ -13,6 +13,7 @@
<string name="favorite">Favoris</string>
<string name="like">Likes</string>
<string name="profilePict">Image de profil</string>
<string name="send">Envoyer</string>
//Page Login
<string name="titleLogin">Connexion au compte</string>
@ -29,8 +30,8 @@
<string name="EmailSignUp">Email*</string>
<string name="ErrorEmailSignUp">Email invalide</string>
<string name="ErrorPasswordSignUp">Les mots de passe ne correspondent pas</string>
<string name="ErrorUserEmptySignUp">Le nom d\'utilisateur ne peut pas être vide</string>
<string name="ErrorUserExistSignUp">Le nom d\'utilisateur n\'est pas disponible</string>
<string name="ErrorUserSignUp">Le nom d\'utilisateur n\'est pas correct</string>
<string name="ErrorUserExistSignUp">Le nom d\'utilisateur ou l\'email ne sont pas disponibles</string>
<string name="ErrorPasswordEmpty">Vous devez mettre un mot de passe</string>
//Page Profil
@ -51,7 +52,23 @@
//Page Favori
<string name="TitleFavorite">Favoris</string>
<string name="TitleFavorite">▶ Favoris ◀</string>
//Page Accueil
<string name="TitleHomeDailyQuote">▶ Citation du jour ◀</string>
<string name="TitleHomeSuggestion">▶ Suggestions ◀</string>
//Page SubmitQuote
<string name="titleSubmitQuote">Proposez Une Citation</string>
<string name="titleButtonSubmit">Proposez</string>
<string name="titleButtonBack">Profile</string>
<string name="quote">Citation</string>
<string name="character">Personnage</string>
<string name="source2">Source</string>
<string name="timeCode">Time Code</string>
<string name="year">Année</string>
<string name="ErrorSubmitQuote">Champs Invalides</string>
//NavBar
<string name="NavFavorite">Favoris</string>

@ -8,10 +8,11 @@
<string name="charac">Character</string>
<string name="source">Source</string>
<string name="share">Share</string>
<string name="comment">comment</string>
<string name="favorite">favorite</string>
<string name="like">likes</string>
<string name="comment">Comment</string>
<string name="favorite">Favorite</string>
<string name="like">Likes</string>
<string name="profilePict">Profile picture</string>
<string name="send">Send</string>
//Page Login
<string name="titleLogin">Account login</string>
@ -28,8 +29,8 @@
<string name="EmailSignUp">Your email*</string>
<string name="ErrorEmailSignUp">Invalid email</string>
<string name="ErrorPasswordSignUp">Passwords do not match</string>
<string name="ErrorUserEmptySignUp">Username cannot be empty</string>
<string name="ErrorUserExistSignUp">Username is not available</string>
<string name="ErrorUserSignUp">Username invalid</string>
<string name="ErrorUserExistSignUp">Username or email are not available</string>
<string name="ErrorPasswordEmpty">You must put a password</string>
//Page Profil
@ -48,7 +49,22 @@
<string name="CharacterQuote">Character</string>
//Page Favori
<string name="TitleFavorite">Favorites</string>
<string name="TitleFavorite">▶ Favorites ◀</string>
//Page Accueil
<string name="TitleHomeDailyQuote">▶ Quote of the day ◀</string>
<string name="TitleHomeSuggestion">▶ Suggestions ◀</string>
//Page SubmitQuote
<string name="titleSubmitQuote">Submit Quote</string>
<string name="titleButtonSubmit">Submit</string>
<string name="titleButtonBack">Profil</string>
<string name="quote">Quote</string>
<string name="character">Character</string>
<string name="source2">Source</string>
<string name="timeCode">Time Code</string>
<string name="year">Year</string>
<string name="ErrorSubmitQuote"> Invalid Fields </string>
//NavBar
<string name="NavFavorite">Favorite</string>

Loading…
Cancel
Save