mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-23 04:00:53 -05:00
show poster on details screen
This commit is contained in:
@@ -65,6 +65,7 @@ dependencies {
|
|||||||
implementation "com.google.accompanist:accompanist-systemuicontroller:${Versions.compose_accompanist}"
|
implementation "com.google.accompanist:accompanist-systemuicontroller:${Versions.compose_accompanist}"
|
||||||
implementation "androidx.navigation:navigation-compose:${Versions.compose_navigation}"
|
implementation "androidx.navigation:navigation-compose:${Versions.compose_navigation}"
|
||||||
implementation "androidx.paging:paging-compose:${Versions.compose_paging}"
|
implementation "androidx.paging:paging-compose:${Versions.compose_paging}"
|
||||||
|
implementation "androidx.constraintlayout:constraintlayout-compose:${Versions.compose_constraint_layout}"
|
||||||
|
|
||||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:${Versions.lifecycle_runtime}"
|
implementation "androidx.lifecycle:lifecycle-runtime-ktx:${Versions.lifecycle_runtime}"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.owenlejeune.tvtime.api.tmdb
|
||||||
|
|
||||||
|
import com.owenlejeune.tvtime.api.tmdb.model.DetailedItem
|
||||||
|
import retrofit2.Response
|
||||||
|
|
||||||
|
interface DetailService {
|
||||||
|
|
||||||
|
suspend fun getById(id: Int): Response<DetailedItem>
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package com.owenlejeune.tvtime.api.tmdb
|
package com.owenlejeune.tvtime.api.tmdb
|
||||||
|
|
||||||
|
import com.owenlejeune.tvtime.api.tmdb.model.DetailedMovie
|
||||||
|
import com.owenlejeune.tvtime.api.tmdb.model.PopularMovie
|
||||||
import com.owenlejeune.tvtime.api.tmdb.model.PopularMoviesResponse
|
import com.owenlejeune.tvtime.api.tmdb.model.PopularMoviesResponse
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Path
|
||||||
import retrofit2.http.Query
|
import retrofit2.http.Query
|
||||||
|
|
||||||
interface MoviesApi {
|
interface MoviesApi {
|
||||||
@@ -10,4 +13,7 @@ interface MoviesApi {
|
|||||||
@GET("movie/popular")
|
@GET("movie/popular")
|
||||||
suspend fun getPopularMovies(@Query("page") page: Int = 1): Response<PopularMoviesResponse>
|
suspend fun getPopularMovies(@Query("page") page: Int = 1): Response<PopularMoviesResponse>
|
||||||
|
|
||||||
|
@GET("movie/{id}")
|
||||||
|
suspend fun getMovieById(@Path("id") id: Int): Response<DetailedMovie>
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
package com.owenlejeune.tvtime.api.tmdb
|
package com.owenlejeune.tvtime.api.tmdb
|
||||||
|
|
||||||
|
import com.owenlejeune.tvtime.api.tmdb.model.DetailedItem
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
|
import retrofit2.Response
|
||||||
|
|
||||||
class MoviesService: KoinComponent {
|
class MoviesService: KoinComponent, DetailService {
|
||||||
|
|
||||||
private val service by lazy { TmdbClient().createMovieService() }
|
private val service by lazy { TmdbClient().createMovieService() }
|
||||||
|
|
||||||
suspend fun getPopularMovies(page: Int = 1) = service.getPopularMovies(page)
|
suspend fun getPopularMovies(page: Int = 1) = service.getPopularMovies(page)
|
||||||
|
|
||||||
|
override suspend fun getById(id: Int): Response<DetailedItem> = service.getMovieById(id) as Response<DetailedItem>
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.owenlejeune.tvtime.api.tmdb
|
package com.owenlejeune.tvtime.api.tmdb
|
||||||
|
|
||||||
import com.owenlejeune.tvtime.api.tmdb.model.MediaItem
|
import com.owenlejeune.tvtime.api.tmdb.model.TmdbItem
|
||||||
|
|
||||||
object TmdbUtils {
|
object TmdbUtils {
|
||||||
|
|
||||||
@@ -8,8 +8,8 @@ object TmdbUtils {
|
|||||||
return "https://image.tmdb.org/t/p/original${posterPath}"
|
return "https://image.tmdb.org/t/p/original${posterPath}"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFullPosterPath(mediaItem: MediaItem): String {
|
fun getFullPosterPath(tmdbItem: TmdbItem): String {
|
||||||
return getFullPosterPath(mediaItem.posterPath)
|
return getFullPosterPath(tmdbItem.posterPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.owenlejeune.tvtime.api.tmdb
|
package com.owenlejeune.tvtime.api.tmdb
|
||||||
|
|
||||||
import com.owenlejeune.tvtime.api.tmdb.model.PopularTvResponse
|
import com.owenlejeune.tvtime.api.tmdb.model.PopularTvResponse
|
||||||
|
import com.owenlejeune.tvtime.api.tmdb.model.DetailedTv
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Path
|
||||||
import retrofit2.http.Query
|
import retrofit2.http.Query
|
||||||
|
|
||||||
interface TvApi {
|
interface TvApi {
|
||||||
@@ -10,4 +12,7 @@ interface TvApi {
|
|||||||
@GET("tv/popular")
|
@GET("tv/popular")
|
||||||
suspend fun getPoplarTv(@Query("page") page: Int = 1): Response<PopularTvResponse>
|
suspend fun getPoplarTv(@Query("page") page: Int = 1): Response<PopularTvResponse>
|
||||||
|
|
||||||
|
@GET("tv/{id}")
|
||||||
|
suspend fun getTvShowById(@Path("id") id: Int): Response<DetailedTv>
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,16 @@
|
|||||||
package com.owenlejeune.tvtime.api.tmdb
|
package com.owenlejeune.tvtime.api.tmdb
|
||||||
|
|
||||||
|
import com.owenlejeune.tvtime.api.tmdb.model.DetailedItem
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
|
import retrofit2.Response
|
||||||
|
|
||||||
class TvService: KoinComponent {
|
class TvService: KoinComponent, DetailService {
|
||||||
|
|
||||||
private val service by lazy { TmdbClient().createTvService() }
|
private val service by lazy { TmdbClient().createTvService() }
|
||||||
|
|
||||||
suspend fun getPopularTv(page: Int = 1) = service.getPoplarTv(page)
|
suspend fun getPopularTv(page: Int = 1) = service.getPoplarTv(page)
|
||||||
|
|
||||||
|
override suspend fun getById(id: Int): Response<DetailedItem> {
|
||||||
|
return service.getTvShowById(id) as Response<DetailedItem>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package com.owenlejeune.tvtime.api.tmdb.model
|
||||||
|
|
||||||
|
abstract class DetailedItem(id: Int, title: String, posterPath: String?): TmdbItem(id, title, posterPath)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.owenlejeune.tvtime.api.tmdb.model
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
class DetailedMovie(
|
||||||
|
@SerializedName("id") override val id: Int,
|
||||||
|
@SerializedName("origina_title") override val title: String,
|
||||||
|
@SerializedName("poster_path") override val posterPath: String?
|
||||||
|
): DetailedItem(id, title, posterPath)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.owenlejeune.tvtime.api.tmdb.model
|
||||||
|
|
||||||
|
import com.owenlejeune.tvtime.api.tmdb.model.DetailedItem
|
||||||
|
|
||||||
|
class DetailedTv(
|
||||||
|
id: Int,
|
||||||
|
title: String,
|
||||||
|
posterPath: String?
|
||||||
|
): DetailedItem(id, title, posterPath)
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package com.owenlejeune.tvtime.api.tmdb.model
|
|
||||||
|
|
||||||
abstract class MediaItem(
|
|
||||||
open val posterPath: String?,
|
|
||||||
@Transient open val title: String,
|
|
||||||
@Transient open val id: Int
|
|
||||||
)
|
|
||||||
@@ -3,7 +3,7 @@ package com.owenlejeune.tvtime.api.tmdb.model
|
|||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
data class PopularMovie(
|
data class PopularMovie(
|
||||||
@SerializedName("poster_path") override val posterPath: String?,
|
@SerializedName("id") override val id: Int,
|
||||||
@SerializedName("title") override val title: String,
|
@SerializedName("title") override val title: String,
|
||||||
@SerializedName("id") override val id: Int
|
@SerializedName("poster_path") override val posterPath: String?
|
||||||
): MediaItem(posterPath, title, id)
|
): TmdbItem(id, title, posterPath)
|
||||||
@@ -3,7 +3,7 @@ package com.owenlejeune.tvtime.api.tmdb.model
|
|||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
data class PopularTv(
|
data class PopularTv(
|
||||||
@SerializedName("poster_path") override val posterPath: String?,
|
@SerializedName("id") override val id: Int,
|
||||||
@SerializedName("name") val name: String,
|
@SerializedName("name") override val title: String,
|
||||||
@SerializedName("id") override val id: Int
|
@SerializedName("poster_path") override val posterPath: String?
|
||||||
): MediaItem(posterPath, name, id)
|
): TmdbItem(id, title, posterPath)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.owenlejeune.tvtime.api.tmdb.model
|
||||||
|
|
||||||
|
abstract class TmdbItem(
|
||||||
|
@Transient open val id: Int,
|
||||||
|
@Transient open val title: String,
|
||||||
|
@Transient open val posterPath: String?
|
||||||
|
)
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.owenlejeune.tvtime.ui.components
|
package com.owenlejeune.tvtime.ui.components
|
||||||
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
@@ -15,25 +14,29 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import coil.compose.rememberImagePainter
|
import coil.compose.rememberImagePainter
|
||||||
import coil.transform.RoundedCornersTransformation
|
import coil.transform.RoundedCornersTransformation
|
||||||
import com.owenlejeune.tvtime.R
|
import com.owenlejeune.tvtime.R
|
||||||
import com.owenlejeune.tvtime.api.tmdb.TmdbUtils
|
import com.owenlejeune.tvtime.api.tmdb.TmdbUtils
|
||||||
import com.owenlejeune.tvtime.api.tmdb.model.MediaItem
|
import com.owenlejeune.tvtime.api.tmdb.model.TmdbItem
|
||||||
import com.owenlejeune.tvtime.extensions.dpToPx
|
import com.owenlejeune.tvtime.extensions.dpToPx
|
||||||
import com.owenlejeune.tvtime.extensions.listItems
|
import com.owenlejeune.tvtime.extensions.listItems
|
||||||
import com.owenlejeune.tvtime.ui.navigation.MainNavItem
|
import com.owenlejeune.tvtime.ui.navigation.MainNavItem
|
||||||
|
import com.owenlejeune.tvtime.ui.screens.DetailViewType
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun PosterGrid(
|
fun PosterGrid(
|
||||||
appNavController: NavController,
|
appNavController: NavController,
|
||||||
fetchMedia: (MutableState<List<MediaItem>>) -> Unit
|
type: DetailViewType,
|
||||||
|
fetchMedia: (MutableState<List<TmdbItem>>) -> Unit
|
||||||
) {
|
) {
|
||||||
val mediaList = remember { mutableStateOf(emptyList<MediaItem>()) }
|
val mediaList = remember { mutableStateOf(emptyList<TmdbItem>()) }
|
||||||
fetchMedia(mediaList)
|
fetchMedia(mediaList)
|
||||||
|
|
||||||
LazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
@@ -41,36 +44,50 @@ fun PosterGrid(
|
|||||||
contentPadding = PaddingValues(8.dp)
|
contentPadding = PaddingValues(8.dp)
|
||||||
) {
|
) {
|
||||||
listItems(mediaList.value) { item ->
|
listItems(mediaList.value) { item ->
|
||||||
PosterItem(appNavController = appNavController, mediaItem = item)
|
PosterItem(
|
||||||
|
appNavController = appNavController,
|
||||||
|
mediaItem = item,
|
||||||
|
type = type
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PosterItem(
|
fun PosterItem(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
appNavController: NavController,
|
appNavController: NavController,
|
||||||
mediaItem: MediaItem
|
mediaItem: TmdbItem?,
|
||||||
|
type: DetailViewType? = null,
|
||||||
|
width: Dp = 127.dp,
|
||||||
|
height: Dp = 190.dp
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val poster = TmdbUtils.getFullPosterPath(mediaItem)
|
val poster = mediaItem?.let { TmdbUtils.getFullPosterPath(mediaItem) }
|
||||||
Image(
|
Image(
|
||||||
painter = rememberImagePainter(
|
painter = if (mediaItem != null) {
|
||||||
|
rememberImagePainter(
|
||||||
data = poster,
|
data = poster,
|
||||||
builder = {
|
builder = {
|
||||||
transformations(RoundedCornersTransformation(5f.dpToPx(context)))
|
transformations(RoundedCornersTransformation(5f.dpToPx(context)))
|
||||||
placeholder(R.drawable.placeholder)
|
placeholder(R.drawable.placeholder)
|
||||||
}
|
}
|
||||||
),
|
)
|
||||||
contentDescription = mediaItem.title,
|
} else {
|
||||||
modifier = Modifier
|
rememberImagePainter(ContextCompat.getDrawable(context, R.drawable.placeholder))
|
||||||
.size(190.dp)
|
},
|
||||||
|
contentDescription = mediaItem?.title,
|
||||||
|
modifier = modifier
|
||||||
|
.size(width = width, height = height)
|
||||||
.padding(5.dp)
|
.padding(5.dp)
|
||||||
.clickable {
|
.clickable {
|
||||||
appNavController.navigate("${MainNavItem.DetailView.route}/${mediaItem.id}")
|
type?.let {
|
||||||
// appNavController.n
|
mediaItem?.let {
|
||||||
// Toast
|
appNavController.navigate(
|
||||||
// .makeText(context, "${mediaItem.title} clicked", Toast.LENGTH_SHORT)
|
"${MainNavItem.DetailView.route}/${type}/${mediaItem.id}"
|
||||||
// .show()
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -6,9 +6,6 @@ import androidx.compose.animation.core.animateFloatAsState
|
|||||||
import androidx.compose.foundation.*
|
import androidx.compose.foundation.*
|
||||||
import androidx.compose.foundation.gestures.detectTapGestures
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.GridCells
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.LazyVerticalGrid
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.Card
|
import androidx.compose.material.Card
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
@@ -26,20 +23,12 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.draw.scale
|
import androidx.compose.ui.draw.scale
|
||||||
import androidx.compose.ui.geometry.CornerRadius
|
import androidx.compose.ui.geometry.CornerRadius
|
||||||
import androidx.compose.ui.geometry.Offset
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import coil.compose.rememberImagePainter
|
|
||||||
import coil.transform.RoundedCornersTransformation
|
|
||||||
import com.owenlejeune.tvtime.R
|
|
||||||
import com.owenlejeune.tvtime.api.tmdb.TmdbUtils
|
|
||||||
import com.owenlejeune.tvtime.api.tmdb.model.MediaItem
|
|
||||||
import com.owenlejeune.tvtime.extensions.dpToPx
|
|
||||||
import com.owenlejeune.tvtime.extensions.listItems
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TopLevelSwitch(
|
fun TopLevelSwitch(
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import androidx.navigation.NavType
|
|||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.navArgument
|
import androidx.navigation.navArgument
|
||||||
import com.owenlejeune.tvtime.ui.screens.*
|
import com.owenlejeune.tvtime.ui.screens.DetailView
|
||||||
|
import com.owenlejeune.tvtime.ui.screens.DetailViewType
|
||||||
|
import com.owenlejeune.tvtime.ui.screens.MainAppView
|
||||||
import com.owenlejeune.tvtime.ui.screens.tabs.FavouritesTab
|
import com.owenlejeune.tvtime.ui.screens.tabs.FavouritesTab
|
||||||
import com.owenlejeune.tvtime.ui.screens.tabs.MoviesTab
|
import com.owenlejeune.tvtime.ui.screens.tabs.MoviesTab
|
||||||
import com.owenlejeune.tvtime.ui.screens.tabs.SettingsTab
|
import com.owenlejeune.tvtime.ui.screens.tabs.SettingsTab
|
||||||
@@ -20,13 +22,17 @@ fun MainNavigationRoutes(navController: NavHostController) {
|
|||||||
MainAppView(appNavController = navController)
|
MainAppView(appNavController = navController)
|
||||||
}
|
}
|
||||||
composable(
|
composable(
|
||||||
MainNavItem.DetailView.route.plus("/{ID_KEY}"),
|
MainNavItem.DetailView.route.plus("/{TYPE_KEY}/{ID_KEY}"),
|
||||||
arguments = listOf(navArgument("ID_KEY") { type = NavType.IntType })
|
arguments = listOf(
|
||||||
|
navArgument("ID_KEY") { type = NavType.IntType },
|
||||||
|
navArgument("TYPE_KEY") { type = NavType.EnumType(DetailViewType::class.java) }
|
||||||
|
)
|
||||||
) { navBackStackEntry ->
|
) { navBackStackEntry ->
|
||||||
val args = navBackStackEntry.arguments
|
val args = navBackStackEntry.arguments
|
||||||
DetailView(
|
DetailView(
|
||||||
appNavController = navController,
|
appNavController = navController,
|
||||||
itemId = navBackStackEntry.arguments?.getInt("ID_KEY")
|
itemId = args?.getInt("ID_KEY"),
|
||||||
|
type = args?.getSerializable("TYPE_KEY") as DetailViewType
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,71 @@
|
|||||||
package com.owenlejeune.tvtime.ui.screens
|
package com.owenlejeune.tvtime.ui.screens
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
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.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.runtime.MutableState
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.constraintlayout.compose.ConstraintLayout
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import com.owenlejeune.tvtime.api.tmdb.DetailService
|
||||||
|
import com.owenlejeune.tvtime.api.tmdb.MoviesService
|
||||||
|
import com.owenlejeune.tvtime.api.tmdb.TvService
|
||||||
|
import com.owenlejeune.tvtime.api.tmdb.model.DetailedItem
|
||||||
|
import com.owenlejeune.tvtime.ui.components.PosterItem
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DetailView(
|
fun DetailView(
|
||||||
appNavController: NavController,
|
appNavController: NavController,
|
||||||
itemId: Int?
|
itemId: Int?,
|
||||||
|
type: DetailViewType
|
||||||
) {
|
) {
|
||||||
Column(
|
val mediaItem = remember { mutableStateOf<DetailedItem?>(null) }
|
||||||
|
val service = when(type) {
|
||||||
|
DetailViewType.MOVIE -> MoviesService()
|
||||||
|
DetailViewType.TV -> TvService()
|
||||||
|
}
|
||||||
|
itemId?.let {
|
||||||
|
fetchMediaItem(itemId, service, mediaItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstraintLayout(
|
||||||
|
modifier = Modifier.fillMaxSize()
|
||||||
|
) {
|
||||||
|
val (
|
||||||
|
posterImage,
|
||||||
|
title
|
||||||
|
) = createRefs()
|
||||||
|
|
||||||
|
PosterItem(
|
||||||
|
appNavController = appNavController,
|
||||||
|
mediaItem = mediaItem.value,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.constrainAs(posterImage) {
|
||||||
.wrapContentSize(Alignment.Center)
|
top.linkTo(parent.top, margin = 16.dp)
|
||||||
) {
|
start.linkTo(parent.start, margin = 16.dp)
|
||||||
Text(
|
}
|
||||||
text = itemId.toString(),
|
|
||||||
color = MaterialTheme.colorScheme.onBackground
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun fetchMediaItem(id: Int, service: DetailService, mediaItem: MutableState<DetailedItem?>) {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
val response = service.getById(id)
|
||||||
|
if (response.isSuccessful) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
mediaItem.value = response.body()!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class DetailViewType {
|
||||||
|
MOVIE,
|
||||||
|
TV
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.owenlejeune.tvtime.api.tmdb.MoviesService
|
import com.owenlejeune.tvtime.api.tmdb.MoviesService
|
||||||
import com.owenlejeune.tvtime.ui.components.PosterGrid
|
import com.owenlejeune.tvtime.ui.components.PosterGrid
|
||||||
|
import com.owenlejeune.tvtime.ui.screens.DetailViewType
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -16,7 +17,7 @@ fun MoviesTab(appNavController: NavController) {
|
|||||||
// val moviesViewModel = viewModel(PopularMovieViewModel::class.java)
|
// val moviesViewModel = viewModel(PopularMovieViewModel::class.java)
|
||||||
// val moviesList = moviesViewModel.moviePage
|
// val moviesList = moviesViewModel.moviePage
|
||||||
// val movieListItems: LazyPagingItems<PopularMovie> = moviesList.collectAsLazyPagingItems()
|
// val movieListItems: LazyPagingItems<PopularMovie> = moviesList.collectAsLazyPagingItems()
|
||||||
PosterGrid(appNavController = appNavController) { moviesList ->
|
PosterGrid(appNavController = appNavController, type = DetailViewType.MOVIE) { moviesList ->
|
||||||
val service = MoviesService()
|
val service = MoviesService()
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val response = service.getPopularMovies()
|
val response = service.getPopularMovies()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.owenlejeune.tvtime.api.tmdb.TvService
|
import com.owenlejeune.tvtime.api.tmdb.TvService
|
||||||
import com.owenlejeune.tvtime.ui.components.PosterGrid
|
import com.owenlejeune.tvtime.ui.components.PosterGrid
|
||||||
|
import com.owenlejeune.tvtime.ui.screens.DetailViewType
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -13,7 +14,7 @@ import kotlinx.coroutines.withContext
|
|||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun TvTab(appNavController: NavController) {
|
fun TvTab(appNavController: NavController) {
|
||||||
PosterGrid(appNavController = appNavController) { tvList ->
|
PosterGrid(appNavController = appNavController, type = DetailViewType.TV) { tvList ->
|
||||||
val service = TvService()
|
val service = TvService()
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val response = service.getPopularTv()
|
val response = service.getPopularTv()
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ object Versions {
|
|||||||
const val compose_accompanist = "0.22.1-rc"
|
const val compose_accompanist = "0.22.1-rc"
|
||||||
const val compose_navigation = "2.4.0"
|
const val compose_navigation = "2.4.0"
|
||||||
const val compose_paging = "1.0.0-alpha14"
|
const val compose_paging = "1.0.0-alpha14"
|
||||||
|
const val compose_constraint_layout = "1.0.0"
|
||||||
const val gradle = "7.1.0"
|
const val gradle = "7.1.0"
|
||||||
const val junit = "4.13.2"
|
const val junit = "4.13.2"
|
||||||
const val androidx_junit = "1.1.3"
|
const val androidx_junit = "1.1.3"
|
||||||
|
|||||||
Reference in New Issue
Block a user