diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 22d9498..0b0534c 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,7 +4,6 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index 0ad17cb..8978d23 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b64cb85..f01e222 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -82,4 +82,8 @@ dependencies { androidTestImplementation(libs.androidx.ui.test.junit4) debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) +} + +kotlin { + tasks.register("testClasses") } \ No newline at end of file diff --git a/app/release/app-release.apk b/app/release/app-release.apk new file mode 100644 index 0000000..8d3da56 Binary files /dev/null and b/app/release/app-release.apk differ diff --git a/app/release/baselineProfiles/0/app-release.dm b/app/release/baselineProfiles/0/app-release.dm new file mode 100644 index 0000000..da05a1c Binary files /dev/null and b/app/release/baselineProfiles/0/app-release.dm differ diff --git a/app/release/baselineProfiles/1/app-release.dm b/app/release/baselineProfiles/1/app-release.dm new file mode 100644 index 0000000..ac181c0 Binary files /dev/null and b/app/release/baselineProfiles/1/app-release.dm differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json new file mode 100644 index 0000000..e814f6a --- /dev/null +++ b/app/release/output-metadata.json @@ -0,0 +1,37 @@ +{ + "version": 3, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "com.dreamteam.timelapse", + "variantName": "release", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "attributes": [], + "versionCode": 1, + "versionName": "1.0", + "outputFile": "app-release.apk" + } + ], + "elementType": "File", + "baselineProfiles": [ + { + "minApi": 28, + "maxApi": 30, + "baselineProfiles": [ + "baselineProfiles/1/app-release.dm" + ] + }, + { + "minApi": 31, + "maxApi": 2147483647, + "baselineProfiles": [ + "baselineProfiles/0/app-release.dm" + ] + } + ], + "minSdkVersionForDexing": 28 +} \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/MainActivity.kt b/app/src/main/java/com/dreamteam/timelapse/MainActivity.kt index 9c4c350..c3e2647 100644 --- a/app/src/main/java/com/dreamteam/timelapse/MainActivity.kt +++ b/app/src/main/java/com/dreamteam/timelapse/MainActivity.kt @@ -93,13 +93,27 @@ class MainActivity : AppCompatActivity() { val builder: AlertDialog.Builder = AlertDialog.Builder(this) builder.setView(layout) - builder.setPositiveButton("Save", + builder.setPositiveButton("Sauvegarder", DialogInterface.OnClickListener { dialog, which -> - val onSuccess : () -> Unit = {dialog.dismiss() ; Snackbar.make(viewfortoast, "Nouveau projet créé", Snackbar.LENGTH_LONG).setAnchorView(Rtmp.id.fab).show() ; } + val onSuccess : () -> Unit = { + dialog.dismiss() ; + Snackbar.make(viewfortoast, "Nouveau projet créé", Snackbar.LENGTH_LONG).setAnchorView(Rtmp.id.fab).show() ; + } val onError : (s:String) -> Unit = { s-> Snackbar.make(viewfortoast, "Erreur lors de la création du projet. ${s}", Snackbar.LENGTH_LONG).setAnchorView(Rtmp.id.fab).show() } - projectRepository.createProject(project_name.text.toString(), project_desc.text.toString(), onSuccess, onError) - + val name = project_name.text.toString() + val desc = project_desc.text.toString() + if (name.isBlank() || desc.isBlank() || name == "" || desc == "") { + Snackbar.make(viewfortoast, "Les champs ne doivent pas être vides", Snackbar.LENGTH_LONG) + .show() + }else { + projectRepository.createProject( + project_name.text.toString(), + project_desc.text.toString(), + onSuccess, + onError + ) + } }) builder.setNegativeButton("Cancel", DialogInterface.OnClickListener { dialog, which -> dialog.dismiss() }) diff --git a/app/src/main/java/com/dreamteam/timelapse/ProjectActivity.kt b/app/src/main/java/com/dreamteam/timelapse/ProjectActivity.kt index 179308f..14dad86 100644 --- a/app/src/main/java/com/dreamteam/timelapse/ProjectActivity.kt +++ b/app/src/main/java/com/dreamteam/timelapse/ProjectActivity.kt @@ -1,14 +1,20 @@ package com.dreamteam.timelapse +import android.content.Intent import android.graphics.Color import android.graphics.Rect import android.os.Bundle import android.util.Log +import android.view.LayoutInflater import android.view.View +import android.widget.EditText import android.widget.TextView +import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import com.dreamteam.timelapse.data.ApiService +import com.dreamteam.timelapse.data.CaptureQuery +import com.dreamteam.timelapse.data.Confirmation import com.dreamteam.timelapse.data.Measurement import com.dreamteam.timelapse.data.Project import com.dreamteam.timelapse.data.ProjectRepository @@ -21,6 +27,11 @@ import com.github.mikephil.charting.data.LineData import com.github.mikephil.charting.data.LineDataSet import com.github.mikephil.charting.formatter.ValueFormatter import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.google.android.material.floatingactionbutton.FloatingActionButton +import com.google.android.material.snackbar.Snackbar +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import java.text.SimpleDateFormat @@ -30,6 +41,9 @@ import java.util.Locale class ProjectActivity : AppCompatActivity() { + private lateinit var stopingProcedureDialog: AlertDialog + private lateinit var videoRenderDialog: AlertDialog + private lateinit var startingProcedureDialog: AlertDialog private lateinit var binding: ProjectBinding private lateinit var projectRepository: ProjectRepository private lateinit var videoRepository: VideoRepository @@ -37,6 +51,11 @@ class ProjectActivity : AppCompatActivity() { private var measures: List = emptyList() // Déclare une liste de projets vide private var project: Project? = null private var imageUrls = emptyList() + enum class ButtonState { + START, LOADING, FINISHED, ENDING + } + + private var buttonState = ButtonState.START class GridSpacingItemDecoration(private val spacing: Int) : RecyclerView.ItemDecoration() { override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) { @@ -48,6 +67,16 @@ class ProjectActivity : AppCompatActivity() { outRect.top = spacing } } + + fun refreshMultiuseButton(){ + val floatingButton = findViewById(R.id.multiusefloating) + var icon = when (buttonState) { + ButtonState.START -> android.R.drawable.ic_media_play + ButtonState.LOADING -> R.drawable.baseline_stop_24 + ButtonState.FINISHED, ButtonState.ENDING -> android.R.drawable.ic_menu_save + } + floatingButton.setImageResource(icon) + } override fun onCreate(savedInstanceState: Bundle?) { val retrofit = Retrofit.Builder() .baseUrl("https://timelapse.kerboul.me/api/") @@ -65,36 +94,77 @@ class ProjectActivity : AppCompatActivity() { setContentView(binding.root) initProjectInfo() - + binding.imagesList.layoutManager = GridLayoutManager(this.baseContext, 2, GridLayoutManager.HORIZONTAL, false) + binding.imagesList.addItemDecoration(GridSpacingItemDecoration(16)) // 16px spacing + binding.videosList.layoutManager = GridLayoutManager(this.baseContext, 2, GridLayoutManager.HORIZONTAL, false) + binding.videosList.addItemDecoration(GridSpacingItemDecoration(16)) // 16px spacing fetchMeasuresAndRebuildGraph() + fetchVideos() val swipeRefreshLayout = binding.swipeRefreshLayout swipeRefreshLayout.setOnRefreshListener { fetchMeasuresAndRebuildGraph() + fetchVideos() Log.d("ProjetsFrag", "Actualisation des projets") } - fetchVideos() + val floatingButton = findViewById(R.id.multiusefloating) + this.buttonState = when(project?.getStatusText()) { + "Brouillon" -> ButtonState.START + "En Cours" -> ButtonState.LOADING + "Terminé" -> ButtonState.FINISHED + "En cours d'arret" -> ButtonState.ENDING + else -> ButtonState.START + } + var icon = when (buttonState) { + ButtonState.START -> android.R.drawable.ic_media_play + ButtonState.LOADING -> R.drawable.baseline_stop_24 + ButtonState.FINISHED -> android.R.drawable.ic_menu_save + ButtonState.ENDING -> android.R.drawable.ic_menu_save + } + floatingButton.setImageResource(icon) + + floatingButton.setOnClickListener { +// when (buttonState) { +// ButtonState.LOADING -> { +// buttonState = ButtonState.FINISHED +// } +// else -> {} +// } +// refreshMultiuseButton() + when (buttonState) { + ButtonState.START -> clickStartProcess() + ButtonState.LOADING -> clickStopProcess() + ButtonState.FINISHED, ButtonState.ENDING -> clickSave() + } + } + + + var but = findViewById(R.id.multiusefloating) + but.post { + project?.let { + createVideoRenderDialog(but, it.id, measures) + createStopProcedureDialog(but, it.id) + createStartingProcedureDialog(but, it.id) + } + } // Bouton flottant // binding.fab.setOnClickListener { view -> -// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) -// //.setAction("Action", null) //sert à rien -// .setAnchorView(R.id.fab).show() //au dessus du bouton mail +// // } } fun fetchVideos(){ this.project?.let{ - videoRepository.fetchVideosOfProject(it.id, onSuccess = { videos -> + videoRepository.fetchRenderedVideosOfProject(it.id, onSuccess = { videos -> val adapter = VideoAdapter(false, videos.toMutableList(), null) //ImageAdapter(imageUrls) - binding.videosList.layoutManager = GridLayoutManager(this.baseContext, 2, GridLayoutManager.HORIZONTAL, false) - binding.videosList.addItemDecoration(GridSpacingItemDecoration(16)) // 16px spacing binding.videosList.adapter = adapter + binding.swipeRefreshLayout.isRefreshing = false }, onError = {errorMessage -> - Log.e("ProjectActivity", errorMessage) + Log.e("ProjectActivity", "Fetch Video " + errorMessage) fetchVideos() }) } @@ -109,8 +179,7 @@ class ProjectActivity : AppCompatActivity() { initGraph(this.measures) val adapter = ImageAdapter(this.measures.map { m-> "https://timelapse.kerboul.me/api/images/${m.project_id}/${m.order_id}"}) //ImageAdapter(imageUrls) - binding.imagesList.layoutManager = GridLayoutManager(this.baseContext, 2, GridLayoutManager.HORIZONTAL, false) - binding.imagesList.addItemDecoration(GridSpacingItemDecoration(16)) // 16px spacing + Log.d("ProjectActivity", "Je vais mettre l'adapter") binding.imagesList.adapter = adapter binding.swipeRefreshLayout.isRefreshing = false @@ -124,7 +193,6 @@ class ProjectActivity : AppCompatActivity() { }) } } - fun initGraph(lm: List) { val temperatureHumidityChart = this.binding.temperatureHumidityChart @@ -160,8 +228,15 @@ class ProjectActivity : AppCompatActivity() { val xAxis = temperatureHumidityChart.xAxis xAxis.valueFormatter = object : ValueFormatter() { override fun getFormattedValue(value: Float): String { - // Map the index back to the corresponding timestamp - val timestamp = lm.sortedBy { it.order_id }[value.toInt()].timestamp + val index = value.toInt() + val sortedList = lm.sortedBy { it.order_id } + + if (index < 0 || index >= sortedList.size) { + // Index out of bounds, return empty string or something neutral + return "" + } + + val timestamp = sortedList[index].timestamp val date = Date(timestamp.time) val sdf = SimpleDateFormat("dd/MM/yyyy:HH:mm:ss", Locale.getDefault()) return sdf.format(date) @@ -222,9 +297,6 @@ class ProjectActivity : AppCompatActivity() { // Refresh the chart temperatureHumidityChart.invalidate() } - - - fun initProjectInfo(){ val nameview = findViewById(R.id.project_name) val descriptionview = findViewById(R.id.project_description) @@ -236,4 +308,200 @@ class ProjectActivity : AppCompatActivity() { beginview.text = project!!.start_date.toString() statusview.text = project!!.getStatusText() } + private fun clickStartProcess() { + Log.i("ProjectActivity", "Start collect...") + + // Simule une durée avant la finalisation du processus +// Handler(Looper.getMainLooper()).postDelayed({ +// val floatingButton = findViewById(R.id.multiusefloating) +// floatingButton.setImageResource(android.R.drawable.ic_menu_save) // Icône d'enregistrement +// buttonState = ButtonState.FINISHED +// }, 5000) // 5 secondes de chargement + startingProcedureDialog.show() + } + + private fun clickStopProcess() { + Log.i("ProjectActivity", "Stop collect...") + stopingProcedureDialog.show() + // Implémente l'arrêt du processus (annulation si nécessaire) + } + + private fun clickSave() { + Log.i("ProjectActivity", "Create video...") + videoRenderDialog.show() + //videoRepository.createVideo(project.id, measures, ) +// Toast.makeText(context, "Downloading...", Toast.LENGTH_SHORT).show() +// +// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) +// .setAction("Action", null) //sert à rien +// .setAnchorView(R.id.fab).show() //au dessus du bouton mail + // Implémente la création d'une vidéo + } + + fun createVideoRenderDialog(viewfortoast: View, projectId: Int, measurements: List) { + val inflater = getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater + val layout: View = inflater.inflate(R.layout.video_render_dialog_layout, findViewById(R.id.layout_root)) + + val videoName = layout.findViewById(R.id.video_name_dialog) + //val videoResolution = layout.findViewById(R.id.video_resolution_dialog) + val videoDuration = layout.findViewById(R.id.video_duration_dialog) + + val builder = AlertDialog.Builder(this) + builder.setView(layout) + .setPositiveButton("Render Video") { dialog, _ -> + val name = videoName.text.toString() + //val resolution = videoResolution.text.toString() + val durationText = videoDuration.text.toString() + + if (name.isBlank() || durationText.isBlank()) { + Snackbar.make(viewfortoast, "All fields must be filled", Snackbar.LENGTH_LONG) + .show() + return@setPositiveButton + } + + val duration = durationText.toIntOrNull() + if (duration == null || duration <= 0) { + Snackbar.make(viewfortoast, "Invalid duration", Snackbar.LENGTH_LONG) + .show() + return@setPositiveButton + } + + val onSuccess: (Confirmation?) -> Unit = { + dialog.dismiss() + Snackbar.make(viewfortoast, "Video render started", Snackbar.LENGTH_LONG) + .show() + } + + val onError: (String) -> Unit = { error -> + Snackbar.make(viewfortoast, "Error: $error", Snackbar.LENGTH_LONG) + .show() + } + + videoRepository.createVideo(projectId, measures, name, "1920x1080", duration, onSuccess, onError) + } + .setNegativeButton("Cancel") { dialog, _ -> dialog.dismiss() } + + this.videoRenderDialog = builder.create() + } + fun createStartingProcedureDialog(viewfortoast: View, projectId: Int) { + val inflater = getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater + val layout: View = inflater.inflate(R.layout.capture_start_dialog_layout, findViewById(R.id.layout_root)) + + val intervalView = layout.findViewById(R.id.interval) + //val videoResolution = layout.findViewById(R.id.video_resolution_dialog) + val nbImView = layout.findViewById(R.id.nb_images) + + val builder = AlertDialog.Builder(this) + builder.setView(layout) + .setPositiveButton("Run capture procedure") { dialog, _ -> + val intervalStr = intervalView.text.toString() + //val resolution = videoResolution.text.toString() + val nb_imagesStr = nbImView.text.toString() + + if (intervalStr.isBlank() || nb_imagesStr.isBlank()) { + Snackbar.make(viewfortoast, "Les champs doivent être remplis", Snackbar.LENGTH_LONG) + .show() + return@setPositiveButton + } + + val interval = intervalStr.toIntOrNull() + val nb_images = nb_imagesStr.toIntOrNull() + if (interval == null || interval <= 0 || nb_images == null || nb_images <= 0) { + Snackbar.make(viewfortoast, "Les chiffres fournis doivent être superieurs à 1", Snackbar.LENGTH_LONG) + .show() + return@setPositiveButton + } + + val onSuccess: () -> Unit = { + dialog.dismiss() + Snackbar.make(viewfortoast, "Processus de capture lancé", Snackbar.LENGTH_LONG) + .show() + buttonState = ButtonState.LOADING + refreshMultiuseButton() + + } + + val onError: (String) -> Unit = { error -> + Snackbar.make(viewfortoast, "Error : $error", Snackbar.LENGTH_LONG) + .show() + } + + apiService.procedureStart(CaptureQuery(interval, nb_images, projectId)).enqueue(object : + Callback { + override fun onResponse(call: Call, response: Response) { + if (response.isSuccessful) { + refreshProjectInfo(onSuccess, onError) + } else { + onError("Erreur serveur : ${response.code()}") + } + } + + override fun onFailure(call: Call, t: Throwable) { + onError("Erreur réseau : ${t.message}") + } + }) + } + .setNegativeButton("Cancel") { dialog, _ -> dialog.dismiss() } + + this.startingProcedureDialog = builder.create() + } + fun createStopProcedureDialog(viewfortoast: View, projectId: Int) { + val inflater = getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater + val layout: View = inflater.inflate(R.layout.capture_stop_dialog_layout, findViewById(R.id.layout_root)) + + val builder = AlertDialog.Builder(this) + builder.setView(layout) + .setPositiveButton("Stop") { dialog, _ -> + val onSuccess: () -> Unit = { + dialog.dismiss() + Snackbar.make(viewfortoast, "Processus arreté", Snackbar.LENGTH_LONG) + .show() + buttonState = ButtonState.FINISHED + refreshMultiuseButton() + + } + + val onError: (String) -> Unit = { error -> + Snackbar.make(viewfortoast, "Error : $error", Snackbar.LENGTH_LONG) + .show() + } + + apiService.procedureStop().enqueue(object : + Callback { + override fun onResponse(call: Call, response: Response) { + if (response.isSuccessful) { + refreshProjectInfo(onSuccess, onError) + } else { + onError("Erreur serveur : ${response.code()}") + } + } + + override fun onFailure(call: Call, t: Throwable) { + onError("Erreur réseau : ${t.message}") + } + }) + } + .setNegativeButton("Cancel") { dialog, _ -> dialog.dismiss() } + + this.stopingProcedureDialog = builder.create() + } + + fun refreshProjectInfo(cbGood: ()->Unit, cbBad: (String)->Unit){ + this.project?.let { + projectRepository.fetchProject(it.id, onSuccess = { + Log.i("ProjectActivity", "Pull projet ok") + this.project = it; + this.initProjectInfo() + cbGood() + }, onError = { + Log.i("ProjectActivity", "Erreur de pull projet : $it") + cbBad("Erreur de pull projet : $it") + }) + } + } + + override fun onBackPressed() { + super.onBackPressed() + startActivity(Intent(this, MainActivity::class.java)) + } } diff --git a/app/src/main/java/com/dreamteam/timelapse/ProjectAdapter.kt b/app/src/main/java/com/dreamteam/timelapse/ProjectAdapter.kt index b0db57b..9c30610 100644 --- a/app/src/main/java/com/dreamteam/timelapse/ProjectAdapter.kt +++ b/app/src/main/java/com/dreamteam/timelapse/ProjectAdapter.kt @@ -74,24 +74,28 @@ class ProjectAdapter(private val projects: MutableList, private val lis } fun removeItem(position: Int, context: Context, v : View) { val builder = AlertDialog.Builder(context) - val dialog = builder.setTitle("Confirm Deletion") + val dialog = builder.setTitle("Confirmer la supression") .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() + if(projects[position].status != 3 && projects[position].status != 2){ + 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() + }) + }else{ notifyItemChanged(position) - Snackbar.make(v.rootView, "Error while trying to delete ${projects[position].name} : $s", Snackbar.LENGTH_SHORT).show() - }) + Snackbar.make(v.rootView, "On ne peut pas supprimer un projet dans un état intermédiaire", Snackbar.LENGTH_SHORT).show() + } } .setNegativeButton("Annuler") { dialog, _ -> dialog.dismiss() - notifyItemChanged(position) // Reset swipe animation } .show() dialog.setOnDismissListener { diff --git a/app/src/main/java/com/dreamteam/timelapse/data/ApiService.kt b/app/src/main/java/com/dreamteam/timelapse/data/ApiService.kt index ec38904..2b1beac 100644 --- a/app/src/main/java/com/dreamteam/timelapse/data/ApiService.kt +++ b/app/src/main/java/com/dreamteam/timelapse/data/ApiService.kt @@ -17,6 +17,8 @@ interface ApiService { fun getMeasurements(@Path("id") projectId: Int): Call> @GET("videos") fun getVideos(): Call> + @POST("videos") + fun createVideo(@Body video: VideoDTO): Call @DELETE("videos/{id}") fun deleteVideo(@Path("id") videoId : Int): Call @POST("projects/") @@ -25,4 +27,8 @@ interface ApiService { fun getVideosOfProject(@Path("id") projectId:Int): Call> @DELETE("projects/{id}") fun deleteProject(@Path("id") projectId:Int) : Call + @POST("procedure/start") + fun procedureStart(@Body captureQuery: CaptureQuery): Call + @POST("procedure/stop") + fun procedureStop(): Call } \ No newline at end of file diff --git a/app/src/main/java/com/dreamteam/timelapse/data/CaptureQuery.kt b/app/src/main/java/com/dreamteam/timelapse/data/CaptureQuery.kt new file mode 100644 index 0000000..887eb28 --- /dev/null +++ b/app/src/main/java/com/dreamteam/timelapse/data/CaptureQuery.kt @@ -0,0 +1,8 @@ +package com.dreamteam.timelapse.data + +data class CaptureQuery ( + val interval: Int, + val nb_images: Int, + val project_id: Int +) +{} diff --git a/app/src/main/java/com/dreamteam/timelapse/data/Project.kt b/app/src/main/java/com/dreamteam/timelapse/data/Project.kt index 217a483..5b135d2 100644 --- a/app/src/main/java/com/dreamteam/timelapse/data/Project.kt +++ b/app/src/main/java/com/dreamteam/timelapse/data/Project.kt @@ -24,7 +24,7 @@ data class Project( fun getStatusText(): String{ Log.i("Project", "Status $status being trasnlated") - val statusArr = arrayOf("Brouillon", "En Cours", "Terminé", "Annulé") + val statusArr = arrayOf("Brouillon", "En Cours", "Terminé", "En cours d'arret") return statusArr[status] } fun getStatusColor(): Int{ diff --git a/app/src/main/java/com/dreamteam/timelapse/data/ProjectRepository.kt b/app/src/main/java/com/dreamteam/timelapse/data/ProjectRepository.kt index e4cacd2..8d921fe 100644 --- a/app/src/main/java/com/dreamteam/timelapse/data/ProjectRepository.kt +++ b/app/src/main/java/com/dreamteam/timelapse/data/ProjectRepository.kt @@ -56,7 +56,8 @@ class ProjectRepository(private val apiService: ApiService) { onSuccess(it) } ?: onError("Aucune mesure trouvé") } else { - onError("Erreur : ${response.code()}") + onSuccess(emptyList()) + //onError("Erreur reception measures: ${response.code()}") } } @@ -72,7 +73,7 @@ class ProjectRepository(private val apiService: ApiService) { if (response.isSuccessful) { onSuccess() } else { - onError("Erreur : ${response.code()}") + onError("Erreur creation projet : ${response.code()}, ${response.body()}") } } diff --git a/app/src/main/java/com/dreamteam/timelapse/data/VideoDTO.kt b/app/src/main/java/com/dreamteam/timelapse/data/VideoDTO.kt index 53ea7c5..9f3c1e2 100644 --- a/app/src/main/java/com/dreamteam/timelapse/data/VideoDTO.kt +++ b/app/src/main/java/com/dreamteam/timelapse/data/VideoDTO.kt @@ -1,5 +1,6 @@ package com.dreamteam.timelapse.data +import android.util.Log import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -16,7 +17,15 @@ data class VideoDTO ( fun toVideo(): Video { fun parseIntArray(jsonString: String): List { val type = object : TypeToken>() {}.type - return Gson().fromJson>(jsonString, type) + try { + Log.d("VideoDTO", Gson().fromJson>(jsonString, type).toString()) + return Gson().fromJson>(jsonString, type) + }catch (e: Exception){ + Log.d("VideoDTO", jsonString) + return Gson().fromJson>("[]", type) + + //throw Exception("Tentative de transformer une videoDTO en video alors que le format est pas bon") + } } return Video(id, project_id, parseIntArray(measurement_ids), video_file, resolution, duration, status, name) } diff --git a/app/src/main/java/com/dreamteam/timelapse/data/VideoRepository.kt b/app/src/main/java/com/dreamteam/timelapse/data/VideoRepository.kt index 1542c22..52509d3 100644 --- a/app/src/main/java/com/dreamteam/timelapse/data/VideoRepository.kt +++ b/app/src/main/java/com/dreamteam/timelapse/data/VideoRepository.kt @@ -1,5 +1,6 @@ package com.dreamteam.timelapse.data +import android.util.Log import retrofit2.Call import retrofit2.Callback import retrofit2.Response @@ -39,15 +40,20 @@ class VideoRepository(private val apiService: ApiService) { } }) } - fun fetchVideosOfProject(id:Int, onSuccess: (List