🚧 add retrofit

add retrofit instance and the api
features/retrofit/1
Jordan ARTZET 2 years ago
parent ae147111a7
commit 3cfc7d73b4

@ -42,6 +42,8 @@ dependencies {
implementation "androidx.appcompat:appcompat:$rootProject.appCompatVersion"
implementation "androidx.activity:activity-ktx:$rootProject.activityVersion"
implementation 'androidx.core:core-ktx:1.9.0'
implementation "androidx.fragment:fragment-ktx:1.5.5"
// Room components
implementation "androidx.room:room-ktx:$rootProject.roomVersion"
@ -62,6 +64,15 @@ dependencies {
implementation "androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion"
implementation "com.google.android.material:material:$rootProject.materialVersion"
// Moshi
implementation "com.squareup.moshi:moshi-kotlin:1.13.0"
// Retrofit
implementation "com.squareup.retrofit2:retrofit:2.9.0"
// Retrofit with Scalar Converter
implementation "com.squareup.retrofit2:converter-scalars:2.9.0"
// Retrofit with Moshi Converter
implementation "com.squareup.retrofit2:converter-moshi:2.9.0"
// Testing
testImplementation "junit:junit:$rootProject.junitVersion"
androidTestImplementation "androidx.arch.core:core-testing:$rootProject.coreTestingVersion"

@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"

@ -0,0 +1,18 @@
package fr.iut.pm.movieapplication.api
import fr.iut.pm.movieapplication.network.dtos.PopularDTO
import fr.iut.pm.movieapplication.utils.Constants
import fr.iut.pm.movieapplication.utils.Constants.Companion.API_KEY
import kotlinx.coroutines.flow.Flow
import retrofit2.Call
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Query
interface MovieApplicationAPI {
@GET("movie/popular")
suspend fun getPopularMovies(@Query("api_key") apiKey : String) : Call<PopularDTO>
}

@ -0,0 +1,27 @@
package fr.iut.pm.movieapplication.api
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import fr.iut.pm.movieapplication.utils.Constants.Companion.BASE_URL
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
object RetrofitInstance {
private val retrofit by lazy {
Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.baseUrl(BASE_URL)
.build()
}
val api : MovieApplicationAPI by lazy {
retrofit.create(MovieApplicationAPI::class.java)
}
}

@ -1,6 +1,8 @@
package fr.iut.pm.movieapplication.data.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import fr.iut.pm.movieapplication.model.Movie
import kotlinx.coroutines.flow.Flow
@ -11,5 +13,11 @@ interface MovieDAO {
@Query("SELECT * FROM movies_table ORDER BY original_title ASC")
fun getMovieByAlphabetizeMovie() : Flow<List<Movie>>
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(movie : Movie)
@Query("DELETE FROM movies_table")
suspend fun deleteAll()
}

@ -0,0 +1,9 @@
package fr.iut.pm.movieapplication.data.dao
import androidx.room.Entity
@Entity("movies_table")
class MovieEntity {
}

@ -0,0 +1,17 @@
package fr.iut.pm.movieapplication.model
import androidx.room.ColumnInfo
import androidx.room.Embedded
data class Popular(
@ColumnInfo("page")
val page : Int,
@ColumnInfo("results")
@Embedded
val results : List<Movie>,
val totalResults : Int,
val totalPages : Int
){
}

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

@ -0,0 +1,25 @@
package fr.iut.pm.movieapplication.network.dtos
import com.squareup.moshi.Json
data class MovieDTO(
@Json(name = "poster_path")
val posterPath : String?,
val adult : Boolean,
val overview : String?,
@Json(name = "release_date")
val releaseDate : 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
) {
}

@ -0,0 +1,12 @@
package fr.iut.pm.movieapplication.network.dtos
import com.squareup.moshi.Json
data class PopularDTO(
val page : Int,
val results : List<MovieDTO>,
@Json(name = "total_pages")
val totalPages : Int,
@Json(name = "total_results")
val totalResults : Int
) {}

@ -0,0 +1,15 @@
package fr.iut.pm.movieapplication.repository
import fr.iut.pm.movieapplication.data.dao.MovieDAO
import fr.iut.pm.movieapplication.model.Movie
import fr.iut.pm.movieapplication.network.dtos.MovieDTO
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.transform
class MovieRepository() {
suspend fun getPopularMovies() : List<MovieDTO>{
return PopularRepository().getPopular()!!.results
}
}

@ -0,0 +1,33 @@
package fr.iut.pm.movieapplication.repository
import android.util.Log
import fr.iut.pm.movieapplication.api.RetrofitInstance
import fr.iut.pm.movieapplication.network.dtos.PopularDTO
import fr.iut.pm.movieapplication.utils.Constants.Companion.API_KEY
import kotlinx.coroutines.flow.Flow
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class PopularRepository() {
suspend fun getPopular(): PopularDTO? {
lateinit var popularDTO : PopularDTO
RetrofitInstance.api.getPopularMovies(API_KEY).enqueue(object : Callback<PopularDTO> {
override fun onResponse(call: Call<PopularDTO>, response: Response<PopularDTO>) {
if (response.isSuccessful) {
Log.d("RESPONSE ::", response.body()?.page.toString())
popularDTO = response.body()!!
}
}
override fun onFailure(call: Call<PopularDTO>, t: Throwable) {
TODO("Not yet implemented")
}
})
return popularDTO
}
}

@ -6,11 +6,13 @@ import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import fr.iut.pm.movieapplication.R
import fr.iut.pm.movieapplication.network.dtos.MovieDTO
import fr.iut.pm.movieapplication.ui.activity.MainActivity
class HomeItemAdapter(
private val context : MainActivity,
private val layoutId : Int
private val layoutId : Int,
private val list : List<MovieDTO>
) : RecyclerView.Adapter<HomeItemAdapter.ViewHolder>() {
class ViewHolder(view : View) : RecyclerView.ViewHolder(view) {
@ -23,7 +25,9 @@ class HomeItemAdapter(
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val currentItem = list?.get(position)
}
override fun getItemCount(): Int = 5
override fun getItemCount(): Int = list?.size!!
}

@ -7,30 +7,33 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import fr.iut.pm.movieapplication.R
import fr.iut.pm.movieapplication.network.dtos.MovieDTO
import fr.iut.pm.movieapplication.network.dtos.PopularDTO
import fr.iut.pm.movieapplication.ui.activity.MainActivity
import fr.iut.pm.movieapplication.ui.adapter.HomeItemAdapter
import fr.iut.pm.movieapplication.ui.adapter.HomeItemDecoration
import fr.iut.pm.movieapplication.ui.viewmodel.HomeSectionsVM
class HomeSectionsFragment(
private val context : MainActivity
) : Fragment() {
class HomeSectionsFragment(private val context : MainActivity) : Fragment() {
private lateinit var homeSectionsViewModel : HomeSectionsVM
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_home_sections, container, false)
//get the trends RecyclerView
val homeTrendsRecyclerView = view?.findViewById<RecyclerView>(R.id.home_trends_recycler_view)
homeTrendsRecyclerView?.adapter = HomeItemAdapter(context,R.layout.item_horizontal_home_page)
homeTrendsRecyclerView?.adapter = HomeItemAdapter(context,R.layout.item_horizontal_home_page,ArrayList<MovieDTO>())
homeTrendsRecyclerView?.addItemDecoration(HomeItemDecoration())
//get the popularity RecyclerView
val homePopularityRecyclerView = view?.findViewById<RecyclerView>(R.id.home_popularity_recycler_view)
homePopularityRecyclerView?.adapter = HomeItemAdapter(context,R.layout.item_horizontal_home_page)
homePopularityRecyclerView?.adapter = HomeItemAdapter(context,R.layout.item_horizontal_home_page,ArrayList<MovieDTO>())
homePopularityRecyclerView?.addItemDecoration(HomeItemDecoration())
//get the free RecyclerView
val homeFreeRecyclerView = view?.findViewById<RecyclerView>(R.id.home_free_recycler_view)
homeFreeRecyclerView?.adapter = HomeItemAdapter(context,R.layout.item_horizontal_home_page)
homeFreeRecyclerView?.adapter = HomeItemAdapter(context,R.layout.item_horizontal_home_page,ArrayList())
homeFreeRecyclerView?.addItemDecoration(HomeItemDecoration())
return view
}

@ -5,13 +5,25 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.viewModelFactory
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import fr.iut.pm.movieapplication.R
import fr.iut.pm.movieapplication.data.dao.MovieDAO
import fr.iut.pm.movieapplication.network.dtos.MovieDTO
import fr.iut.pm.movieapplication.network.dtos.PopularDTO
import fr.iut.pm.movieapplication.repository.MovieRepository
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.HomeItemDecoration
import fr.iut.pm.movieapplication.ui.viewmodel.MoviesVM
import fr.iut.pm.movieapplication.ui.viewmodel.MoviesVMFactory
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.runBlocking
class MoviesFragment(
private val context : MainActivity
@ -20,10 +32,15 @@ class MoviesFragment(
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_movies, container, false)
val viewModel by viewModels<MoviesVM> {
MoviesVMFactory(MovieRepository())
}
//get the recycler view
val moviesRecyclerView = view?.findViewById<RecyclerView>(R.id.movies_item_recycler_view)
moviesRecyclerView?.adapter = HomeItemAdapter(context,R.layout.item_vertical_fragment)
moviesRecyclerView?.adapter = HomeItemAdapter(context, R.layout.item_vertical_fragment,viewModel.popularMovies.value!!)
moviesRecyclerView?.layoutManager = GridLayoutManager(context, 2)
moviesRecyclerView?.addItemDecoration(CategoryItemDecoration())

@ -0,0 +1,4 @@
package fr.iut.pm.movieapplication.ui.viewmodel
class HomeSectionsVM {
}

@ -0,0 +1,46 @@
package fr.iut.pm.movieapplication.ui.viewmodel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import fr.iut.pm.movieapplication.network.dtos.MovieDTO
import fr.iut.pm.movieapplication.repository.MovieRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class MoviesVM(private val repository: MovieRepository) : ViewModel() {
private val _popularMovies = MutableLiveData<List<MovieDTO>>()
val popularMovies : MutableLiveData<List<MovieDTO>> = _popularMovies
init {
getPopularMovies()
}
private fun getPopularMovies() {
viewModelScope.launch {
try {
_popularMovies.value = repository.getPopularMovies()}
catch (e : Exception) {
e.stackTrace
}
}
}
}
class MoviesVMFactory(
private val repository: MovieRepository
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MoviesVM::class.java)) {
return MoviesVM(repository) as T
}
throw java.lang.IllegalArgumentException("Unknown ViewModel class")
}
}

@ -0,0 +1,9 @@
package fr.iut.pm.movieapplication.utils
class Constants {
companion object {
const val BASE_URL = "https://api.themoviedb.org/3/"
const val API_KEY = "8f14a279249638d7f247d0d7298b21b4"
}
}

@ -24,6 +24,7 @@
android:background="@color/black" />
<TextView
android:id="@+id/item_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Nom du film"

@ -12,7 +12,7 @@ ext {
coreTestingVersion = '2.1.0'
coroutines = '1.6.4'
lifecycleVersion = '2.5.1'
materialVersion = '1.7.0'
materialVersion = '1.8.0'
roomVersion = '2.5.0'
kotlin_version = '1.7.20'
// testing

Loading…
Cancel
Save