supression projet

This commit is contained in:
Raphael
2025-03-13 10:19:47 +01:00
parent 204058c839
commit 133f45fc7b
6 changed files with 126 additions and 3 deletions

View File

@@ -1,5 +1,6 @@
package com.dreamteam.timelapse package com.dreamteam.timelapse
import android.content.Context
import android.content.Intent import android.content.Intent
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
@@ -7,14 +8,28 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat 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
import com.dreamteam.timelapse.data.ApiService
import com.dreamteam.timelapse.data.Project import com.dreamteam.timelapse.data.Project
import com.dreamteam.timelapse.data.ProjectRepository
import com.google.android.material.snackbar.Snackbar
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class ProjectAdapter(private val projects: List<Project>, private val listener: OnEmptyStateListener) : RecyclerView.Adapter<ProjectAdapter.ProjectViewHolder>() { class ProjectAdapter(private val projects: MutableList<Project>, private val listener: OnEmptyStateListener) : RecyclerView.Adapter<ProjectAdapter.ProjectViewHolder>() {
val projectRepository : ProjectRepository;
init{ init{
val retrofit = Retrofit.Builder()
.baseUrl("https://timelapse.kerboul.me/api/")
.addConverterFactory(GsonConverterFactory.create())
.build()
projectRepository = ProjectRepository(retrofit.create(ApiService::class.java))
listener.onEmptyStateChanged(projects.isEmpty()) listener.onEmptyStateChanged(projects.isEmpty())
} }
@@ -57,7 +72,32 @@ class ProjectAdapter(private val projects: List<Project>, private val listener:
context.startActivity(intent) context.startActivity(intent)
} }
} }
fun removeItem(position: Int, context: Context, v : View) {
val builder = AlertDialog.Builder(context)
val dialog = builder.setTitle("Confirm Deletion")
.setMessage("Voulez vous supprimer ce projet ?")
.setPositiveButton("Supprimer") { dialog, _ ->
projectRepository.deleteProject(projects[position].id, onSuccess = {
val name = projects[position].name
projects.removeAt(position)
notifyItemRemoved(position)
Snackbar.make(v.rootView, "$name supprimé avec succès !", Snackbar.LENGTH_SHORT).show()
}, onError = {s ->
dialog.dismiss()
notifyItemChanged(position)
Snackbar.make(v.rootView, "Error while trying to delete ${projects[position].name} : $s", Snackbar.LENGTH_SHORT).show()
})
}
.setNegativeButton("Annuler") { dialog, _ ->
dialog.dismiss()
notifyItemChanged(position) // Reset swipe animation
}
.show()
dialog.setOnDismissListener {
notifyItemChanged(position) // Ensure the card resets when dialog closes
}
}
override fun getItemCount(): Int { override fun getItemCount(): Int {
return projects.size return projects.size
} }

View File

@@ -1,5 +1,8 @@
package com.dreamteam.timelapse package com.dreamteam.timelapse
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.util.TypedValue import android.util.TypedValue
@@ -8,7 +11,9 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.GridLayout import android.widget.GridLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.dreamteam.timelapse.data.ProjectRepository import com.dreamteam.timelapse.data.ProjectRepository
@@ -72,6 +77,48 @@ class ProjetsFrag : Fragment(), ProjectAdapter.OnEmptyStateListener {
recyclerView = binding.recyclerView // view.findViewById(R.id.recyclerView) recyclerView = binding.recyclerView // view.findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(context) recyclerView.layoutManager = LinearLayoutManager(context)
val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
private val background = ColorDrawable(Color.RED) // Red background
private val deleteIcon = context?.let { ContextCompat.getDrawable(it, R.drawable.ic_delete) }
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val position = viewHolder.adapterPosition
context?.let { (recyclerView.adapter as ProjectAdapter).removeItem(position, it, viewHolder.itemView) }
}
override fun onChildDraw(
c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder,
dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean
) {
val itemView = viewHolder.itemView
val backgroundCornerOffset = 20 // Slight offset for smooth animation
background.setBounds(
itemView.left,
itemView.top,
itemView.left + dX.toInt() - backgroundCornerOffset,
itemView.bottom
)
//background.draw(c)
// Position the delete icon
val iconMargin = (itemView.height - deleteIcon!!.intrinsicHeight) / 2
val iconRight = itemView.left + iconMargin + deleteIcon.intrinsicWidth
val iconLeft = itemView.left + iconMargin
val iconTop = itemView.top + (itemView.height - deleteIcon.intrinsicHeight) / 2
val iconBottom = iconTop + deleteIcon.intrinsicHeight
deleteIcon.setBounds(iconLeft, iconTop, iconRight, iconBottom)
deleteIcon.draw(c)
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
}
})
itemTouchHelper.attachToRecyclerView(recyclerView)
} }
private fun fetchProjects() { private fun fetchProjects() {
@@ -86,7 +133,7 @@ class ProjetsFrag : Fragment(), ProjectAdapter.OnEmptyStateListener {
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, this) //TODO : Potentiel problème pour les refresh ici (update de l'adapter ou un truc du genre à voir) this.projectAdapter = ProjectAdapter(this.projects.toMutableList(), 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,7 +141,7 @@ class ProjetsFrag : Fragment(), ProjectAdapter.OnEmptyStateListener {
Log.e("ProjetsFrag prout", errorMessage) Log.e("ProjetsFrag prout", errorMessage)
//onEmptyStateChanged(true) //onEmptyStateChanged(true)
this.projects = listOf<Project>() this.projects = listOf<Project>()
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.projectAdapter = ProjectAdapter(this.projects.toMutableList(), 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
} }

View File

@@ -1,6 +1,7 @@
package com.dreamteam.timelapse.data package com.dreamteam.timelapse.data
import retrofit2.Call import retrofit2.Call
import retrofit2.http.Body import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.Field import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET import retrofit2.http.GET
@@ -20,4 +21,6 @@ interface ApiService {
fun createProject(@Body project: Project): Call<Confirmation> fun createProject(@Body project: Project): Call<Confirmation>
@GET("projects/{id}/videos") @GET("projects/{id}/videos")
fun getVideosOfProject(@Path("id") projectId:Int): Call<List<VideoDTO>> fun getVideosOfProject(@Path("id") projectId:Int): Call<List<VideoDTO>>
@DELETE("projects/{id}")
fun deleteProject(@Path("id") projectId:Int) : Call<Void>
} }

View File

@@ -82,4 +82,21 @@ class ProjectRepository(private val apiService: ApiService) {
}) })
} }
fun deleteProject(id : Int, onSuccess: ()->Unit, onError: (String) -> Unit){
val call = apiService.deleteProject(id)
call.enqueue(object : Callback<Void> {
override fun onResponse(call: Call<Void>, response: Response<Void>) {
if (response.isSuccessful) {
onSuccess()
} else {
onError("Erreur : ${response.code()}")
}
}
override fun onFailure(call: Call<Void>, t: Throwable) {
onError("Échec de l'appel API : ${t.message}")
}
})
}
} }

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12M19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z" />
</vector>

View File

@@ -22,6 +22,10 @@
android:clipChildren="false" android:clipChildren="false"
android:clipToPadding="false"> android:clipToPadding="false">
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -67,6 +71,7 @@
<!-- Ajouter d'autres vues comme une image ou une description --> <!-- Ajouter d'autres vues comme une image ou une description -->
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>