j'essaye de comprendre

workShana
Shana CASCARRA 1 year ago
commit 76a51f1de0

@ -1,6 +1,7 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
kotlin("plugin.serialization") version "1.5.10"
}
android {
@ -55,6 +56,9 @@ dependencies {
implementation ("com.squareup.retrofit2:retrofit:2.9.0")
implementation ("com.squareup.retrofit2:converter-gson:2.9.0")
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0")
implementation ("androidx.compose.runtime:runtime-livedata:1.0.0-alpha07")
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
@ -71,6 +75,11 @@ dependencies {
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")
implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")
implementation ("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0")
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")

@ -12,7 +12,10 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.VeraxApplication"
tools:targetApi="31">
tools:targetApi="31"
android:networkSecurityConfig="@xml/network_security_config"
>
<activity
android:name=".MainActivity"
android:exported="true"

@ -1,15 +1,16 @@
package com.example.veraxapplication
import ArticlesViewModel
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.ui.graphics.Color
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.modele.ApiClient
import com.example.veraxapplication.modele.articles.Article
import com.example.veraxapplication.navigation.VeraxNavHost
import com.example.veraxapplication.ui.article.AfficherArticle
import com.example.veraxapplication.ui.topBar.TopBarVerax
@ -19,31 +20,40 @@ import com.example.veraxapplication.ui.topBar.TopBarVerax
class MainActivity : ComponentActivity() {
// un truc vite fait pour avoir un visi
// var article = listOf("Thinkerview", "thinkerview.jgp", "Thinkerview est une chaîne youtube d'interview-débat")
//var articles = listOf( Article("Thinkerview", "This is a descrition", Author = "IAmAGreatAuthor", Image = "https://www.gstatic.com/webp/gallery/1.jpg", LectureTime = "12", Content = listOf(Paragraph("This is a paragraph"), Paragraph("This is another paragraph"), Paragraph("This is a third paragraph"))), Article("Thinkerview", "This is a descrition", Author = "IAmAGreatAuthor", Image = "https://www.gstatic.com/webp/gallery/1.jpg", LectureTime = "12", Content = listOf(Paragraph("This is a paragraph"), Paragraph("This is another paragraph"), Paragraph("This is a third paragraph"))))
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
VeraxContent()
}
}
}
@Composable
fun VeraxContent() {
// Initialiser les données ou observer les données du ViewModel
var dataManager: IArticlesDataManager = StubArticles()
var articles = dataManager.getDerniersArticles(4)
val articlesApi = ApiClient.apiService.getArticles()
// Observer les données du ViewModel
val articlesViewModel: ArticlesViewModel = viewModel()
var theme = listOf("Economique", "Culture", "Politique", "Faits divers")
// Observez les articles du ViewModel
val articlesApi by articlesViewModel.articles.observeAsState(initial = articles)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var theme = listOf("Economique", "Culture", "Politique", "Faits divers")
// TopBarVerax(theme = theme, articles = articlesApi)
TopBarVerax(theme = theme, articles = articles)
for(a in articlesApi){
Log.d("Articles : ", a.contenus.toString())
}
// VeraxNavHost()
TopBarVerax(articles = articlesApi, theme = theme)
}
}
}
}

@ -1,22 +0,0 @@
package com.example.veraxapplication.modele
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object RetrofitClient {
private const val BASE_URL = "http://181.214.189.133:9092/"
val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
}
object ApiClient {
val apiService: ApiService by lazy {
RetrofitClient.retrofit.create(ApiService::class.java)
}
}

@ -0,0 +1,27 @@
package com.example.veraxapplication.modele
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object RetrofitClientUser {
private const val BASE_URL = "https://codefirst.iut.uca.fr/containers/Verax-verax-api"
val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
// interface UserApiService {
// @GET("users")
// suspend fun getUsers() : List<User>
// }
}
object ApiClientUser {
val apiService: UserApiService by lazy {
RetrofitClientUser.retrofit.create(UserApiService::class.java)
}
}

@ -1,10 +0,0 @@
package com.example.veraxapplication.modele
import com.example.veraxapplication.modele.articles.Article
import retrofit2.Call
import retrofit2.http.GET
interface ApiService {
@GET("articles/")
fun getArticles(): Call<List<Article>>
}

