🚧 add the tv show request and display the data in the tvshow cateogry

features/api/requests/2
Jordan ARTZET 2 years ago
parent 635a458cad
commit 724e6cb75c

@ -28,8 +28,8 @@ interface MovieApplicationAPI {
// TvShow
@GET
fun getPopularTvShow(@Query("api_key") apiKey : String = API_KEY, @Query("page") page : Int = 1) : Call<PopularDTO>
@GET("tv/popular")
suspend fun getPopularTvShow(@Query("api_key") apiKey : String = API_KEY, @Query("page") page : Int = 1) : Response<PopularDTO>
@GET("trending/{media_type}/{time_window}")

@ -8,7 +8,7 @@ data class MediaResultDTO(
@Json(name = "poster_path")
val posterPath : String?,
val adult : Boolean,
val adult : Boolean?,
val overview : String,
@Json(name = "first_air_date")
val firstAirDate : String?,

@ -1,20 +1,62 @@
package fr.iut.pm.movieapplication.model.media.tvshow
class TvShow(
val posterPath: String?,
val popularity: Double,
val id: Int,
val backdropPath: String,
val voteAverage: Double,
val overview: String,
val firstAirDate: String?,
val originCountry: List<String>,
val genreIds: List<Int>,
val originalLanguage: String,
val voteCount: Int,
val name: String,
val originalName: String,
val mediaType: String = "tv",
open class TvShow(
open val posterPath: String?,
open val popularity: Double,
open val id: Int,
open val backdropPath: String,
open val voteAverage: Double,
open val overview: String,
open val firstAirDate: String?,
open val originCountry: List<String>,
open val genreIds: List<Int>,
open val originalLanguage: String,
open val voteCount: Int,
open val name: String,
open val originalName: String,
open val mediaType: String = "tv",
)
{
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as TvShow
if (posterPath != other.posterPath) return false
if (popularity != other.popularity) return false
if (id != other.id) return false
if (backdropPath != other.backdropPath) return false
if (voteAverage != other.voteAverage) return false
if (overview != other.overview) return false
if (firstAirDate != other.firstAirDate) return false
if (originCountry != other.originCountry) return false
if (genreIds != other.genreIds) return false
if (originalLanguage != other.originalLanguage) return false
if (voteCount != other.voteCount) return false
if (name != other.name) return false
if (originalName != other.originalName) return false
if (mediaType != other.mediaType) return false
return true
}
override fun hashCode(): Int {
var result = posterPath?.hashCode() ?: 0
result = 31 * result + popularity.hashCode()
result = 31 * result + id
result = 31 * result + backdropPath.hashCode()
result = 31 * result + voteAverage.hashCode()
result = 31 * result + overview.hashCode()
result = 31 * result + (firstAirDate?.hashCode() ?: 0)
result = 31 * result + originCountry.hashCode()
result = 31 * result + genreIds.hashCode()
result = 31 * result + originalLanguage.hashCode()
result = 31 * result + voteCount
result = 31 * result + name.hashCode()
result = 31 * result + originalName.hashCode()
result = 31 * result + mediaType.hashCode()
return result
}
}

@ -1,43 +0,0 @@
package fr.iut.pm.movieapplication.repository
import android.util.Log
import fr.iut.pm.movieapplication.api.RetrofitInstance
import fr.iut.pm.movieapplication.api.dtos.PopularDTO
import fr.iut.pm.movieapplication.model.media.movie.Movie
import fr.iut.pm.movieapplication.model.media.tvshow.TvShow
import fr.iut.pm.movieapplication.utils.MediaResultMapper
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class TVShowRepository {
// fun getPopularTvShow(page : Int = 1 ,callback: (List<TvShow>) -> Unit ) {
//
// val listMovie : MutableList<TvShow> = mutableListOf()
//
// RetrofitInstance.api.getPopularMovies(page = page).enqueue(object :
// Callback<PopularDTO> {
// override fun onResponse(call: Call<PopularDTO>, response: Response<PopularDTO>) {
// if (response.isSuccessful) {
// Log.d("List :", response.body().toString())
// val popularDTO = response.body()
// val listMoviesDTO = popularDTO?.results
// listMoviesDTO?.forEach {
//
// val tvShow = MediaResultMapper.mapToTvShow(it)
// listMovie.add(tvShow)
// Log.d("Movie ", tvShow.name )
// }
//
// }
// callback(listMovie)
// }
//
// override fun onFailure(call: Call<PopularDTO>, t: Throwable) {
// Log.d("Error failure", t.message.toString())
// }
//
// })
// }
}

@ -0,0 +1,29 @@
package fr.iut.pm.movieapplication.repository
import android.util.Log
import fr.iut.pm.movieapplication.api.RetrofitInstance
import fr.iut.pm.movieapplication.model.media.tvshow.TvShow
import fr.iut.pm.movieapplication.utils.MediaResultMapper
class TvShowRepository {
suspend fun getPopularTvShow(page : Int = 1 ) : List<TvShow> {
val listMovie : MutableList<TvShow> = mutableListOf()
val response = RetrofitInstance.api.getPopularTvShow(page = page)
if (response.isSuccessful) {
Log.d("List :", response.body().toString())
val popularDTO = response.body()
val listMoviesDTO = popularDTO?.results
listMoviesDTO?.forEach {
val tvShow = MediaResultMapper.mapToTvShow(it)
listMovie.add(tvShow)
Log.d("Movie ", tvShow.name )
}
}
else Log.d("Error failure", response.message())
return listMovie
}
}

@ -40,7 +40,7 @@ class MainActivity : AppCompatActivity() {
}
R.id.series_page -> {
loadFragments(TvShowsFragment(this))
loadFragments(TvShowsFragment())
return@setOnItemSelectedListener true
}
else -> false

@ -11,9 +11,9 @@ import fr.iut.pm.movieapplication.databinding.ItemMovieCategoryBinding
import fr.iut.pm.movieapplication.model.media.movie.Movie
import fr.iut.pm.movieapplication.utils.Constants
class MovieAdapter : ListAdapter<Movie, MovieAdapter.ViewHolder>(DiffUtilDogCallback) {
class MovieAdapter() : ListAdapter<Movie, MovieAdapter.ViewHolder>(DiffUtilMovieCallback) {
private object DiffUtilDogCallback : DiffUtil.ItemCallback<Movie>() {
private object DiffUtilMovieCallback : DiffUtil.ItemCallback<Movie>() {
override fun areItemsTheSame(oldItem: Movie, newItem: Movie) = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: Movie, newItem: Movie) = oldItem == newItem
}
@ -40,4 +40,5 @@ class MovieAdapter : ListAdapter<Movie, MovieAdapter.ViewHolder>(DiffUtilDogCall
ViewHolder(ItemMovieCategoryBinding.inflate(LayoutInflater.from(parent.context)))
override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind(getItem(position))
}

@ -0,0 +1,48 @@
package fr.iut.pm.movieapplication.ui.adapter
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.net.toUri
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import coil.load
import fr.iut.pm.movieapplication.databinding.ItemTvShowCategoryBinding
import fr.iut.pm.movieapplication.model.media.tvshow.TvShow
import fr.iut.pm.movieapplication.utils.Constants
class TvShowAdapter() : ListAdapter<TvShow, TvShowAdapter.ViewHolder>(DiffUtilTvShowCallback) {
private object DiffUtilTvShowCallback : DiffUtil.ItemCallback<TvShow>() {
override fun areItemsTheSame(oldItem: TvShow, newItem: TvShow) = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: TvShow, newItem: TvShow) = oldItem == newItem
}
class ViewHolder(private val binding : ItemTvShowCategoryBinding)
: RecyclerView.ViewHolder(binding.root){
val tvShow : TvShow? get() = binding.tvShow
init {
itemView.setOnClickListener {}
}
fun bind(tvShow : TvShow) {
binding.tvShow = tvShow
val imgUri = tvShow.posterPath?.let { (Constants.IMG_URL +it).toUri().buildUpon().scheme("https").build() }
binding.itemImage.load(imgUri)
binding.executePendingBindings()
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TvShowAdapter.ViewHolder =
TvShowAdapter.ViewHolder(ItemTvShowCategoryBinding.inflate(LayoutInflater.from(parent.context)))
override fun onBindViewHolder(holder: TvShowAdapter.ViewHolder, position: Int) = holder.bind(getItem(position))
}

@ -32,7 +32,7 @@ class MoviesFragment(
)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
with(binding.categorySpinner)
with(binding.categoryMovieSpinner)
{
this.adapter = adapter
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {

@ -1,15 +1,68 @@
package fr.iut.pm.movieapplication.ui.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import fr.iut.pm.movieapplication.R
import fr.iut.pm.movieapplication.databinding.FragmentTvShowsBinding
import fr.iut.pm.movieapplication.ui.activity.MainActivity
import fr.iut.pm.movieapplication.ui.viewmodel.TvShowVM
class TvShowsFragment(
private val context : MainActivity
) : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
private val tvShowVM by viewModels<TvShowVM>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?)
: View {
val binding = FragmentTvShowsBinding.inflate(inflater)
binding.tvShowVM = tvShowVM
binding.lifecycleOwner = viewLifecycleOwner
val adapter = ArrayAdapter.createFromResource(
requireContext(),
R.array.tv_show_filter,
android.R.layout.simple_spinner_item
)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
with(binding.categoryTvShowSpinner)
{
this.adapter = adapter
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
tvShowVM.getData(selectedItem.toString())
}
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("Not yet implemented")
}
}
}
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tvShowVM.getTvShowLiveData().observe(viewLifecycleOwner) {
tvShowVM.tvShowAdapter.submitList(it)
}
}
}

@ -6,6 +6,8 @@ import androidx.recyclerview.widget.RecyclerView
import fr.iut.pm.movieapplication.model.media.movie.Movie
import fr.iut.pm.movieapplication.repository.MovieRepository
import fr.iut.pm.movieapplication.ui.adapter.MovieAdapter
import fr.iut.pm.movieapplication.utils.Constants.Companion.MAX_PAGE
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class MoviesVM() : ViewModel() {
@ -43,11 +45,15 @@ class MoviesVM() : ViewModel() {
if(lastVisibleItemPosition == totalItemCount -1) {
++currentPage
getMoreData(currentPage)
//1000 is the MAX_PAGE
if(currentPage <= MAX_PAGE) getMoreData(currentPage)
}
}
}
/**
* Currrent page where the data are obtained
*/
private var currentPage = 1
/**

@ -0,0 +1,34 @@
package fr.iut.pm.movieapplication.ui.viewmodel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import fr.iut.pm.movieapplication.model.media.tvshow.TvShow
import fr.iut.pm.movieapplication.repository.TvShowRepository
import fr.iut.pm.movieapplication.ui.adapter.TvShowAdapter
import kotlinx.coroutines.launch
class TvShowVM : ViewModel() {
private val tvShowRepository = TvShowRepository()
private var tvShowLiveData : MutableLiveData<List<TvShow>> = MutableLiveData<List<TvShow>>()
fun getTvShowLiveData() : LiveData<List<TvShow>> = tvShowLiveData
private var currentFilter : String = ""
val tvShowAdapter = TvShowAdapter()
private var currentPage = 1
fun getData(filter : String) {
currentFilter = filter
currentPage = 1
when(currentFilter) {
"Populaires" -> viewModelScope.launch {
tvShowLiveData.postValue(tvShowRepository.getPopularTvShow())
}
}
}
}

@ -12,5 +12,6 @@ class Constants {
//VIEW PAGINATION
const val PAGE_SIZE = 20
const val MAX_PAGE = 1000
}
}

@ -12,7 +12,7 @@ object MediaResultMapper {
posterPath = mediaResultDTO.posterPath,
popularity = mediaResultDTO.popularity,
id = mediaResultDTO.id,
backdropPath = mediaResultDTO.backdropPath!!,
backdropPath = mediaResultDTO.backdropPath ?: "",
voteAverage = mediaResultDTO.voteAverage,
overview = mediaResultDTO.overview,
firstAirDate = mediaResultDTO.firstAirDate,
@ -28,7 +28,7 @@ object MediaResultMapper {
fun mapToMovie(mediaResultDTO: MediaResultDTO): Movie {
return Movie(
posterPath = mediaResultDTO.posterPath,
adult = !mediaResultDTO.adult,
adult = mediaResultDTO.adult!!,
overview = mediaResultDTO.overview,
releaseDate = mediaResultDTO.releaseDate ?: "",
genreIds = mediaResultDTO.genreIds,
@ -47,7 +47,7 @@ object MediaResultMapper {
fun mapToMediaResult(mediaResultDTO: MediaResultDTO) : MediaResult {
return MediaResult(
posterPath = mediaResultDTO.posterPath,
adult = !mediaResultDTO.adult,
adult = mediaResultDTO.adult!!,
overview = mediaResultDTO.overview,
releaseDate = mediaResultDTO.releaseDate ?: mediaResultDTO.firstAirDate!! ,
originCountry = mediaResultDTO.originCountry,

@ -20,7 +20,7 @@
<Spinner
android:id="@+id/category_spinner"
android:id="@+id/category_movie_spinner"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginLeft="@dimen/default_margin"

@ -1,13 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<layout 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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/tv_shows_item_recycler_view"
<data>
<import type="android.view.View" />
<variable
name="tvShowVM"
type="fr.iut.pm.movieapplication.ui.viewmodel.TvShowVM" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/default_margin"
/>
android:orientation="vertical">
<Spinner
android:id="@+id/category_tv_show_spinner"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginStart="@dimen/default_margin"
android:layout_marginEnd="@dimen/default_margin"
android:layout_marginTop="@dimen/default_margin"
android:layout_marginBottom="@dimen/default_margin"
android:background="@color/light_grey"
android:layout_marginRight="@dimen/default_margin" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/tv_shows_item_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/default_margin"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="3"
android:adapter="@{tvShowVM.tvShowAdapter}"
tools:listitem="@layout/item_tv_show_category"
/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<data>
<variable
name="tvShow"
type="fr.iut.pm.movieapplication.model.media.tvshow.TvShow" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="4dp"
android:layout_marginLeft="4dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="8dp"
app:cardCornerRadius="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/item_image"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="@color/black"
android:scaleType="centerCrop"
/>
<TextView
android:id="@+id/item_name"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_gravity="center"
android:textAlignment="center"
android:text="@{tvShow.name}"/>
<TextView
android:id="@+id/item_date"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_gravity="center"
android:textAlignment="center"
android:text="@{tvShow.firstAirDate}"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

@ -22,4 +22,11 @@
<item>Les mieux notés</item>
</string-array>
<string-array name="tv_show_filter">
<item>Populaires</item>
<item>Diffusées aujourd\'hui</item>
<item>En cours de diffusion</item>
<item>Les mieux notées</item>
</string-array>
</resources>
Loading…
Cancel
Save