fix #10 telechargement videos

This commit is contained in:
Raphael
2025-03-11 16:22:29 +01:00
parent 491849e8fe
commit 204058c839
2 changed files with 129 additions and 7 deletions

View File

@@ -1,8 +1,15 @@
package com.dreamteam.timelapse package com.dreamteam.timelapse
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.ProgressDialog
import android.content.ContentValues
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.provider.MediaStore
import android.util.Log import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.LayoutInflater import android.view.LayoutInflater
@@ -10,6 +17,8 @@ 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.widget.PopupMenu
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
@@ -24,6 +33,16 @@ import retrofit2.converter.gson.GsonConverterFactory
import com.bumptech.glide.load.resource.bitmap.RoundedCorners import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import com.google.android.material.imageview.ShapeableImageView import com.google.android.material.imageview.ShapeableImageView
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.internal.http2.Http2Reader
import okio.IOException
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
class VideoAdapter( class VideoAdapter(
public val withProjectNames : Boolean, public val withProjectNames : Boolean,
@@ -70,14 +89,7 @@ class VideoAdapter(
// Load video thumbnail // Load video thumbnail
val url = "https://timelapse.kerboul.me/api/videos/file/${video.id}" val url = "https://timelapse.kerboul.me/api/videos/file/${video.id}"
// val shapeAppearanceModel = holder.videoThumbnail.shapeAppearanceModel
// .toBuilder()
// .setAllCornerSizes(
// TypedValue.applyDimension(
// TypedValue.COMPLEX_UNIT_DIP, 25f, holder.itemView.resources.displayMetrics)) // 16dp fixed
// .build()
//holder.videoThumbnail.shapeAppearanceModel = shapeAppearanceModel
Glide.with(context) Glide.with(context)
.load(url) // Load the video URL .load(url) // Load the video URL
@@ -92,6 +104,107 @@ class VideoAdapter(
intent.setFlags(FLAG_ACTIVITY_NEW_TASK) intent.setFlags(FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent) context.startActivity(intent)
} }
holder.itemView.setOnLongClickListener {
showPopupMenu(it, url)
true
}
}
private fun showPopupMenu(view: View, videoUrl: String) {
val popupMenu = PopupMenu(view.context, view)
popupMenu.menuInflater.inflate(R.menu.video_popup_menu, popupMenu.menu)
popupMenu.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.menu_download -> {
downloadVideo(view.context, videoUrl)
true
}
else -> false
}
}
popupMenu.show()
}
fun downloadVideo(context: Context, videoUrl: String) {
val request = Request.Builder().url(videoUrl).build()
val client = OkHttpClient()
val progressDialog = ProgressDialog(context).apply {
setTitle("Téléchargement en cours")
setMessage("Patientez...")
setCancelable(false)
setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)
show()
}
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
Log.e("DownloadError", "Failed: ${e.message}")
progressDialog.dismiss()
Handler(Looper.getMainLooper()).post {
Toast.makeText(context, "Une erreur s'est produite lors du téléchargement", Toast.LENGTH_SHORT).show()
} }
override fun onResponse(call: Call, response: Response) {
if (!response.isSuccessful) {
Log.e("DownloadError", "Error: ${response.code}")
progressDialog.dismiss()
Handler(Looper.getMainLooper()).post {
Toast.makeText(context, "Une erreur s'est produite lors du téléchargement (Erreur ${response.code})", Toast.LENGTH_SHORT).show()
}
return
}
val fileName = "video_${System.currentTimeMillis()}.mp4"
val file = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), fileName)
val body = response.body ?: return
val totalSize = body.contentLength()
var downloadedSize = 0L
body.byteStream().use { input ->
FileOutputStream(file).use { output ->
val buffer = ByteArray(1024)
var bytesRead: Int
while (input.read(buffer).also { bytesRead = it } != -1) {
output.write(buffer, 0, bytesRead)
downloadedSize += bytesRead
progressDialog.progress = ((downloadedSize * 100) / totalSize).toInt()
}
}
}
progressDialog.dismiss()
Handler(Looper.getMainLooper()).post {
moveFileToDownloads(file)
Toast.makeText(context, "Téléchargé : $fileName", Toast.LENGTH_SHORT).show()
}
}
})
}
fun moveFileToDownloads(sourceFile: File) {
val downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val destFile = File(downloadsDir, sourceFile.name)
try {
// Create streams for copying data
FileInputStream(sourceFile).use { input ->
FileOutputStream(destFile).use { output ->
input.copyTo(output)
}
}
// Optionally delete the original file
if (sourceFile.exists()) {
sourceFile.delete()
}
Log.d("FileMove", "File moved to: ${destFile.absolutePath}")
} catch (e: Exception) {
Log.e("FileMoveError", "Error moving file: ${e.message}")
}
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_download"
android:title="Télécharger"
android:icon="@android:drawable/ic_menu_save" />
</menu>