Compare commits

...

13 Commits

@ -64,6 +64,19 @@ dependencies {
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
implementation("androidx.activity:activity-compose:1.7.0")
implementation("androidx.navigation:navigation-compose:2.4.0-alpha08")
implementation ("com.squareup.okhttp3:logging-interceptor:4.9.1")
// Jetpack Compose
implementation("androidx.compose.ui:ui:1.6.4")
implementation ("androidx.compose.material:material:1.6.4")
implementation ("androidx.compose.ui:ui-tooling:1.6.4")
// ExoPlayer
implementation ("androidx.media3:media3-session:1.3.0")
implementation("com.google.android.exoplayer:exoplayer-core:2.19.1")
implementation ("com.google.android.exoplayer:exoplayer-ui:2.19.1")
implementation ("com.squareup.okhttp3:logging-interceptor:4.9.1")

@ -4,21 +4,20 @@ import ArticlesViewModel
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.veraxapplication.articles.IArticlesDataManager
import com.example.veraxapplication.articles.StubArticles
import com.example.veraxapplication.navigation.VeraxNavHost
import com.example.veraxapplication.ui.topBar.TopBarVerax
// doc navBar: https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#TopAppBar(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Function0,kotlin.Function1,androidx.compose.foundation.layout.WindowInsets,androidx.compose.material3.TopAppBarColors,androidx.compose.material3.TopAppBarScrollBehavior)
// doc compose, pleins de trucs: https://developer.android.com/jetpack/compose/text?hl=fr
//doc couleur background pas finie: https://developer.android.com/jetpack/compose/components/scaffold
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@ -46,12 +45,8 @@ fun VeraxContent() {
var theme = listOf("Economique", "Culture", "Politique", "Faits divers")
TopBarVerax(articles = articlesApi, theme = theme)
// VeraxNavHost()
VeraxNavHost()
}
}

@ -1,11 +0,0 @@
package com.example.veraxapplication.data
/*
data class Article(
var Title : String,
var Description : String,
var Image : String,
var Author : String,
var Content : List<Paragraph>,
var LectureTime : String
)
*/

@ -1,6 +0,0 @@
package com.example.veraxapplication.data
/*
data class Paragraph(
var Content : String,
)
*/

