🚧 rebuild the dtos correctly

features/api/requests/2
Jordan ARTZET 2 years ago
parent ddc0f661e6
commit 5a6b157c4f

@ -12,7 +12,7 @@ import retrofit2.http.Query
interface MovieApplicationAPI { interface MovieApplicationAPI {
@GET("movie/popular") @GET("movie/popular")
fun getPopularMovies(@Query("api_key") apiKey : String = API_KEY) : Call<PopularDTO> fun getPopularMovies(@Query("api_key") apiKey : String = API_KEY, @Query("page") page : Int = 1) : Call<PopularDTO>
@GET("movie/top_rated") @GET("movie/top_rated")
fun getTopRatedMovies(@Query("api_key") apiKey: String = API_KEY) : Call<PopularDTO> fun getTopRatedMovies(@Query("api_key") apiKey: String = API_KEY) : Call<PopularDTO>

@ -0,0 +1,42 @@
package fr.iut.pm.movieapplication.api.dtos
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@Json(name = "results")
data class MediaResultDTO(
@Json(name = "poster_path")
val posterPath : String,
val adult : Boolean,
val overview : String,
@Json(name = "first_air_date")
val firstAirDate : String?,
@Json(name = "release_date")
val releaseDate : String?,
@Json(name = "origin_country")
val originCountry : List<String>?,
@Json(name = "genre_ids")
val genreIds : List<Int>,
val id : Int,
@Json(name = "original_title")
val originalTitle : String?,
@Json(name = "original_language")
val originalLanguage : String,
val title : String?,
@Json(name = "backdrop_path")
val backdropPath : String,
val popularity : Double,
@Json(name = "vote_count")
val voteCount : Int,
val video : Boolean?,
@Json(name = "vote_average")
val voteAverage : Double,
val name: String?,
@Json(name = "original_name")
val originalName : String?,
@Json(name = "media_type")
val mediaType : String
) {
}

@ -1,44 +1,32 @@
package fr.iut.pm.movieapplication.api.dtos package fr.iut.pm.movieapplication.api.dtos
import androidx.room.ColumnInfo
import androidx.room.Embedded
import androidx.room.PrimaryKey
import androidx.room.Relation
import com.squareup.moshi.Json import com.squareup.moshi.Json
import fr.iut.pm.movieapplication.model.Genre
import fr.iut.pm.movieapplication.model.ProductionCompany
import fr.iut.pm.movieapplication.model.ProductionCountry
import fr.iut.pm.movieapplication.network.dtos.GenreDTO
class MovieDTO ( open class MovieDTO (
val adult: Boolean,
val budget: Int,
val genres: Array<GenreDTO>?,
val homepage: String?,
val id: Int,
@Json(name = "original_language")
val originalLanguage: String,
@Json(name = "original_title")
val originalTitle: String,
val overview: String?,
val popularity: Double,
@Json(name = "poster_path") @Json(name = "poster_path")
val posterPath: String?, open val posterPath: String?,
@Json(name = "production_countries") open val adult: Boolean,
val productionCountries: Array<ProductionCountry>, open val overview: String,
@Json(name = "release_date") @Json(name = "release_date")
val releaseDate: String, open val releaseDate: String,
val revenue: Int, @Json(name = "genre_ids")
val runtime: Int?, open val genreIds: List<Int>,
//var spokenLanguages : Array<SpokenLanguage>, open val id: Int,
val status: String, @Json(name = "original_title")
@Json(name = "tag_line") open val originalTitle: String,
val tagLine: String?, @Json(name = "original_language")
val title: String, open val originalLanguage: String,
@Json(name = "vote_average") open val title: String,
val voteAverage: Double, @Json(name = "backdrop_path")
open val backdropPath: String?,
open val popularity: Double,
@Json(name = "vote_count") @Json(name = "vote_count")
val voteCount: Int, open val voteCount: Int,
val backdropPath: String? open val video : Boolean,
@Json(name = "vote_average")
open val voteAverage: Double
){ ){
} }

@ -28,7 +28,6 @@ class MovieResultDTO(
val popularity : Double?, val popularity : Double?,
@Json(name = "vote_count") @Json(name = "vote_count")
val voteCount : Int?, val voteCount : Int?,
val video : Boolean?,
@Json(name = "vote_average") @Json(name = "vote_average")
val voteAverage : Double? val voteAverage : Double?

@ -9,7 +9,7 @@ class PopularDTO(
@Json(name = "page") @Json(name = "page")
val page : Int, val page : Int,
@Json(name = "results") @Json(name = "results")
val results : List<MovieResultDTO>, val results : List<MediaResultDTO>,
@Json(name = "total_results") @Json(name = "total_results")
val totalResults : Int, val totalResults : Int,
@Json(name = "total_pages") @Json(name = "total_pages")

@ -2,8 +2,29 @@ package fr.iut.pm.movieapplication.api.dtos
import com.squareup.moshi.Json import com.squareup.moshi.Json
data class TvShowDTO( open class TvShowDTO(
@Json(name = "poster_path")
open val posterPath: String?,
open val popularity: Double,
open val id: Int,
@Json(name = "backdrop_path") @Json(name = "backdrop_path")
val backdropPath : String? open val backdropPath: String?,
) { @Json(name = "vote_average")
} open val voteAverage: Double,
open val overview: String,
@Json(name = "first_air_date")
open val firstAirDate: String,
@Json(name = "origin_country")
open val originCountry: List<String>,
@Json(name = "genre_ids")
open val genreIds: List<Int>,
@Json(name = "original_language")
open val originalLanguage: String,
@Json(name = "vote_count")
open val voteCount: Int,
open val name: String,
@Json(name = "original_name")
open val originalName: String,
)
{}

@ -4,17 +4,17 @@ import androidx.room.Dao
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import fr.iut.pm.movieapplication.model.Movie import fr.iut.pm.movieapplication.model.media.movie.MovieDetails
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface MovieDAO { interface MovieDAO {
@Query("SELECT * FROM movies_table ORDER BY original_title ASC") @Query("SELECT * FROM movies_table ORDER BY original_title ASC")
fun getMovieByAlphabetizeMovie() : Flow<List<Movie>> fun getMovieByAlphabetizeMovie() : Flow<List<MovieDetails>>
@Insert(onConflict = OnConflictStrategy.IGNORE) @Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(movie : Movie) suspend fun insert(movie : MovieDetails)
@Query("DELETE FROM movies_table") @Query("DELETE FROM movies_table")
suspend fun deleteAll() suspend fun deleteAll()

@ -1,64 +0,0 @@
package fr.iut.pm.movieapplication.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "movies_table")
data class Movie(
@ColumnInfo(name = "adult")
val adult: Boolean,
@ColumnInfo(name = "budget")
val budget: Int?,
@ColumnInfo(name = "genres")
val genres: Array<Genre>?,
@ColumnInfo(name = "homepage")
val homePage: String?,
@PrimaryKey
@ColumnInfo(name = "id")
val movieId: Int,
@ColumnInfo(name = "original_language")
val originalLanguage: String?,
@ColumnInfo(name = "original_title")
val originalTitle: String?,
val overview: String?,
val popularity: Double?,
@ColumnInfo(name = "poster_path")
val posterPath: String?,
val productionCompanies: Array<ProductionCompany>?,
@ColumnInfo(name = "production_countries")
val productionCountries: Array<ProductionCountry>?,
@ColumnInfo(name = "release_date")
val releaseDate: String?,
val revenue: Int?,
val runtime: Int?,
//var spokenLanguages : Array<SpokenLanguage>,
val status: String?,
@ColumnInfo(name = "tag_line")
val tagLine: String?,
val title: String?,
@ColumnInfo(name = "vote_average")
val voteAverage: Double?,
@ColumnInfo(name = "vote_count")
val voteCount: Int?,
val backdropPath: String?
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Movie
if (movieId != other.movieId) return false
return true
}
override fun hashCode(): Int {
return movieId
}
}

@ -2,13 +2,14 @@ package fr.iut.pm.movieapplication.model
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Embedded import androidx.room.Embedded
import fr.iut.pm.movieapplication.model.media.movie.MovieDetails
data class Popular( data class Popular(
@ColumnInfo("page") @ColumnInfo("page")
val page : Int, val page : Int,
@ColumnInfo("results") @ColumnInfo("results")
@Embedded @Embedded
val results : List<Movie>, val results : List<MovieDetails>,
val totalResults : Int, val totalResults : Int,
val totalPages : Int val totalPages : Int

@ -0,0 +1,24 @@
package fr.iut.pm.movieapplication.model.media
data class MediaResult(
val posterPath: String? = null,
val adult: Boolean,
val overview: String,
val firstAirDate: String? = null,
val releaseDate: String? = null,
val originCountry: List<String>? = null,
val genreIds: List<Int>,
val id: Int,
val originalTitle: String? = null,
val originalLanguage: String,
val title: String?,
val backdropPath: String? = null,
val popularity: Double,
val voteCount: Int,
val voteAverage: Double,
val name: String? = null,
val originalName: String? = null,
val mediaType : String
)
{}

@ -0,0 +1,22 @@
package fr.iut.pm.movieapplication.model.media.movie
open class Movie(
open val posterPath: String?,
open val adult: Boolean,
open val overview: String,
open val releaseDate: String,
open val genreIds: List<Int>,
open val id: Int,
open val originalTitle: String,
open val originalLanguage: String,
open val title: String?,
open val backdropPath: String?,
open val popularity: Double,
open val voteCount: Int,
open val video: Boolean?,
open val voteAverage: Double,
)
{
}

@ -0,0 +1,50 @@
package fr.iut.pm.movieapplication.model.media.movie
import fr.iut.pm.movieapplication.model.ProductionCompany
import fr.iut.pm.movieapplication.model.ProductionCountry
data class MovieDetails(
override val posterPath: String,
override val adult: Boolean,
override val overview: String,
override val releaseDate: String,
override val genreIds : List<Int>,
override val id: Int,
override val originalTitle: String,
override val originalLanguage: String,
override val title: String?,
override val backdropPath: String?,
override val popularity: Double,
override val voteCount: Int,
override val video: Boolean?,
override val voteAverage: Double,
val mediaType: String,
val budget: Int?,
val homePage: String?,
val productionCompanies: Array<ProductionCompany>?,
val productionCountries: Array<ProductionCountry>?,
val revenue: Int?,
val runtime: Int?,
val status: String?,
val tagLine: String?
) : Movie(posterPath,
adult,
overview,
releaseDate,
genreIds,
id,
originalTitle,
originalLanguage,
title,
backdropPath,
popularity,
voteCount,
video,
voteAverage) {
}

@ -0,0 +1,20 @@
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",
)
{
}

@ -0,0 +1,4 @@
package fr.iut.pm.movieapplication.model.media.tvshow
class TvShowDetails {
}

@ -1,7 +0,0 @@
package fr.iut.pm.movieapplication.network.dtos
data class GenreDTO(
private val id : Int,
private val name : String
) {
}

@ -3,20 +3,20 @@ package fr.iut.pm.movieapplication.repository
import android.util.Log import android.util.Log
import fr.iut.pm.movieapplication.api.RetrofitInstance import fr.iut.pm.movieapplication.api.RetrofitInstance
import fr.iut.pm.movieapplication.api.dtos.PopularDTO import fr.iut.pm.movieapplication.api.dtos.PopularDTO
import fr.iut.pm.movieapplication.model.Movie import fr.iut.pm.movieapplication.model.media.MediaResult
import fr.iut.pm.movieapplication.utils.Constants.Companion.API_KEY import fr.iut.pm.movieapplication.model.media.movie.Movie
import fr.iut.pm.movieapplication.utils.Mapper import fr.iut.pm.movieapplication.utils.MediaResultMapper
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
class MovieRepository() { class MovieRepository() {
fun getPopularMovies(callback: (List<Movie>) -> Unit ) { fun getPopularMovies(page : Int = 1 ,callback: (List<Movie>) -> Unit ) {
val listMovie : MutableList<Movie> = mutableListOf() val listMovie : MutableList<Movie> = mutableListOf()
RetrofitInstance.api.getPopularMovies().enqueue(object : RetrofitInstance.api.getPopularMovies(page = page).enqueue(object :
Callback<PopularDTO> { Callback<PopularDTO> {
override fun onResponse(call: Call<PopularDTO>, response: Response<PopularDTO>) { override fun onResponse(call: Call<PopularDTO>, response: Response<PopularDTO>) {
if (response.isSuccessful) { if (response.isSuccessful) {
@ -25,7 +25,7 @@ class MovieRepository() {
val listMoviesDTO = popularDTO?.results val listMoviesDTO = popularDTO?.results
listMoviesDTO?.forEach { listMoviesDTO?.forEach {
val movie = Mapper.MapToMovie(it) val movie = MediaResultMapper.mapToMovie(it)
listMovie.add(movie) listMovie.add(movie)
Log.d("Movie ", movie.title!! ) Log.d("Movie ", movie.title!! )
} }
@ -41,8 +41,8 @@ class MovieRepository() {
}) })
} }
fun getTrends(callback: (List<Movie>) -> Unit) { fun getTrends(callback: (List<MediaResult>) -> Unit) {
val listMovie : MutableList<Movie> = mutableListOf() val listMovie : MutableList<MediaResult> = mutableListOf()
RetrofitInstance.api.getTrending().enqueue(object : Callback<PopularDTO> { RetrofitInstance.api.getTrending().enqueue(object : Callback<PopularDTO> {
override fun onResponse(call: Call<PopularDTO>, response: Response<PopularDTO>) { override fun onResponse(call: Call<PopularDTO>, response: Response<PopularDTO>) {
@ -50,7 +50,7 @@ class MovieRepository() {
Log.d("Response",response.body().toString()) Log.d("Response",response.body().toString())
val popularDTO = response.body() val popularDTO = response.body()
popularDTO?.results?.forEach { popularDTO?.results?.forEach {
val movie = Mapper.MapToMovie(it) val movie = MediaResultMapper.mapToMediaResult(it)
listMovie.add(movie) listMovie.add(movie)
movie.title?.let { it1 -> Log.d("Movie", it1) } movie.title?.let { it1 -> Log.d("Movie", it1) }
} }
@ -59,7 +59,7 @@ class MovieRepository() {
} }
override fun onFailure(call: Call<PopularDTO>, t: Throwable) { override fun onFailure(call: Call<PopularDTO>, t: Throwable) {
Log.d("Error failure", t.message.toString()) Log.d("Error failure", t.printStackTrace().toString())
} }
}) })
} }

@ -0,0 +1,4 @@
package fr.iut.pm.movieapplication.repository
class TVShowRepository {
}

@ -11,14 +11,17 @@ import androidx.recyclerview.widget.RecyclerView
import coil.load import coil.load
import fr.iut.pm.movieapplication.R import fr.iut.pm.movieapplication.R
import fr.iut.pm.movieapplication.api.config.GlobalImageConfig import fr.iut.pm.movieapplication.api.config.GlobalImageConfig
import fr.iut.pm.movieapplication.model.Movie import fr.iut.pm.movieapplication.model.media.MediaResult
import fr.iut.pm.movieapplication.model.media.movie.Movie
import fr.iut.pm.movieapplication.model.media.movie.MovieDetails
import fr.iut.pm.movieapplication.model.media.tvshow.TvShow
import fr.iut.pm.movieapplication.ui.activity.MainActivity import fr.iut.pm.movieapplication.ui.activity.MainActivity
import fr.iut.pm.movieapplication.utils.Constants.Companion.IMG_URL import fr.iut.pm.movieapplication.utils.Constants.Companion.IMG_URL
class HomeItemAdapter( class HomeItemAdapter(
private val context: MainActivity, private val context: MainActivity,
private val layoutId: Int, private val layoutId: Int,
private val list: List<Movie> private val list: List<MediaResult>
) : RecyclerView.Adapter<HomeItemAdapter.ViewHolder>() { ) : RecyclerView.Adapter<HomeItemAdapter.ViewHolder>() {
class ViewHolder(view : View) : RecyclerView.ViewHolder(view) { class ViewHolder(view : View) : RecyclerView.ViewHolder(view) {
@ -39,13 +42,19 @@ class HomeItemAdapter(
Log.d("SINGLETON", GlobalImageConfig.baseUrl) Log.d("SINGLETON", GlobalImageConfig.baseUrl)
val imgUri = currentItem.posterPath?.let { val imgUri = currentItem.posterPath?.let {
(IMG_URL + it).toUri().buildUpon().scheme("https").build() (IMG_URL + it).toUri().buildUpon().scheme("https").build()
} }
Log.d("SINGLETON", imgUri.toString() ) Log.d("SINGLETON", imgUri.toString() )
holder.itemImage.load(imgUri) holder.itemImage.load(imgUri)
holder.itemName.text = currentItem.title holder.itemName.text = currentItem.title
holder.itemDate.text = currentItem.releaseDate holder.itemDate.text = currentItem.releaseDate
holder.itemView.setOnClickListener {
onItemClick(currentItem)
}
}
private fun onItemClick(item : MediaResult) {
Log.d("item clicked", item.toString())
} }
override fun getItemCount(): Int = list.size override fun getItemCount(): Int = list.size

@ -0,0 +1,59 @@
package fr.iut.pm.movieapplication.ui.adapter
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.net.toUri
import androidx.recyclerview.widget.RecyclerView
import coil.load
import fr.iut.pm.movieapplication.R
import fr.iut.pm.movieapplication.api.config.GlobalImageConfig
import fr.iut.pm.movieapplication.model.media.movie.Movie
import fr.iut.pm.movieapplication.ui.activity.MainActivity
import fr.iut.pm.movieapplication.utils.Constants
class MovieAdapter(
private val context: MainActivity,
private val layoutId: Int,
private val list: List<Movie>
) : RecyclerView.Adapter<HomeItemAdapter.ViewHolder>(){
class ViewHolder(view : View) : RecyclerView.ViewHolder(view) {
val itemImage: ImageView = view.findViewById<ImageView>(R.id.item_image)
val itemName: TextView = view.findViewById<TextView>(R.id.item_name)
val itemDate: TextView = view.findViewById<TextView>(R.id.item_date)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeItemAdapter.ViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(layoutId, parent, false)
return HomeItemAdapter.ViewHolder(view)
}
override fun getItemCount(): Int = list.size
override fun onBindViewHolder(holder: HomeItemAdapter.ViewHolder, position: Int) {
val currentItem = list[position]
Log.d("SINGLETON", GlobalImageConfig.baseUrl)
val imgUri = currentItem.posterPath?.let {
(Constants.IMG_URL + it).toUri().buildUpon().scheme("https").build()
}
Log.d("SINGLETON", imgUri.toString() )
holder.itemImage.load(imgUri)
holder.itemName.text = currentItem.title
holder.itemDate.text = currentItem.releaseDate
holder.itemView.setOnClickListener {
onItemClick(currentItem)
}
}
private fun onItemClick(item : Movie) {
Log.d("item clicked", item.toString())
}
}

@ -7,11 +7,10 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import fr.iut.pm.movieapplication.R import fr.iut.pm.movieapplication.R
import fr.iut.pm.movieapplication.api.dtos.MovieResultDTO
import fr.iut.pm.movieapplication.model.Movie
import fr.iut.pm.movieapplication.ui.activity.MainActivity import fr.iut.pm.movieapplication.ui.activity.MainActivity
import fr.iut.pm.movieapplication.ui.adapter.HomeItemAdapter import fr.iut.pm.movieapplication.ui.adapter.HomeItemAdapter
import fr.iut.pm.movieapplication.ui.adapter.HomeItemDecoration import fr.iut.pm.movieapplication.ui.adapter.HomeItemDecoration
import fr.iut.pm.movieapplication.ui.adapter.MovieAdapter
import fr.iut.pm.movieapplication.ui.viewmodel.HomeSectionsVM import fr.iut.pm.movieapplication.ui.viewmodel.HomeSectionsVM
class HomeSectionsFragment( class HomeSectionsFragment(
@ -33,7 +32,7 @@ class HomeSectionsFragment(
//get the popularity RecyclerView //get the popularity RecyclerView
context.movieRepository.getPopularMovies { context.movieRepository.getPopularMovies {
val homePopularityRecyclerView = view?.findViewById<RecyclerView>(R.id.home_popularity_recycler_view) val homePopularityRecyclerView = view?.findViewById<RecyclerView>(R.id.home_popularity_recycler_view)
homePopularityRecyclerView?.adapter = HomeItemAdapter(context,R.layout.item_horizontal_home_page,it) homePopularityRecyclerView?.adapter = MovieAdapter(context,R.layout.item_horizontal_home_page,it)
homePopularityRecyclerView?.addItemDecoration(HomeItemDecoration()) homePopularityRecyclerView?.addItemDecoration(HomeItemDecoration())
} }
//get the free RecyclerView //get the free RecyclerView

@ -6,37 +6,89 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import fr.iut.pm.movieapplication.R import fr.iut.pm.movieapplication.R
import fr.iut.pm.movieapplication.api.RetrofitInstance import fr.iut.pm.movieapplication.model.media.MediaResult
import fr.iut.pm.movieapplication.model.Movie import fr.iut.pm.movieapplication.model.media.movie.Movie
import fr.iut.pm.movieapplication.model.media.movie.MovieDetails
import fr.iut.pm.movieapplication.repository.MovieRepository import fr.iut.pm.movieapplication.repository.MovieRepository
import fr.iut.pm.movieapplication.ui.activity.MainActivity import fr.iut.pm.movieapplication.ui.activity.MainActivity
import fr.iut.pm.movieapplication.ui.adapter.CategoryItemDecoration
import fr.iut.pm.movieapplication.ui.adapter.HomeItemAdapter import fr.iut.pm.movieapplication.ui.adapter.HomeItemAdapter
import fr.iut.pm.movieapplication.ui.adapter.MovieAdapter
import fr.iut.pm.movieapplication.ui.viewmodel.MoviesVM import fr.iut.pm.movieapplication.ui.viewmodel.MoviesVM
import fr.iut.pm.movieapplication.ui.viewmodel.MoviesVMFactory import fr.iut.pm.movieapplication.ui.viewmodel.MoviesVMFactory
import fr.iut.pm.movieapplication.ui.viewmodel.viewModelFactory import fr.iut.pm.movieapplication.utils.Constants.Companion.PAGE_SIZE
import kotlinx.coroutines.launch
class MoviesFragment( class MoviesFragment(
private val context : MainActivity private val context : MainActivity
) : Fragment() { ) : Fragment() {
private var isLoading = false
private var isLastPage = false
private var currentPage = 1
private var currentList : MutableList<Movie> = mutableListOf()
private val moviesVM: MoviesVM by viewModels{ MoviesVMFactory(repository = MovieRepository())} private val moviesVM: MoviesVM by viewModels{ MoviesVMFactory(repository = MovieRepository())}
lateinit var moviesRecyclerView : RecyclerView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_movies, container, false) val view = inflater.inflate(R.layout.fragment_movies, container, false)
// Get the RecyclerView
moviesRecyclerView = view.findViewById<RecyclerView>(R.id.movies_item_recycler_view)
// Initialized the data inside our RecyclerView
context.movieRepository.getPopularMovies { listMovies -> context.movieRepository.getPopularMovies { listMovies ->
val moviesRecyclerView = view?.findViewById<RecyclerView>(R.id.movies_item_recycler_view) currentList.addAll(0,listMovies)
moviesRecyclerView?.adapter = HomeItemAdapter(context, R.layout.item_vertical_fragment, listMovies) moviesRecyclerView.adapter = MovieAdapter(context, R.layout.item_vertical_fragment, currentList)
moviesRecyclerView ?. layoutManager = GridLayoutManager (context, 2) moviesRecyclerView.layoutManager = GridLayoutManager (context, 3)
moviesRecyclerView?.addItemDecoration(CategoryItemDecoration()) }
// Create the ScrollListener
val scrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val layoutManager = moviesRecyclerView.layoutManager as GridLayoutManager
val visibleItemCount = layoutManager.childCount
val totalItemCount = layoutManager.itemCount
val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
// If we are not already loading data and it's not the last page
if(!isLoading && !isLastPage) {
if(visibleItemCount + firstVisibleItemPosition >= totalItemCount
&& firstVisibleItemPosition >= 0
&& totalItemCount >= PAGE_SIZE
) {
loadMoreMovies()
}
}
}
} }
// Add the ScrollLister created before to our RecyclerView
moviesRecyclerView.addOnScrollListener(scrollListener)
return view return view
} }
/**
* Method to load data when the user reaches the bottom of the view
*/
private fun loadMoreMovies() {
isLoading = true
currentPage += 1
if(currentPage == 1000) isLastPage = true
val start = currentList.size
context.movieRepository.getPopularMovies(currentPage) { listMovies ->
currentList.addAll(start, listMovies)
moviesRecyclerView.adapter?.notifyItemRangeChanged(start, listMovies.size)
}
isLoading = false
}
} }

@ -1,28 +1,18 @@
package fr.iut.pm.movieapplication.ui.viewmodel package fr.iut.pm.movieapplication.ui.viewmodel
import androidx.lifecycle.* import androidx.lifecycle.*
import fr.iut.pm.movieapplication.api.dtos.MovieResultDTO import fr.iut.pm.movieapplication.model.media.movie.MovieDetails
import fr.iut.pm.movieapplication.model.Movie
import fr.iut.pm.movieapplication.repository.MovieRepository import fr.iut.pm.movieapplication.repository.MovieRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class MoviesVM(private val repository: MovieRepository) : ViewModel() { class MoviesVM(private val repository: MovieRepository) : ViewModel() {
private val _popularMovies = MutableLiveData<List<Movie>>() private val _popularMovies = MutableLiveData<List<MovieDetails>>()
val popularMovies : LiveData<List<Movie>> = _popularMovies val popularMovies : LiveData<List<MovieDetails>> = _popularMovies
init { init {
//loadData() //loadData()
} }
suspend fun loadData() {
viewModelScope.launch {
repository.getPopularMovies { movies ->
_popularMovies.value = movies
}
}.join()
}
} }

@ -3,8 +3,14 @@ package fr.iut.pm.movieapplication.utils
class Constants { class Constants {
companion object { companion object {
//API
const val BASE_URL = "https://api.themoviedb.org/3/" const val BASE_URL = "https://api.themoviedb.org/3/"
const val IMG_URL = "https://image.tmdb.org/t/p/w500" const val IMG_URL = "https://image.tmdb.org/t/p/w500"
const val API_KEY = "8f14a279249638d7f247d0d7298b21b4" const val API_KEY = "8f14a279249638d7f247d0d7298b21b4"
//VIEW PAGINATION
const val PAGE_SIZE = 20
} }
} }

@ -1,36 +0,0 @@
package fr.iut.pm.movieapplication.utils
import fr.iut.pm.movieapplication.api.dtos.MovieResultDTO
import fr.iut.pm.movieapplication.model.Movie
object Mapper {
fun MapToMovie( movieDTO : MovieResultDTO) : Movie {
return Movie(
adult = movieDTO.adult,
posterPath = movieDTO.posterPath,
overview = movieDTO.overview,
releaseDate = movieDTO.releaseDate,
movieId = movieDTO.id,
originalTitle = movieDTO.originalTitle,
originalLanguage = movieDTO.originalLanguage,
title = movieDTO.title,
backdropPath = movieDTO.backdropPath,
popularity = movieDTO.popularity,
voteCount = movieDTO.voteCount,
voteAverage = movieDTO.voteAverage,
budget = null,
genres = null,
homePage = null,
productionCompanies = null,
productionCountries = null,
revenue = null,
runtime = null,
status = null,
tagLine = null
)
}
}

@ -0,0 +1,71 @@
package fr.iut.pm.movieapplication.utils
import fr.iut.pm.movieapplication.api.dtos.MediaResultDTO
import fr.iut.pm.movieapplication.model.media.MediaResult
import fr.iut.pm.movieapplication.model.media.movie.Movie
import fr.iut.pm.movieapplication.model.media.tvshow.TvShow
object MediaResultMapper {
fun mapToTvShow(mediaResultDTO: MediaResultDTO): TvShow {
return TvShow(
posterPath = mediaResultDTO.posterPath,
popularity = mediaResultDTO.popularity,
id = mediaResultDTO.id,
backdropPath = mediaResultDTO.backdropPath!!,
voteAverage = mediaResultDTO.voteAverage,
overview = mediaResultDTO.overview,
firstAirDate = mediaResultDTO.firstAirDate,
originCountry = mediaResultDTO.originCountry!!,
genreIds = mediaResultDTO.genreIds,
originalLanguage = mediaResultDTO.originalLanguage,
voteCount = mediaResultDTO.voteCount,
name = mediaResultDTO.name!!,
originalName = mediaResultDTO.originalName!!
)
}
fun mapToMovie(mediaResultDTO: MediaResultDTO): Movie {
return Movie(
posterPath = mediaResultDTO.posterPath,
adult = mediaResultDTO.adult == false,
overview = mediaResultDTO.overview,
releaseDate = mediaResultDTO.releaseDate!!,
genreIds = mediaResultDTO.genreIds,
id = mediaResultDTO.id,
originalTitle = mediaResultDTO.originalTitle!!,
originalLanguage = mediaResultDTO.originalLanguage,
title = mediaResultDTO.title,
backdropPath = mediaResultDTO.backdropPath,
popularity = mediaResultDTO.popularity,
voteCount = mediaResultDTO.voteCount,
video = mediaResultDTO.video,
voteAverage = mediaResultDTO.voteAverage
)
}
fun mapToMediaResult(mediaResultDTO: MediaResultDTO) : MediaResult {
return MediaResult(
posterPath = mediaResultDTO.posterPath,
adult = mediaResultDTO.adult == false,
overview = mediaResultDTO.overview,
firstAirDate = mediaResultDTO.firstAirDate,
releaseDate = mediaResultDTO.releaseDate,
originCountry = mediaResultDTO.originCountry,
genreIds = mediaResultDTO.genreIds,
id = mediaResultDTO.id,
originalTitle = mediaResultDTO.originalTitle,
originalLanguage = mediaResultDTO.originalLanguage,
title = mediaResultDTO.title,
backdropPath = mediaResultDTO.backdropPath,
popularity = mediaResultDTO.popularity,
voteCount = mediaResultDTO.voteCount,
voteAverage = mediaResultDTO.voteAverage,
name = mediaResultDTO.name,
originalName = mediaResultDTO.originalName,
mediaType = mediaResultDTO.mediaType
)
}
}

@ -7,7 +7,7 @@
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/movies_item_recycler_view" android:id="@+id/movies_item_recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginBottom="@dimen/default_margin" android:layout_marginBottom="@dimen/default_margin"
/> />

@ -1,18 +1,23 @@
<?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" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="175dp" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="250dp" android:layout_height="match_parent"
android:layout_marginLeft="10dp" android:layout_marginStart="4dp"
android:layout_marginStart="10dp" android:layout_marginLeft="4dp"
android:layout_marginEnd="10dp" android:layout_marginTop="8dp"
android:layout_marginTop="@dimen/default_margin" android:layout_marginEnd="4dp"
app:layout_constraintTop_toTopOf="parent" android:layout_marginRight="4dp"
app:cardCornerRadius="10dp"> 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 <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -22,25 +27,23 @@
<ImageView <ImageView
android:id="@+id/item_image" android:id="@+id/item_image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="210dp" android:layout_height="180dp"
android:scaleType="centerCrop" android:background="@color/black"
android:background="@color/black" /> android:scaleType="centerCrop" />
<TextView <TextView
android:id="@+id/item_name" android:id="@+id/item_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="20dp" android:layout_height="20dp"
android:layout_gravity="center" android:layout_gravity="center"
android:textAlignment="center" android:textAlignment="center" />
/>
<TextView <TextView
android:id="@+id/item_date" android:id="@+id/item_date"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="20dp" android:layout_height="20dp"
android:layout_gravity="center" android:layout_gravity="center"
android:textAlignment="center" android:textAlignment="center" />
/>
</LinearLayout> </LinearLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>

Loading…
Cancel
Save