From 46ca466d36c1c3a16bbcd694ced91ed6372d4786 Mon Sep 17 00:00:00 2001 From: Slee Date: Sun, 11 Feb 2024 12:03:09 -0800 Subject: [PATCH] Add similar items to detail screen --- .../main/java/com/sample/tmdb/ui/TMDbApp.kt | 34 +++++++++-- .../sample/tmdb/common/MainDestinations.kt | 4 +- .../tmdb/common/ui/component/TMDbCard.kt | 58 +++++++++++++++++++ .../sample/tmdb/data/network/MovieService.kt | 9 +++ .../sample/tmdb/data/network/TVShowService.kt | 9 +++ .../data/repository/MovieDetailRepository.kt | 5 ++ .../data/repository/TVShowDetailRepository.kt | 5 ++ .../sample/tmdb/domain/model/DetailWrapper.kt | 5 +- .../domain/repository/BaseDetailRepository.kt | 16 ++++- .../com/sample/tmdb/detail/DetailScreen.kt | 47 ++++++++++++--- .../src/main/res/values/strings.xml | 2 + .../java/com/sample/tmdb/feed/FeedScreen.kt | 51 +++------------- 12 files changed, 185 insertions(+), 60 deletions(-) create mode 100644 common/src/main/java/com/sample/tmdb/common/ui/component/TMDbCard.kt diff --git a/app/src/main/java/com/sample/tmdb/ui/TMDbApp.kt b/app/src/main/java/com/sample/tmdb/ui/TMDbApp.kt index e035167..003bcdf 100644 --- a/app/src/main/java/com/sample/tmdb/ui/TMDbApp.kt +++ b/app/src/main/java/com/sample/tmdb/ui/TMDbApp.kt @@ -90,11 +90,20 @@ fun TMDbApp() { onSearchTVShow = appState::navigateToSearchTVShow, navController = appState.navController ) - detailScreens( + movieDetailScreens( onAllCastSelected = appState::navigateToCastList, onAllCrewSelected = appState::navigateToCrewList, onCreditSelected = appState::navigateToPerson, onImagesSelected = appState::navigateToImages, + onTMDbItemSelected = appState::navigateToMovieDetail, + upPress = appState::upPress + ) + tvShowDetailScreens( + onAllCastSelected = appState::navigateToCastList, + onAllCrewSelected = appState::navigateToCrewList, + onCreditSelected = appState::navigateToPerson, + onImagesSelected = appState::navigateToImages, + onTMDbItemSelected = appState::navigateToTVShowDetail, upPress = appState::upPress ) moviePagingScreens( @@ -192,11 +201,12 @@ private fun NavGraphBuilder.navigationScreens( } } -private fun NavGraphBuilder.detailScreens( +private fun NavGraphBuilder.movieDetailScreens( onAllCastSelected: (String) -> Unit, onAllCrewSelected: (String) -> Unit, onCreditSelected: (String) -> Unit, onImagesSelected: (String, Int) -> Unit, + onTMDbItemSelected: (Int) -> Unit, upPress: () -> Unit ) { composable( @@ -219,8 +229,20 @@ private fun NavGraphBuilder.detailScreens( Uri.encode(gson.toJson(images, object : TypeToken>() {}.type)), index ) + }, onTMDbItemSelected = { + onTMDbItemSelected(it.id) }) } +} + +private fun NavGraphBuilder.tvShowDetailScreens( + onAllCastSelected: (String) -> Unit, + onAllCrewSelected: (String) -> Unit, + onCreditSelected: (String) -> Unit, + onImagesSelected: (String, Int) -> Unit, + onTMDbItemSelected: (Int) -> Unit, + upPress: () -> Unit +) { composable( route = "${MainDestinations.TMDB_TV_SHOW_DETAIL_ROUTE}/{${MainDestinations.TMDB_ID_KEY}}", arguments = listOf( @@ -241,6 +263,8 @@ private fun NavGraphBuilder.detailScreens( Uri.encode(gson.toJson(images, object : TypeToken>() {}.type)), index ) + }, onTMDbItemSelected = { + onTMDbItemSelected(it.id) }) } } @@ -410,10 +434,10 @@ private fun NavGraphBuilder.personScreen( private fun NavGraphBuilder.imagesScreen() { composable( - route = "${MainDestinations.TMDB_IMAGES_ROUTE}/{${MainDestinations.TMDB_IMAGES_KEY}}/{${MainDestinations.TMDB_IMAGE_ID}}", + route = "${MainDestinations.TMDB_IMAGES_ROUTE}/{${MainDestinations.TMDB_IMAGES_KEY}}/{${MainDestinations.TMDB_IMAGE_PAGE}}", arguments = listOf( navArgument(MainDestinations.TMDB_IMAGES_KEY) { type = NavType.StringType }, - navArgument(MainDestinations.TMDB_IMAGE_ID) { type = NavType.IntType } + navArgument(MainDestinations.TMDB_IMAGE_PAGE) { type = NavType.IntType } ) ) { from -> ImagesScreen( @@ -421,7 +445,7 @@ private fun NavGraphBuilder.imagesScreen() { from.arguments?.getString(MainDestinations.TMDB_IMAGES_KEY), object : TypeToken>() {}.type ), - initialPage = from.arguments?.getInt(MainDestinations.TMDB_IMAGE_ID)!! + initialPage = from.arguments?.getInt(MainDestinations.TMDB_IMAGE_PAGE)!! ) } } diff --git a/common/src/main/java/com/sample/tmdb/common/MainDestinations.kt b/common/src/main/java/com/sample/tmdb/common/MainDestinations.kt index 24f6e29..75358cc 100644 --- a/common/src/main/java/com/sample/tmdb/common/MainDestinations.kt +++ b/common/src/main/java/com/sample/tmdb/common/MainDestinations.kt @@ -24,7 +24,7 @@ object MainDestinations { const val TMDB_CREDIT_KEY = "credit_list" const val TMDB_PERSON_ROUTE = "person" const val TMDB_PERSON_KEY = "personId" - const val TMDB_IMAGES_ROUTE = "image" + const val TMDB_IMAGES_ROUTE = "images" const val TMDB_IMAGES_KEY = "imagesKey" - const val TMDB_IMAGE_ID = "imageId" + const val TMDB_IMAGE_PAGE = "imagePage" } \ No newline at end of file diff --git a/common/src/main/java/com/sample/tmdb/common/ui/component/TMDbCard.kt b/common/src/main/java/com/sample/tmdb/common/ui/component/TMDbCard.kt new file mode 100644 index 0000000..4cd0b92 --- /dev/null +++ b/common/src/main/java/com/sample/tmdb/common/ui/component/TMDbCard.kt @@ -0,0 +1,58 @@ +package com.sample.tmdb.common.ui.component + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Card +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import coil.compose.AsyncImage +import com.sample.tmdb.common.model.TMDbItem +import com.sample.tmdb.common.ui.Dimens +import com.sample.tmdb.common.ui.theme.TmdbPagingComposeTheme + +@Composable +fun TMDbCard( + tmdbItem: TMDbItem, + onFeedClick: (TMDbItem) -> Unit, + imageUrl: String? = tmdbItem.posterUrl, + itemWidth: Dp = 120.dp +) { + Card( + modifier = Modifier + .padding(Dimens.PaddingSmall) + .clickable(onClick = { onFeedClick(tmdbItem) }), + shape = RoundedCornerShape(10.dp) + ) { + Column { + AsyncImage( + model = imageUrl, + contentDescription = null, + modifier = Modifier + .size(width = itemWidth, height = 180.dp), + contentScale = ContentScale.Crop + ) + Text( + text = tmdbItem.name, + fontSize = TmdbPagingComposeTheme.fontSizes.sp_11, + color = MaterialTheme.colors.onSurface, + textAlign = TextAlign.Center, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + modifier = Modifier + .size(width = itemWidth, height = 36.dp) + .wrapContentHeight() + ) + } + } +} \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/network/MovieService.kt b/core/data/src/main/java/com/sample/tmdb/data/network/MovieService.kt index dd49235..d91b627 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/network/MovieService.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/network/MovieService.kt @@ -61,4 +61,13 @@ interface MovieService { @GET("3/movie/{movie_id}/images") suspend fun fetchImages(@Path("movie_id") movieId: Int): ImagesResponse + + @GET("3/movie/{movie_id}/similar") + suspend fun fetchSimilarMovies(@Path("movie_id") movieId: Int): TMDbWrapper + + @GET("3/movie/{movie_id}/similar") + suspend fun fetchSimilarMovies( + @Path("movie_id") movieId: Int, + @Query("page") page: Int + ): TMDbWrapper } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/network/TVShowService.kt b/core/data/src/main/java/com/sample/tmdb/data/network/TVShowService.kt index 71413ee..c513303 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/network/TVShowService.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/network/TVShowService.kt @@ -61,4 +61,13 @@ interface TVShowService { @GET("3/tv/{tvId}/images") suspend fun fetchImages(@Path("tvId") tvId: Int): ImagesResponse + + @GET("3/tv/{tvId}/similar") + suspend fun fetchSimilarMovies(@Path("tvId") tvId: Int): TMDbWrapper + + @GET("3/tv/{TvId}/similar") + suspend fun fetchSimilarMovies( + @Path("TvId") tvId: Int, + @Query("page") page: Int + ): TMDbWrapper } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/MovieDetailRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/MovieDetailRepository.kt index ce865b3..e69f3aa 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/MovieDetailRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/MovieDetailRepository.kt @@ -1,11 +1,13 @@ package com.sample.tmdb.data.repository import android.content.Context +import com.sample.tmdb.common.model.TMDbItem import com.sample.tmdb.data.di.IoDispatcher import com.sample.tmdb.data.network.MovieService import com.sample.tmdb.data.response.asCastDomainModel import com.sample.tmdb.data.response.asCrewDomainModel import com.sample.tmdb.data.response.asDomainModel +import com.sample.tmdb.data.response.asMovieDomainModel import com.sample.tmdb.domain.model.Cast import com.sample.tmdb.domain.model.Crew import com.sample.tmdb.domain.model.MovieDetails @@ -36,4 +38,7 @@ class MovieDetailRepository @Inject constructor( override suspend fun getImages(id: Int): List = movieApi.fetchImages(id).asDomainModel() + + override suspend fun getSimilarItems(id: Int): List = + movieApi.fetchSimilarMovies(id).items.asMovieDomainModel() } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/TVShowDetailRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/TVShowDetailRepository.kt index 4f531fd..e5e3abf 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/TVShowDetailRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/TVShowDetailRepository.kt @@ -1,11 +1,13 @@ package com.sample.tmdb.data.repository import android.content.Context +import com.sample.tmdb.common.model.TMDbItem import com.sample.tmdb.data.di.IoDispatcher import com.sample.tmdb.data.network.TVShowService import com.sample.tmdb.data.response.asCastDomainModel import com.sample.tmdb.data.response.asCrewDomainModel import com.sample.tmdb.data.response.asDomainModel +import com.sample.tmdb.data.response.asTVShowDomainModel import com.sample.tmdb.domain.model.Cast import com.sample.tmdb.domain.model.Crew import com.sample.tmdb.domain.model.TMDbImage @@ -36,4 +38,7 @@ class TVShowDetailRepository @Inject constructor( override suspend fun getImages(id: Int): List = tvShowApi.fetchImages(id).asDomainModel() + + override suspend fun getSimilarItems(id: Int): List = + tvShowApi.fetchSimilarMovies(id).items.asTVShowDomainModel() } \ No newline at end of file diff --git a/core/domain/src/main/java/com/sample/tmdb/domain/model/DetailWrapper.kt b/core/domain/src/main/java/com/sample/tmdb/domain/model/DetailWrapper.kt index 4f3ff47..b5ab284 100644 --- a/core/domain/src/main/java/com/sample/tmdb/domain/model/DetailWrapper.kt +++ b/core/domain/src/main/java/com/sample/tmdb/domain/model/DetailWrapper.kt @@ -1,8 +1,11 @@ package com.sample.tmdb.domain.model +import com.sample.tmdb.common.model.TMDbItem + class DetailWrapper( val cast: List, val crew: List, val details: T, - val images: List + val images: List, + val similarItems: List ) \ No newline at end of file diff --git a/core/domain/src/main/java/com/sample/tmdb/domain/repository/BaseDetailRepository.kt b/core/domain/src/main/java/com/sample/tmdb/domain/repository/BaseDetailRepository.kt index f10e769..ecee5d0 100644 --- a/core/domain/src/main/java/com/sample/tmdb/domain/repository/BaseDetailRepository.kt +++ b/core/domain/src/main/java/com/sample/tmdb/domain/repository/BaseDetailRepository.kt @@ -2,6 +2,7 @@ package com.sample.tmdb.domain.repository import android.content.Context import com.sample.tmdb.common.base.BaseRepository +import com.sample.tmdb.common.model.TMDbItem import com.sample.tmdb.domain.model.Cast import com.sample.tmdb.domain.model.Crew import com.sample.tmdb.domain.model.DetailWrapper @@ -23,19 +24,30 @@ abstract class BaseDetailRepository( protected abstract suspend fun getImages(id: Int): List + protected abstract suspend fun getSimilarItems(id: Int): List + override suspend fun getSuccessResult(id: Any?): DetailWrapper { val detailsDeferred: Deferred val creditDeferred: Deferred, List>> val imageDeferred: Deferred> + val similarDeferred: Deferred> coroutineScope { detailsDeferred = async { getDetails(id as Int) } creditDeferred = async { getCredit(id as Int) } - imageDeferred= async { getImages(id as Int) } + imageDeferred = async { getImages(id as Int) } + similarDeferred = async { getSimilarItems(id as Int) } } val details = detailsDeferred.await() val creditWrapper = creditDeferred.await() val images = imageDeferred.await() + val similarItems = similarDeferred.await() - return DetailWrapper(creditWrapper.first, creditWrapper.second, details, images) + return DetailWrapper( + creditWrapper.first, + creditWrapper.second, + details, + images, + similarItems + ) } } \ No newline at end of file diff --git a/features/feature-detail/src/main/java/com/sample/tmdb/detail/DetailScreen.kt b/features/feature-detail/src/main/java/com/sample/tmdb/detail/DetailScreen.kt index aaff68d..5d0124b 100644 --- a/features/feature-detail/src/main/java/com/sample/tmdb/detail/DetailScreen.kt +++ b/features/feature-detail/src/main/java/com/sample/tmdb/detail/DetailScreen.kt @@ -108,6 +108,7 @@ import com.sample.tmdb.common.model.TMDbItem import com.sample.tmdb.common.ui.Content import com.sample.tmdb.common.ui.Dimens import com.sample.tmdb.common.ui.component.PersonCard +import com.sample.tmdb.common.ui.component.TMDbCard import com.sample.tmdb.common.ui.theme.imageTint import com.sample.tmdb.common.utils.dpToPx import com.sample.tmdb.common.utils.toDp @@ -128,6 +129,7 @@ fun MovieDetailScreen( onAllCrewSelected: (List) -> Unit, onCreditSelected: (String) -> Unit, onImagesSelected: (List, Int) -> Unit, + onTMDbItemSelected: (TMDbItem) -> Unit, viewModel: MovieDetailViewModel = hiltViewModel() ) { DetailScreen( @@ -136,7 +138,8 @@ fun MovieDetailScreen( onAllCastSelected = onAllCastSelected, onAllCrewSelected = onAllCrewSelected, onCreditSelected = onCreditSelected, - onImagesSelected = onImagesSelected + onImagesSelected = onImagesSelected, + onTMDbItemSelected = onTMDbItemSelected ) { details -> Movie( id = details.id, @@ -158,6 +161,7 @@ fun TVShowDetailScreen( onAllCrewSelected: (List) -> Unit, onCreditSelected: (String) -> Unit, onImagesSelected: (List, Int) -> Unit, + onTMDbItemSelected: (TMDbItem) -> Unit, viewModel: TVShowDetailViewModel = hiltViewModel() ) { DetailScreen( @@ -166,7 +170,8 @@ fun TVShowDetailScreen( onAllCastSelected = onAllCastSelected, onAllCrewSelected = onAllCrewSelected, onCreditSelected = onCreditSelected, - onImagesSelected = onImagesSelected + onImagesSelected = onImagesSelected, + onTMDbItemSelected = onTMDbItemSelected ) { details -> TVShow( id = details.id, @@ -189,6 +194,7 @@ private fun DetailScreen( onAllCrewSelected: (List) -> Unit, onCreditSelected: (String) -> Unit, onImagesSelected: (List, Int) -> Unit, + onTMDbItemSelected: (TMDbItem) -> Unit, getBookmarkedItem: (T) -> E ) { DetailScreen( @@ -198,6 +204,7 @@ private fun DetailScreen( onAllCrewSelected = onAllCrewSelected, onCreditSelected = onCreditSelected, onImagesSelected = onImagesSelected, + onTMDbItemSelected = onTMDbItemSelected, fab = { isFabVisible, isBookmark, details -> ToggleBookmarkFab(isBookmark = isBookmark, isVisible = isFabVisible) { if (isBookmark) { @@ -221,6 +228,7 @@ fun DetailScreen( onAllCrewSelected: (List) -> Unit, onCreditSelected: (String) -> Unit, onImagesSelected: (List, Int) -> Unit, + onTMDbItemSelected: (TMDbItem) -> Unit, fab: @Composable (MutableState, Boolean, T) -> Unit ) { // Visibility for FAB @@ -267,7 +275,7 @@ fun DetailScreen( .padding(contentPadding) ) { val (appbar, backdrop, poster, title, originalTitle, genres, specs, rateStars, tagline, overview) = createRefs() - val (castSection, crewSection, imagesSection, space) = createRefs() + val (castSection, crewSection, imagesSection, similarSection, space) = createRefs() val startGuideline = createGuidelineFromStart(16.dp) val endGuideline = createGuidelineFromEnd(16.dp) @@ -447,11 +455,25 @@ fun DetailScreen( }, ) + TMDbDetailItemSection( + items = it.similarItems, + headerResId = R.string.similar, + onSeeAllClicked = {}, + itemContent = { item, _ -> + TMDbCard(item, onTMDbItemSelected) + }, + showSize = false, + modifier = Modifier.constrainAs(similarSection) { + top.linkTo(imagesSection.bottom, 16.dp) + linkTo(startGuideline, endGuideline) + }, + ) + Spacer( modifier = Modifier .windowInsetsBottomHeight(WindowInsets.navigationBars) .constrainAs(space) { - top.linkTo(imagesSection.bottom) + top.linkTo(similarSection.bottom) } ) } @@ -649,10 +671,11 @@ private fun TMDbDetailItemSection( @StringRes headerResId: Int, onSeeAllClicked: (List) -> Unit, itemContent: @Composable (T, Int) -> Unit, + showSize: Boolean = true, modifier: Modifier, ) { Column(modifier = modifier.fillMaxWidth()) { - SectionHeader(headerResId, items, onSeeAllClicked) + SectionHeader(headerResId, items, onSeeAllClicked, showSize) LazyRow( modifier = Modifier.testTag(LocalContext.current.getString(headerResId)), contentPadding = PaddingValues(Dimens.PaddingLarge), @@ -672,7 +695,8 @@ private fun TMDbDetailItemSection( private fun SectionHeader( @StringRes headerResId: Int, items: List, - onAllSelected: (List) -> Unit + onAllSelected: (List) -> Unit, + showSize: Boolean ) { Row( horizontalArrangement = Arrangement.SpaceBetween, @@ -695,14 +719,14 @@ private fun SectionHeader( } ) { Text( - text = stringResource(R.string.see_all, items.size), + text = getHeaderText(showSize, items), color = localVibrantColor.current.value, style = MaterialTheme.typography.body2.copy(fontWeight = FontWeight.Bold), modifier = Modifier.padding(end = Dimens.PaddingExtraSmall) ) Icon( Icons.Filled.ArrowForward, - contentDescription = stringResource(R.string.see_all), + contentDescription = getHeaderText(showSize, items), tint = localVibrantColor.current.value, ) } @@ -799,3 +823,10 @@ class BottomArcShape(private val arcHeight: Float) : Shape { return Outline.Generic(path) } } + +@Composable +private fun getHeaderText(showSize: Boolean, items: List) = + if (showSize) stringResource( + R.string.see_all, + items.size + ) else stringResource(R.string.see_all_items) diff --git a/features/feature-detail/src/main/res/values/strings.xml b/features/feature-detail/src/main/res/values/strings.xml index 0e0d02e..9b845a8 100644 --- a/features/feature-detail/src/main/res/values/strings.xml +++ b/features/feature-detail/src/main/res/values/strings.xml @@ -3,6 +3,7 @@ Release Date Vote Avg Votes + See All See All(%1$d) Cast Crew @@ -10,4 +11,5 @@ Favorite Un-favorite Images + Similar \ No newline at end of file diff --git a/features/feature-feed/src/main/java/com/sample/tmdb/feed/FeedScreen.kt b/features/feature-feed/src/main/java/com/sample/tmdb/feed/FeedScreen.kt index 0bdb49c..fddc5e8 100644 --- a/features/feature-feed/src/main/java/com/sample/tmdb/feed/FeedScreen.kt +++ b/features/feature-feed/src/main/java/com/sample/tmdb/feed/FeedScreen.kt @@ -11,37 +11,30 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.add import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.layout.windowInsetsTopHeight -import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Card import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController -import coil.compose.AsyncImage import com.sample.tmdb.common.MainDestinations import com.sample.tmdb.common.model.TMDbItem import com.sample.tmdb.common.ui.Content import com.sample.tmdb.common.ui.Dimens import com.sample.tmdb.common.ui.component.DestinationBar +import com.sample.tmdb.common.ui.component.TMDbCard import com.sample.tmdb.common.ui.theme.TmdbPagingComposeTheme import com.sample.tmdb.domain.model.FeedWrapper import com.sample.tmdb.domain.model.Movie @@ -86,7 +79,7 @@ private inline fun FeedScreen( viewModel: BaseFeedViewModel, navController: NavController, noinline onSearchClicked: () -> Unit, - crossinline onClick: (TMDbItem) -> Unit, + noinline onClick: (TMDbItem) -> Unit, @StringRes resourceId: Int ) { @@ -106,7 +99,7 @@ private inline fun FeedScreen( private inline fun FeedCollectionList( navController: NavController, collection: List>, - crossinline onFeedClick: (TMDbItem) -> Unit + noinline onFeedClick: (TMDbItem) -> Unit ) { LazyColumn { item { @@ -131,7 +124,7 @@ private inline fun FeedCollectionList( private inline fun FeedCollection( navController: NavController, feedCollection: FeedWrapper, - crossinline onFeedClick: (TMDbItem) -> Unit, + noinline onFeedClick: (TMDbItem) -> Unit, index: Int, modifier: Modifier = Modifier, ) { @@ -222,9 +215,9 @@ private inline fun FeedCollection( } @Composable -private inline fun Feeds( +private fun Feeds( feeds: List, - crossinline onFeedClick: (TMDbItem) -> Unit, + onFeedClick: (TMDbItem) -> Unit, index: Int, modifier: Modifier = Modifier ) { @@ -239,9 +232,9 @@ private inline fun Feeds( } @Composable -private inline fun TMDbItem( +private fun TMDbItem( tmdbItem: T, - crossinline onFeedClick: (TMDbItem) -> Unit, + onFeedClick: (TMDbItem) -> Unit, index: Int ) { val itemWidth: Dp @@ -253,33 +246,7 @@ private inline fun TMDbItem( itemWidth = 120.dp imageUrl = tmdbItem.posterUrl } - Card( - modifier = Modifier - .padding(Dimens.PaddingSmall) - .clickable(onClick = { onFeedClick(tmdbItem) }), - shape = RoundedCornerShape(10.dp) - ) { - Column { - AsyncImage( - model = imageUrl, - contentDescription = null, - modifier = Modifier - .size(width = itemWidth, height = 180.dp), - contentScale = ContentScale.Crop - ) - Text( - text = tmdbItem.name, - fontSize = TmdbPagingComposeTheme.fontSizes.sp_11, - color = MaterialTheme.colors.onSurface, - textAlign = TextAlign.Center, - maxLines = 2, - overflow = TextOverflow.Ellipsis, - modifier = Modifier - .size(width = itemWidth, height = 36.dp) - .wrapContentHeight() - ) - } - } + TMDbCard(tmdbItem, onFeedClick, imageUrl, itemWidth) } @Preview("default")