@ -1,9 +1,7 @@
package com.example.veraxapplication.modele
import com.example.veraxapplication.modele.user.User
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
object RetrofitClientUser {

@ -1,22 +1,46 @@
package com.example.veraxapplication.navigation
import androidx.compose.runtime.Composable
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.example.veraxapplication.MainActivity
import com.example.veraxapplication.modele.articles.Article
import com.example.veraxapplication.ui.article.AffichageLesArticles
import com.example.veraxapplication.ui.article.AfficherArticle
@Composable
fun VeraxNavHost() {
fun VeraxNavHost(articles : List<Article>, navController: NavHostController) {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = "accueil"
){
composable(route="accueil"){
AffichageLesArticles(
articles = articles,
goToArticle = {
navController.navigate("article/${it.id}")
}
)
}
composable(
route="article/{articleid}",
arguments= listOf(navArgument("articleid"){ type= NavType.IntType})
){
it.arguments?.getInt("articleid")?.let { articleid ->
articles.find { it.id == articleid }?.let {
AfficherArticle(
e = it
)
}
}
}
}

@ -1,17 +1,15 @@
package com.example.veraxapplication.ui.article
import VideoPlayer
import android.util.Log
import androidx.compose.foundation.BorderStroke
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
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
@ -31,46 +29,46 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.rememberImagePainter
import com.example.veraxapplication.modele.articles.Article
import com.example.veraxapplication.modele.articles.contenus.Contenu
import com.example.veraxapplication.modele.articles.contenus.ContenuMedia
import com.example.veraxapplication.modele.articles.contenus.ContenuParagraphe
import com.example.veraxapplication.ui.theme.Salmon
@Composable
fun AffichageLesArticles(articles : List<Article>){
fun AffichageLesArticles(articles : List<Article>, goToArticle: (Article) -> Unit){
Column(modifier = Modifier.verticalScroll(rememberScrollState())){
for(article in articles){
Box (Modifier.clickable { /*faut je regarde la doc*/ }){
AffichageUnArticleInfo(e = article)
Box {
AffichageUnArticleInfo(e = article, goToArticle)
}
}
}
}
@Composable
fun AffichageUnArticleInfo(e : Article){
fun AffichageUnArticleInfo(e : Article, goToArticle: (Article) -> Unit){
Column(modifier = Modifier
.padding(7.dp)
.border(width = 1.dp, color = Color.Black, shape = RoundedCornerShape(10.dp))
.padding(5.dp)) {
/*DisplayTitle(title = e.Title)
DisplayHeader(author = e.Author, description = e.Description, lectureTime = e.LectureTime)
DisplayImage(image = e.Image)
DisplayContentArticle(content = e.Content)*/
Text(text = e.titre, fontFamily = FontFamily.Serif, fontSize = 30.sp)
DisplayHeader(author = e.auteur, description = e.description , lectureTime = e.temps)
var imageURl = e.note
Log.d("ImageLoad", "URL de l'image reçue de l'API : $imageURl")
Box(modifier = Modifier
.padding(15.dp)
.border(width = 1.dp, color = Color.Black, shape = RoundedCornerShape(10.dp))
.clip(RoundedCornerShape(10.dp))
.background(Salmon)
) {
Column (modifier = Modifier.padding(15.dp)) {
Text(text = "Auteur : "+e.auteur, fontSize = 17.sp)
Text(text = "Description : "+e.description, fontSize = 17.sp)
Text(text = "Temps de lecture : "+e.temps+" minutes", fontSize = 17.sp)
}
}
Log.d("ImageLoad", e.toString())
Image(
painter = rememberImagePainter(
data = imageURl
data = e.imagePrincipale
),
contentScale = ContentScale.Crop,
contentDescription = null,
@ -79,15 +77,16 @@ fun AffichageUnArticleInfo(e : Article){
.align(Alignment.CenterHorizontally)
.padding(5.dp, 35.dp)
)
Button(onClick = { /*TODO*/ },
Button(onClick = { goToArticle(e)},
colors = ButtonDefaults.buttonColors(
containerColor = Salmon,
contentColor = Color.Black
),
containerColor = Salmon,
contentColor = Color.Black
),
border = BorderStroke(1.dp, Color.Black),
modifier = Modifier
.align(Alignment.CenterHorizontally)
modifier = Modifier
.align(Alignment.CenterHorizontally)
) {
Text(text = "Voir plus")
}
@ -95,41 +94,91 @@ fun AffichageUnArticleInfo(e : Article){
}
}
@Composable
fun AfficherArticle(e : Article){
Column(modifier = Modifier
.verticalScroll(rememberScrollState())
.padding(7.dp)
.padding(5.dp)) {
Text(text = e.titre, fontFamily = FontFamily.Serif, fontSize = 30.sp)
// Affichage des informations de l'article
DisplayHeader(author = e.auteur, description = e.description, lectureTime = e.temps)
@Composable
fun AfficherArticle(e : Article) {
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
.padding(7.dp)
.padding(5.dp)
) {
Text(text = "coucou")
Text(text = e.titre, fontFamily = FontFamily.Serif, fontSize = 30.sp)
/*
Box(
modifier = Modifier
.padding(15.dp)
.border(width = 1.dp, color = Color.Black, shape = RoundedCornerShape(10.dp))
.clip(RoundedCornerShape(10.dp))
.background(Salmon)
) {
Column(modifier = Modifier.padding(15.dp)) {
Text(text = "Auteur : " + e.auteur, fontSize = 17.sp)
Text(text = "Description : " + e.description, fontSize = 17.sp)
Text(text = "Temps de lecture : " + e.temps + " minutes", fontSize = 17.sp)
}
}
Image(
painter = rememberImagePainter(data = e.imagePrincipale),
contentScale = ContentScale.FillHeight,
painter = rememberImagePainter(
data = e.imagePrincipale
),
contentScale = ContentScale.Crop,
contentDescription = null,
modifier = Modifier
.size(350.dp)
.align(Alignment.CenterHorizontally)
.padding(5.dp, 35.dp)
.fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally)
)*/
)
Column(modifier = Modifier) {
for (text in e.contenus) {
when (text) {
is ContenuMedia -> {
Text(text = text.titre, fontSize = 20.sp, fontWeight = FontWeight.Bold)
when (text.typeContenu) {
"image" -> {
Image(
painter = rememberImagePainter(
data = text.lien
),
contentScale = ContentScale.FillHeight,
contentDescription = null,
modifier = Modifier
.size(350.dp)
.align(Alignment.CenterHorizontally)
.padding(5.dp, 35.dp)
)
}
"video" -> {
Text(
text = "Ici une video ..." + text.toString(),
fontSize = 15.sp,
textAlign = TextAlign.Start
)
// le player video marche a moitié mais honnetenement je comprends pas le soucis
VideoPlayer(videoUrl = text.lien)
}
}
// Affichage contenus
//DisplayContenu(e.lContenus)
}
is ContenuParagraphe -> {
Text(text = text.titre, fontSize = 20.sp, fontWeight = FontWeight.Bold)
Text(text = text.toString(), fontSize = 16.sp, textAlign = TextAlign.Start)
}
}
}
}
}
}
@Composable
fun DisplayHeader(author: String, description: String, lectureTime: String) {
Box(
@ -147,104 +196,17 @@ fun DisplayHeader(author: String, description: String, lectureTime: String) {
}
}
@Composable
fun DisplayContenu(contenus: List<Contenu>) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
for (contenu in contenus) {
when (contenu) {
is ContenuMedia -> {
Text(text = contenu.titre, fontSize = 20.sp, fontWeight = FontWeight.Bold)
when (contenu.typeContenu) {
"image" -> {
Image(
painter = rememberImagePainter(data = contenu.lien),
contentScale = ContentScale.FillHeight,
contentDescription = null,
modifier = Modifier
.size(350.dp)
.padding(5.dp, 35.dp)
.fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally) // Centrer l'image
)
}
"video" -> {
// Pour l'instant, un simple texte pour les vidéos
Text(text = "Ici une vidéo ... ${contenu.lien}", fontSize = 15.sp, textAlign = TextAlign.Start)
// Implémentation pour vidéo à venir...
}
}
}
is ContenuParagraphe -> {
Text(text = contenu.titre, fontSize = 20.sp, fontWeight = FontWeight.Bold)
Text(text = contenu.texte, fontSize = 16.sp, textAlign = TextAlign.Start)
}
}
}
}
}
fun DisplayImage(imageURl : String){
Log.d("ImageLoad", "URL de l'image reçue de l'API : $imageURl")
/*
@Composable
fun DisplayImage(image: String) {
Image(
painter = rememberImagePainter(
data = image
data = imageURl
),
contentScale = ContentScale.Crop,
contentDescription = null,
modifier = Modifier
.size(350.dp)
.align(Alignment.CenterHorizontally)
.padding(5.dp, 35.dp)
)
}
@Composable
fun DisplayImage(image: String) {
Image(
painter = rememberImagePainter(
data = e.imagePrincipale
),
contentScale = ContentScale.Crop,
contentDescription = null,
modifier = Modifier
.size(350.dp)
.align(Alignment.CenterHorizontally)
.padding(5.dp, 35.dp)
)
}
@Composable
fun DisplayHeader(author: String, description: String, lectureTime: String) {
Box(modifier = Modifier
.fillMaxWidth()
.border(width = 1.dp, color = Color.Black, shape = RoundedCornerShape(10.dp))
.clip(RoundedCornerShape(10.dp))
.background(Salmon)
.padding(10.dp)) {
Column () {
Text(text = author)
Text(text = description)
Text(text = "Lecture Time: " + lectureTime + " minutes")
}
}
}
@Composable
fun DisplayTitle(title: String) {
Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally){
Text(text = title, fontFamily = FontFamily.Serif, fontSize = 30.sp)
}
}
@Composable
fun DisplayContentArticle(content: List<Contenu>) {
Column {
for(e in content){
Text(text = e.Content, fontSize = 15.sp, fontFamily = FontFamily.Serif, textAlign = TextAlign.Justify, modifier = Modifier.padding(10.dp))
}
}
}*/
}

@ -0,0 +1,42 @@
import android.view.ViewGroup
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.ui.PlayerView
@Composable
fun VideoPlayer(videoUrl : String){
val context = LocalContext.current
val player = ExoPlayer.Builder(context).build()
val playerView = PlayerView(context).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}
val mediaItem = MediaItem.Builder()
.setUri(videoUrl)
.build()
player.setMediaItem(mediaItem)
player.prepare()
player.play()
AndroidView(
factory = { context -> playerView },
modifier = Modifier.fillMaxSize(),
update = { view ->
view.player = player
}
)
}

@ -5,12 +5,13 @@ import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
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.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.DropdownMenu
@ -32,9 +33,11 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.example.veraxapplication.R
import com.example.veraxapplication.modele.articles.Article
import com.example.veraxapplication.ui.article.AffichageLesArticles
import com.example.veraxapplication.navigation.VeraxNavHost
import com.example.veraxapplication.ui.theme.Orange
@OptIn(ExperimentalMaterial3Api::class)
@ -43,7 +46,12 @@ fun TopBarVerax(theme: List<String>, articles: List<Article>) {
var leMenu by remember {
mutableStateOf(false)
}
Row() {
val navController = rememberNavController()
val navBackStackEntry by navController.currentBackStackEntryAsState()
Row( modifier = Modifier.background(Color.Blue).fillMaxSize()) {
Scaffold(
topBar = {
CenterAlignedTopAppBar(
@ -58,14 +66,16 @@ fun TopBarVerax(theme: List<String>, articles: List<Article>) {
modifier = Modifier.fillMaxWidth()
)
},
navigationIcon = {
IconButton(onClick = { /* action() */ }) {
navigationIcon = { if (navBackStackEntry?.destination?.route != "accueil"){
IconButton(onClick = { navController.popBackStack() }) {
Icon(
imageVector = Icons.Filled.ArrowBack,
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = "Retour",
Modifier.size(30.dp)
)
}
}
},
actions = {
IconButton(onClick = { leMenu = !leMenu }) {
@ -78,7 +88,11 @@ fun TopBarVerax(theme: List<String>, articles: List<Article>) {
DropdownMenu(
expanded = leMenu, onDismissRequest = { leMenu = false },
modifier = Modifier
.border(width = 1.dp, color = Color.Black, shape = RoundedCornerShape(10.dp))
.border(
width = 1.dp,
color = Color.Black,
shape = RoundedCornerShape(10.dp)
)
.background(Orange)
) {
theme.sorted().forEach {
@ -125,8 +139,10 @@ fun TopBarVerax(theme: List<String>, articles: List<Article>) {
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
AffichageLesArticles(articles = articles)
// AfficherArticle(articles.get(0));
// AffichageLesArticles(articles = articles)
// AfficherArticle(articles.get(0))
VeraxNavHost(articles = articles, navController)
}

Loading…
Cancel
Save