🚧 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 // TvShow
@GET @GET("tv/popular")
fun getPopularTvShow(@Query("api_key") apiKey : String = API_KEY, @Query("page") page : Int = 1) : Call<PopularDTO> suspend fun getPopularTvShow(@Query("api_key") apiKey : String = API_KEY, @Query("page") page : Int = 1) : Response<PopularDTO>
@GET("trending/{media_type}/{time_window}") @GET("trending/{media_type}/{time_window}")

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

@ -1,20 +1,62 @@
package fr.iut.pm.movieapplication.model.media.tvshow package fr.iut.pm.movieapplication.model.media.tvshow
class TvShow( open class TvShow(
val posterPath: String?, open val posterPath: String?,
val popularity: Double, open val popularity: Double,
val id: Int, open val id: Int,
val backdropPath: String, open val backdropPath: String,
val voteAverage: Double, open val voteAverage: Double,
val overview: String, open val overview: String,
val firstAirDate: String?, open val firstAirDate: String?,
val originCountry: List<String>, open val originCountry: List<String>,
val genreIds: List<Int>, open val genreIds: List<Int>,
val originalLanguage: String, open val originalLanguage: String,
val voteCount: Int, open val voteCount: Int,
val name: String, open val name: String,
val originalName: String, open val originalName: String,
val mediaType: String = "tv", 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 -> { R.id.series_page -> {
loadFragments(TvShowsFragment(this)) loadFragments(TvShowsFragment())
return@setOnItemSelectedListener true return@setOnItemSelectedListener true
} }
else -> false 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.model.media.movie.Movie
import fr.iut.pm.movieapplication.utils.Constants 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 areItemsTheSame(oldItem: Movie, newItem: Movie) = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: Movie, newItem: Movie) = oldItem == newItem 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))) ViewHolder(ItemMovieCategoryBinding.inflate(LayoutInflater.from(parent.context)))
override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind(getItem(position)) 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) adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
with(binding.categorySpinner) with(binding.categoryMovieSpinner)
{ {
this.adapter = adapter this.adapter = adapter
onItemSelectedListener = object : AdapterView.OnItemSelectedListener { onItemSelectedListener = object : AdapterView.OnItemSelectedListener {

@ -1,15 +1,68 @@
package fr.iut.pm.movieapplication.ui.fragments package fr.iut.pm.movieapplication.ui.fragments
import android.os.Bundle 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.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.activity.MainActivity
import fr.iut.pm.movieapplication.ui.viewmodel.TvShowVM
class TvShowsFragment( class TvShowsFragment(
private val context : MainActivity
) : Fragment() { ) : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) { private val tvShowVM by viewModels<TvShowVM>()
super.onCreate(savedInstanceState) 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.model.media.movie.Movie
import fr.iut.pm.movieapplication.repository.MovieRepository import fr.iut.pm.movieapplication.repository.MovieRepository
import fr.iut.pm.movieapplication.ui.adapter.MovieAdapter 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 import kotlinx.coroutines.launch
class MoviesVM() : ViewModel() { class MoviesVM() : ViewModel() {
@ -43,11 +45,15 @@ class MoviesVM() : ViewModel() {
if(lastVisibleItemPosition == totalItemCount -1) { if(lastVisibleItemPosition == totalItemCount -1) {
++currentPage ++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 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 //VIEW PAGINATION
const val PAGE_SIZE = 20 const val PAGE_SIZE = 20
const val MAX_PAGE = 1000
} }
} }

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

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

@ -1,13 +1,45 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <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">
<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_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
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 <androidx.recyclerview.widget.RecyclerView
android:id="@+id/tv_shows_item_recycler_view" android:id="@+id/tv_shows_item_recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginBottom="@dimen/default_margin" 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"
/> />
</androidx.constraintlayout.widget.ConstraintLayout> </LinearLayout>
</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> <item>Les mieux notés</item>
</string-array> </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> </resources>
Loading…
Cancel
Save