@ -0,0 +1,9 @@
import com.example.veraxapplication.modele.user.User
interface IUsersDataManager {
val allUsers: List<Any?>?
fun getUser(pseudo : String): User?
fun getUsers(): List<User>
}

@ -0,0 +1,11 @@
package com.example.veraxapplication.modele
import com.example.veraxapplication.modele.user.User
import retrofit2.Call
import retrofit2.http.GET
interface UserApiService {
@GET("users/")
suspend fun getUsers(): Call<List<User>>
}

@ -0,0 +1,54 @@
package com.example.veraxapplication.modele.api
import com.example.veraxapplication.modele.articles.Article
import com.google.gson.annotations.SerializedName
data class ArticleDTO (
@SerializedName("id")
val id: Int,
@SerializedName("titre")
val titre: String,
@SerializedName("description")
val description: String,
@SerializedName("temps")
val temps: String,
@SerializedName("date")
val date: String,
@SerializedName("auteur")
val auteur: String,
@SerializedName("categorie")
val categorie: String,
@SerializedName("imagePrincipale")
val imagePrincipale: String,
@SerializedName("note")
val note: String,
) {
fun toModel(): Article {
return Article(
id,
titre,
description,
temps,
date,
auteur,
categorie,
imagePrincipale,
note,
)
}
}
data class ContenuDTO (
@SerializedName("id")
val id: Int,
@SerializedName("typeContenu")
val typeContenu: String,
@SerializedName("titre")
val titre: String,
@SerializedName("texte")
val texte: String,
)

@ -0,0 +1,54 @@
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.veraxapplication.modele.api.IArticleService
import com.example.veraxapplication.modele.articles.Article
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object ArticleApiClient {
private const val BASE_URL = "http://181.214.189.133:9092/"
private val logging = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
private val httpClient = OkHttpClient.Builder().apply {
addInterceptor(logging)
}.build()
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient)
.build()
}
class ArticlesViewModel : ViewModel() {
private val _articles = MutableLiveData<List<Article>>()
val articles: LiveData<List<Article>> = _articles
private val service = ArticleApiClient.retrofit.create(IArticleService::class.java)
init {
loadArticles()
}
fun loadArticles() {
viewModelScope.launch {
try {
val articlesDto = service.getArticles() // Pas besoin d'appeler .execute()
// Convertissez les DTO en modèles de données si nécessaire
_articles.value = articlesDto.map { it.toModel() }
} catch (e: Exception) {
Log.e("ArticlesViewModel", "Erreur lors du chargement des articles", e)
}
}
}
}

@ -0,0 +1,8 @@
package com.example.veraxapplication.modele.api
import retrofit2.http.GET
interface IArticleService {
@GET("articles")
suspend fun getArticles(): List<ArticleDTO>
}

