parent
7b8d1cdb9d
commit
e6571ba2bf
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetDropDown">
|
||||
<targetSelectedWithDropDown>
|
||||
<Target>
|
||||
<type value="QUICK_BOOT_TARGET" />
|
||||
<deviceKey>
|
||||
<Key>
|
||||
<type value="VIRTUAL_DEVICE_PATH" />
|
||||
<value value="$USER_HOME$/.android/avd/pixel_5_-_api_33.avd" />
|
||||
</Key>
|
||||
</deviceKey>
|
||||
</Target>
|
||||
</targetSelectedWithDropDown>
|
||||
<timeTargetWasSelectedWithDropDown value="2023-01-28T19:11:20.665081Z" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,13 @@
|
||||
package com.example.cinapp.Request
|
||||
|
||||
import com.example.cinapp.model.Movie
|
||||
|
||||
|
||||
class Demmy (
|
||||
var page: Int,
|
||||
var results: List<MediaResponse>,
|
||||
var total_pages: Int,
|
||||
var total_results: Int
|
||||
){
|
||||
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.example.cinapp.Request
|
||||
|
||||
import android.util.Log
|
||||
import com.example.cinapp.model.Media
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.moshi.MoshiConverterFactory
|
||||
|
||||
class MediaApi {
|
||||
private val retrofit = Retrofit.Builder()
|
||||
.baseUrl("https://api.themoviedb.org/3/")
|
||||
.addConverterFactory(MoshiConverterFactory.create())
|
||||
.build()
|
||||
|
||||
private val service = retrofit.create(MediaService::class.java)
|
||||
val mediaMapper = MediaMapper()
|
||||
|
||||
fun search(apiKey: String, language: String, query: String, page: Int, includeAdult: Boolean, callback: (List<Media>) -> Unit) {
|
||||
val response: Call<Demmy> = service.searchMedia(apiKey, language, query, page, includeAdult)
|
||||
val listMedia: MutableList<Media> = mutableListOf()
|
||||
Log.d("TAG", "search: " + response.request().url())
|
||||
|
||||
response.enqueue(object : Callback<Demmy> {
|
||||
override fun onResponse(call: Call<Demmy>, response: Response<Demmy>) {
|
||||
Log.d("Liste1", response.body().toString())
|
||||
val allMedia = response.body()
|
||||
val listMediaResponse = allMedia?.results
|
||||
listMediaResponse?.forEach { mediaResponse ->
|
||||
val media = mediaMapper.searchMapToMedia(mediaResponse)
|
||||
Log.d("Media", media.toString())
|
||||
listMedia.add(media)
|
||||
}
|
||||
callback(listMedia)
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<Demmy>, t: Throwable) {
|
||||
Log.d("ErrorRetrofit", t.message.toString())
|
||||
}
|
||||
})
|
||||
Log.d("Liste2", listMedia.size.toString())
|
||||
}
|
||||
|
||||
fun getPopularMovies(apiKey: String): List<Media> {
|
||||
val response: Call<Demmy> = service.getPopularMovies(apiKey)
|
||||
val listMedia: MutableList<Media> = mutableListOf()
|
||||
|
||||
response.enqueue(object : Callback<Demmy> {
|
||||
override fun onResponse(call: Call<Demmy>, response: Response<Demmy>) {
|
||||
Log.d("Liste1", response.body().toString())
|
||||
val allMedia = response.body()!!
|
||||
val listMediaResponse = allMedia.results
|
||||
listMediaResponse.forEach { mediaResponse ->
|
||||
listMedia.add(mediaMapper.searchMapToMedia(mediaResponse))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<Demmy>, t: Throwable) {
|
||||
Log.d("ErrorRetrofit", t.message.toString())
|
||||
}
|
||||
})
|
||||
|
||||
return listMedia
|
||||
}
|
||||
|
||||
fun getForrestGump(): List<Media> {
|
||||
val response: Call<Demmy> = service.getForrestGump()
|
||||
val listMedia: MutableList<Media> = mutableListOf()
|
||||
|
||||
response.enqueue(object : Callback<Demmy> {
|
||||
override fun onResponse(call: Call<Demmy>, response: Response<Demmy>) {
|
||||
Log.d("Liste1", response.body().toString())
|
||||
val allMedia = response.body()!!
|
||||
val listMediaResponse = allMedia.results
|
||||
listMediaResponse.forEach { mediaResponse ->
|
||||
listMedia.add(mediaMapper.searchMapToMedia(mediaResponse))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<Demmy>, t: Throwable) {
|
||||
Log.d("ErrorRetrofit", t.message.toString())
|
||||
}
|
||||
})
|
||||
|
||||
return listMedia
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.example.cinapp.Request
|
||||
|
||||
import com.example.cinapp.model.Media
|
||||
import com.example.cinapp.model.Movie
|
||||
import com.example.cinapp.model.Serie
|
||||
|
||||
class MediaMapper {
|
||||
fun searchMapToMedia(mediaResponse: MediaResponse): Media {
|
||||
return when (mediaResponse.media_type) {
|
||||
"movie" -> searchMapToMovie(mediaResponse)
|
||||
"tv" -> searchMapToSerie(mediaResponse)
|
||||
else -> throw IllegalArgumentException("Invalid media type")
|
||||
}
|
||||
}
|
||||
|
||||
private fun searchMapToMovie(mediaResponse: MediaResponse): Movie {
|
||||
return Movie(
|
||||
id = mediaResponse.id,
|
||||
title = mediaResponse.title,
|
||||
overview = mediaResponse.overview,
|
||||
posterPath = mediaResponse.poster_path,
|
||||
releaseDate = mediaResponse.release_date,
|
||||
genreIds = mediaResponse.genre_ids,
|
||||
popularity = mediaResponse.popularity,
|
||||
voteAverage = mediaResponse.vote_average,
|
||||
voteCount = mediaResponse.vote_count,
|
||||
adult = mediaResponse.adult,
|
||||
backdropPath = mediaResponse.backdrop_path,
|
||||
originalLanguage = mediaResponse.original_language,
|
||||
originalName = mediaResponse.original_title,
|
||||
originCountry = mediaResponse.origin_country
|
||||
)
|
||||
}
|
||||
|
||||
private fun searchMapToSerie(mediaResponse: MediaResponse): Serie {
|
||||
return Serie(
|
||||
id = mediaResponse.id,
|
||||
title = mediaResponse.name,
|
||||
overview = mediaResponse.overview,
|
||||
posterPath = mediaResponse.poster_path,
|
||||
releaseDate = mediaResponse.first_air_date,
|
||||
genreIds = mediaResponse.genre_ids,
|
||||
popularity = mediaResponse.popularity,
|
||||
voteAverage = mediaResponse.vote_average,
|
||||
voteCount = mediaResponse.vote_count,
|
||||
adult = mediaResponse.adult,
|
||||
backdropPath = mediaResponse.backdrop_path,
|
||||
originalLanguage = mediaResponse.original_language,
|
||||
originalName = mediaResponse.original_name,
|
||||
originCountry = mediaResponse.origin_country
|
||||
//seasons = mediaResponse.seasons,
|
||||
//numberOfSeasons = mediaResponse.numberOfSeasons,
|
||||
//numberOfEpisodes = mediaResponse.numberOfEpisodes
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.example.cinapp.Request
|
||||
|
||||
import com.example.cinapp.model.Season
|
||||
|
||||
class MediaResponse(
|
||||
val adult: Boolean,
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val media_type: String,
|
||||
val backdrop_path: String,
|
||||
val first_air_date: String,
|
||||
val origin_country: List<String>,
|
||||
val original_language: String,
|
||||
val original_name: String,
|
||||
val overview : String,
|
||||
val popularity: Double,
|
||||
val poster_path: String,
|
||||
val vote_average: Double,
|
||||
val vote_count: Int,
|
||||
val genre_ids: List<Int>,
|
||||
val original_title: String,
|
||||
val title: String,
|
||||
val video: Boolean,
|
||||
val release_date: String,
|
||||
var seasons: List<Season>? = null,
|
||||
var numberOfSeasons: Int? = null,
|
||||
var numberOfEpisodes: Int? = null
|
||||
) {
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.example.cinapp.Request
|
||||
|
||||
import retrofit2.Call
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface MediaService {
|
||||
@GET("search/movie?api_key=e53e59cf1e29b9afff93d9ca1208f0cf&query=Forrest%20Gump&language=fr")
|
||||
fun getForrestGump(): Call<Demmy>
|
||||
|
||||
@GET("search/multi")
|
||||
fun searchMedia(
|
||||
@Query("api_key") apiKey: String,
|
||||
@Query("language") language: String,
|
||||
@Query("query") query: String,
|
||||
@Query("page") page: Int,
|
||||
@Query("include_adult") includeAdult: Boolean
|
||||
): Call<Demmy>
|
||||
|
||||
@GET("movie/popular")
|
||||
fun getPopularMovies(@Query("api_key") apiKey: String): Call<Demmy>
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.example.cinapp.Request
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.example.cinapp.R
|
||||
import com.example.cinapp.model.Movie
|
||||
|
||||
class MoviesAdapter(private val movies: List<Movie>) : RecyclerView.Adapter<MoviesAdapter.ViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_movie, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val movie = movies[position]
|
||||
//holder.name.text = movie.name
|
||||
Glide.with(holder.itemView.context).load(movie.posterPath).into(holder.image)
|
||||
}
|
||||
|
||||
override fun getItemCount() = movies.size
|
||||
|
||||
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
//val name: TextView = itemView.findViewById(R.id.text_view_movie_name)
|
||||
val image: ImageView = itemView.findViewById(R.id.image_view_movie)
|
||||
}
|
||||
}
|
@ -1,17 +1,19 @@
|
||||
package com.example.cinapp.model
|
||||
|
||||
abstract class Media {
|
||||
abstract val id: Int
|
||||
abstract val name: String
|
||||
abstract val backdropPath: String
|
||||
abstract val releaseDate: String
|
||||
abstract val originCountry: List<String>
|
||||
abstract val originalLanguage: String
|
||||
abstract val originalName: String
|
||||
abstract val overview : String
|
||||
abstract val popularity: Double
|
||||
abstract val posterPath: String
|
||||
abstract val voteAverage: Double
|
||||
abstract val voteCount: Int
|
||||
abstract val genreIds: List<Int>
|
||||
open class Media (
|
||||
val adult: Boolean? = null,
|
||||
val id: Int,
|
||||
val title: String? = null,
|
||||
val backdropPath: String? = null,
|
||||
val releaseDate: String? = null,
|
||||
val originCountry: List<String>? = null,
|
||||
val originalLanguage: String? = null,
|
||||
val originalName: String? = null,
|
||||
val overview : String? = null,
|
||||
val popularity: Double? = null,
|
||||
val posterPath: String? = null,
|
||||
val voteAverage: Double? = null,
|
||||
val voteCount: Int? = null,
|
||||
val genreIds: List<Int>? = null
|
||||
){
|
||||
}
|
@ -1,44 +1,6 @@
|
||||
package com.example.cinapp.model
|
||||
|
||||
class MediasLibrary(
|
||||
var id : Int,
|
||||
var mediasLibrary: List<Media>
|
||||
){
|
||||
override fun toString(): String {
|
||||
return "MediasLibrary(id=$id, mediasLibrary=$mediasLibrary)"
|
||||
}
|
||||
|
||||
//add a media to the library
|
||||
fun addMedia(media: Media){
|
||||
mediasLibrary += media
|
||||
}
|
||||
|
||||
//remove a media from the library
|
||||
fun removeMedia(media: Media){
|
||||
mediasLibrary -= media
|
||||
}
|
||||
|
||||
//get a media from the library
|
||||
fun getMedia(media: Media): Media?{
|
||||
return mediasLibrary.find { it.id == media.id }
|
||||
}
|
||||
|
||||
//get all medias from the library
|
||||
fun getAllMedias(): List<Media>{
|
||||
return mediasLibrary
|
||||
}
|
||||
|
||||
//get all medias from the library
|
||||
fun getAllMediasByType(type: String): List<Media>{
|
||||
var medias = mutableListOf<Media>()
|
||||
for (media in mediasLibrary){
|
||||
if (media is Movie && type == "movie"){
|
||||
medias.add(media)
|
||||
}
|
||||
if (media is Serie && type == "serie"){
|
||||
medias.add(media)
|
||||
}
|
||||
}
|
||||
return medias
|
||||
}
|
||||
}
|
@ -1,19 +1,34 @@
|
||||
package com.example.cinapp.model
|
||||
|
||||
class Movie(
|
||||
override val id: Int,
|
||||
override val name: String,
|
||||
override val backdropPath: String,
|
||||
override val releaseDate: String,
|
||||
override val originCountry: List<String>,
|
||||
override val originalLanguage: String,
|
||||
override val originalName: String,
|
||||
override val overview: String,
|
||||
override val popularity: Double,
|
||||
override val posterPath: String,
|
||||
override val voteAverage: Double,
|
||||
override val voteCount: Int,
|
||||
override val genreIds: List<Int>
|
||||
) : Media() {
|
||||
|
||||
adult: Boolean? = null,
|
||||
id: Int,
|
||||
title: String? = null,
|
||||
backdropPath: String? = null,
|
||||
releaseDate: String? = null,
|
||||
originCountry: List<String>? = null,
|
||||
originalLanguage: String? = null,
|
||||
originalName: String? = null,
|
||||
overview : String? = null,
|
||||
popularity: Double? = null,
|
||||
posterPath: String? = null,
|
||||
voteAverage: Double? = null,
|
||||
voteCount: Int? = null,
|
||||
genreIds: List<Int>? = null
|
||||
): Media(
|
||||
adult,
|
||||
id,
|
||||
title,
|
||||
backdropPath,
|
||||
releaseDate,
|
||||
originCountry,
|
||||
originalLanguage,
|
||||
originalName,
|
||||
overview,
|
||||
popularity,
|
||||
posterPath,
|
||||
voteAverage,
|
||||
voteCount,
|
||||
genreIds
|
||||
) {
|
||||
}
|
@ -1,21 +1,37 @@
|
||||
package com.example.cinapp.model
|
||||
|
||||
class Serie(
|
||||
override val id: Int,
|
||||
override val name: String,
|
||||
override val backdropPath: String,
|
||||
override val releaseDate: String,
|
||||
override val originCountry: List<String>,
|
||||
override val originalLanguage: String,
|
||||
override val originalName: String,
|
||||
override val overview: String,
|
||||
override val popularity: Double,
|
||||
override val posterPath: String,
|
||||
override val voteAverage: Double,
|
||||
override val voteCount: Int,
|
||||
override val genreIds: List<Int>,
|
||||
var seasons: List<Season>,
|
||||
var numberOfSeasons: Int,
|
||||
var numberOfEpisodes: Int
|
||||
) : Media() {
|
||||
adult: Boolean? = null,
|
||||
id: Int,
|
||||
title: String? = null,
|
||||
backdropPath: String? = null,
|
||||
releaseDate: String? = null,
|
||||
originCountry: List<String>? = null,
|
||||
originalLanguage: String? = null,
|
||||
originalName: String? = null,
|
||||
overview : String? = null,
|
||||
popularity: Double? = null,
|
||||
posterPath: String? = null,
|
||||
voteAverage: Double? = null,
|
||||
voteCount: Int? = null,
|
||||
genreIds: List<Int>? = null,
|
||||
var seasons: List<Season>? = null,
|
||||
var numberOfSeasons: Int? = null,
|
||||
var numberOfEpisodes: Int? = null
|
||||
) : Media(
|
||||
adult,
|
||||
id,
|
||||
title,
|
||||
backdropPath,
|
||||
releaseDate,
|
||||
originCountry,
|
||||
originalLanguage,
|
||||
originalName,
|
||||
overview,
|
||||
popularity,
|
||||
posterPath,
|
||||
voteAverage,
|
||||
voteCount,
|
||||
genreIds
|
||||
) {
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.example.cinapp.navigation
|
||||
package com.example.cinapp.model.navigation
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
@ -1,4 +1,4 @@
|
||||
package com.example.cinapp.navigation
|
||||
package com.example.cinapp.model.navigation
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
@ -1,4 +1,4 @@
|
||||
package com.example.cinapp.navigation
|
||||
package com.example.cinapp.model.navigation
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
@ -1,4 +1,4 @@
|
||||
package com.example.cinapp.navigation
|
||||
package com.example.cinapp.model.navigation
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
@ -1,24 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout 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:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/searchcl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/purple_700"
|
||||
tools:context=".navigation.SearchFragment">
|
||||
tools:context=".model.navigation.SearchFragment">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Search"
|
||||
android:textSize="26dp"
|
||||
android:layout_gravity="center"/>
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="MissingConstraints">
|
||||
|
||||
<SearchView
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Seen movies" />
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Movies to see" />
|
||||
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
<androidx.appcompat.widget.SearchView
|
||||
android:id="@+id/searchView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/white"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
android:background="@color/black"
|
||||
android:queryHint="Search"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||
app:iconifiedByDefault="false"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tabLayout" />
|
||||
|
||||
</FrameLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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"
|
||||
android:background="@color/material_dynamic_secondary30"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_view_movie"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleType="centerCrop"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:ignore="MissingConstraints"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_view_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Title"/>
|
||||
|
||||
<!--<TextView
|
||||
android:id="@+id/text_view_movie_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8dp"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:layout_editor_absoluteY="16dp" />-->
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
Loading…
Reference in new issue