delete video notament
This commit is contained in:
@@ -89,7 +89,7 @@ class ProjectActivity : AppCompatActivity() {
|
|||||||
fun fetchVideos(){
|
fun fetchVideos(){
|
||||||
this.project?.let{
|
this.project?.let{
|
||||||
videoRepository.fetchVideosOfProject(it.id, onSuccess = { videos ->
|
videoRepository.fetchVideosOfProject(it.id, onSuccess = { videos ->
|
||||||
val adapter = VideoAdapter(false, videos, null) //ImageAdapter(imageUrls)
|
val adapter = VideoAdapter(false, videos.toMutableList(), null) //ImageAdapter(imageUrls)
|
||||||
binding.videosList.layoutManager = GridLayoutManager(this.baseContext, 2, GridLayoutManager.HORIZONTAL, false)
|
binding.videosList.layoutManager = GridLayoutManager(this.baseContext, 2, GridLayoutManager.HORIZONTAL, false)
|
||||||
binding.videosList.addItemDecoration(GridSpacingItemDecoration(16)) // 16px spacing
|
binding.videosList.addItemDecoration(GridSpacingItemDecoration(16)) // 16px spacing
|
||||||
binding.videosList.adapter = adapter
|
binding.videosList.adapter = adapter
|
||||||
|
|||||||
@@ -46,10 +46,11 @@ import java.io.FileOutputStream
|
|||||||
|
|
||||||
class VideoAdapter(
|
class VideoAdapter(
|
||||||
public val withProjectNames : Boolean,
|
public val withProjectNames : Boolean,
|
||||||
private val videos: List<Video>,
|
private val videos: MutableList<Video>,
|
||||||
private val listener: OnEmptyStateListener?
|
private val listener: OnEmptyStateListener?
|
||||||
) : RecyclerView.Adapter<VideoAdapter.VideoViewHolder>() {
|
) : RecyclerView.Adapter<VideoAdapter.VideoViewHolder>() {
|
||||||
private var projectRepository: ProjectRepository;
|
private var projectRepository: ProjectRepository;
|
||||||
|
private var videoRepository : VideoRepository;
|
||||||
init {
|
init {
|
||||||
val retrofit = Retrofit.Builder()
|
val retrofit = Retrofit.Builder()
|
||||||
.baseUrl("https://timelapse.kerboul.me/api/")
|
.baseUrl("https://timelapse.kerboul.me/api/")
|
||||||
@@ -57,6 +58,7 @@ class VideoAdapter(
|
|||||||
.build()
|
.build()
|
||||||
|
|
||||||
projectRepository = ProjectRepository(retrofit.create(ApiService::class.java))
|
projectRepository = ProjectRepository(retrofit.create(ApiService::class.java))
|
||||||
|
videoRepository = VideoRepository(retrofit.create(ApiService::class.java))
|
||||||
listener?.onEmptyStateChanged(videos.isEmpty())
|
listener?.onEmptyStateChanged(videos.isEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,12 +107,12 @@ class VideoAdapter(
|
|||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
}
|
}
|
||||||
holder.itemView.setOnLongClickListener {
|
holder.itemView.setOnLongClickListener {
|
||||||
showPopupMenu(it, url)
|
showPopupMenu(it, url, video.id)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showPopupMenu(view: View, videoUrl: String) {
|
private fun showPopupMenu(view: View, videoUrl: String, id:Int) {
|
||||||
val popupMenu = PopupMenu(view.context, view)
|
val popupMenu = PopupMenu(view.context, view)
|
||||||
popupMenu.menuInflater.inflate(R.menu.video_popup_menu, popupMenu.menu)
|
popupMenu.menuInflater.inflate(R.menu.video_popup_menu, popupMenu.menu)
|
||||||
|
|
||||||
@@ -120,6 +122,22 @@ class VideoAdapter(
|
|||||||
downloadVideo(view.context, videoUrl)
|
downloadVideo(view.context, videoUrl)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.menu_delete -> {
|
||||||
|
videoRepository.deleteVideo(id, onSuccess = {
|
||||||
|
val v = videos.find {v -> v.id == id}
|
||||||
|
val i = videos.indexOf(v)
|
||||||
|
this.videos.removeAt(i)
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
Toast.makeText(view.context, "Video supprimée", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
notifyItemRemoved(i)
|
||||||
|
}, onError = {s ->
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
Toast.makeText(view.context, "Erreur lors de la suppression : $s", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
true
|
||||||
|
}
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,13 @@ package com.dreamteam.timelapse
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.dreamteam.timelapse.data.VideoRepository
|
import com.dreamteam.timelapse.data.VideoRepository
|
||||||
import com.dreamteam.timelapse.databinding.FragmentProjetsBinding
|
|
||||||
import com.dreamteam.timelapse.data.ApiService
|
import com.dreamteam.timelapse.data.ApiService
|
||||||
import com.dreamteam.timelapse.data.Video
|
import com.dreamteam.timelapse.data.Video
|
||||||
import com.dreamteam.timelapse.databinding.FragmentVideosBinding
|
import com.dreamteam.timelapse.databinding.FragmentVideosBinding
|
||||||
@@ -84,11 +81,11 @@ class VideoFrag : Fragment(), VideoAdapter.OnEmptyStateListener {
|
|||||||
|
|
||||||
//binding.swipeRefreshLayout.dragDown()
|
//binding.swipeRefreshLayout.dragDown()
|
||||||
Log.d("ProjetsFrag", "User has refreshed the videos list")
|
Log.d("ProjetsFrag", "User has refreshed the videos list")
|
||||||
videoRepository.fetchVideos(
|
videoRepository.fetchRenderedVideos(
|
||||||
onSuccess = { videos ->
|
onSuccess = { videos ->
|
||||||
Log.d("ProjetsFrag", "Projets reçus : $videos")
|
Log.d("ProjetsFrag", "Projets reçus : $videos")
|
||||||
this.videos = videos
|
this.videos = videos
|
||||||
this.videoAdapter = VideoAdapter(true, this.videos, this) //TODO : Potentiel problème pour les refresh ici (update de l'adapter ou un truc du genre à voir)
|
this.videoAdapter = VideoAdapter(true, this.videos.toMutableList(), this) //TODO : Potentiel problème pour les refresh ici (update de l'adapter ou un truc du genre à voir)
|
||||||
this.recyclerView.adapter = this.videoAdapter
|
this.recyclerView.adapter = this.videoAdapter
|
||||||
// Mettre à jour le RecyclerView ou autre traitement
|
// Mettre à jour le RecyclerView ou autre traitement
|
||||||
},
|
},
|
||||||
@@ -96,7 +93,7 @@ class VideoFrag : Fragment(), VideoAdapter.OnEmptyStateListener {
|
|||||||
Log.e("ProjetsFrag prout", errorMessage)
|
Log.e("ProjetsFrag prout", errorMessage)
|
||||||
//onEmptyStateChanged(true)
|
//onEmptyStateChanged(true)
|
||||||
this.videos = listOf<Video>()
|
this.videos = listOf<Video>()
|
||||||
this.videoAdapter = VideoAdapter(true, this.videos, this) //TODO : Potentiel problème pour les refresh ici (update de l'adapter ou un truc du genre à voir)
|
this.videoAdapter = VideoAdapter(true, this.videos.toMutableList(), this) //TODO : Potentiel problème pour les refresh ici (update de l'adapter ou un truc du genre à voir)
|
||||||
this.recyclerView.adapter = this.videoAdapter
|
this.recyclerView.adapter = this.videoAdapter
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ interface ApiService {
|
|||||||
fun getMeasurements(@Path("id") projectId: Int): Call<List<Measurement>>
|
fun getMeasurements(@Path("id") projectId: Int): Call<List<Measurement>>
|
||||||
@GET("videos")
|
@GET("videos")
|
||||||
fun getVideos(): Call<List<VideoDTO>>
|
fun getVideos(): Call<List<VideoDTO>>
|
||||||
|
@DELETE("videos/{id}")
|
||||||
|
fun deleteVideo(@Path("id") videoId : Int): Call<Void>
|
||||||
@POST("projects/")
|
@POST("projects/")
|
||||||
fun createProject(@Body project: Project): Call<Confirmation>
|
fun createProject(@Body project: Project): Call<Confirmation>
|
||||||
@GET("projects/{id}/videos")
|
@GET("projects/{id}/videos")
|
||||||
|
|||||||
@@ -3,16 +3,32 @@ package com.dreamteam.timelapse.data
|
|||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import java.util.Date
|
|
||||||
|
|
||||||
class VideoRepository(private val apiService: ApiService) {
|
class VideoRepository(private val apiService: ApiService) {
|
||||||
fun fetchVideos(onSuccess: (List<Video>) -> Unit, onError: (String) -> Unit) {
|
fun fetchRenderedVideos(onSuccess: (List<Video>) -> Unit, onError: (String) -> Unit) {
|
||||||
apiService.getVideos().enqueue(object : Callback<List<VideoDTO>> {
|
apiService.getVideos().enqueue(object : Callback<List<VideoDTO>> {
|
||||||
override fun onResponse(call: Call<List<VideoDTO>>, response: Response<List<VideoDTO>>) {
|
override fun onResponse(call: Call<List<VideoDTO>>, response: Response<List<VideoDTO>>) {
|
||||||
if (response.isSuccessful) {
|
if (response.isSuccessful) {
|
||||||
val videoDtos = response.body() ?: emptyList()
|
val videoDtos = response.body() ?: emptyList()
|
||||||
val videos = videoDtos.map { it.toVideo() } // Convert ugly data to clean Video objects
|
val videos = videoDtos.map { it.toVideo() } // Convert ugly data to clean Video objects
|
||||||
onSuccess(videos)
|
onSuccess(videos.filter { v -> v.video_file != null })
|
||||||
|
} else {
|
||||||
|
onError("Erreur serveur : ${response.code()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call<List<VideoDTO>>, t: Throwable) {
|
||||||
|
onError("Erreur réseau : ${t.message}")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fun fetchUnrenderedVideos(onSuccess: (List<Video>) -> Unit, onError: (String) -> Unit) {
|
||||||
|
apiService.getVideos().enqueue(object : Callback<List<VideoDTO>> {
|
||||||
|
override fun onResponse(call: Call<List<VideoDTO>>, response: Response<List<VideoDTO>>) {
|
||||||
|
if (response.isSuccessful) {
|
||||||
|
val videoDtos = response.body() ?: emptyList()
|
||||||
|
val videos = videoDtos.map { it.toVideo() } // Convert ugly data to clean Video objects
|
||||||
|
onSuccess(videos.filter { v -> v.video_file == null })
|
||||||
} else {
|
} else {
|
||||||
onError("Erreur serveur : ${response.code()}")
|
onError("Erreur serveur : ${response.code()}")
|
||||||
}
|
}
|
||||||
@@ -40,4 +56,36 @@ class VideoRepository(private val apiService: ApiService) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
fun fetchUnrenderedVideosOfProject(id:Int, onSuccess: (List<Video>) -> Unit, onError: (String) -> Unit){
|
||||||
|
apiService.getVideosOfProject(id).enqueue(object : Callback<List<VideoDTO>> {
|
||||||
|
override fun onResponse(call: Call<List<VideoDTO>>, response: Response<List<VideoDTO>>) {
|
||||||
|
if (response.isSuccessful) {
|
||||||
|
val videoDtos = response.body() ?: emptyList()
|
||||||
|
val videos = videoDtos.map { it.toVideo() } // Convert ugly data to clean Video objects
|
||||||
|
onSuccess(videos.filter { v -> v.video_file == null })
|
||||||
|
} else {
|
||||||
|
onError("Erreur serveur : ${response.code()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call<List<VideoDTO>>, t: Throwable) {
|
||||||
|
onError("Erreur réseau : ${t.message}")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteVideo(id:Int, onSuccess: () -> Unit, onError: (String) -> Unit){
|
||||||
|
apiService.deleteVideo(id).enqueue(object : Callback<Void> {
|
||||||
|
override fun onResponse(call: Call<Void>, response: Response<Void>) {
|
||||||
|
if (response.isSuccessful) {
|
||||||
|
onSuccess()
|
||||||
|
} else {
|
||||||
|
onError("Erreur serveur : ${response.code()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call<Void>, t: Throwable) {
|
||||||
|
onError("Erreur réseau : ${t.message}")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
@@ -18,18 +18,25 @@
|
|||||||
tools:ignore="MissingConstraints"
|
tools:ignore="MissingConstraints"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
>
|
>
|
||||||
|
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
|
android:id="@+id/collapsingToolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="100sp"
|
||||||
|
app:layout_scrollFlags="scroll|exitUntilCollapsed"
|
||||||
|
app:expandedTitleTextAppearance="@style/TextAppearance.AppCompat.Large"
|
||||||
|
app:collapsedTitleTextAppearance="@style/TextAppearance.AppCompat.Small">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/project_name"
|
android:id="@+id/project_name"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginTop="16dp"
|
android:gravity="center"
|
||||||
|
android:padding="10dp"
|
||||||
android:text="Nom du projet"
|
android:text="Nom du projet"
|
||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold" />
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -6,4 +6,8 @@
|
|||||||
android:id="@+id/menu_download"
|
android:id="@+id/menu_download"
|
||||||
android:title="Télécharger"
|
android:title="Télécharger"
|
||||||
android:icon="@android:drawable/ic_menu_save" />
|
android:icon="@android:drawable/ic_menu_save" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_delete"
|
||||||
|
android:title="Supprimer"
|
||||||
|
android:icon="@android:drawable/ic_delete" />
|
||||||
</menu>
|
</menu>
|
||||||
Reference in New Issue
Block a user