@ -9,10 +9,11 @@ class Article(
val temps: String,
val date: String,
val auteur: String,
val categorie: String,
val note: String,
val imagePrincipale: String
) {
val note = 1.0
private val lContenus: MutableList<Contenu> = java.util.ArrayList()
public val lContenus: MutableList<Contenu> = java.util.ArrayList()
init {
// Initialisation des contenus si nécessaire
@ -30,4 +31,6 @@ class Article(
override fun toString(): String {
return "Article(id=$id, titre='$titre', description='$description', temps='$temps', date='$date', auteur='$auteur', imagePrincipale='$imagePrincipale', note=$note, contenus=${lContenus.size} contenus)"
}
}

@ -1,13 +1,9 @@
package com.example.veraxapplication.articles
import android.os.Build
import androidx.annotation.RequiresApi
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 java.time.LocalDate
import kotlin.math.min
class StubArticles() : IArticlesDataManager {
@ -28,8 +24,10 @@ class StubArticles() : IArticlesDataManager {
"Thinkerview",
"Thinkerview est une chaîne passionnante chaîne youtube d'interview-débat.",
"3",
"date a revoir",
"Siwa",
"02/09/2024",
"Tony",
"Politique",
"12",
"https://cdn.discordapp.com/attachments/1150826798549049554/1219554341388816437/stub1.webp?ex=660bb97d&is=65f9447d&hm=3e1e8d3372ae897fa4e2aa1ec730d976d74b35fce96cb8d78d6f9239e2836564&"
)
article1.remplirArticle(contenuMap["article1"])
@ -41,8 +39,10 @@ class StubArticles() : IArticlesDataManager {
"Le réchauffement climatique : un mythe ?",
"Revenons sur les différentes controverses à ce sujet.",
"7",
"date a revoir",
"Siwa",
"02/09/2024",
"Tony",
"Politique",
"12",
"https://cdn.discordapp.com/attachments/1150826798549049554/1219555874339815454/stub2.webp?ex=660bbaea&is=65f945ea&hm=80aef945e8410b18395c716fdd19265608f7b1263731192d5c69f807fce9e944&"
)
article2.remplirArticle(contenuMap["article5"])
@ -54,8 +54,11 @@ class StubArticles() : IArticlesDataManager {
"La terre plate : vraiment ?",
"Pour réfuter la fausse croyance que la Terre est plate, il est essentiel de s'appuyer sur des preuves scientifiques et des observations historiques. ",
"5",
"date a revoir",
"Siwa",
"02/09/2024",
"Tony",
"Politique",
"12",
"https://cdn.discordapp.com/attachments/1150826798549049554/1219547864196317225/stub1.webp?ex=660bb374&is=65f93e74&hm=a9e5dd48faa3ae68c358309af8949c46dfd4dea9c4d6e3d845d707784e5341cf&"
)
article3.remplirArticle(contenuMap["article4"])
@ -67,8 +70,10 @@ class StubArticles() : IArticlesDataManager {
"L'ia & humanité : quel avenir ? ",
"Explorons les progrès remarquables dans le domaine de l'IA, les secteurs qu'elle révolutionne, et les implications éthiques majeures qu'elle soulève.",
"9",
"date a revoir",
"Luthen",
"02/09/2024",
"Tony",
"Politique",
"12",
"https://cdn.discordapp.com/attachments/1150826798549049554/1219560686254817290/stub1.webp?ex=660bbf65&is=65f94a65&hm=021bd8c90c89347f31373468cc7a03ae15f1d3f9988a5b4325149c6df938d7bb&"
)
article4.remplirArticle(contenuMap["article6"])

@ -0,0 +1,3 @@
package com.example.veraxapplication.modele.user
data class User(val pseudo : String, val mdp : String, val mail : String, val nom : String, val prenom : String, val role : Char)

@ -1,11 +1,11 @@
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.padding
@ -33,15 +33,14 @@ 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>, goToArticle: (Article) -> Unit
){
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*/ }){
Box {
AffichageUnArticleInfo(e = article, goToArticle)
}
}
}
}
@ -52,30 +51,17 @@ fun AffichageUnArticleInfo(e : Article, goToArticle: (Article) -> Unit){
.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)
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)
}
}
var imageURl = e.note
Log.d("ImageLoad", "URL de l'image reçue de l'API : $imageURl")
Image(
painter = rememberImagePainter(
data = e.imagePrincipale
data = imageURl
),
contentScale = ContentScale.Crop,
contentDescription = null,
@ -84,7 +70,7 @@ fun AffichageUnArticleInfo(e : Article, goToArticle: (Article) -> Unit){
.align(Alignment.CenterHorizontally)
.padding(5.dp, 35.dp)
)
Button(onClick = { goToArticle(e) },
colors = ButtonDefaults.buttonColors(
containerColor = Salmon,
@ -171,62 +157,4 @@ fun AfficherArticle(e : Article){
}
}
}
}
/*
@Composable
fun DisplayImage(image: String) {
Log.d("DisplayImage", "Chargement de l'image à partir de l'URL : $image")
Log.d("DisplayImage", "Painter créé avec succès")
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Image(
painter = rememberImagePainter(
data = image,
builder = {
scale(Scale.FILL)
}
),
contentDescription = null,
modifier = Modifier.fillMaxSize(),
)
}
}
@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))
}
}
}*/
}

@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.size
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.filled.ArrowBack
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.DropdownMenu
@ -38,8 +37,6 @@ import androidx.navigation.compose.rememberNavController
import com.example.veraxapplication.R
import com.example.veraxapplication.modele.articles.Article
import com.example.veraxapplication.navigation.VeraxNavHost
import com.example.veraxapplication.ui.article.AffichageLesArticles
import com.example.veraxapplication.ui.article.AfficherArticle
import com.example.veraxapplication.ui.theme.Orange
@OptIn(ExperimentalMaterial3Api::class)

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">181.214.189.133</domain>
</domain-config>
</network-security-config>
Loading…
Cancel
Save