Merge pull request 'Vu_Master' (#17) from Vu_Master into master

Reviewed-on: #17
Système_de_proximité
Louis DUFOUR 2 years ago
commit ba7ef937ec

@ -7,6 +7,7 @@
<option name="testRunner" value="GRADLE" /> <option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" /> <option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="Embedded JDK" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />

@ -0,0 +1,55 @@
package fr.iut.cinecool
class ApiClient {
companion object {
/*private const val BASE_URL = "https://api.themoviedb.org/3/"
fun create(): ApiService {
val gson = GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.create()
val logger = HttpLoggingInterceptor()
logger.level = HttpLoggingInterceptor.Level.BASIC
val client = OkHttpClient.Builder()
.addInterceptor(logger)
.build()
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build()
return retrofit.create(ApiService::class.java)
}
val retrofit = Retrofit.Builder()
.baseUrl("https://api.themoviedb.org/3/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val movieApiService = retrofit.create(ApiService::class.java)
val apiKey = "a97243d7813d31446f6c43284e6854d5"
val call = movieApiService.getPopularMovies(apiKey)
call.enqueue(object : Callback<MovieResponse> {
override fun onResponse(call: Call<MovieResponse>, response: Response<MovieResponse>) {
// Code à exécuter lorsque la réponse est reçue
val movies = response.body()?.results
// Traitez les films renvoyés ici
}
override fun onFailure(call: Call<MovieResponse>, t: Throwable) {
// Code à exécuter en cas d'échec de la requête
}
})
*/
}
}

@ -0,0 +1,45 @@
package fr.iut.cinecool
import android.os.Bundle
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import fr.iut.cinecool.interfaces.ITheMovieDbApiCallback
import fr.iut.cinecool.model.Movie
import fr.iut.cinecool.model.MovieAPI
import fr.iut.cinecool.services.TheMovieDbApiClient
import retrofit2.Call
import retrofit2.Response
import javax.security.auth.callback.Callback
class DetailActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.vu_detail)
// Récupérer l'identifiant du film depuis les extras de l'intent
val movieId = intent.getIntExtra("movieId", -1)
// Appeler la méthode pour charger les détails du film
// loadMovieDetails(movieId)
}
/*private fun loadMovieDetails(movieId: Int) {
val apiClient = TheMovieDbApiClient(getString(R.string.tmdb_api_key))
apiClient.getMovieDetails(movieId, object : ITheMovieDbApiCallback<MovieAPI> {
override fun onSuccess(result: MovieAPI) {
// Afficher les détails du film dans la vue
titreFilm.text = result.title
description.text = result.overview
Picasso.get().load("https://image.tmdb.org/t/p/w500/${result.posterPath}").into(afficheFilm)
}
override fun onError(error: Throwable) {
// Gérer l'erreur de récupération des détails du film
}
})
}*/
}

@ -1,18 +1,10 @@
package fr.iut.cinecool package fr.iut.cinecool
import android.Manifest
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.widget.EditText import android.widget.EditText
import android.widget.ImageView import android.widget.ImageView
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import fr.iut.cinecool.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -37,3 +29,4 @@ class MainActivity : AppCompatActivity() {
} }
} }
} }

@ -0,0 +1,75 @@
package fr.iut.cinecool
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class MovieDetailFragment : Fragment() {
/*
private lateinit var binding: FragmentMovieDetailBinding
override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?, savedInstanceState: Bundle?): View
{
binding = FragmentMovieDetailBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
super.onViewCreated(view, savedInstanceState)
val movieId = arguments?.getInt(ARG_MOVIE_ID)
// Appel de l'API pour récupérer les détails du film
CoroutineScope(Dispatchers.IO).launch {
val response = movieId?.let { MovieApiService().getMovieDetails(it) }
withContext(Dispatchers.Main)
{
if (response != null) {
if (response.isSuccessful)
{
val movie = response.body()
if (movie != null)
{
// Affichage des détails du film dans l'interface utilisateur
binding.titreFilm.text = movie.title
binding.description.text = movie.overview
binding.afficheFilm.load("https://image.tmdb.org/t/p/w500${movie.posterPath}") // Utilisation de la librairie Coil pour charger l'image
}
} else
{
Toast.makeText(
requireContext(),
getString(R.string.error_loading_movie),
Toast.LENGTH_SHORT
).show()
}
}
}
}
// Ajout d'un écouteur de clic pour le bouton de retour
binding.backButton.setOnClickListener {
requireActivity().onBackPressed()
}
}
companion object {
private const val ARG_MOVIE_ID = "movie_id"
fun newInstance(movieId: Int): MovieDetailFragment {
val args = Bundle().apply {
putInt(ARG_MOVIE_ID, movieId)
}
return MovieDetailFragment().apply {
arguments = args
}
}
}*/
}

@ -0,0 +1,25 @@
package fr.iut.cinecool
import fr.iut.cinecool.services.TheMovieDbApiClient
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
object RetrofitClient {
private const val BASE_URL = "https://api.themoviedb.org/3/"
private val okHttpClient = OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build()
private val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
val api: TheMovieDbApiClient = retrofit.create(TheMovieDbApiClient::class.java)
}

