diff --git a/app/src/main/java/com/london/app/navigation/graph/mainNavGraph.kt b/app/src/main/java/com/london/app/navigation/graph/mainNavGraph.kt index 0afeb4169..83c4f22fc 100644 --- a/app/src/main/java/com/london/app/navigation/graph/mainNavGraph.kt +++ b/app/src/main/java/com/london/app/navigation/graph/mainNavGraph.kt @@ -266,22 +266,22 @@ private fun NavGraphBuilder.trendingNavGraph(navController: NavHostController) = composable { TrendingMoviesScreen( - onNavigateToMovieDetailsClick = ::navigateToMovieDetails, - onNavigateBackClick = ::navigateUp + onNavigateToMovieDetails = ::navigateToMovieDetails, + onNavigateBack = ::navigateUp ) } composable { TrendingTvShowsScreen( - onNavigateToTvShowDetailsClick = ::navigateToTvShowDetails, + onNavigateToTvShowDetails = ::navigateToTvShowDetails, onNavigateBack = ::navigateUp ) } composable { TrendingActorsScreen( - onNavigateToActorDetailsClick = ::navigateToActorDetails, - onNavigateBackClick = ::navigateUp + onNavigateToActorDetails = ::navigateToActorDetails, + onNavigateBack = ::navigateUp ) } diff --git a/designSystem/src/main/java/com/london/designsystem/component/TopBar.kt b/designSystem/src/main/java/com/london/designsystem/component/TopBar.kt index 445b7ec04..8e3f1c690 100644 --- a/designSystem/src/main/java/com/london/designsystem/component/TopBar.kt +++ b/designSystem/src/main/java/com/london/designsystem/component/TopBar.kt @@ -118,7 +118,7 @@ private fun ButtonTopBar( @Composable @ThemePreviews -private fun TopBarPreview() { +private fun Preview() { TopBar( onClickOption1 = {}, onClickOption2 = {} diff --git a/presentation/src/main/java/com/london/presentation/feature/account/AccountScreen.kt b/presentation/src/main/java/com/london/presentation/feature/account/AccountScreen.kt index 62172e728..e67a9282e 100644 --- a/presentation/src/main/java/com/london/presentation/feature/account/AccountScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/account/AccountScreen.kt @@ -69,9 +69,11 @@ private fun Content( Box( modifier = Modifier.fillMaxSize() - ){ + ) { BackgroundGradient( - modifier = Modifier.align(Alignment.TopStart).zIndex(1f) + modifier = Modifier + .align(Alignment.TopStart) + .zIndex(1f) ) Column(Modifier.navBarBottomPadding()) { diff --git a/presentation/src/main/java/com/london/presentation/feature/account/rating/MyRatingScreen.kt b/presentation/src/main/java/com/london/presentation/feature/account/rating/MyRatingScreen.kt index 9fe9d0272..8faeb8833 100644 --- a/presentation/src/main/java/com/london/presentation/feature/account/rating/MyRatingScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/account/rating/MyRatingScreen.kt @@ -31,6 +31,7 @@ import com.london.presentation.shared.base.ErrorState import com.london.presentation.shared.buildscreen.BuildScreen import com.london.presentation.shared.container.MediaLazyVerticalGrid import com.london.presentation.utils.Listen +import com.london.presentation.utils.detailsTopBar import com.london.presentation.utils.toLocalizedNumbers import com.london.designsystem.R as dsR @@ -92,11 +93,10 @@ private fun Content( Column( modifier = Modifier.fillMaxSize() + ) { TopBar( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 12.dp), + modifier = Modifier.detailsTopBar(1f), title = stringResource(R.string.my_rating), onBackClick = contract::onBackClick ) @@ -104,7 +104,7 @@ private fun Content( RatingChipsRow( selected = selectedCategory, onSelect = contract::onRatingCategorySelected, - modifier = Modifier.padding(bottom = 12.dp) + modifier = Modifier.padding(vertical = 12.dp) ) if (items.isEmpty()) { @@ -117,10 +117,8 @@ private fun Content( items = items, imageUrl = { it.posterPath }, name = { it.title }, - rate = { rated -> rated.rating.toLocalizedNumbers() }, hasSaveIcon = false, - isItemSaved = { false }, - onSaveClick = {}, + rate = { rated -> rated.rating.toLocalizedNumbers() }, onDeleteClick = { rated -> when (rated.mediaType) { MediaType.Movie -> contract.onDeleteMovieClick(rated.id) diff --git a/presentation/src/main/java/com/london/presentation/feature/authentication/login/LoginScreen.kt b/presentation/src/main/java/com/london/presentation/feature/authentication/login/LoginScreen.kt index bf73b42d9..41f44b304 100644 --- a/presentation/src/main/java/com/london/presentation/feature/authentication/login/LoginScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/authentication/login/LoginScreen.kt @@ -89,7 +89,9 @@ private fun Content( ) { BackgroundGradient( - modifier = Modifier.align(Alignment.TopStart).zIndex(1f) + modifier = Modifier + .align(Alignment.TopStart) + .zIndex(1f) ) Image( diff --git a/presentation/src/main/java/com/london/presentation/feature/category/main/CategoriesScreen.kt b/presentation/src/main/java/com/london/presentation/feature/category/main/CategoriesScreen.kt index 172116865..8ccd45409 100644 --- a/presentation/src/main/java/com/london/presentation/feature/category/main/CategoriesScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/category/main/CategoriesScreen.kt @@ -71,9 +71,11 @@ private fun Content( Box( modifier = Modifier.fillMaxSize() - ){ + ) { BackgroundGradient( - modifier = Modifier.align(Alignment.TopStart).zIndex(1f) + modifier = Modifier + .align(Alignment.TopStart) + .zIndex(1f) ) Column(Modifier.navBarBottomPadding()) { diff --git a/presentation/src/main/java/com/london/presentation/feature/category/movie/MovieCategoryContract.kt b/presentation/src/main/java/com/london/presentation/feature/category/movie/MovieCategoryContract.kt index c005e8d48..dd8fe624e 100644 --- a/presentation/src/main/java/com/london/presentation/feature/category/movie/MovieCategoryContract.kt +++ b/presentation/src/main/java/com/london/presentation/feature/category/movie/MovieCategoryContract.kt @@ -1,8 +1,8 @@ package com.london.presentation.feature.category.movie interface MovieCategoryContract { - fun onBack() + fun onBackClick() fun onMovieClick(movieId: Int) fun onBookmarkSheetDismiss() - fun onManageBookmarkClicked(movieId: Int) + fun onManageBookmarkClick(movieId: Int) } diff --git a/presentation/src/main/java/com/london/presentation/feature/category/movie/MovieCategoryScreen.kt b/presentation/src/main/java/com/london/presentation/feature/category/movie/MovieCategoryScreen.kt index b8830f1a0..e5c160e0e 100644 --- a/presentation/src/main/java/com/london/presentation/feature/category/movie/MovieCategoryScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/category/movie/MovieCategoryScreen.kt @@ -1,7 +1,6 @@ package com.london.presentation.feature.category.movie import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding @@ -21,10 +20,11 @@ import com.london.designsystem.component.TopBar import com.london.designsystem.theme.ThemePreviews import com.london.presentation.R import com.london.presentation.shared.BackgroundGradient -import com.london.presentation.shared.MediaLazyPagingGrid import com.london.presentation.shared.bookmarkSheet.BookmarkBottomSheet import com.london.presentation.shared.buildscreen.BuildScreen +import com.london.presentation.shared.container.MediaLazyVerticalGrid import com.london.presentation.utils.Listen +import com.london.presentation.utils.detailsTopBar import com.london.presentation.utils.isLoading @Composable @@ -58,55 +58,50 @@ private fun Content( ) { val moviesLazyList = state.moviesFlow.collectAsLazyPagingItems() + BuildScreen( - onBack = contract::onBack, + onBack = contract::onBackClick, isLoading = moviesLazyList.isLoading(), isError = moviesLazyList.loadState.refresh is LoadState.Error, onRetry = moviesLazyList::refresh, emptyLayoutMessage = R.string.there_is_no_items_for_this_genre, emptyLayoutImage = R.drawable.empty ) { - Box( modifier = Modifier.fillMaxSize() - ){ + ) { BackgroundGradient( - modifier = Modifier.align(Alignment.TopStart).zIndex(1f) + modifier = Modifier + .align(Alignment.TopStart) + .zIndex(1f) ) - Column( - modifier = Modifier - .fillMaxSize() - .padding(top = 12.dp) - ) { - TopBar( - title = stringResource( - state.genre.stringResId - ), - onBackClick = contract::onBack, - modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 12.dp) - ) + MediaLazyVerticalGrid( + pagingItems = moviesLazyList, + imageUrl = { it.posterUrl }, + name = { it.name }, + hasSaveIcon = true, + onSaveClick = { contract.onManageBookmarkClick(it.id) }, + isItemSaved = { false }, + onNavigateToMovie = { id -> contract.onMovieClick(id) }, + topBar = { + TopBar( + modifier = Modifier + .detailsTopBar(1f) + .padding(bottom = 12.dp), + title = stringResource(state.genre.stringResId), + onBackClick = contract::onBackClick + ) + }, + modifier = Modifier.fillMaxWidth() + ) - MediaLazyPagingGrid( - pagingFlow = moviesLazyList, - onItemClick = { contract.onMovieClick(it.id) }, - getImageUrl = { it.posterUrl }, - getTitle = { "${it.name} movie img" }, - modifier = Modifier - .weight(1f) - .fillMaxWidth() - .padding(horizontal = 16.dp), - onSaveClick = { contract.onManageBookmarkClicked(it.id) }, - isItemSaved = { false }, - hasSaveIcon = true - ) + BookmarkBottomSheet( + onSheetDismiss = contract::onBookmarkSheetDismiss, + isSheetVisible = state.isBookmarkSheetVisible, + bookmarkedMovieId = state.bookmarkedMovieId + ) - BookmarkBottomSheet( - onSheetDismiss = contract::onBookmarkSheetDismiss, - isSheetVisible = state.isBookmarkSheetVisible, - bookmarkedMovieId = state.bookmarkedMovieId - ) - } } } } @@ -119,8 +114,8 @@ private fun MoviesByCategoryContentPreview() { contract = object : MovieCategoryContract { override fun onMovieClick(movieId: Int) {} override fun onBookmarkSheetDismiss() {} - override fun onManageBookmarkClicked(movieId: Int) {} - override fun onBack() {} + override fun onManageBookmarkClick(movieId: Int) {} + override fun onBackClick() {} }, ) } diff --git a/presentation/src/main/java/com/london/presentation/feature/category/movie/MovieCategoryViewModel.kt b/presentation/src/main/java/com/london/presentation/feature/category/movie/MovieCategoryViewModel.kt index dde1f28a7..b112be57e 100644 --- a/presentation/src/main/java/com/london/presentation/feature/category/movie/MovieCategoryViewModel.kt +++ b/presentation/src/main/java/com/london/presentation/feature/category/movie/MovieCategoryViewModel.kt @@ -33,10 +33,10 @@ class MovieCategoryViewModel @Inject constructor( override fun onMovieClick(movieId: Int) = emitEffect(MovieCategoryEffect.MovieDetailsNavigation(movieId = movieId)) - override fun onBack() = + override fun onBackClick() = emitEffect(MovieCategoryEffect.BackNavigation) - override fun onManageBookmarkClicked(movieId: Int) { + override fun onManageBookmarkClick(movieId: Int) { updateState { copy( isBookmarkSheetVisible = true, diff --git a/presentation/src/main/java/com/london/presentation/feature/category/tvshow/TvShowCategoryContract.kt b/presentation/src/main/java/com/london/presentation/feature/category/tvshow/TvShowCategoryContract.kt index aa63e5d21..b9b2ae301 100644 --- a/presentation/src/main/java/com/london/presentation/feature/category/tvshow/TvShowCategoryContract.kt +++ b/presentation/src/main/java/com/london/presentation/feature/category/tvshow/TvShowCategoryContract.kt @@ -1,7 +1,7 @@ package com.london.presentation.feature.category.tvshow interface TvShowCategoryContract { - fun onBack() + fun onBackClick() fun onSavedClick(tvShowId: Int) fun onTvShowClick(tvShowId: Int) } diff --git a/presentation/src/main/java/com/london/presentation/feature/category/tvshow/TvShowCategoryScreen.kt b/presentation/src/main/java/com/london/presentation/feature/category/tvshow/TvShowCategoryScreen.kt index be9e9a9ef..7738eb358 100644 --- a/presentation/src/main/java/com/london/presentation/feature/category/tvshow/TvShowCategoryScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/category/tvshow/TvShowCategoryScreen.kt @@ -1,7 +1,6 @@ package com.london.presentation.feature.category.tvshow import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding @@ -21,9 +20,10 @@ import com.london.designsystem.component.TopBar import com.london.designsystem.theme.ThemePreviews import com.london.presentation.R import com.london.presentation.shared.BackgroundGradient -import com.london.presentation.shared.MediaLazyPagingGrid import com.london.presentation.shared.buildscreen.BuildScreen +import com.london.presentation.shared.container.MediaLazyVerticalGrid import com.london.presentation.utils.Listen +import com.london.presentation.utils.detailsTopBar import com.london.presentation.utils.isLoading @Composable @@ -58,47 +58,39 @@ private fun Content( val tvShowLazyList = state.tvShowFlow.collectAsLazyPagingItems() BuildScreen( - onBack = contract::onBack, + onBack = contract::onBackClick, isLoading = tvShowLazyList.isLoading(), isError = tvShowLazyList.loadState.refresh is LoadState.Error, onRetry = tvShowLazyList::refresh, emptyLayoutMessage = R.string.there_is_no_items_for_this_genre, emptyLayoutImage = R.drawable.empty ) { - Box( modifier = Modifier.fillMaxSize() - ){ + ) { BackgroundGradient( - modifier = Modifier.align(Alignment.TopStart).zIndex(1f) - ) - - Column( modifier = Modifier - .fillMaxSize() - .padding(top = 12.dp) - ) { - TopBar( - title = stringResource( - state.genre.stringResId - ), - onBackClick = contract::onBack, - modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 12.dp) - ) + .align(Alignment.TopStart) + .zIndex(1f) + ) - MediaLazyPagingGrid( - pagingFlow = tvShowLazyList, - onItemClick = { contract.onTvShowClick(it.id) }, - getImageUrl = { it.posterPicture }, - getTitle = { "${it.name} tv show img" }, - modifier = Modifier - .weight(1f) - .fillMaxWidth() - .padding(horizontal = 16.dp), - onSaveClick = { /* TODO: Implement save functionality */ }, - isItemSaved = { false }, - ) - } + MediaLazyVerticalGrid( + pagingItems = tvShowLazyList, + imageUrl = { it.posterPicture }, + name = { it.name }, + hasSaveIcon = false, + onNavigateToTvShow = { id -> contract.onTvShowClick(id) }, + topBar = { + TopBar( + modifier = Modifier + .detailsTopBar(1f) + .padding(bottom = 12.dp), + title = stringResource(state.genre.stringResId), + onBackClick = contract::onBackClick + ) + }, + modifier = Modifier.fillMaxWidth() + ) } } } @@ -112,7 +104,7 @@ private fun Preview() { contract = object : TvShowCategoryContract { override fun onSavedClick(tvShowId: Int) {} override fun onTvShowClick(tvShowId: Int) {} - override fun onBack() {} + override fun onBackClick() {} } ) } diff --git a/presentation/src/main/java/com/london/presentation/feature/category/tvshow/TvShowCategoryViewModel.kt b/presentation/src/main/java/com/london/presentation/feature/category/tvshow/TvShowCategoryViewModel.kt index 8a7ca8cdc..a2c9700e5 100644 --- a/presentation/src/main/java/com/london/presentation/feature/category/tvshow/TvShowCategoryViewModel.kt +++ b/presentation/src/main/java/com/london/presentation/feature/category/tvshow/TvShowCategoryViewModel.kt @@ -33,7 +33,7 @@ class TvShowCategoryViewModel @Inject constructor( override fun onTvShowClick(tvShowId: Int) = emitEffect(TvShowCategoryEffect.TvShowDetailsNavigation(tvShowId = tvShowId)) - override fun onBack() = + override fun onBackClick() = emitEffect(TvShowCategoryEffect.BackNavigation) override fun onSavedClick(tvShowId: Int) = Unit //TODO("Save Tv Show Not yet implemented") diff --git a/presentation/src/main/java/com/london/presentation/feature/details/actor/ActorDetailsScreen.kt b/presentation/src/main/java/com/london/presentation/feature/details/actor/ActorDetailsScreen.kt index 22b79ed31..949869c06 100644 --- a/presentation/src/main/java/com/london/presentation/feature/details/actor/ActorDetailsScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/details/actor/ActorDetailsScreen.kt @@ -127,7 +127,9 @@ private fun Content( ) { BackgroundGradient( - modifier = Modifier.align(Alignment.TopStart).zIndex(1f) + modifier = Modifier + .align(Alignment.TopStart) + .zIndex(1f) ) EmptyScreen(uiState) @@ -336,7 +338,6 @@ private fun TopTvShowsPicksList( imageUrl = tvShow[index].posterUrl, isSaved = false, hasSaveIcon = false, - onSaveClick = {}, modifier = Modifier.clickable { onNavigateToTvShowPicks(tvShow[index].id) } diff --git a/presentation/src/main/java/com/london/presentation/feature/details/actor/info/gallery/ActorsGalleryScreen.kt b/presentation/src/main/java/com/london/presentation/feature/details/actor/info/gallery/ActorsGalleryScreen.kt index 9b0dc1742..f4fc8579a 100644 --- a/presentation/src/main/java/com/london/presentation/feature/details/actor/info/gallery/ActorsGalleryScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/details/actor/info/gallery/ActorsGalleryScreen.kt @@ -45,51 +45,53 @@ fun ActorsGalleryScreen( effect.Listen { onNavigateBack() } - BuildScreen( - onBack = viewModel::onBackClick, - isLoading = uiState.isLoading, - isError = uiState.error != null, - onRetry = viewModel::onRetryClick - ) { - Content( - uiState = uiState, - actorsGalleryContract = viewModel - ) - } + Content( + uiState = uiState, + contract = viewModel + ) } @Composable private fun Content( uiState: ActorsGalleryUiState, - actorsGalleryContract: ActorsGalleryContract + contract: ActorsGalleryContract ) { - - Box( - modifier = Modifier.fillMaxSize() - ){ - - BackgroundGradient( - modifier = Modifier.fillMaxSize().align(Alignment.TopStart).zIndex(1f) - ) - - Column( - modifier = Modifier - .fillMaxSize() - .background(NovixTheme.colors.surface) - .navigationBarsPadding() - .padding(horizontal = 16.dp, vertical = 12.dp), + BuildScreen( + onBack = contract::onBackClick, + isLoading = uiState.isLoading, + isError = uiState.error != null, + onRetry = contract::onRetryClick + ) { + Box( + modifier = Modifier.fillMaxSize() ) { - TopBar( - modifier = Modifier.padding(bottom = 16.dp), - title = stringResource(R.string.gallery), - onBackClick = actorsGalleryContract::onBackClick + + BackgroundGradient( + modifier = Modifier + .fillMaxSize() + .align(Alignment.TopStart) + .zIndex(1f) ) - Box(modifier = Modifier.weight(1f)) { - if (uiState.isLoading) { - CircularLoading(modifier = Modifier.align(Alignment.Center)) - } else { - GalleryContent(uiState = uiState) + Column( + modifier = Modifier + .fillMaxSize() + .background(NovixTheme.colors.surface) + .navigationBarsPadding() + .padding(horizontal = 16.dp, vertical = 12.dp), + ) { + TopBar( + modifier = Modifier.padding(bottom = 16.dp), + title = stringResource(R.string.gallery), + onBackClick = contract::onBackClick + ) + + Box(modifier = Modifier.weight(1f)) { + if (uiState.isLoading) { + CircularLoading(modifier = Modifier.align(Alignment.Center)) + } else { + GalleryContent(uiState = uiState) + } } } } diff --git a/presentation/src/main/java/com/london/presentation/feature/details/actor/info/topmoviespicks/TopMoviesPicksScreen.kt b/presentation/src/main/java/com/london/presentation/feature/details/actor/info/topmoviespicks/TopMoviesPicksScreen.kt index 4df70e698..9a77121ca 100644 --- a/presentation/src/main/java/com/london/presentation/feature/details/actor/info/topmoviespicks/TopMoviesPicksScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/details/actor/info/topmoviespicks/TopMoviesPicksScreen.kt @@ -2,22 +2,26 @@ package com.london.presentation.feature.details.actor.info.topmoviespicks import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.london.designsystem.component.TopBar import com.london.presentation.R import com.london.presentation.shared.BackgroundGradient -import com.london.presentation.shared.MediaLazyGrid import com.london.presentation.shared.base.ErrorState import com.london.presentation.shared.bookmarkSheet.BookmarkBottomSheet import com.london.presentation.shared.buildscreen.BuildScreen +import com.london.presentation.shared.container.MediaLazyVerticalGrid import com.london.presentation.utils.Listen +import com.london.presentation.utils.detailsTopBar @Composable fun TopMoviesPicksScreen( @@ -53,22 +57,30 @@ private fun Content( isError = state.errorState is ErrorState.NoInternet, onRetry = contract::onRetryClick, ) { - Box( modifier = Modifier.fillMaxSize() - ){ + ) { BackgroundGradient( - modifier = Modifier.align(Alignment.TopStart).zIndex(1f) + modifier = Modifier + .align(Alignment.TopStart) + .zIndex(1f) ) - MediaLazyGrid( - title = stringResource(R.string.top_movies_picks), + MediaLazyVerticalGrid( items = state.movieDetails.mediaItems, - onBack = contract::onBackClick, - getImageUrl = { it.posterUrl }, + imageUrl = { it.posterUrl }, + hasSaveIcon = true, onItemClick = { contract.onMovieClick(it.id) }, - onSavedClick = { contract.onManageBookmarkClicked(it.id) }, - hasSaveIcon = true + onSaveClick = { contract.onManageBookmarkClicked(it.id) }, + topBar = { + TopBar( + modifier = Modifier + .detailsTopBar(1f) + .padding(bottom = 12.dp), + title = stringResource(R.string.top_movies_picks), + onBackClick = contract::onBackClick + ) + } ) BookmarkBottomSheet( diff --git a/presentation/src/main/java/com/london/presentation/feature/details/actor/info/toptvshowspicks/TopTvShowsPicksScreen.kt b/presentation/src/main/java/com/london/presentation/feature/details/actor/info/toptvshowspicks/TopTvShowsPicksScreen.kt index f9fe372a5..226b42681 100644 --- a/presentation/src/main/java/com/london/presentation/feature/details/actor/info/toptvshowspicks/TopTvShowsPicksScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/details/actor/info/toptvshowspicks/TopTvShowsPicksScreen.kt @@ -2,21 +2,25 @@ package com.london.presentation.feature.details.actor.info.toptvshowspicks import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.london.designsystem.component.TopBar import com.london.presentation.R import com.london.presentation.shared.BackgroundGradient -import com.london.presentation.shared.MediaLazyGrid import com.london.presentation.shared.base.ErrorState import com.london.presentation.shared.buildscreen.BuildScreen +import com.london.presentation.shared.container.MediaLazyVerticalGrid import com.london.presentation.utils.Listen +import com.london.presentation.utils.detailsTopBar @Composable fun TopTvShowsPicksScreen( @@ -51,20 +55,28 @@ private fun Content( isError = state.errorState is ErrorState.NoInternet, onRetry = contract::onRetryClick ) { - Box( modifier = Modifier.fillMaxSize() - ){ + ) { BackgroundGradient( - modifier = Modifier.align(Alignment.TopStart).zIndex(1f) + modifier = Modifier + .align(Alignment.TopStart) + .zIndex(1f) ) - - MediaLazyGrid( - title = stringResource(R.string.top_tv_shows_picks), + MediaLazyVerticalGrid( items = state.tvShowDetails.mediaItems, - onBack = contract::onBackClick, - getImageUrl = { it.posterUrl }, - onItemClick = { contract.onTvShowClick(it.id) } + imageUrl = { it.posterUrl }, + onItemClick = { contract.onTvShowClick(it.id) }, + hasSaveIcon = false, + topBar = { + TopBar( + modifier = Modifier + .detailsTopBar(1f) + .padding(bottom = 12.dp), + title = stringResource(R.string.top_tv_shows_picks), + onBackClick = contract::onBackClick, + ) + } ) } } diff --git a/presentation/src/main/java/com/london/presentation/feature/details/movie/MovieDetailsScreen.kt b/presentation/src/main/java/com/london/presentation/feature/details/movie/MovieDetailsScreen.kt index 74eee1b64..de2cf1818 100644 --- a/presentation/src/main/java/com/london/presentation/feature/details/movie/MovieDetailsScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/details/movie/MovieDetailsScreen.kt @@ -161,7 +161,10 @@ private fun Content( ) { BackgroundGradient( - modifier = Modifier.fillMaxSize().align(Alignment.TopStart).zIndex(2f) + modifier = Modifier + .fillMaxSize() + .align(Alignment.TopStart) + .zIndex(2f) ) TopBar( @@ -313,14 +316,14 @@ private fun HomeLazyVerticalGrid( if (uiState.actors.isNotEmpty()) { item(span = { GridItemSpan(maxLineSpan) }) { Text( - text = stringResource(com.london.presentation.R.string.cast), + text = stringResource(R.string.cast), style = NovixTheme.typography.title.medium, - color = NovixTheme.colors.title, + color = NovixTheme.colors.title ) LazyHorizontalGrid( modifier = Modifier - .padding(top = 16.dp) + .padding(top = 25.dp) .requiredWidth(screenWidthDp) .height(100.dp), rows = GridCells.Fixed(1), diff --git a/presentation/src/main/java/com/london/presentation/feature/details/tvshow/info/TvShowDetailScreen.kt b/presentation/src/main/java/com/london/presentation/feature/details/tvshow/info/TvShowDetailScreen.kt index add6b0464..314ad5005 100644 --- a/presentation/src/main/java/com/london/presentation/feature/details/tvshow/info/TvShowDetailScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/details/tvshow/info/TvShowDetailScreen.kt @@ -171,7 +171,10 @@ private fun Content( ) BackgroundGradient( - modifier = Modifier.fillMaxSize().align(Alignment.TopStart).zIndex(1f) + modifier = Modifier + .fillMaxSize() + .align(Alignment.TopStart) + .zIndex(1f) ) LazyColumn( @@ -215,79 +218,85 @@ private fun Content( ) } - // Overview title - item { - Text( - text = stringResource(R.string.overview), - style = NovixTheme.typography.title.medium, - color = NovixTheme.colors.title, - modifier = Modifier.padding(top = 16.dp, start = 16.dp, end = 16.dp) - ) - } - - // Overview content - item { - var isExpanded by remember { mutableStateOf(false) } - ConditionalText( - text = uiState.overview, - expandedState = isExpanded, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp) - ) { - isExpanded = !isExpanded - } - } - item { - CastSection( - modifier = Modifier.padding(top = 16.dp), - castMembers = uiState.cast?.cast ?: emptyList(), - onNavigateToCast = tvShowDetailsContract::onCastClicked - ) - } - item { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - ) { + if (uiState.overview.isNotBlank()) { + item { Text( - text = stringResource(R.string.season), + text = stringResource(R.string.overview), style = NovixTheme.typography.title.medium, color = NovixTheme.colors.title, - modifier = Modifier.padding(top = 16.dp, bottom = 12.dp) - ) - - SeasonEpisodesDetails( - modifier = Modifier.fillMaxWidth(), - uiState = uiState + modifier = Modifier.padding(top = 16.dp, start = 16.dp, end = 16.dp) ) + } - Text( - text = "${ - uiState.tvShowEpisodeCountBySeason?.episodes?.size.toString() - .toLocalizedNumbers() - } ${stringResource(R.string.episodes)}", - style = NovixTheme.typography.label.small, - color = NovixTheme.colors.hint, - modifier = Modifier.padding(top = 8.dp, bottom = 12.dp) + item { + var isExpanded by remember { mutableStateOf(false) } + ConditionalText( + text = uiState.overview, + expandedState = isExpanded, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp) + ) { + isExpanded = !isExpanded + } + } + } + if (uiState.cast?.cast?.isNotEmpty() == true) { + item { + CastSection( + modifier = Modifier.padding(top = 16.dp), + castMembers = uiState.cast.cast, + onNavigateToCast = tvShowDetailsContract::onCastClicked ) } } - items( - items = uiState.tvShowEpisodes, - key = { episode -> "${episode.showId}_${episode.seasonNumber}_${episode.episodeNumber}" } - ) { episode -> - EpisodeItem( - episodes = episode, - onEpisodeClick = { - tvShowDetailsContract.onEpisodeClicked( - episode.showId, - episode.episodeNumber, - episode.seasonNumber, + if (uiState.tvShowEpisodes.isNotEmpty() && uiState.numberOfSeasons > 0) { + item { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + ) { + Text( + text = stringResource(R.string.season), + style = NovixTheme.typography.title.medium, + color = NovixTheme.colors.title, + modifier = Modifier.padding(top = 16.dp, bottom = 12.dp) ) - }, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp) - ) + + SeasonEpisodesDetails( + modifier = Modifier.fillMaxWidth(), + uiState = uiState + ) + + uiState.tvShowEpisodeCountBySeason?.episodes?.size?.let { episodeCount -> + if (episodeCount > 0) { + Text( + text = "${episodeCount.toLocalizedNumbers()} ${stringResource(R.string.episodes)}", + style = NovixTheme.typography.label.small, + color = NovixTheme.colors.hint, + modifier = Modifier.padding(top = 8.dp, bottom = 12.dp) + ) + } + } + } + } + + items( + items = uiState.tvShowEpisodes, + key = { episode -> "${episode.showId}_${episode.seasonNumber}_${episode.episodeNumber}" } + ) { episode -> + EpisodeItem( + episodes = episode, + onEpisodeClick = { + tvShowDetailsContract.onEpisodeClicked( + episode.showId, + episode.episodeNumber, + episode.seasonNumber, + ) + }, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp) + ) + } } } @@ -433,8 +442,9 @@ private fun TvShowBasicDetails( } TvShowDate(date) - - Seasons(numberOfSeasons) + if (numberOfSeasons != 0) { + Seasons(numberOfSeasons) + } } } diff --git a/presentation/src/main/java/com/london/presentation/feature/home/continuewatching/ContinueWatchingScreen.kt b/presentation/src/main/java/com/london/presentation/feature/home/continuewatching/ContinueWatchingScreen.kt index 1e1387713..05806cd0b 100644 --- a/presentation/src/main/java/com/london/presentation/feature/home/continuewatching/ContinueWatchingScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/home/continuewatching/ContinueWatchingScreen.kt @@ -4,20 +4,23 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.london.designsystem.component.TopBar import com.london.designsystem.theme.NovixTheme import com.london.domain.entity.movie.Movie import com.london.presentation.R import com.london.presentation.shared.BackgroundGradient -import com.london.presentation.shared.DefaultAppTopBar import com.london.presentation.shared.MediaCategory import com.london.presentation.shared.base.ErrorState import com.london.presentation.shared.bookmarkSheet.BookmarkBottomSheet @@ -25,6 +28,7 @@ import com.london.presentation.shared.buildscreen.BuildScreen import com.london.presentation.shared.container.MediaGridConfig import com.london.presentation.shared.container.MediaLazyGridWithTabs import com.london.presentation.utils.Listen +import com.london.presentation.utils.detailsTopBar @Composable fun ContinueWatchingScreen( @@ -70,13 +74,14 @@ private fun Content( contract: ContinueWatchingContract, screenTitle: String = stringResource(R.string.continue_watch) ) { - Box( modifier = Modifier.fillMaxSize() - ){ + ) { BackgroundGradient( - modifier = Modifier.align(Alignment.TopStart).zIndex(1f) + modifier = Modifier + .align(Alignment.TopStart) + .zIndex(1f) ) Column( @@ -100,13 +105,13 @@ private fun Content( onNavigateToMovie = contract::onNavigateToMovieClick, onNavigateToTvShow = contract::onNavigateToTvShowClick, onSaveClick = { if (it is Movie) contract.onManageBookmarkClicked(it.id) }, - isItemSaved = { false }, - rate = null + isItemSaved = { false } ), topBar = { - DefaultAppTopBar( + TopBar( + modifier = Modifier.detailsTopBar(1f), title = screenTitle, - onBack = contract::onBackClick + onBackClick = contract::onBackClick ) }, isLoading = state.isLoading diff --git a/presentation/src/main/java/com/london/presentation/feature/home/trending/actor/TrendingActorsScreen.kt b/presentation/src/main/java/com/london/presentation/feature/home/trending/actor/TrendingActorsScreen.kt index a7548ddf8..e3f7b5c30 100644 --- a/presentation/src/main/java/com/london/presentation/feature/home/trending/actor/TrendingActorsScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/home/trending/actor/TrendingActorsScreen.kt @@ -4,10 +4,10 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -24,16 +24,17 @@ import androidx.paging.compose.collectAsLazyPagingItems import com.london.designsystem.component.TopBar import com.london.designsystem.theme.NovixTheme import com.london.presentation.R -import com.london.presentation.shared.ActorItem import com.london.presentation.shared.BackgroundGradient -import com.london.presentation.shared.LazyPagingColumn import com.london.presentation.shared.buildscreen.BuildScreen +import com.london.presentation.shared.container.ActorLazyVerticalColumn import com.london.presentation.utils.Listen +import com.london.presentation.utils.detailsTopBar +import com.london.presentation.utils.isLoading @Composable fun TrendingActorsScreen( - onNavigateBackClick: () -> Unit, - onNavigateToActorDetailsClick: (Int) -> Unit, + onNavigateBack: () -> Unit, + onNavigateToActorDetails: (Int) -> Unit, viewModel: TrendingActorsViewModel = hiltViewModel() ) { val state by viewModel.state.collectAsStateWithLifecycle() @@ -41,29 +42,18 @@ fun TrendingActorsScreen( effect?.Listen { currentEffect -> when (currentEffect) { - is TrendingActorsEffect.ActorDetailsNavigation -> onNavigateToActorDetailsClick( + is TrendingActorsEffect.ActorDetailsNavigation -> onNavigateToActorDetails( currentEffect.actorId ) - is TrendingActorsEffect.BackNavigation -> onNavigateBackClick() + is TrendingActorsEffect.BackNavigation -> onNavigateBack() } } - val actorsLazyItems = state.actorsFlow.collectAsLazyPagingItems() - - BuildScreen( - isLoading = state.isLoading, - isError = actorsLazyItems.loadState.refresh is LoadState.Error, - onBack = viewModel::onBackClick, - onRetry = viewModel::onRetryClick, - emptyLayoutMessage = R.string.no_trending_actors_in_genre, - emptyLayoutImage = R.drawable.img_no_result, - ) { - Content( - state = state, - contract = viewModel, - ) - } + Content( + state = state, + contract = viewModel + ) } @Composable @@ -71,51 +61,40 @@ private fun Content( state: TrendingActorsUiState, contract: TrendingActorsContract, ) { + val actorsLazyItems = state.actorsFlow.collectAsLazyPagingItems() - Box( - modifier = Modifier.fillMaxSize() + BuildScreen( + isLoading = actorsLazyItems.isLoading(), + isError = actorsLazyItems.loadState.refresh is LoadState.Error, + onBack = contract::onBackClick, + onRetry = contract::onRetryClick, + emptyLayoutMessage = R.string.no_trending_actors_in_genre, + emptyLayoutImage = R.drawable.img_no_result, + pagingFlow = actorsLazyItems ) { - BackgroundGradient( - modifier = Modifier - .align(Alignment.TopStart) - .zIndex(1f) - ) - - Column ( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 16.dp) + Box( + modifier = Modifier.fillMaxSize() ) { - TopBar( - title = stringResource(R.string.trending_people), - onBackClick = contract::onBackClick, + BackgroundGradient( modifier = Modifier - .fillMaxWidth() - .background(NovixTheme.colors.surface) - .padding(vertical = 12.dp) + .align(Alignment.TopStart) + .zIndex(1f) ) - - LazyColumn( + Column( modifier = Modifier .fillMaxSize() - .background(color = NovixTheme.colors.surface), - contentPadding = PaddingValues(bottom = 24.dp) + .background(color = NovixTheme.colors.surface) ) { - - item { - LazyPagingColumn( - pagingItems = state.actorsFlow.collectAsLazyPagingItems(), - modifier = Modifier.fillMaxSize(), - itemContent = { actor -> - ActorItem( - actorName = actor.name, - characterName = null, - imageRes = actor.profilePictureUrl, - onClick = { contract.onActorClick(actor.id) } - ) - } + TopBar( + title = stringResource(R.string.trending_people), + onBackClick = contract::onBackClick, + modifier = Modifier.detailsTopBar(1f), ) - } + + ActorLazyVerticalColumn( + items = actorsLazyItems, + onActorClick = { contract.onActorClick(it.id) } + ) } } } @@ -126,6 +105,10 @@ private fun Content( private fun Preview() = NovixTheme { Content( state = TrendingActorsUiState(), - contract = defaultTrendingActorsContract() + contract = object : TrendingActorsContract { + override fun onActorClick(id: Int) {} + override fun onBackClick() {} + override fun onRetryClick() {} + } ) } diff --git a/presentation/src/main/java/com/london/presentation/feature/home/trending/movie/TrendingMoviesScreen.kt b/presentation/src/main/java/com/london/presentation/feature/home/trending/movie/TrendingMoviesScreen.kt index cb2902d90..b17a82b50 100644 --- a/presentation/src/main/java/com/london/presentation/feature/home/trending/movie/TrendingMoviesScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/home/trending/movie/TrendingMoviesScreen.kt @@ -19,6 +19,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.paging.LoadState import androidx.paging.compose.collectAsLazyPagingItems import com.london.designsystem.component.TopBar @@ -26,42 +27,35 @@ import com.london.designsystem.theme.NovixTheme import com.london.presentation.R import com.london.presentation.shared.BackgroundGradient import com.london.presentation.shared.GenresSection -import com.london.presentation.shared.MediaLazyPagingGrid import com.london.presentation.shared.bookmarkSheet.BookmarkBottomSheet import com.london.presentation.shared.buildscreen.BuildScreen +import com.london.presentation.shared.container.MediaLazyVerticalGrid import com.london.presentation.utils.Listen +import com.london.presentation.utils.detailsTopBar @Composable fun TrendingMoviesScreen( - onNavigateBackClick: () -> Unit, - onNavigateToMovieDetailsClick: (Int) -> Unit, + onNavigateBack: () -> Unit, + onNavigateToMovieDetails: (Int) -> Unit, viewModel: TrendingMoviesViewModel = hiltViewModel() ) { - val state by viewModel.state.collectAsState() + val state by viewModel.state.collectAsStateWithLifecycle() val effect by viewModel.effect.collectAsState(null) effect?.Listen { currentEffect -> when (currentEffect) { - is TrendingMoviesEffect.MovieDetailsNavigation -> onNavigateToMovieDetailsClick( + is TrendingMoviesEffect.MovieDetailsNavigation -> onNavigateToMovieDetails( currentEffect.movieId ) - is TrendingMoviesEffect.BackNavigation -> onNavigateBackClick() + is TrendingMoviesEffect.BackNavigation -> onNavigateBack() } } - BuildScreen( - isLoading = state.isLoading, - isError = state.moviesFlow.collectAsLazyPagingItems().loadState.refresh is LoadState.Error, - onBack = viewModel::onBackClick, - onRetry = viewModel::onRetryClick, - emptyLayoutMessage = R.string.no_trending_movies_in_genre, - emptyLayoutImage = R.drawable.img_no_result, - ) { - Content( - state = state, - contract = viewModel - ) - } + Content( + state = state, + contract = viewModel + ) + } @Composable @@ -71,54 +65,60 @@ private fun Content( ) { val screenWidth = with(LocalDensity.current) { LocalConfiguration.current.screenWidthDp.dp } - Box( - modifier = Modifier.fillMaxSize() + BuildScreen( + isLoading = state.isLoading, + isError = state.moviesFlow.collectAsLazyPagingItems().loadState.refresh is LoadState.Error, + onBack = contract::onBackClick, + onRetry = contract::onRetryClick, + emptyLayoutMessage = R.string.no_trending_movies_in_genre, + emptyLayoutImage = R.drawable.img_no_result, ) { - BackgroundGradient( - modifier = Modifier - .align(Alignment.TopStart) - .zIndex(1f) - ) - Column( - modifier = Modifier - .fillMaxSize() - .background(NovixTheme.colors.surface) + Box( + modifier = Modifier.fillMaxSize() ) { - TopBar( + BackgroundGradient( modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 12.dp), - title = stringResource(R.string.trending_movies), - onBackClick = contract::onBackClick - ) - GenresSection( - genres = state.movieGenres, - selectedGenre = state.selectedGenre, - screenWidth = screenWidth, - onGenreClick = contract::onGenreClick, - modifier = Modifier.padding(bottom = 12.dp), - getGenreName = { stringResource(it.stringResId) } + .align(Alignment.TopStart) + .zIndex(1f) ) - - MediaLazyPagingGrid( - pagingFlow = state.moviesFlow.collectAsLazyPagingItems(), - onItemClick = { contract.onMovieClick(it.id) }, - getImageUrl = { it.posterPath }, - getTitle = { it.title }, + Column( modifier = Modifier - .weight(1f) - .fillMaxWidth() - .padding(horizontal = 16.dp), - onSaveClick = { contract.onManageBookmarkClicked(it.id) }, - hasSaveIcon = true, - contentPadding = PaddingValues(bottom = 24.dp) - ) + .fillMaxSize() + .background(NovixTheme.colors.surface) + ) { - BookmarkBottomSheet( - onSheetDismiss = contract::onBookmarkSheetDismiss, - isSheetVisible = state.isBookmarkSheetVisible, - bookmarkedMovieId = state.bookmarkedMovieId - ) + TopBar( + modifier = Modifier.detailsTopBar(1f), + title = stringResource(R.string.trending_movies), + onBackClick = contract::onBackClick + ) + GenresSection( + genres = state.movieGenres, + selectedGenre = state.selectedGenre, + screenWidth = screenWidth, + onGenreClick = contract::onGenreClick, + modifier = Modifier.padding(vertical = 12.dp), + getGenreName = { stringResource(it.stringResId) } + ) + + MediaLazyVerticalGrid( + pagingItems = state.moviesFlow.collectAsLazyPagingItems(), + imageUrl = { it.posterPath }, + name = { it.title }, + hasSaveIcon = true, + onSaveClick = { contract.onManageBookmarkClicked(it.id) }, + onItemClick = { item -> contract.onMovieClick(item.id) }, + modifier = Modifier + .weight(1f) + .fillMaxWidth() + ) + + BookmarkBottomSheet( + onSheetDismiss = contract::onBookmarkSheetDismiss, + isSheetVisible = state.isBookmarkSheetVisible, + bookmarkedMovieId = state.bookmarkedMovieId + ) + } } } } diff --git a/presentation/src/main/java/com/london/presentation/feature/home/trending/tvshow/TrendingTvShowsScreen.kt b/presentation/src/main/java/com/london/presentation/feature/home/trending/tvshow/TrendingTvShowsScreen.kt index db4064a69..f1cb8598a 100644 --- a/presentation/src/main/java/com/london/presentation/feature/home/trending/tvshow/TrendingTvShowsScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/home/trending/tvshow/TrendingTvShowsScreen.kt @@ -3,7 +3,6 @@ package com.london.presentation.feature.home.trending.tvshow import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding @@ -27,14 +26,15 @@ import com.london.designsystem.theme.NovixTheme import com.london.presentation.R import com.london.presentation.shared.BackgroundGradient import com.london.presentation.shared.GenresSection -import com.london.presentation.shared.MediaLazyPagingGrid import com.london.presentation.shared.buildscreen.BuildScreen +import com.london.presentation.shared.container.MediaLazyVerticalGrid import com.london.presentation.utils.Listen +import com.london.presentation.utils.detailsTopBar @Composable fun TrendingTvShowsScreen( onNavigateBack: () -> Unit, - onNavigateToTvShowDetailsClick: (Int) -> Unit, + onNavigateToTvShowDetails: (Int) -> Unit, viewModel: TrendingTvShowsViewModel = hiltViewModel() ) { val state by viewModel.state.collectAsStateWithLifecycle() @@ -42,26 +42,18 @@ fun TrendingTvShowsScreen( effect?.Listen { currentEffect -> when (currentEffect) { - is TrendingTvShowsEffect.TvShowDetailsNavigation -> onNavigateToTvShowDetailsClick( + is TrendingTvShowsEffect.TvShowDetailsNavigation -> onNavigateToTvShowDetails( currentEffect.tvShowId ) is TrendingTvShowsEffect.BackNavigation -> onNavigateBack() } } + Content( + state = state, + contract = viewModel, + ) - BuildScreen( - isLoading = state.isLoading, - isError = state.tvShowsFlow.collectAsLazyPagingItems().loadState.refresh is LoadState.Error, - onBack = viewModel::onBackClick, - emptyLayoutMessage = R.string.no_trending_shows_in_genre, - emptyLayoutImage = R.drawable.img_no_result, - ) { - Content( - state = state, - contract = viewModel, - ) - } } @Composable @@ -72,47 +64,51 @@ private fun Content( val screenWidth = with(LocalDensity.current) { LocalConfiguration.current.screenWidthDp.dp } val tvShowsLazyItems = state.tvShowsFlow.collectAsLazyPagingItems() - Box( - modifier = Modifier.fillMaxSize() + BuildScreen( + isLoading = state.isLoading, + isError = state.tvShowsFlow.collectAsLazyPagingItems().loadState.refresh is LoadState.Error, + onBack = contract::onBackClick, + emptyLayoutMessage = R.string.no_trending_shows_in_genre, + emptyLayoutImage = R.drawable.img_no_result, ) { - BackgroundGradient( - modifier = Modifier - .align(Alignment.TopStart) - .zIndex(1f) - ) - Column( - modifier = Modifier - .fillMaxSize() - .background(NovixTheme.colors.surface) + Box( + modifier = Modifier.fillMaxSize() ) { - TopBar( + BackgroundGradient( modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 12.dp), - title = stringResource(R.string.trending_tv_shows), - onBackClick = contract::onBackClick - ) - GenresSection( - genres = state.tvShowsGenres, - selectedGenre = state.selectedGenre, - screenWidth = screenWidth, - onGenreClick = contract::onGenreClick, - modifier = Modifier.padding(bottom = 12.dp), - getGenreName = { stringResource(it.stringResId) } + .align(Alignment.TopStart) + .zIndex(1f) ) - MediaLazyPagingGrid( - pagingFlow = tvShowsLazyItems, - onItemClick = { contract.onTvShowClick(it.id) }, - getImageUrl = { it.posterPath }, - getTitle = { it.title }, + Column( modifier = Modifier - .weight(1f) - .fillMaxWidth() - .padding(horizontal = 16.dp), - onSaveClick = { }, - isItemSaved = { false }, - contentPadding = PaddingValues(bottom = 24.dp) - ) + .fillMaxSize() + .background(NovixTheme.colors.surface) + ) { + TopBar( + modifier = Modifier.detailsTopBar(1f), + title = stringResource(R.string.trending_tv_shows), + onBackClick = contract::onBackClick + ) + GenresSection( + genres = state.tvShowsGenres, + selectedGenre = state.selectedGenre, + screenWidth = screenWidth, + onGenreClick = contract::onGenreClick, + modifier = Modifier.padding(vertical = 12.dp), + getGenreName = { stringResource(it.stringResId) } + ) + + MediaLazyVerticalGrid( + pagingItems = tvShowsLazyItems, + imageUrl = { it.posterPath }, + name = { it.title }, + hasSaveIcon = false, + onItemClick = { item -> contract.onTvShowClick(item.id) }, + modifier = Modifier + .weight(1f) + .fillMaxWidth() + ) + } } } } diff --git a/presentation/src/main/java/com/london/presentation/feature/list/viewitems/ViewItemsContract.kt b/presentation/src/main/java/com/london/presentation/feature/list/viewitems/ViewItemsContract.kt index 45b65befd..6cbbaf74c 100644 --- a/presentation/src/main/java/com/london/presentation/feature/list/viewitems/ViewItemsContract.kt +++ b/presentation/src/main/java/com/london/presentation/feature/list/viewitems/ViewItemsContract.kt @@ -1,8 +1,8 @@ package com.london.presentation.feature.list.viewitems interface ViewListItemsContract { - fun onBack() - fun onRetry() + fun onBackClick() + fun onRetryClick() fun onDeleteClick() fun onConfirmDelete() fun onMovieClick(id: Int) diff --git a/presentation/src/main/java/com/london/presentation/feature/list/viewitems/ViewItemsScreen.kt b/presentation/src/main/java/com/london/presentation/feature/list/viewitems/ViewItemsScreen.kt index c1b2becce..2164086bb 100644 --- a/presentation/src/main/java/com/london/presentation/feature/list/viewitems/ViewItemsScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/list/viewitems/ViewItemsScreen.kt @@ -23,9 +23,9 @@ import com.london.designsystem.utils.string import com.london.presentation.R import com.london.presentation.feature.list.bottomsheets.DeleteListBottomSheet import com.london.presentation.shared.BackgroundGradient -import com.london.presentation.shared.MediaLazyPagingGrid import com.london.presentation.shared.base.ErrorState import com.london.presentation.shared.buildscreen.BuildScreen +import com.london.presentation.shared.container.MediaLazyVerticalGrid import com.london.presentation.utils.Listen @Composable @@ -60,22 +60,24 @@ private fun Content( Box( modifier = Modifier.fillMaxSize() - ){ + ) { BackgroundGradient( - modifier = Modifier.align(Alignment.TopStart).zIndex(1f) + modifier = Modifier + .align(Alignment.TopStart) + .zIndex(1f) ) Column { TopBar( title = state.listTitle, - onBackClick = contract::onBack, + onBackClick = contract::onBackClick, option2Icon = R.drawable.ic_delete, onClickOption2 = contract::onDeleteClick, option2IconTint = NovixTheme.colors.redAccent, - modifier = Modifier - .padding(horizontal = 16.dp, vertical = 12.dp) - ) + modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 12.dp), + + ) BuildScreen( onBack = null, @@ -86,18 +88,17 @@ private fun Content( emptyLayoutImage = R.drawable.img_no_result, pagingFlow = listItems, ) { - MediaLazyPagingGrid( - pagingFlow = listItems, - modifier = Modifier.padding(horizontal = 16.dp), - onItemClick = { contract.onMovieClick(it.id) }, - getImageUrl = { it.posterUrl }, - getTitle = { "${it.id} media img" }, + MediaLazyVerticalGrid( + pagingItems = listItems, + imageUrl = { it.posterUrl }, + name = { it.id.toString() }, + hasSaveIcon = true, onSaveClick = { contract.onRemoveMovieClick(it.id) - contract.onRetry() + contract.onRetryClick() }, isItemSaved = { true }, - hasSaveIcon = true + onNavigateToMovie = { id -> contract.onMovieClick(id) }, ) } } @@ -145,8 +146,8 @@ private fun Preview() { Content( state = ViewItemsUiState(), contract = object : ViewListItemsContract { - override fun onBack() {} - override fun onRetry() {} + override fun onBackClick() {} + override fun onRetryClick() {} override fun onDeleteClick() {} override fun onConfirmDelete() {} override fun onMovieClick(id: Int) {} diff --git a/presentation/src/main/java/com/london/presentation/feature/list/viewitems/ViewItemsViewModel.kt b/presentation/src/main/java/com/london/presentation/feature/list/viewitems/ViewItemsViewModel.kt index 79e5012f1..cde1f0a1c 100644 --- a/presentation/src/main/java/com/london/presentation/feature/list/viewitems/ViewItemsViewModel.kt +++ b/presentation/src/main/java/com/london/presentation/feature/list/viewitems/ViewItemsViewModel.kt @@ -35,11 +35,11 @@ class ViewItemsViewModel @Inject constructor( fetchMovieListDetails(listId = listId) } - override fun onBack() { + override fun onBackClick() { emitEffect(ViewItemsEffect.NavigateBack) } - override fun onRetry() { + override fun onRetryClick() { updateState { copy(error = null) } fetchMovieListDetails(listId) } diff --git a/presentation/src/main/java/com/london/presentation/feature/search/SearchContract.kt b/presentation/src/main/java/com/london/presentation/feature/search/SearchContract.kt index 856c84152..7d2bc0b5b 100644 --- a/presentation/src/main/java/com/london/presentation/feature/search/SearchContract.kt +++ b/presentation/src/main/java/com/london/presentation/feature/search/SearchContract.kt @@ -27,5 +27,5 @@ interface SearchContract { fun incrementGenreInterest(genre: Genre, mediaType: String) fun updateRecentData() fun onBookmarkSheetDismiss() - fun onManageBookmarkClicked(movieId: Int) + fun onManageBookmarkClick(movieId: Int) } diff --git a/presentation/src/main/java/com/london/presentation/feature/search/SearchScreen.kt b/presentation/src/main/java/com/london/presentation/feature/search/SearchScreen.kt index e96ba5a40..b3f5367eb 100644 --- a/presentation/src/main/java/com/london/presentation/feature/search/SearchScreen.kt +++ b/presentation/src/main/java/com/london/presentation/feature/search/SearchScreen.kt @@ -54,18 +54,19 @@ import com.london.designsystem.component.Text import com.london.designsystem.component.TopBar import com.london.designsystem.theme.NovixTheme import com.london.designsystem.theme.ThemePreviews +import com.london.domain.entity.movie.Movie import com.london.domain.entity.recent.RecentSearch import com.london.domain.entity.recent.RecentViewed import com.london.domain.entity.shared.MediaType import com.london.domain.entity.shared.MediaType.Companion.isMovie import com.london.presentation.R -import com.london.presentation.shared.ActorsLayout import com.london.presentation.shared.BackgroundGradient import com.london.presentation.shared.HomeCard import com.london.presentation.shared.base.ErrorState import com.london.presentation.shared.bookmarkSheet.BookmarkBottomSheet import com.london.presentation.shared.buildscreen.BuildScreen import com.london.presentation.shared.buildscreen.NetworkErrorScreen +import com.london.presentation.shared.container.ActorLazyVerticalColumn import com.london.presentation.shared.container.MediaLazyVerticalGrid import com.london.presentation.utils.Listen import com.london.presentation.utils.ResultOrEmpty @@ -112,6 +113,23 @@ private fun Content( val interactionSource = remember { MutableInteractionSource() } val focusManager = LocalFocusManager.current + SearchMainContent( + state = state, + contract = contract, + interactionSource = interactionSource, + keyboardController = keyboardController, + onClearFocus = { focusManager.clearFocus() } + ) +} + +@Composable +private fun SearchMainContent( + state: SearchUiState, + contract: SearchContract, + interactionSource: MutableInteractionSource, + keyboardController: SoftwareKeyboardController?, + onClearFocus: () -> Unit +) { val currentPagingFlow = when (state.selectedCategory) { SearchCategory.Movies -> state.moviesFlow.collectAsLazyPagingItems() SearchCategory.TvShows -> state.tvShowsFlow.collectAsLazyPagingItems() @@ -125,65 +143,48 @@ private fun Content( pagingFlow = currentPagingFlow, handlePagingLoadingAutomatically = false ) { - SearchMainContent( - state = state, - contract = contract, - interactionSource = interactionSource, - keyboardController = keyboardController, - onClearFocus = { focusManager.clearFocus() } - ) - } -} - -@Composable -private fun SearchMainContent( - state: SearchUiState, - contract: SearchContract, - interactionSource: MutableInteractionSource, - keyboardController: SoftwareKeyboardController?, - onClearFocus: () -> Unit, -) { - Box( - modifier = Modifier - .fillMaxSize() - .navBarBottomPadding() - .pointerInput(Unit) { detectTapGestures(onTap = { onClearFocus() }) } - ) { - - BackgroundGradient( - modifier = Modifier - .align(Alignment.TopStart) - .zIndex(1f) - ) - - Column( + Box( modifier = Modifier .fillMaxSize() - .background(NovixTheme.colors.surface), - verticalArrangement = Arrangement.Top + .navBarBottomPadding() + .pointerInput(Unit) { detectTapGestures(onTap = { onClearFocus() }) } ) { - TopBar( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), - title = stringResource(R.string.search), - ) - SearchBar( - uiState = state, - contract = contract, - interactionSource = interactionSource, - keyboardController = keyboardController, + BackgroundGradient( modifier = Modifier - .padding(start = 16.dp, end = 16.dp, bottom = 12.dp) - .fillMaxWidth() + .align(Alignment.TopStart) + .zIndex(1f) ) - SearchBody(state = state, contract = contract) + Column( + modifier = Modifier + .fillMaxSize() + .background(NovixTheme.colors.surface), + verticalArrangement = Arrangement.Top + ) { + TopBar( + modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), + title = stringResource(R.string.search), + ) - BookmarkBottomSheet( - onSheetDismiss = contract::onBookmarkSheetDismiss, - isSheetVisible = state.isBookmarkSheetVisible, - bookmarkedMovieId = state.bookmarkedMovieId - ) + SearchBar( + uiState = state, + contract = contract, + interactionSource = interactionSource, + keyboardController = keyboardController, + modifier = Modifier + .padding(start = 16.dp, end = 16.dp, bottom = 12.dp) + .fillMaxWidth() + ) + + SearchBody(state = state, contract = contract) + + BookmarkBottomSheet( + onSheetDismiss = contract::onBookmarkSheetDismiss, + isSheetVisible = state.isBookmarkSheetVisible, + bookmarkedMovieId = state.bookmarkedMovieId + ) + } } } } @@ -201,7 +202,6 @@ private fun SearchBody( SearchChipsRow( selected = state.selectedCategory, onSelect = contract::onCategorySelected, - modifier = Modifier.padding(bottom = 12.dp) ) } ) @@ -231,8 +231,7 @@ private fun SearchResultsWithCategory( ) { SearchChipsRow( selected = state.selectedCategory, - onSelect = contract::onCategorySelected, - modifier = Modifier.padding(bottom = 12.dp) + onSelect = contract::onCategorySelected ) if (state.error == ErrorState.NoInternet) { @@ -316,7 +315,7 @@ private fun ActorSearchContent(state: SearchUiState, contract: SearchContract) { } }, content = { - ActorsLayout( + ActorLazyVerticalColumn( items = actorsLazyList, onActorClick = { contract.onActorClick(it.id) } @@ -355,8 +354,7 @@ private fun MediaSearchContent( MediaLazyVerticalGrid( pagingItems = pagingItems, hasSaveIcon = hasSaveIcon, - onSaveClick = contract::onManageBookmarkClicked, - isItemSaved = { false }, + onSaveClick = { if (it is Movie) contract.onManageBookmarkClick(it.id) }, onNavigateToMovie = onNavigateToMovie, onNavigateToTvShow = onNavigateToTvShow ) @@ -524,7 +522,7 @@ private fun RecentSectionContent( onClearAll = contract::clearRecentViewed, onNavigateToTvShowDetails = onNavigateToTvShowDetails, onNavigateToMovieDetails = onNavigateToMovieDetails, - onManageBookmarkClicked = contract::onManageBookmarkClicked + onManageBookmarkClicked = contract::onManageBookmarkClick ) } } @@ -669,7 +667,7 @@ private fun SearchChipsRow( Row( modifier = modifier .fillMaxWidth() - .padding(horizontal = 16.dp), + .padding(start = 16.dp, end = 16.dp, bottom = 12.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), ) { SearchCategory.entries.forEach { category -> diff --git a/presentation/src/main/java/com/london/presentation/feature/search/SearchViewModel.kt b/presentation/src/main/java/com/london/presentation/feature/search/SearchViewModel.kt index c6d971ba1..b48d006da 100644 --- a/presentation/src/main/java/com/london/presentation/feature/search/SearchViewModel.kt +++ b/presentation/src/main/java/com/london/presentation/feature/search/SearchViewModel.kt @@ -190,7 +190,7 @@ class SearchViewModel @Inject constructor( setupSearchDebouncing() } - override fun onManageBookmarkClicked(movieId: Int) { + override fun onManageBookmarkClick(movieId: Int) { updateState { copy( isBookmarkSheetVisible = true, diff --git a/presentation/src/main/java/com/london/presentation/shared/DefaultAppTopBar.kt b/presentation/src/main/java/com/london/presentation/shared/DefaultAppTopBar.kt deleted file mode 100644 index d522e7bd5..000000000 --- a/presentation/src/main/java/com/london/presentation/shared/DefaultAppTopBar.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.london.presentation.shared - -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.london.designsystem.component.TopBar - -@Composable -fun DefaultAppTopBar( - title: String, - onBack: () -> Unit, -) { - TopBar( - modifier = Modifier - .fillMaxWidth() - .padding(start = 16.dp, end = 16.dp, top = 12.dp), - title = title, - onBackClick = onBack - ) -} diff --git a/presentation/src/main/java/com/london/presentation/shared/HomeCard.kt b/presentation/src/main/java/com/london/presentation/shared/HomeCard.kt index a23e2b368..4069d73ce 100644 --- a/presentation/src/main/java/com/london/presentation/shared/HomeCard.kt +++ b/presentation/src/main/java/com/london/presentation/shared/HomeCard.kt @@ -30,9 +30,9 @@ fun HomeCard( imageUrl: Any, modifier: Modifier = Modifier, rate: String? = null, - onSaveClick: () -> Unit, isSaved: Boolean = false, hasSaveIcon: Boolean = true, + onSaveClick: () -> Unit = {}, onDeleteClick: () -> Unit = {}, imageDescription: String? = null, hasOverlay: Boolean = false, diff --git a/presentation/src/main/java/com/london/presentation/shared/LazyPagingColumn.kt b/presentation/src/main/java/com/london/presentation/shared/LazyPagingColumn.kt deleted file mode 100644 index 6f1bc9793..000000000 --- a/presentation/src/main/java/com/london/presentation/shared/LazyPagingColumn.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.london.presentation.shared - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import androidx.paging.compose.LazyPagingItems - -@Composable -fun LazyPagingColumn( - pagingItems: LazyPagingItems, - modifier: Modifier = Modifier, - itemContent: @Composable (T) -> Unit, -) { - Content( - modifier = modifier, - items = pagingItems, - itemContent = itemContent - ) -} - -@Composable -private fun Content( - modifier: Modifier, - items: LazyPagingItems, - itemContent: @Composable (T) -> Unit -) { - Column( - modifier = modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(12.dp) - ) { - items.itemSnapshotList.forEach { item -> - if (item != null) { - itemContent(item) - } - } - } -} diff --git a/presentation/src/main/java/com/london/presentation/shared/MediaLazyGrid.kt b/presentation/src/main/java/com/london/presentation/shared/MediaLazyGrid.kt deleted file mode 100644 index 06bcd7783..000000000 --- a/presentation/src/main/java/com/london/presentation/shared/MediaLazyGrid.kt +++ /dev/null @@ -1,137 +0,0 @@ -package com.london.presentation.shared - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.items -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.london.designsystem.component.CircularLoading -import com.london.designsystem.component.EmptyLayout -import com.london.designsystem.component.TopBar -import com.london.designsystem.theme.NovixTheme -import com.london.presentation.utils.gridColumns - -@Deprecated( - message = "Use MediaLazyVerticalGrid or MediaLazyGridWithFilter instead. This composable will be removed in a future version. Note: Both have two overloads - one for List and one for LazyPagingItems.", - replaceWith = ReplaceWith( - expression = "MediaLazyGridWithFilter(" + - "items = items, " + - "modifier = modifier, " + - "imageUrl = getImageUrl, " + - "name = { it.getName() }, " + - "onSaveClick = onSavedClick, " + - "isItemSaved = isItemSaved, " + - "onDeleteClick = onDeleteClick, " + - "onMovieGenreClick = {}, " + - "onTvShowGenreClick = {}, " + - "config = MediaGridConfig(" + - " showSaveIcon = hasSaveIcon, " + - " isDarkMode = isDarkMode, " + - " myRatingList = myRatingList, " + - " rate = rate, " + - " isMovieSelected = true, " + - " isTvShowSelected = false, " + - " selectedMovieGenre = MovieGenre.All, " + - " selectedTvShowGenre = TvShowGenre.All, " + - " onNavigateToMovie = onItemClick, " + - "), " + - "topBar = {" + - " DefaultAppTopBar(" + - " title = title," + - " onBack = onBack" + - " )" + - "}" + - ")", - imports = ["com.london.presentation.shared.container.MediaLazyGridWithFilter", "com.london.presentation.shared.container.MediaGridConfig", "com.london.presentation.utils.MovieGenre", "com.london.presentation.utils.TvShowGenre"] - ), - level = DeprecationLevel.WARNING -) - -@Composable -fun MediaLazyGrid( - title: String, - items: List, - onBack: () -> Unit, - getImageUrl: (T) -> String, - modifier: Modifier = Modifier, - onItemClick: (T) -> Unit = {}, - onSavedClick: (T) -> Unit = {}, - isItemSaved: (T) -> Boolean = { false }, - isLoading: Boolean = false, - emptyTitle: String = "", - emptyImage: Int? = null, - myRatingList: Boolean = false, - hasSaveIcon: Boolean = false, - rate: String = "5", - onDeleteClick: () -> Unit = {} -) { - Column( - modifier = modifier - .fillMaxSize() - .background(color = NovixTheme.colors.surface) - ) { - TopBar( - modifier = Modifier - .fillMaxWidth() - .padding(start = 16.dp, end = 16.dp, top = 12.dp), - title = title, - onBackClick = onBack - ) - - when { - isLoading -> CircularLoading( - modifier = Modifier - .fillMaxSize() - .wrapContentSize(Alignment.Center) - ) - - !isLoading && items.isEmpty() && emptyImage != null -> EmptyLayout( - text = emptyTitle, - image = emptyImage, - modifier = Modifier - .fillMaxSize() - .navigationBarsPadding() - ) - - else -> { - LazyVerticalGrid( - columns = GridCells.Fixed(gridColumns()), - contentPadding = PaddingValues( - top = 12.dp, - bottom = 16.dp - ), - horizontalArrangement = Arrangement.spacedBy(12.dp), - verticalArrangement = Arrangement.spacedBy(12.dp), - modifier = Modifier - .fillMaxSize() - .navigationBarsPadding() - .padding(horizontal = 16.dp) - ) { - items(items) { item -> - HomeCard( - imageUrl = getImageUrl(item), - isSaved = isItemSaved(item), - onSaveClick = { onSavedClick(item) }, - rate = rate, - onDeleteClick = onDeleteClick, - hasSaveIcon = hasSaveIcon, - modifier = Modifier.clickable { onItemClick(item) } - ) - } - } - } - } - } -} diff --git a/presentation/src/main/java/com/london/presentation/shared/MediaLazyPagingGrid.kt b/presentation/src/main/java/com/london/presentation/shared/MediaLazyPagingGrid.kt deleted file mode 100644 index aa38d2887..000000000 --- a/presentation/src/main/java/com/london/presentation/shared/MediaLazyPagingGrid.kt +++ /dev/null @@ -1,88 +0,0 @@ -package com.london.presentation.shared - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.rememberLazyGridState -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import androidx.paging.compose.LazyPagingItems -import com.london.presentation.utils.gridColumns -import com.london.presentation.utils.isNotLoading - -@Deprecated( - message = "Use MediaLazyVerticalGrid or MediaLazyGridWithFilter instead. This composable will be removed in a future version. Note: Both have two overloads - one for List and one for LazyPagingItems.", - replaceWith = ReplaceWith( - expression = "MediaLazyGridWithFilter(" + - "items = items, " + - "modifier = modifier, " + - "imageUrl = getImageUrl, " + - "name = { it.getName() }, " + - "onSaveClick = onSavedClick, " + - "isItemSaved = isItemSaved, " + - "onDeleteClick = onDeleteClick, " + - "onMovieGenreClick = {}, " + - "onTvShowGenreClick = {}, " + - "config = MediaGridConfig(" + - " showSaveIcon = hasSaveIcon, " + - " isDarkMode = isDarkMode, " + - " myRatingList = myRatingList, " + - " rate = rate, " + - " isMovieSelected = true, " + - " isTvShowSelected = false, " + - " selectedMovieGenre = MovieGenre.All, " + - " selectedTvShowGenre = TvShowGenre.All, " + - " onNavigateToMovie = onItemClick, " + - "), " + - "topBar = {" + - " DefaultAppTopBar(" + - " title = title," + - " onBack = onBack" + - " )" + - "}" + - ")", - imports = ["com.london.presentation.shared.container.MediaLazyGridWithFilter", "com.london.presentation.shared.container.MediaGridConfig", "com.london.presentation.utils.MovieGenre", "com.london.presentation.utils.TvShowGenre"] - ), - level = DeprecationLevel.WARNING -) - -@Composable -fun MediaLazyPagingGrid( - pagingFlow: LazyPagingItems, - onItemClick: (T) -> Unit, - getImageUrl: (T) -> String, - getTitle: (T) -> String, - modifier: Modifier = Modifier, - onSaveClick: (T) -> Unit = {}, - isItemSaved: (T) -> Boolean = { false }, - hasSaveIcon: Boolean = false, - contentPadding: PaddingValues = PaddingValues(bottom = 16.dp) -) { - LazyVerticalGrid( - state = rememberLazyGridState(), - columns = GridCells.Fixed(gridColumns()), - modifier = modifier.fillMaxSize(), - horizontalArrangement = Arrangement.spacedBy(12.dp), - verticalArrangement = Arrangement.spacedBy(12.dp), - contentPadding = contentPadding - ) { - items(pagingFlow.itemCount) { index -> - val item = pagingFlow[index] - if (item != null) { - HomeCard( - imageUrl = getImageUrl(item), - hasSaveIcon = hasSaveIcon, - onSaveClick = { onSaveClick(item) }, - isSaved = isItemSaved(item), - imageDescription = getTitle(item), - modifier = Modifier.clickable { onItemClick(item) }, - isLoadingShimmer = true - ) - } - } - } -} diff --git a/presentation/src/main/java/com/london/presentation/shared/MoviesLayout.kt b/presentation/src/main/java/com/london/presentation/shared/MoviesLayout.kt deleted file mode 100644 index e4c031b6e..000000000 --- a/presentation/src/main/java/com/london/presentation/shared/MoviesLayout.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.london.presentation.shared - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import androidx.paging.compose.LazyPagingItems -import com.london.domain.entity.movie.Movie -import com.london.presentation.utils.gridColumns - -@Deprecated( - message = "Use MediaLazyVerticalGrid or MediaLazyGridWithFilter instead. This composable will be removed in a future version. Note: Both have two overloads - one for List and one for LazyPagingItems.", - replaceWith = ReplaceWith( - expression = "MediaLazyGridWithFilter(" + - "items = items, " + - "modifier = modifier, " + - "imageUrl = getImageUrl, " + - "name = { it.getName() }, " + - "onSaveClick = onSavedClick, " + - "isItemSaved = isItemSaved, " + - "onDeleteClick = onDeleteClick, " + - "onMovieGenreClick = {}, " + - "onTvShowGenreClick = {}, " + - "config = MediaGridConfig(" + - " showSaveIcon = hasSaveIcon, " + - " isDarkMode = isDarkMode, " + - " myRatingList = myRatingList, " + - " rate = rate, " + - " isMovieSelected = true, " + - " isTvShowSelected = false, " + - " selectedMovieGenre = MovieGenre.All, " + - " onNavigateToMovie = onItemClick, " + - "), " + - "topBar = {" + - " DefaultAppTopBar(" + - " title = title," + - " onBack = onBack" + - " )" + - "}" + - ")", - imports = ["com.london.presentation.shared.container.MediaLazyGridWithFilter", "com.london.presentation.shared.container.MediaGridConfig", "com.london.presentation.utils.MovieGenre", "com.london.presentation.utils.TvShowGenre"] - ), - level = DeprecationLevel.WARNING -) - -@Composable -fun MoviesLayOut( - movieUis: LazyPagingItems, - onSaveClick: (Movie) -> Unit, - isMovieSaved: (Movie) -> Boolean, - onMovieClick: (Movie) -> Unit, - modifier: Modifier = Modifier -) { - LazyVerticalGrid( - columns = GridCells.Fixed(gridColumns()), - modifier = modifier.fillMaxSize(), - horizontalArrangement = Arrangement.spacedBy(12.dp), - verticalArrangement = Arrangement.spacedBy(12.dp), - contentPadding = PaddingValues(bottom = 16.dp) - ) { - items(movieUis.itemCount) { index -> - val movie = movieUis[index] - if (movie != null) { - HomeCard( - imageUrl = movie.posterUrl, - onSaveClick = { onSaveClick(movie) }, - isSaved = isMovieSaved(movie), - imageDescription = movie.name, - modifier = Modifier.clickable { onMovieClick(movie) } - ) - } - } - } -} diff --git a/presentation/src/main/java/com/london/presentation/shared/TvShowsLayout.kt b/presentation/src/main/java/com/london/presentation/shared/TvShowsLayout.kt deleted file mode 100644 index 15282abfa..000000000 --- a/presentation/src/main/java/com/london/presentation/shared/TvShowsLayout.kt +++ /dev/null @@ -1,81 +0,0 @@ -package com.london.presentation.shared - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import androidx.paging.compose.LazyPagingItems -import com.london.domain.entity.tvshow.TvShow -import com.london.presentation.utils.gridColumns - -@Deprecated( - message = "Use MediaLazyVerticalGrid or MediaLazyGridWithFilter instead. This composable will be removed in a future version. Note: Both have two overloads - one for List and one for LazyPagingItems.", - replaceWith = ReplaceWith( - expression = "MediaLazyGridWithFilter(" + - "items = items, " + - "modifier = modifier, " + - "imageUrl = getImageUrl, " + - "name = { it.getName() }, " + - "onSaveClick = onSavedClick, " + - "isItemSaved = isItemSaved, " + - "onDeleteClick = onDeleteClick, " + - "onMovieGenreClick = {}, " + - "onTvShowGenreClick = {}, " + - "config = MediaGridConfig(" + - " showSaveIcon = hasSaveIcon, " + - " isDarkMode = isDarkMode, " + - " myRatingList = myRatingList, " + - " rate = rate, " + - " isMovieSelected = true, " + - " isTvShowSelected = false, " + - " selectedTvShowGenre = TvShowGenre.All, " + - " onNavigateToMovie = onItemClick, " + - "), " + - "topBar = {" + - " DefaultAppTopBar(" + - " title = title," + - " onBack = onBack" + - " )" + - "}" + - ")", - imports = ["com.london.presentation.shared.container.MediaLazyGridWithFilter", "com.london.presentation.shared.container.MediaGridConfig", "com.london.presentation.utils.MovieGenre", "com.london.presentation.utils.TvShowGenre"] - ), - level = DeprecationLevel.WARNING -) - -@Composable -fun TvShowLayOut( - tvShowUis: LazyPagingItems, - onSaveClick: (TvShow) -> Unit, - isTvShowSaved: (TvShow) -> Boolean, - onTvShowClick: (TvShow) -> Unit -) { - LazyVerticalGrid( - columns = GridCells.Fixed(gridColumns()), - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 16.dp), - horizontalArrangement = Arrangement.spacedBy(12.dp), - verticalArrangement = Arrangement.spacedBy(12.dp), - contentPadding = PaddingValues(bottom = 16.dp) - ) { - items(tvShowUis.itemCount) { index -> - val tvShow = tvShowUis[index] - if (tvShow != null) { - HomeCard( - imageUrl = tvShow.posterPicture, - onSaveClick = { onSaveClick(tvShow) }, - isSaved = isTvShowSaved(tvShow), - imageDescription = tvShow.name, - modifier = Modifier.clickable { onTvShowClick(tvShow) } - ) - } - } - } -} diff --git a/presentation/src/main/java/com/london/presentation/shared/ActorsLayout.kt b/presentation/src/main/java/com/london/presentation/shared/container/ActorLazyVerticalColumn.kt similarity index 87% rename from presentation/src/main/java/com/london/presentation/shared/ActorsLayout.kt rename to presentation/src/main/java/com/london/presentation/shared/container/ActorLazyVerticalColumn.kt index faca3197f..19c288be3 100644 --- a/presentation/src/main/java/com/london/presentation/shared/ActorsLayout.kt +++ b/presentation/src/main/java/com/london/presentation/shared/container/ActorLazyVerticalColumn.kt @@ -1,4 +1,4 @@ -package com.london.presentation.shared +package com.london.presentation.shared.container import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.PaddingValues @@ -9,16 +9,17 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.paging.compose.LazyPagingItems import com.london.domain.entity.actor.Actor +import com.london.presentation.shared.ActorItem @Composable -fun ActorsLayout( +fun ActorLazyVerticalColumn( items: LazyPagingItems, onActorClick: (Actor) -> Unit, modifier: Modifier = Modifier ) { LazyColumn( modifier = modifier.fillMaxWidth(), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, bottom = 16.dp), + contentPadding = PaddingValues(start = 16.dp, end = 16.dp, bottom = 16.dp, top = 12.dp), verticalArrangement = Arrangement.spacedBy(12.dp) ) { items(items.itemCount) { index -> diff --git a/presentation/src/main/java/com/london/presentation/shared/container/MediaGridConfig.kt b/presentation/src/main/java/com/london/presentation/shared/container/MediaGridConfig.kt index 890a6847a..b05a3ec08 100644 --- a/presentation/src/main/java/com/london/presentation/shared/container/MediaGridConfig.kt +++ b/presentation/src/main/java/com/london/presentation/shared/container/MediaGridConfig.kt @@ -4,16 +4,15 @@ import com.london.presentation.shared.genre.MovieGenreUi import com.london.presentation.shared.genre.TvShowGenreUi data class MediaGridConfig( - val rate: String? = "", - val isDarkMode: Boolean = true, val showSaveIcon: Boolean = true, + val isDarkMode: Boolean = true, val isMovieSelected: Boolean = true, + val isTvShowSelected: Boolean = false, + val isItemSaved: (Any) -> Boolean = { false }, val onSaveClick: (Any) -> Unit = {}, val onDeleteClick: (Any) -> Unit = {}, - val isTvShowSelected: Boolean = false, val onNavigateToMovie: (Int) -> Unit = {}, val onNavigateToTvShow: (Int) -> Unit = {}, - val isItemSaved: (Any) -> Boolean = { false }, val selectedMovieGenre: MovieGenreUi = MovieGenreUi.All, - val selectedTvShowGenre: TvShowGenreUi = TvShowGenreUi.All, + val selectedTvShowGenre: TvShowGenreUi = TvShowGenreUi.All ) diff --git a/presentation/src/main/java/com/london/presentation/shared/container/MediaLazyGridWithFilter.kt b/presentation/src/main/java/com/london/presentation/shared/container/MediaLazyGridWithFilter.kt index 8fb81abf1..cb7b9e47b 100644 --- a/presentation/src/main/java/com/london/presentation/shared/container/MediaLazyGridWithFilter.kt +++ b/presentation/src/main/java/com/london/presentation/shared/container/MediaLazyGridWithFilter.kt @@ -21,11 +21,11 @@ fun MediaLazyGridWithFilter( modifier: Modifier = Modifier, isLoading: Boolean = false, name: (T) -> String = { it.getName() }, - topBar: @Composable (() -> Unit)? = null, - config: MediaGridConfig = MediaGridConfig(), - onMovieGenreClick: (MovieGenreUi) -> Unit = {}, imageUrl: (T) -> String? = { it.getImageUrl() }, + onMovieGenreClick: (MovieGenreUi) -> Unit = {}, onTvShowGenreClick: (TvShowGenreUi) -> Unit = {}, + config: MediaGridConfig = MediaGridConfig(), + topBar: @Composable (() -> Unit)? = null ) { Column( @@ -52,7 +52,6 @@ fun MediaLazyGridWithFilter( imageUrl = imageUrl, name = name, config = config, - topBar = topBar ) } @@ -90,7 +89,7 @@ fun MediaLazyGridWithFilter( selectedMovieGenre = config.selectedMovieGenre, selectedTvShowGenre = config.selectedTvShowGenre, onMovieGenreClick = onMovieGenreClick, - onTvShowGenreClick = onTvShowGenreClick, + onTvShowGenreClick = onTvShowGenreClick ) if (pagingItems.itemCount > 0) { @@ -98,8 +97,7 @@ fun MediaLazyGridWithFilter( pagingItems = pagingItems, imageUrl = imageUrl, name = name, - config = config, - topBar = topBar + config = config ) } else if (!isLoading) { EmptyGenreLayout() @@ -112,8 +110,7 @@ private fun RenderFilteredItemsGrid( filteredItems: List, imageUrl: (T) -> String?, name: (T) -> String, - config: MediaGridConfig, - topBar: @Composable (() -> Unit)? + config: MediaGridConfig ) { if (filteredItems.isNotEmpty()) { MediaLazyVerticalGrid( @@ -124,8 +121,8 @@ private fun RenderFilteredItemsGrid( onSaveClick = { config.onSaveClick(it) }, isItemSaved = { config.isItemSaved(it) }, onDeleteClick = { config.onDeleteClick(it) }, - rate = { config.rate }, - topBar = topBar, + rate = { null }, + topBar = null, modifier = Modifier.fillMaxSize(), onNavigateToMovie = config.onNavigateToMovie, onNavigateToTvShow = config.onNavigateToTvShow @@ -140,8 +137,7 @@ private fun RenderPagingItemsGrid( pagingItems: LazyPagingItems, imageUrl: (T) -> String?, name: (T) -> String, - config: MediaGridConfig, - topBar: @Composable (() -> Unit)? + config: MediaGridConfig ) { MediaLazyVerticalGrid( pagingItems = pagingItems, @@ -151,8 +147,8 @@ private fun RenderPagingItemsGrid( onSaveClick = { config.onSaveClick(it) }, isItemSaved = { config.isItemSaved(it) }, onDeleteClick = { config.onDeleteClick(it) }, - rate = { config.rate }, - topBar = topBar, + rate = { null }, + topBar = null, modifier = Modifier.fillMaxSize(), onNavigateToMovie = config.onNavigateToMovie, onNavigateToTvShow = config.onNavigateToTvShow @@ -188,7 +184,6 @@ private fun Preview() { config = MediaGridConfig( showSaveIcon = true, isDarkMode = true, - rate = "3", isMovieSelected = true, isTvShowSelected = false, selectedMovieGenre = MovieGenreUi.Action, diff --git a/presentation/src/main/java/com/london/presentation/shared/container/MediaLazyGridWithTabs.kt b/presentation/src/main/java/com/london/presentation/shared/container/MediaLazyGridWithTabs.kt index 65eb16dd3..589f5eddc 100644 --- a/presentation/src/main/java/com/london/presentation/shared/container/MediaLazyGridWithTabs.kt +++ b/presentation/src/main/java/com/london/presentation/shared/container/MediaLazyGridWithTabs.kt @@ -173,7 +173,6 @@ private fun Preview() { config = MediaGridConfig( showSaveIcon = true, isDarkMode = true, - rate = "3", isMovieSelected = true, isTvShowSelected = false, selectedMovieGenre = MovieGenreUi.All, diff --git a/presentation/src/main/java/com/london/presentation/shared/container/MediaLazyVerticalGrid.kt b/presentation/src/main/java/com/london/presentation/shared/container/MediaLazyVerticalGrid.kt index 2cc61cabf..d0ac3eeaa 100644 --- a/presentation/src/main/java/com/london/presentation/shared/container/MediaLazyVerticalGrid.kt +++ b/presentation/src/main/java/com/london/presentation/shared/container/MediaLazyVerticalGrid.kt @@ -27,17 +27,17 @@ import com.london.presentation.utils.gridColumns fun MediaLazyVerticalGrid( items: List, modifier: Modifier = Modifier, + rate: (T) -> String? = { null }, + name: (T) -> String = { it.getName() }, + imageUrl: (T) -> String? = { it.getImageUrl() }, hasSaveIcon: Boolean = true, onSaveClick: (T) -> Unit = {}, - onDeleteClick: (T) -> Unit = {}, - rate: (T) -> String? = { null }, + isItemSaved: (T) -> Boolean = { false }, onItemClick: ((T) -> Unit)? = null, + onDeleteClick: (T) -> Unit = {}, onNavigateToMovie: (Int) -> Unit = {}, onNavigateToTvShow: (Int) -> Unit = {}, - name: (T) -> String = { it.getName() }, - isItemSaved: (T) -> Boolean = { false }, - topBar: @Composable (() -> Unit)? = null, - imageUrl: (T) -> String? = { it.getImageUrl() }, + topBar: @Composable (() -> Unit)? = null ) { MediaGridContainer( modifier = modifier, @@ -82,8 +82,9 @@ fun MediaLazyVerticalGrid( name: (T) -> String = { it.getName() }, imageUrl: (T) -> String? = { it.getImageUrl() }, hasSaveIcon: Boolean = true, - onSaveClick: (Int) -> Unit = {}, + onSaveClick: (T) -> Unit = {}, isItemSaved: (T) -> Boolean = { false }, + onItemClick: ((T) -> Unit)? = null, onDeleteClick: (T) -> Unit = {}, topBar: @Composable (() -> Unit)? = null, onNavigateToMovie: (Int) -> Unit = {}, @@ -111,6 +112,7 @@ fun MediaLazyVerticalGrid( isItemSaved = isItemSaved, hasSaveIcon = hasSaveIcon, onSaveClick = onSaveClick, + onItemClick = onItemClick, onDeleteClick = onDeleteClick, rate = rate, onNavigateToMovie = onNavigateToMovie, @@ -139,7 +141,7 @@ private fun MediaGridContainer( modifier = Modifier.fillMaxSize(), horizontalArrangement = Arrangement.spacedBy(12.dp), verticalArrangement = Arrangement.spacedBy(12.dp), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, bottom = 16.dp), + contentPadding = PaddingValues(start = 16.dp, end = 16.dp, bottom = 24.dp), content = content ) } @@ -153,7 +155,8 @@ private fun RenderPagingGridItem( name: (T) -> String, isItemSaved: (T) -> Boolean, hasSaveIcon: Boolean, - onSaveClick: (Int) -> Unit, + onSaveClick: (T) -> Unit, + onItemClick: ((T) -> Unit)?, onDeleteClick: (T) -> Unit, rate: (T) -> String?, onNavigateToMovie: (Int) -> Unit, @@ -164,15 +167,19 @@ private fun RenderPagingGridItem( HomeCard( imageUrl = it, modifier = Modifier.clickable { - when (item) { - is Movie -> onNavigateToMovie(item.id) - is TvShow -> onNavigateToTvShow(item.id) + if (onItemClick != null) { + onItemClick(item) + } else { + when (item) { + is Movie -> onNavigateToMovie(item.id) + is TvShow -> onNavigateToTvShow(item.id) + } } }, imageDescription = name(item), isSaved = isItemSaved(item), hasSaveIcon = hasSaveIcon, - onSaveClick = { if (item is Movie) onSaveClick(item.id) }, + onSaveClick = { onSaveClick(item) }, onDeleteClick = { onDeleteClick(item) }, rate = rate(item) ) diff --git a/presentation/src/test/java/com/london/presentation/feature/category/movie/MovieCategoryViewModelTest.kt b/presentation/src/test/java/com/london/presentation/feature/category/movie/MovieCategoryViewModelTest.kt index 7e3aece55..026727476 100644 --- a/presentation/src/test/java/com/london/presentation/feature/category/movie/MovieCategoryViewModelTest.kt +++ b/presentation/src/test/java/com/london/presentation/feature/category/movie/MovieCategoryViewModelTest.kt @@ -115,7 +115,7 @@ class MovieCategoryViewModelTest { fun `onMovieClick should emit NavigateBack effect`() = runTest { // When & Then viewModel?.effect?.test { - viewModel?.onBack() + viewModel?.onBackClick() assertThat(awaitItem()).isInstanceOf(MovieCategoryEffect.BackNavigation::class.java) cancelAndIgnoreRemainingEvents() } diff --git a/presentation/src/test/java/com/london/presentation/feature/category/tvshow/TvShowCategoryViewModelTest.kt b/presentation/src/test/java/com/london/presentation/feature/category/tvshow/TvShowCategoryViewModelTest.kt index 175838be7..f77741c59 100644 --- a/presentation/src/test/java/com/london/presentation/feature/category/tvshow/TvShowCategoryViewModelTest.kt +++ b/presentation/src/test/java/com/london/presentation/feature/category/tvshow/TvShowCategoryViewModelTest.kt @@ -125,7 +125,7 @@ class TvShowCategoryViewModelTest { fun `onMovieClick should emit NavigateBack effect`() = runTest { // When & Then viewModel?.effect?.test { - viewModel?.onBack() + viewModel?.onBackClick() assertThat(awaitItem()).isInstanceOf(TvShowCategoryEffect.BackNavigation::class.java) cancelAndIgnoreRemainingEvents() }