Project activity debut

This commit is contained in:
Raphael
2025-01-12 18:21:32 +01:00
parent f6ecbc8909
commit d7c313c013
10 changed files with 267 additions and 56 deletions

View File

@@ -73,6 +73,7 @@ dependencies {
implementation("com.squareup.okhttp3:logging-interceptor:4.9.0") // Pour le logging implementation("com.squareup.okhttp3:logging-interceptor:4.9.0") // Pour le logging
implementation("com.github.bumptech.glide:glide:4.15.1") // Pour curl des images d'internet en gros implementation("com.github.bumptech.glide:glide:4.15.1") // Pour curl des images d'internet en gros
kapt("com.github.bumptech.glide:compiler:4.15.1") kapt("com.github.bumptech.glide:compiler:4.15.1")
implementation("com.github.PhilJay:MPAndroidChart:v3.1.0")
testImplementation(libs.junit) testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(libs.androidx.espresso.core)

View File

@@ -1,5 +1,7 @@
package com.dreamteam.timelapse package com.dreamteam.timelapse
import android.os.Parcel
import android.os.Parcelable
import java.util.Date import java.util.Date
//{ //{
@@ -9,14 +11,60 @@ import java.util.Date
// "description": "Projet de Test", // "description": "Projet de Test",
// "titre": "Test Project" // "titre": "Test Project"
//} //}
data class Project ( data class Project(
val id: Int, val id: Int,
val creation: Date, val name: String,
val status: String,
val description: String, val description: String,
val titre: String, val start_date: Date,
val status: Int,
val thumbnail_url: String? val thumbnail_url: String?
) { ) : Parcelable {
fun getStatusText(): String{
val statusArr = arrayOf("Brouillon", "En Cours", "Terminé", "Annulé")
return statusArr[status]
}
fun getStatusColor(): Int{
return when (status) {
0 -> R.color.brouillon
1 -> R.color.en_cours
2 -> R.color.termine
3 -> R.color.annule
else -> R.color.default_badge
}
}
// Constructor to recreate from Parcel
constructor(parcel: Parcel) : this(
parcel.readInt(),
parcel.readString() ?: "",
parcel.readString() ?: "",
Date(parcel.readLong()),
parcel.readInt(),
parcel.readString()
)
// Write object to Parcel
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(id)
parcel.writeString(name)
parcel.writeString(description)
parcel.writeString(start_date.toString())
parcel.writeInt(status)
}
// Describe the contents of the Parcel
override fun describeContents(): Int = 0
companion object CREATOR : Parcelable.Creator<Project> {
override fun createFromParcel(parcel: Parcel): Project {
return Project(parcel)
}
override fun newArray(size: Int): Array<Project?> {
return arrayOfNulls(size)
}
}
// fun getThumbnail(): String { // fun getThumbnail(): String {
// return images[0] // return images[0]
// } // }

View File

@@ -1,7 +0,0 @@
package com.dreamteam.timelapse;
import androidx.appcompat.app.AppCompatActivity;
public class ProjectActivity extends AppCompatActivity {
//FIX
}

View File

@@ -1,48 +1,62 @@
package com.dreamteam.timelapse package com.dreamteam.timelapse
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.AppBarConfiguration
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import com.dreamteam.timelapse.databinding.ActivityMainBinding import com.dreamteam.timelapse.databinding.ProjectBinding
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.dreamteam.timelapse.R as Rtmp import com.dreamteam.timelapse.R
import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
class ProjectActivity : AppCompatActivity() { class ProjectActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var binding: ProjectBinding
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
// super.onCreate(savedInstanceState) val project = intent.getParcelableExtra<Project>("PROJECT") // -1 est la valeur par défaut si l'ID n'est pas trouvé
// Log.d("project", "La project activity "+project?.id+" est créée")
Log.d("mainActivity", "La main activity est créée")
// setSupportActionBar(binding.toolbar)
//
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
//val navController = findNavController(R.id.nav_host_fragment_content_main) binding = ProjectBinding.inflate(layoutInflater)
//appBarConfiguration = AppBarConfiguration(navController.graph) setContentView(binding.root)
//setupActionBarWithNavController(navController, appBarConfiguration) // Initialisation du graphique
val temperatureHumidityChart = binding.temperatureHumidityChart
// R.layout contient : // Données fictives (température et humidité)
// - un TabLayout avec l'id tabLayout val temperatureEntries = mutableListOf<Entry>()
// - un ViewPager2 avec l'id viewPager val humidityEntries = mutableListOf<Entry>()
// - un FloatingActionButton avec l'id fab
//setContentView(R.layout.activity_main) // Ajouter des points de données (exemples)
//ce qui corrigé donne : temperatureEntries.add(Entry(0f, 25f)) // (temps, température)
setContentView(Rtmp.layout.activity_main) humidityEntries.add(Entry(0f, 60f)) // (temps, humidité)
val tabLayout = findViewById<View>(Rtmp.id.tabLayout) as TabLayout
val viewPager = findViewById<View>(Rtmp.id.viewPager) as ViewPager2
// Créer des LineDataSet pour chaque série de données
val temperatureDataSet = LineDataSet(temperatureEntries, "Température")
val humidityDataSet = LineDataSet(humidityEntries, "Hygrométrie")
// Ajouter les datasets au graphique
val lineData = LineData(temperatureDataSet, humidityDataSet)
temperatureHumidityChart.data = lineData
// Personnaliser le graphique (par exemple, couleur, légende, etc.)
temperatureDataSet.color = Color.RED
humidityDataSet.color = Color.BLUE
temperatureHumidityChart.invalidate() // Rafraîchir le graphique
//super.onCreate(savedInstanceState)
val nameview = findViewById<TextView>(R.id.project_name)
val descriptionview = findViewById<TextView>(R.id.project_name)
val beginview = findViewById<TextView>(R.id.project_start_date)
val statusview = findViewById<TextView>(R.id.project_status)
// Configurer l'adapter pour ViewPager2
var tabsAdapter = TabsAdapter(this)
viewPager.setAdapter(tabsAdapter)
// Bouton flottant // Bouton flottant

View File

@@ -1,6 +1,7 @@
package com.dreamteam.timelapse package com.dreamteam.timelapse
import android.content.Intent import android.content.Intent
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -11,7 +12,11 @@ import androidx.core.graphics.drawable.DrawableCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
class ProjectAdapter(private val projects: List<Project>) : RecyclerView.Adapter<ProjectAdapter.ProjectViewHolder>() { class ProjectAdapter(private val projects: List<Project>, private val listener: OnEmptyStateListener) : RecyclerView.Adapter<ProjectAdapter.ProjectViewHolder>() {
interface OnEmptyStateListener {
fun onEmptyStateChanged(isEmpty: Boolean)
}
class ProjectViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { class ProjectViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val projectTitle: TextView = itemView.findViewById(R.id.projectTitle) val projectTitle: TextView = itemView.findViewById(R.id.projectTitle)
@@ -23,30 +28,28 @@ class ProjectAdapter(private val projects: List<Project>) : RecyclerView.Adapter
//crée les éléments dans le fragment //crée les éléments dans le fragment
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProjectViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProjectViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_project_card, parent, false) val view = LayoutInflater.from(parent.context).inflate(R.layout.item_project_card, parent, false)
//projects.isEmpty()
listener.onEmptyStateChanged(projects.isEmpty())
return ProjectViewHolder(view) return ProjectViewHolder(view)
} }
// Remplit le ViewHolder avec les données // Remplit le ViewHolder avec les données
override fun onBindViewHolder(holder: ProjectViewHolder, position: Int) { override fun onBindViewHolder(holder: ProjectViewHolder, position: Int) {
val project = projects[position] val project = projects[position]
holder.projectTitle.text = project.titre // Affiche le titre du projet holder.projectTitle.text = project.name // Affiche le titre du projet
holder.projectDescription.text = project.description holder.projectDescription.text = project.description
holder.projectBadge.text = project.status holder.projectBadge.text = project.getStatusText()
val context = holder.itemView.context val context = holder.itemView.context
val color = when (project.status) { val color = project.getStatusColor()
"En Cours" -> R.color.en_cours
"Terminé" -> R.color.termine
"Annulé" -> R.color.annule
"Brouillon" -> R.color.brouillon
else -> R.color.default_badge
}
Glide.with(holder.projectImage.context) Glide.with(holder.projectImage.context)
.load("https://timelapse.kerboul.me/api/smile") // L'URL de l'image .load("https://timelapse.kerboul.me/api/smile") // L'URL de l'image
.into(holder.projectImage) .into(holder.projectImage)
DrawableCompat.setTint(holder.projectBadge.background, ContextCompat.getColor(context, color)) DrawableCompat.setTint(holder.projectBadge.background, ContextCompat.getColor(context, color))
holder.itemView.setOnClickListener { holder.itemView.setOnClickListener {
val intent = Intent(context, ProjectActivity::class.java) val intent = Intent(context, ProjectActivity::class.java)
intent.putExtra("PROJECT_ID", project.id) // Passe les données nécessaires à l'activité cible intent.putExtra("PROJECT", project) // Passe les données nécessaires à l'activité cible
context.startActivity(intent) context.startActivity(intent)
} }
} }

View File

@@ -23,7 +23,7 @@ import retrofit2.converter.gson.GsonConverterFactory
* A simple [Fragment] subclass as the default destination in the navigation. * A simple [Fragment] subclass as the default destination in the navigation.
*/ */
class ProjetsFrag : Fragment() { class ProjetsFrag : Fragment(), ProjectAdapter.OnEmptyStateListener {
private lateinit var projectRepository: ProjectRepository private lateinit var projectRepository: ProjectRepository
//private lateinit var listView: ListView //private lateinit var listView: ListView
@@ -84,7 +84,7 @@ class ProjetsFrag : Fragment() {
onSuccess = { projects -> onSuccess = { projects ->
Log.d("ProjetsFrag", "Projets reçus : $projects") Log.d("ProjetsFrag", "Projets reçus : $projects")
this.projects = projects this.projects = projects
this.projectAdapter = ProjectAdapter(this.projects) //TODO : Potentiel problème pour les refresh ici (update de l'adapter ou un truc du genre à voir) this.projectAdapter = ProjectAdapter(this.projects, this) //TODO : Potentiel problème pour les refresh ici (update de l'adapter ou un truc du genre à voir)
this.recyclerView.adapter = this.projectAdapter this.recyclerView.adapter = this.projectAdapter
// Mettre à jour le RecyclerView ou autre traitement // Mettre à jour le RecyclerView ou autre traitement
}, },
@@ -94,6 +94,14 @@ class ProjetsFrag : Fragment() {
) )
binding.swipeRefreshLayout.isRefreshing = false binding.swipeRefreshLayout.isRefreshing = false
} }
override fun onEmptyStateChanged(isEmpty: Boolean) {
// Afficher ou masquer le message
if (isEmpty) {
binding.noProjectsText.visibility = View.VISIBLE
} else {
binding.noProjectsText.visibility = View.GONE
}
}
// override fun onDestroyView() { // override fun onDestroyView() {
// super.onDestroyView() // super.onDestroyView()

View File

@@ -2,8 +2,11 @@ package com.dreamteam.timelapse.data
import com.dreamteam.timelapse.Project import com.dreamteam.timelapse.Project
import retrofit2.Call import retrofit2.Call
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Path
interface ApiService { interface ApiService {
@GET("itemsdb") // Remplace par l'endpoint de ton API @GET("projects") // Remplace par l'endpoint de ton API
fun getProjets(): Call<List<Project>> fun getProjets(): Call<List<Project>>
@GET("projects/{id}") // Remplace par l'endpoint de ton API
fun getProjet(@Path("id") projectId: Int): Call<Project>
} }

View File

@@ -43,10 +43,28 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView <FrameLayout
android:id="@+id/recyclerView" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="match_parent">
android:layout_height="match_parent"/>
<!-- RecyclerView -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- TextView affichée quand aucun projet n'est disponible -->
<TextView
android:id="@+id/no_projects_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Aucun projet disponible"
android:visibility="gone"
android:gravity="center"
android:textSize="18sp"
android:layout_gravity="center" />
</FrameLayout>
<!--<ListView <!--<ListView
android:id="@+id/listView" android:id="@+id/listView"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProjectActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/project_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Nom du projet"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/appBarLayout"
tools:context=".ProjectActivity">
<!-- Description du projet -->
<TextView
android:id="@+id/project_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Description du projet"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/project_name" />
<!-- Date de début du projet -->
<TextView
android:id="@+id/project_start_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Date de début"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/project_description" />
<!-- Statut du projet -->
<TextView
android:id="@+id/project_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Statut: En cours"
android:textColor="@android:color/holo_green_dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/project_start_date" />
<!-- Liste des vidéos liées au projet -->
<TextView
android:id="@+id/video_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Vidéos associées"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/project_status" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/videos_list"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/video_header" />
<!-- Graphique de température et d'hygrométrie -->
<TextView
android:id="@+id/graph_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Graphique de Température et d'Hygrométrie"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/videos_list" />
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/temperature_humidity_chart"
android:layout_width="0dp"
android:layout_height="250dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/graph_header" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -9,6 +9,7 @@ pluginManagement {
} }
mavenCentral() mavenCentral()
gradlePluginPortal() gradlePluginPortal()
maven { url = uri("https://jitpack.io") } // Ajoute JitPack
} }
} }
dependencyResolutionManagement { dependencyResolutionManagement {
@@ -16,7 +17,9 @@ dependencyResolutionManagement {
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
maven { url = uri("https://jitpack.io") } // Ajoute JitPack
} }
} }
rootProject.name = "Timelapse" rootProject.name = "Timelapse"