@ -0,0 +1,6 @@
package fr.iut.cinecool.interfaces
interface ITheMovieDbApiCallback<T> {
fun onSuccess(result: T)
fun onError(error: Throwable)
}

@ -0,0 +1,12 @@
package fr.iut.cinecool.interfaces
import fr.iut.cinecool.model.Movie
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query
interface ITheMovieDbService {
@GET("movie/{movieId}")
fun getMovieDetails(@Path("movieId") movieId: Int, @Query("api_key") apiKey: String): Call<Movie>
}

@ -1,5 +1,14 @@
package fr.iut.cinecool.model package fr.iut.cinecool.model
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import com.google.gson.annotations.SerializedName
data class Movie(val id:Int, val name:String, var mark:Int, val realisator:String, var duration: Double, val icon:Int) data class Movie(val id:Int, val name:String, var mark:Int, val realisator:String, var duration: Double, val icon:Int)
// D'après l'API (TheMovieDB)
data class MovieAPI(
@SerializedName("id") val id: Int,
@SerializedName("title") val title: String,
@SerializedName("overview") val overview: String,
@SerializedName("poster_path") val posterPath: String?,
@SerializedName("vote_average") val voteAverage: Float
)

@ -0,0 +1,57 @@
package fr.iut.cinecool.services
import fr.iut.cinecool.interfaces.ITheMovieDbApiCallback
import fr.iut.cinecool.interfaces.ITheMovieDbService
import fr.iut.cinecool.model.MovieAPI
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class TheMovieDbApiClient(apiKey: String) {
private val service: ITheMovieDbService = Retrofit.Builder()
.baseUrl("https://api.themoviedb.org/3/")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ITheMovieDbService::class.java)
private val apiKeyInterceptor = Interceptor { chain ->
val url = chain.request().url.newBuilder()
.addQueryParameter("tmdb_api_key", apiKey)
.build()
val request = chain.request().newBuilder()
.url(url)
.build()
chain.proceed(request)
}
private val client: OkHttpClient = OkHttpClient.Builder()
.addInterceptor(apiKeyInterceptor)
.build()
/*fun getMovieDetails(movieId: Int, callback: ITheMovieDbApiCallback<MovieAPI>) {
service.getMovieDetails(movieId).enqueue(object : Callback<MovieAPI> {
override fun onResponse(call: Call<MovieAPI>, response: Response<MovieAPI>) {
if (response.isSuccessful) {
val result = response.body()
if (result != null) {
callback.onSuccess(result)
} else {
callback.onError(Throwable("Empty response body"))
}
} else {
callback.onError(Throwable("Error ${response.code()}: ${response.message()}"))
}
}
override fun onFailure(call: Call<MovieAPI>, t: Throwable) {
callback.onError(t)
}
})
}*/
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

@ -0,0 +1,60 @@
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:id="@+id/backButton"
android:layout_width="60dp"
android:layout_height="55dp"
android:scaleType="fitCenter"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/back_arrow" />
<TextView
android:id="@+id/titreFilm"
android:layout_width="220dp"
android:layout_height="25dp"
android:layout_marginStart="20dp"
android:layout_marginTop="80dp"
android:text="TextView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/logo"
android:layout_width="65dp"
android:layout_height="60dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/cinema"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:scaleType="fitCenter"
/>
<ImageView
android:id="@+id/afficheFilm"
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titreFilm"
app:srcCompat="@drawable/imitation_game" />
<TextView
android:id="@+id/description"
android:layout_width="380dp"
android:layout_height="100dp"
android:layout_marginTop="25dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/afficheFilm" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,50 @@
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="66dp"
android:layout_height="54dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/cinema" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="211dp"
android:layout_height="27dp"
android:background="?attr/colorPrimary"
app:layout_constraintEnd_toStartOf="@+id/imageButton5"
app:layout_constraintStart_toEndOf="@+id/imageView"
tools:layout_editor_absoluteY="29dp">
<androidx.appcompat.widget.SearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:iconifiedByDefault="false"
app:queryHint="Rechercher" />
</androidx.appcompat.widget.Toolbar>
<ImageButton
android:id="@+id/imageButton5"
android:layout_width="56dp"
android:layout_height="56dp"
android:scaleType="fitCenter"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/filtrage"
tools:layout_editor_absoluteY="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -9,6 +9,6 @@
<string name="hello_first_fragment">Hello first fragment</string> <string name="hello_first_fragment">Hello first fragment</string>
<string name="hello_second_fragment">Hello second fragment. Arg: %1$s</string> <string name="hello_second_fragment">Hello second fragment. Arg: %1$s</string>
<!-- TODO: Remove or change this placeholder text --> <string name="error_loading_movie">erreur de chargement des films</string>
<string name="hello_blank_fragment">Hello blank fragment</string> <string name="tmdb_api_key">a97243d7813d31446f6c43284e6854d5</string>
</resources> </resources>

@ -2,5 +2,5 @@
plugins { plugins {
id 'com.android.application' version '7.4.2' apply false id 'com.android.application' version '7.4.2' apply false
id 'com.android.library' version '7.4.2' apply false id 'com.android.library' version '7.4.2' apply false
id 'org.jetbrains.kotlin.android' version '1.8.0' apply false id 'org.jetbrains.kotlin.android' version '1.8.20-RC2' apply false
} }
Loading…
Cancel
Save