mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-23 04:00:53 -05:00
add tv page
This commit is contained in:
@@ -26,6 +26,10 @@ class TmdbClient: KoinComponent {
|
||||
return client.create(MoviesApi::class.java)
|
||||
}
|
||||
|
||||
fun createTvService(): TvApi {
|
||||
return client.create(TvApi::class.java)
|
||||
}
|
||||
|
||||
private inner class TmdbInterceptor: Interceptor {
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val apiParam = QueryParam("api_key", BuildConfig.TMDB_ApiKey)
|
||||
|
||||
13
app/src/main/java/com/owenlejeune/tvtime/api/tmdb/TvApi.kt
Normal file
13
app/src/main/java/com/owenlejeune/tvtime/api/tmdb/TvApi.kt
Normal file
@@ -0,0 +1,13 @@
|
||||
package com.owenlejeune.tvtime.api.tmdb
|
||||
|
||||
import com.owenlejeune.tvtime.api.tmdb.model.PopularTvResponse
|
||||
import retrofit2.Call
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface TvApi {
|
||||
|
||||
@GET("tv/popular")
|
||||
fun getPoplarTv(@Query("page") page: Int = 1): Call<PopularTvResponse>
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.owenlejeune.tvtime.api.tmdb
|
||||
|
||||
import com.owenlejeune.tvtime.api.tmdb.model.PopularTvResponse
|
||||
import org.koin.core.component.KoinComponent
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
|
||||
class TvService: KoinComponent {
|
||||
|
||||
private val service by lazy { TmdbClient().createTvService() }
|
||||
|
||||
fun getPopularTv(page: Int = 1, callback: (isSuccessful: Boolean, response: PopularTvResponse?) -> Unit) {
|
||||
service.getPoplarTv(page = page).enqueue(object : Callback<PopularTvResponse> {
|
||||
override fun onResponse(call: Call<PopularTvResponse>, response: Response<PopularTvResponse>) {
|
||||
response.body()?.let { body ->
|
||||
callback.invoke(true, body)
|
||||
} ?: run {
|
||||
callback.invoke(false, null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<PopularTvResponse>, t: Throwable) {
|
||||
callback.invoke(false, null)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.owenlejeune.tvtime.api.tmdb.model
|
||||
|
||||
abstract class MediaItem(
|
||||
open val posterPath: String?,
|
||||
@Transient open val title: String
|
||||
)
|
||||
@@ -2,7 +2,7 @@ package com.owenlejeune.tvtime.api.tmdb.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class PopularMovie(
|
||||
@SerializedName("poster_path") val posterPath: String?,
|
||||
@SerializedName("title") val title: String
|
||||
)
|
||||
data class PopularMovie(
|
||||
@SerializedName("poster_path") override val posterPath: String?,
|
||||
@SerializedName("title") override val title: String
|
||||
): MediaItem(posterPath, title)
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.owenlejeune.tvtime.api.tmdb.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class PopularTv(
|
||||
@SerializedName("poster_path") override val posterPath: String?,
|
||||
@SerializedName("name") val name: String
|
||||
): MediaItem(posterPath, name)
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.owenlejeune.tvtime.api.tmdb.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class PopularTvResponse(
|
||||
@SerializedName("total_results") val count: Int,
|
||||
@SerializedName("page") val page: Int,
|
||||
@SerializedName("results") val tv: List<PopularTv>
|
||||
)
|
||||
@@ -19,7 +19,7 @@ fun <T: Any> LazyGridScope.items(
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
fun <T: Any> LazyGridScope.items(
|
||||
items: List<T>,
|
||||
itemContent: @Composable (value: T?) -> Unit
|
||||
itemContent: @Composable (value: T) -> Unit
|
||||
) {
|
||||
items(items.size) { index ->
|
||||
itemContent(items[index])
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.owenlejeune.tvtime.ui.components
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.owenlejeune.tvtime.api.tmdb.model.MediaItem
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.GridCells
|
||||
import androidx.compose.foundation.lazy.LazyVerticalGrid
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.rememberImagePainter
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import com.owenlejeune.tvtime.R
|
||||
import com.owenlejeune.tvtime.extensions.dpToPx
|
||||
import com.owenlejeune.tvtime.extensions.items
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun PosterGrid(fetchMedia: (MutableState<List<MediaItem>>) -> Unit) {
|
||||
val mediaList = remember { mutableStateOf(emptyList<MediaItem>()) }
|
||||
fetchMedia(mediaList)
|
||||
|
||||
LazyVerticalGrid(
|
||||
cells = GridCells.Fixed(count = 3),
|
||||
contentPadding = PaddingValues(8.dp)
|
||||
) {
|
||||
items(mediaList.value) { item ->
|
||||
PosterItem(mediaItem = item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PosterItem(mediaItem: MediaItem) {
|
||||
val context = LocalContext.current
|
||||
val poster = "https://image.tmdb.org/t/p/original${mediaItem.posterPath}"
|
||||
Image(
|
||||
painter = rememberImagePainter(
|
||||
data = poster,
|
||||
builder = {
|
||||
transformations(RoundedCornersTransformation(5f.dpToPx(context)))
|
||||
placeholder(R.drawable.placeholder)
|
||||
}
|
||||
),
|
||||
contentDescription = mediaItem.title,
|
||||
modifier = Modifier
|
||||
.size(190.dp)
|
||||
.padding(5.dp)
|
||||
.clickable {
|
||||
Toast
|
||||
.makeText(context, "${mediaItem.title} clicked", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -1,68 +1,22 @@
|
||||
package com.owenlejeune.tvtime.ui.screens
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.GridCells
|
||||
import androidx.compose.foundation.lazy.LazyVerticalGrid
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.rememberImagePainter
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import com.owenlejeune.tvtime.R
|
||||
import com.owenlejeune.tvtime.api.tmdb.MoviesService
|
||||
import com.owenlejeune.tvtime.api.tmdb.model.PopularMovie
|
||||
import com.owenlejeune.tvtime.extensions.dpToPx
|
||||
import com.owenlejeune.tvtime.extensions.items
|
||||
import com.owenlejeune.tvtime.ui.components.PosterGrid
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun MoviesTab() {
|
||||
val context = LocalContext.current
|
||||
// val moviesViewModel = viewModel(PopularMovieViewModel::class.java)
|
||||
// val moviesList = moviesViewModel.moviePage
|
||||
// val movieListItems: LazyPagingItems<PopularMovie> = moviesList.collectAsLazyPagingItems()
|
||||
val moviesList = remember { mutableStateOf(emptyList<PopularMovie>()) }
|
||||
PosterGrid { moviesList ->
|
||||
val service = MoviesService()
|
||||
service.getPopularMovies { isSuccessful, response ->
|
||||
if (isSuccessful) {
|
||||
moviesList.value = response!!.movies
|
||||
}
|
||||
}
|
||||
|
||||
LazyVerticalGrid(
|
||||
cells = GridCells.Fixed(count = 3),
|
||||
contentPadding = PaddingValues(8.dp)
|
||||
) {
|
||||
// items(movieListItems) { item ->
|
||||
items(moviesList.value) { item ->
|
||||
val poster = item?.let { i ->
|
||||
"https://image.tmdb.org/t/p/original${i.posterPath}"
|
||||
}
|
||||
Image(
|
||||
painter = rememberImagePainter(
|
||||
data = poster,
|
||||
builder = {
|
||||
transformations(RoundedCornersTransformation(5f.dpToPx(context)))
|
||||
placeholder(R.drawable.placeholder)
|
||||
}
|
||||
),
|
||||
contentDescription = item?.title,
|
||||
modifier = Modifier
|
||||
.size(190.dp)
|
||||
.padding(5.dp)
|
||||
.clickable {
|
||||
Toast.makeText(context, "${item?.title} clicked", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,19 @@
|
||||
package com.owenlejeune.tvtime.ui.screens
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.owenlejeune.tvtime.api.tmdb.TvService
|
||||
import com.owenlejeune.tvtime.ui.components.PosterGrid
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun TvTab() {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.wrapContentSize(Alignment.Center)
|
||||
) {
|
||||
Text(
|
||||
text = "TV Tab",
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
PosterGrid { tvList ->
|
||||
val service = TvService()
|
||||
service.getPopularTv { isSuccessful, response ->
|
||||
if (isSuccessful) {
|
||||
tvList.value = response!!.tv
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user