From adcf53a6ee8cfdc5a95269ec88f2bb0a8a7b80d6 Mon Sep 17 00:00:00 2001 From: Slee Date: Mon, 12 Feb 2024 06:58:02 -0800 Subject: [PATCH] Load all similar movies and tv shows from detail screen --- .../main/java/com/sample/tmdb/ui/TMDbApp.kt | 32 +++++++++++++++ .../java/com/sample/tmdb/ui/TMDbAppState.kt | 7 ++++ .../sample/tmdb/common/MainDestinations.kt | 3 ++ .../sample/tmdb/data/di/RepositoryModule.kt | 13 ++++++ .../paging/movie/SimilarMoviesPagingSource.kt | 17 ++++++++ .../tvshow/SimilarTvSeriesPagingSource.kt | 17 ++++++++ .../AiringTodayTvSeriesPagingRepository.kt | 2 +- .../DiscoverMoviesPagingRepository.kt | 2 +- .../DiscoverTvSeriesPagingRepository.kt | 2 +- .../NowPlayingMoviesPagingRepository.kt | 2 +- .../OnTheAirTvSeriesPagingRepository.kt | 2 +- .../PopularMoviesPagingRepository.kt | 2 +- .../PopularTvSeriesPagingRepository.kt | 2 +- .../SearchMoviesPagingRepository.kt | 2 +- .../SearchTvSeriesPagingRepository.kt | 2 +- .../SimilarMoviesPagingRepository.kt | 21 ++++++++++ .../SimilarTvSeriesPagingRepository.kt | 21 ++++++++++ .../TopRatedMoviesPagingRepository.kt | 2 +- .../TopRatedTvSeriesPagingRepository.kt | 2 +- .../TrendingMoviesPagingRepository.kt | 2 +- .../TrendingTvSeriesPagingRepository.kt | 2 +- .../UpcomingMoviesPagingRepository.kt | 2 +- .../domain/repository/BasePagingRepository.kt | 6 +-- .../sample/tmdb/domain/utils/Annotations.kt | 6 ++- .../com/sample/tmdb/detail/DetailScreen.kt | 13 ++++-- .../com/sample/tmdb/paging/PagingScreen.kt | 40 +++++++++++++++++++ .../paging/main/BaseMainPagingViewModel.kt | 8 ++-- .../main/movie/SimilarMoviesViewModel.kt | 16 ++++++++ .../main/tvshow/SimilarTvSeriesViewModel.kt | 16 ++++++++ .../src/main/res/values/strings.xml | 1 + 30 files changed, 241 insertions(+), 24 deletions(-) create mode 100644 core/data/src/main/java/com/sample/tmdb/data/paging/movie/SimilarMoviesPagingSource.kt create mode 100644 core/data/src/main/java/com/sample/tmdb/data/paging/tvshow/SimilarTvSeriesPagingSource.kt create mode 100644 core/data/src/main/java/com/sample/tmdb/data/repository/SimilarMoviesPagingRepository.kt create mode 100644 core/data/src/main/java/com/sample/tmdb/data/repository/SimilarTvSeriesPagingRepository.kt create mode 100644 features/feature-paging/src/main/java/com/sample/tmdb/paging/main/movie/SimilarMoviesViewModel.kt create mode 100644 features/feature-paging/src/main/java/com/sample/tmdb/paging/main/tvshow/SimilarTvSeriesViewModel.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 003bcdf..0fecd97 100644 --- a/app/src/main/java/com/sample/tmdb/ui/TMDbApp.kt +++ b/app/src/main/java/com/sample/tmdb/ui/TMDbApp.kt @@ -55,6 +55,8 @@ import com.sample.tmdb.paging.NowPlayingMovieScreen import com.sample.tmdb.paging.OnTheAirTVShowScreen import com.sample.tmdb.paging.PopularMovieScreen import com.sample.tmdb.paging.PopularTVShowScreen +import com.sample.tmdb.paging.SimilarMovieScreen +import com.sample.tmdb.paging.SimilarTVShowScreen import com.sample.tmdb.paging.TopRatedMovieScreen import com.sample.tmdb.paging.TopRatedTVShowScreen import com.sample.tmdb.paging.TrendingMovieScreen @@ -96,6 +98,7 @@ fun TMDbApp() { onCreditSelected = appState::navigateToPerson, onImagesSelected = appState::navigateToImages, onTMDbItemSelected = appState::navigateToMovieDetail, + onAllSimilarSelected = appState::navigateToSimilarMovies, upPress = appState::upPress ) tvShowDetailScreens( @@ -104,6 +107,7 @@ fun TMDbApp() { onCreditSelected = appState::navigateToPerson, onImagesSelected = appState::navigateToImages, onTMDbItemSelected = appState::navigateToTVShowDetail, + onAllSimilarSelected = appState::navigateToSimilarTVShow, upPress = appState::upPress ) moviePagingScreens( @@ -207,6 +211,7 @@ private fun NavGraphBuilder.movieDetailScreens( onCreditSelected: (String) -> Unit, onImagesSelected: (String, Int) -> Unit, onTMDbItemSelected: (Int) -> Unit, + onAllSimilarSelected: (Int) -> Unit, upPress: () -> Unit ) { composable( @@ -231,6 +236,8 @@ private fun NavGraphBuilder.movieDetailScreens( ) }, onTMDbItemSelected = { onTMDbItemSelected(it.id) + }, onAllSimilarSelected = { + onAllSimilarSelected(it) }) } } @@ -241,6 +248,7 @@ private fun NavGraphBuilder.tvShowDetailScreens( onCreditSelected: (String) -> Unit, onImagesSelected: (String, Int) -> Unit, onTMDbItemSelected: (Int) -> Unit, + onAllSimilarSelected: (Int) -> Unit, upPress: () -> Unit ) { composable( @@ -265,6 +273,8 @@ private fun NavGraphBuilder.tvShowDetailScreens( ) }, onTMDbItemSelected = { onTMDbItemSelected(it.id) + }, onAllSimilarSelected = { + onAllSimilarSelected(it) }) } } @@ -316,6 +326,17 @@ private fun NavGraphBuilder.moviePagingScreens( onSearchMovie = onSearchMovie ) } + composable( + route = "${MainDestinations.TMDB_SIMILAR_MOVIES_ROUTE}/{${MainDestinations.TMDB_SIMILAR_ID}}", + arguments = listOf( + navArgument(MainDestinations.TMDB_SIMILAR_ID) { type = NavType.IntType }) + ) { + SimilarMovieScreen( + onClick = { onMovieSelected(it.id) }, + upPress = upPress, + onSearchMovie = onSearchMovie + ) + } } private fun NavGraphBuilder.tvShowPagingScreens( @@ -365,6 +386,17 @@ private fun NavGraphBuilder.tvShowPagingScreens( onSearchTVShow = onSearchTVShow ) } + composable( + route = "${MainDestinations.TMDB_SIMILAR_TV_SHOW_ROUTE}/{${MainDestinations.TMDB_SIMILAR_ID}}", + arguments = listOf( + navArgument(MainDestinations.TMDB_SIMILAR_ID) { type = NavType.IntType }) + ) { + SimilarTVShowScreen( + onClick = { onTVShowSelected(it.id) }, + upPress = upPress, + onSearchMovie = onSearchTVShow + ) + } } private fun NavGraphBuilder.searchScreens( diff --git a/app/src/main/java/com/sample/tmdb/ui/TMDbAppState.kt b/app/src/main/java/com/sample/tmdb/ui/TMDbAppState.kt index c8ac9c5..1ee3afd 100644 --- a/app/src/main/java/com/sample/tmdb/ui/TMDbAppState.kt +++ b/app/src/main/java/com/sample/tmdb/ui/TMDbAppState.kt @@ -97,6 +97,13 @@ class TMDbAppState( navController.navigate("${MainDestinations.TMDB_IMAGES_ROUTE}/$images/$id") } + fun navigateToSimilarMovies(id: Int) { + navController.navigate("${MainDestinations.TMDB_SIMILAR_MOVIES_ROUTE}/$id") + } + + fun navigateToSimilarTVShow(id: Int) { + navController.navigate("${MainDestinations.TMDB_SIMILAR_TV_SHOW_ROUTE}/$id") + } } private val NavGraph.startDestination: NavDestination? 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 75358cc..406c1d8 100644 --- a/common/src/main/java/com/sample/tmdb/common/MainDestinations.kt +++ b/common/src/main/java/com/sample/tmdb/common/MainDestinations.kt @@ -27,4 +27,7 @@ object MainDestinations { const val TMDB_IMAGES_ROUTE = "images" const val TMDB_IMAGES_KEY = "imagesKey" const val TMDB_IMAGE_PAGE = "imagePage" + const val TMDB_SIMILAR_MOVIES_ROUTE = "similar_movies" + const val TMDB_SIMILAR_TV_SHOW_ROUTE = "similar_tv_show" + const val TMDB_SIMILAR_ID = "similarId" } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/di/RepositoryModule.kt b/core/data/src/main/java/com/sample/tmdb/data/di/RepositoryModule.kt index ee55abc..8c20f4d 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/di/RepositoryModule.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/di/RepositoryModule.kt @@ -14,6 +14,7 @@ import com.sample.tmdb.domain.repository.BaseDetailRepository import com.sample.tmdb.domain.repository.BaseFeedRepository import com.sample.tmdb.domain.repository.BasePagingRepository import com.sample.tmdb.domain.repository.BookmarkItemDetailsRepository +import com.sample.tmdb.domain.utils.Similar import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -70,6 +71,12 @@ abstract class RepositoryModule { @Binds internal abstract fun bindDiscoverMoviesRepository(discoverMoviesPagingRepository: DiscoverMoviesPagingRepository): BasePagingRepository + @Singleton + @Similar + @Binds + internal abstract fun bindSimilarMoviesRepository(similarMoviesPagingRepository: SimilarMoviesPagingRepository): BasePagingRepository + + @Singleton @Search @Binds @@ -105,6 +112,12 @@ abstract class RepositoryModule { @Binds internal abstract fun bindDiscoverTVShowRepository(discoverTvSeriesPagingRepository: DiscoverTvSeriesPagingRepository): BasePagingRepository + @Singleton + @Similar + @Binds + internal abstract fun bindSimilarTVShowRepository(similarTvSeriesPagingRepository: SimilarTvSeriesPagingRepository): BasePagingRepository + + @Singleton @Search @Binds diff --git a/core/data/src/main/java/com/sample/tmdb/data/paging/movie/SimilarMoviesPagingSource.kt b/core/data/src/main/java/com/sample/tmdb/data/paging/movie/SimilarMoviesPagingSource.kt new file mode 100644 index 0000000..35e07a3 --- /dev/null +++ b/core/data/src/main/java/com/sample/tmdb/data/paging/movie/SimilarMoviesPagingSource.kt @@ -0,0 +1,17 @@ +package com.sample.tmdb.data.paging.movie + +import android.content.Context +import com.sample.tmdb.data.network.MovieService +import com.sample.tmdb.data.response.asMovieDomainModel +import com.sample.tmdb.domain.model.Movie +import com.sample.tmdb.domain.paging.BasePagingSource + +class SimilarMoviesPagingSource( + context: Context, + private val movieApi: MovieService, + private val movieId: Int +) : BasePagingSource(context) { + + override suspend fun fetchItems(page: Int): List = + movieApi.fetchSimilarMovies(movieId, page).items.asMovieDomainModel() +} \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/paging/tvshow/SimilarTvSeriesPagingSource.kt b/core/data/src/main/java/com/sample/tmdb/data/paging/tvshow/SimilarTvSeriesPagingSource.kt new file mode 100644 index 0000000..dc3d0a2 --- /dev/null +++ b/core/data/src/main/java/com/sample/tmdb/data/paging/tvshow/SimilarTvSeriesPagingSource.kt @@ -0,0 +1,17 @@ +package com.sample.tmdb.data.paging.tvshow + +import android.content.Context +import com.sample.tmdb.data.network.TVShowService +import com.sample.tmdb.data.response.asTVShowDomainModel +import com.sample.tmdb.domain.model.TVShow +import com.sample.tmdb.domain.paging.BasePagingSource + +class SimilarTvSeriesPagingSource( + context: Context, + private val tvShowApi: TVShowService, + private val tvId: Int +) : BasePagingSource(context) { + + override suspend fun fetchItems(page: Int): List = + tvShowApi.fetchSimilarMovies(tvId, page).items.asTVShowDomainModel() +} \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/AiringTodayTvSeriesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/AiringTodayTvSeriesPagingRepository.kt index 45906d4..24c40ca 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/AiringTodayTvSeriesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/AiringTodayTvSeriesPagingRepository.kt @@ -16,6 +16,6 @@ class AiringTodayTvSeriesPagingRepository @Inject constructor( private val tvShowApi: TVShowService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = AiringTodayTvSeriesPagingSource(context, tvShowApi) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/DiscoverMoviesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/DiscoverMoviesPagingRepository.kt index f400429..9c8274c 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/DiscoverMoviesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/DiscoverMoviesPagingRepository.kt @@ -16,6 +16,6 @@ class DiscoverMoviesPagingRepository @Inject constructor( private val movieApi: MovieService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = DiscoverMoviesPagingSource(context, movieApi) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/DiscoverTvSeriesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/DiscoverTvSeriesPagingRepository.kt index f3c0440..1c7f490 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/DiscoverTvSeriesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/DiscoverTvSeriesPagingRepository.kt @@ -16,6 +16,6 @@ class DiscoverTvSeriesPagingRepository @Inject constructor( private val tvShowApi: TVShowService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = DiscoverTvSeriesPagingSource(context, tvShowApi) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/NowPlayingMoviesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/NowPlayingMoviesPagingRepository.kt index 6afd9f7..3f8a6f8 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/NowPlayingMoviesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/NowPlayingMoviesPagingRepository.kt @@ -16,6 +16,6 @@ class NowPlayingMoviesPagingRepository @Inject constructor( private val movieApi: MovieService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = NowPlayingMoviesPagingSource(context, movieApi) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/OnTheAirTvSeriesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/OnTheAirTvSeriesPagingRepository.kt index 2db33e6..d4f29ae 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/OnTheAirTvSeriesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/OnTheAirTvSeriesPagingRepository.kt @@ -16,6 +16,6 @@ class OnTheAirTvSeriesPagingRepository @Inject constructor( private val tvShowApi: TVShowService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = OnTheAirTvSeriesPagingSource(context, tvShowApi) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/PopularMoviesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/PopularMoviesPagingRepository.kt index 3f96cf0..6ff8bd8 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/PopularMoviesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/PopularMoviesPagingRepository.kt @@ -16,6 +16,6 @@ class PopularMoviesPagingRepository @Inject constructor( private val movieApi: MovieService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = PopularMoviesPagingSource(context, movieApi) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/PopularTvSeriesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/PopularTvSeriesPagingRepository.kt index a273ba9..b257455 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/PopularTvSeriesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/PopularTvSeriesPagingRepository.kt @@ -16,6 +16,6 @@ class PopularTvSeriesPagingRepository @Inject constructor( private val tvShowApi: TVShowService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = PopularTvSeriesPagingSource(context, tvShowApi) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/SearchMoviesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/SearchMoviesPagingRepository.kt index 07aa019..a02e9ec 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/SearchMoviesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/SearchMoviesPagingRepository.kt @@ -16,6 +16,6 @@ class SearchMoviesPagingRepository @Inject constructor( private val movieApi: MovieService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = SearchMoviesPagingSource(context, movieApi, query!!) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/SearchTvSeriesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/SearchTvSeriesPagingRepository.kt index e9accf8..2ed3c41 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/SearchTvSeriesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/SearchTvSeriesPagingRepository.kt @@ -14,6 +14,6 @@ class SearchTvSeriesPagingRepository@Inject constructor( private val tvShowApi: TVShowService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = SearchTvSeriesPagingSource(context, tvShowApi, query!!) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/SimilarMoviesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/SimilarMoviesPagingRepository.kt new file mode 100644 index 0000000..611661f --- /dev/null +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/SimilarMoviesPagingRepository.kt @@ -0,0 +1,21 @@ +package com.sample.tmdb.data.repository + +import android.content.Context +import com.sample.tmdb.data.network.MovieService +import com.sample.tmdb.data.paging.movie.SimilarMoviesPagingSource +import com.sample.tmdb.domain.model.Movie +import com.sample.tmdb.domain.paging.BasePagingSource +import com.sample.tmdb.domain.repository.BasePagingRepository +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SimilarMoviesPagingRepository @Inject constructor( + @ApplicationContext private val context: Context, + private val movieApi: MovieService +) : BasePagingRepository() { + + override fun pagingSource(query: String?, id: Int?): BasePagingSource = + SimilarMoviesPagingSource(context, movieApi, id!!) +} \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/SimilarTvSeriesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/SimilarTvSeriesPagingRepository.kt new file mode 100644 index 0000000..2eb052d --- /dev/null +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/SimilarTvSeriesPagingRepository.kt @@ -0,0 +1,21 @@ +package com.sample.tmdb.data.repository + +import android.content.Context +import com.sample.tmdb.data.network.TVShowService +import com.sample.tmdb.data.paging.tvshow.SimilarTvSeriesPagingSource +import com.sample.tmdb.domain.model.TVShow +import com.sample.tmdb.domain.paging.BasePagingSource +import com.sample.tmdb.domain.repository.BasePagingRepository +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SimilarTvSeriesPagingRepository @Inject constructor( + @ApplicationContext private val context: Context, + private val tvShowApi: TVShowService +) : BasePagingRepository() { + + override fun pagingSource(query: String?, id: Int?): BasePagingSource = + SimilarTvSeriesPagingSource(context, tvShowApi, id!!) +} \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/TopRatedMoviesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/TopRatedMoviesPagingRepository.kt index b805a07..9cc2830 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/TopRatedMoviesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/TopRatedMoviesPagingRepository.kt @@ -16,6 +16,6 @@ class TopRatedMoviesPagingRepository @Inject constructor( private val movieApi: MovieService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = TopRatedMoviesPagingSource(context, movieApi) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/TopRatedTvSeriesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/TopRatedTvSeriesPagingRepository.kt index e6e1f3e..5a6c720 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/TopRatedTvSeriesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/TopRatedTvSeriesPagingRepository.kt @@ -16,6 +16,6 @@ class TopRatedTvSeriesPagingRepository @Inject constructor( private val tvShowApi: TVShowService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = TopRatedTvSeriesPagingSource(context, tvShowApi) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/TrendingMoviesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/TrendingMoviesPagingRepository.kt index cd8b22a..2696523 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/TrendingMoviesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/TrendingMoviesPagingRepository.kt @@ -16,6 +16,6 @@ class TrendingMoviesPagingRepository @Inject constructor( private val movieApi: MovieService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = TrendingMoviesPagingSource(context, movieApi) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/TrendingTvSeriesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/TrendingTvSeriesPagingRepository.kt index b1b50b2..c871854 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/TrendingTvSeriesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/TrendingTvSeriesPagingRepository.kt @@ -16,6 +16,6 @@ class TrendingTvSeriesPagingRepository @Inject constructor( private val tvShowApi: TVShowService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = TrendingTvSeriesPagingSource(context, tvShowApi) } \ No newline at end of file diff --git a/core/data/src/main/java/com/sample/tmdb/data/repository/UpcomingMoviesPagingRepository.kt b/core/data/src/main/java/com/sample/tmdb/data/repository/UpcomingMoviesPagingRepository.kt index 5b6f962..0a296f2 100644 --- a/core/data/src/main/java/com/sample/tmdb/data/repository/UpcomingMoviesPagingRepository.kt +++ b/core/data/src/main/java/com/sample/tmdb/data/repository/UpcomingMoviesPagingRepository.kt @@ -16,6 +16,6 @@ class UpcomingMoviesPagingRepository @Inject constructor( private val movieApi: MovieService ) : BasePagingRepository() { - override fun pagingSource(query: String?): BasePagingSource = + override fun pagingSource(query: String?, id: Int?): BasePagingSource = UpcomingMoviesPagingSource(context, movieApi) } \ No newline at end of file diff --git a/core/domain/src/main/java/com/sample/tmdb/domain/repository/BasePagingRepository.kt b/core/domain/src/main/java/com/sample/tmdb/domain/repository/BasePagingRepository.kt index 9e3ed49..be944ad 100644 --- a/core/domain/src/main/java/com/sample/tmdb/domain/repository/BasePagingRepository.kt +++ b/core/domain/src/main/java/com/sample/tmdb/domain/repository/BasePagingRepository.kt @@ -9,11 +9,11 @@ import kotlinx.coroutines.flow.Flow abstract class BasePagingRepository { - protected abstract fun pagingSource(query: String?): BasePagingSource + protected abstract fun pagingSource(query: String?, id: Int?): BasePagingSource - fun fetchResultStream(query: String?= null): Flow> = Pager( + fun fetchResultStream(query: String? = null, id: Int? = null): Flow> = Pager( config = PagingConfig(pageSize = NETWORK_PAGE_SIZE), - pagingSourceFactory = { pagingSource(query) } + pagingSourceFactory = { pagingSource(query, id) } ).flow companion object { diff --git a/core/domain/src/main/java/com/sample/tmdb/domain/utils/Annotations.kt b/core/domain/src/main/java/com/sample/tmdb/domain/utils/Annotations.kt index 928fec4..03e3332 100644 --- a/core/domain/src/main/java/com/sample/tmdb/domain/utils/Annotations.kt +++ b/core/domain/src/main/java/com/sample/tmdb/domain/utils/Annotations.kt @@ -28,4 +28,8 @@ annotation class Discover @Retention(AnnotationRetention.BINARY) @Qualifier -annotation class Search \ No newline at end of file +annotation class Search + +@Retention(AnnotationRetention.BINARY) +@Qualifier +annotation class Similar \ 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 5d0124b..a188d4d 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 @@ -130,6 +130,7 @@ fun MovieDetailScreen( onCreditSelected: (String) -> Unit, onImagesSelected: (List, Int) -> Unit, onTMDbItemSelected: (TMDbItem) -> Unit, + onAllSimilarSelected: (Int) -> Unit, viewModel: MovieDetailViewModel = hiltViewModel() ) { DetailScreen( @@ -139,7 +140,8 @@ fun MovieDetailScreen( onAllCrewSelected = onAllCrewSelected, onCreditSelected = onCreditSelected, onImagesSelected = onImagesSelected, - onTMDbItemSelected = onTMDbItemSelected + onTMDbItemSelected = onTMDbItemSelected, + onAllSimilarSelected = onAllSimilarSelected ) { details -> Movie( id = details.id, @@ -162,6 +164,7 @@ fun TVShowDetailScreen( onCreditSelected: (String) -> Unit, onImagesSelected: (List, Int) -> Unit, onTMDbItemSelected: (TMDbItem) -> Unit, + onAllSimilarSelected: (Int) -> Unit, viewModel: TVShowDetailViewModel = hiltViewModel() ) { DetailScreen( @@ -171,7 +174,8 @@ fun TVShowDetailScreen( onAllCrewSelected = onAllCrewSelected, onCreditSelected = onCreditSelected, onImagesSelected = onImagesSelected, - onTMDbItemSelected = onTMDbItemSelected + onTMDbItemSelected = onTMDbItemSelected, + onAllSimilarSelected = onAllSimilarSelected ) { details -> TVShow( id = details.id, @@ -195,6 +199,7 @@ private fun DetailScreen( onCreditSelected: (String) -> Unit, onImagesSelected: (List, Int) -> Unit, onTMDbItemSelected: (TMDbItem) -> Unit, + onAllSimilarSelected: (Int) -> Unit, getBookmarkedItem: (T) -> E ) { DetailScreen( @@ -205,6 +210,7 @@ private fun DetailScreen( onCreditSelected = onCreditSelected, onImagesSelected = onImagesSelected, onTMDbItemSelected = onTMDbItemSelected, + onAllSimilarSelected = onAllSimilarSelected, fab = { isFabVisible, isBookmark, details -> ToggleBookmarkFab(isBookmark = isBookmark, isVisible = isFabVisible) { if (isBookmark) { @@ -229,6 +235,7 @@ fun DetailScreen( onCreditSelected: (String) -> Unit, onImagesSelected: (List, Int) -> Unit, onTMDbItemSelected: (TMDbItem) -> Unit, + onAllSimilarSelected: (Int) -> Unit, fab: @Composable (MutableState, Boolean, T) -> Unit ) { // Visibility for FAB @@ -458,7 +465,7 @@ fun DetailScreen( TMDbDetailItemSection( items = it.similarItems, headerResId = R.string.similar, - onSeeAllClicked = {}, + onSeeAllClicked = { _ -> onAllSimilarSelected.invoke(it.details.id) }, itemContent = { item, _ -> TMDbCard(item, onTMDbItemSelected) }, diff --git a/features/feature-paging/src/main/java/com/sample/tmdb/paging/PagingScreen.kt b/features/feature-paging/src/main/java/com/sample/tmdb/paging/PagingScreen.kt index 9228088..19907e8 100644 --- a/features/feature-paging/src/main/java/com/sample/tmdb/paging/PagingScreen.kt +++ b/features/feature-paging/src/main/java/com/sample/tmdb/paging/PagingScreen.kt @@ -36,6 +36,7 @@ import com.sample.tmdb.common.utils.toDp import com.sample.tmdb.paging.main.movie.DiscoverMoviesViewModel import com.sample.tmdb.paging.main.movie.NowPlayingMoviesViewModel import com.sample.tmdb.paging.main.movie.PopularMoviesViewModel +import com.sample.tmdb.paging.main.movie.SimilarMoviesViewModel import com.sample.tmdb.paging.main.movie.TopRatedMoviesViewModel import com.sample.tmdb.paging.main.movie.TrendingMoviesViewModel import com.sample.tmdb.paging.main.movie.UpcomingMoviesViewModel @@ -43,6 +44,7 @@ import com.sample.tmdb.paging.main.tvshow.AiringTodayTvSeriesViewModel import com.sample.tmdb.paging.main.tvshow.DiscoverTvSeriesViewModel import com.sample.tmdb.paging.main.tvshow.OnTheAirTvSeriesViewModel import com.sample.tmdb.paging.main.tvshow.PopularTvSeriesViewModel +import com.sample.tmdb.paging.main.tvshow.SimilarTvSeriesViewModel import com.sample.tmdb.paging.main.tvshow.TopRatedTvSeriesViewModel import com.sample.tmdb.paging.main.tvshow.TrendingTvSeriesViewModel import com.sample.tmdb.common.R as R1 @@ -161,6 +163,25 @@ fun DiscoverMovieScreen( ) } +@Composable +fun SimilarMovieScreen( + onClick: (TMDbItem) -> Unit, + upPress: () -> Unit, + onSearchMovie: () -> Unit, + viewModel: SimilarMoviesViewModel = hiltViewModel() +) { + PagingScreen( + viewModel = viewModel, + onClick = onClick, + upPress = upPress, + onSearchClicked = onSearchMovie, + title = stringResource( + R.string.similar_items, + stringResource(R1.string.movies) + ) + ) +} + @Composable fun TrendingTVShowScreen( onClick: (TMDbItem) -> Unit, @@ -275,6 +296,25 @@ fun DiscoverTVShowScreen( ) } +@Composable +fun SimilarTVShowScreen( + onClick: (TMDbItem) -> Unit, + upPress: () -> Unit, + onSearchMovie: () -> Unit, + viewModel: SimilarTvSeriesViewModel = hiltViewModel() +) { + PagingScreen( + viewModel = viewModel, + onClick = onClick, + upPress = upPress, + onSearchClicked = onSearchMovie, + title = stringResource( + R.string.similar_items, + stringResource(R1.string.tv_series) + ) + ) +} + @Composable private fun PagingScreen( viewModel: BasePagingViewModel, diff --git a/features/feature-paging/src/main/java/com/sample/tmdb/paging/main/BaseMainPagingViewModel.kt b/features/feature-paging/src/main/java/com/sample/tmdb/paging/main/BaseMainPagingViewModel.kt index bb9e33b..8e447b0 100644 --- a/features/feature-paging/src/main/java/com/sample/tmdb/paging/main/BaseMainPagingViewModel.kt +++ b/features/feature-paging/src/main/java/com/sample/tmdb/paging/main/BaseMainPagingViewModel.kt @@ -8,9 +8,11 @@ import com.sample.tmdb.domain.repository.BasePagingRepository import com.sample.tmdb.paging.BasePagingViewModel import kotlinx.coroutines.flow.Flow -open class BaseMainPagingViewModel(repository: BasePagingRepository) : - BasePagingViewModel() { +open class BaseMainPagingViewModel( + repository: BasePagingRepository, + id: Int? = null +) : BasePagingViewModel() { override val pagingDataFlow: Flow> = - repository.fetchResultStream().cachedIn(viewModelScope) + repository.fetchResultStream(id = id).cachedIn(viewModelScope) } \ No newline at end of file diff --git a/features/feature-paging/src/main/java/com/sample/tmdb/paging/main/movie/SimilarMoviesViewModel.kt b/features/feature-paging/src/main/java/com/sample/tmdb/paging/main/movie/SimilarMoviesViewModel.kt new file mode 100644 index 0000000..63e7887 --- /dev/null +++ b/features/feature-paging/src/main/java/com/sample/tmdb/paging/main/movie/SimilarMoviesViewModel.kt @@ -0,0 +1,16 @@ +package com.sample.tmdb.paging.main.movie + +import androidx.lifecycle.SavedStateHandle +import com.sample.tmdb.common.MainDestinations +import com.sample.tmdb.domain.model.Movie +import com.sample.tmdb.domain.repository.BasePagingRepository +import com.sample.tmdb.domain.utils.Similar +import com.sample.tmdb.paging.main.BaseMainPagingViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class SimilarMoviesViewModel @Inject constructor( + @Similar repository: BasePagingRepository, + savedStateHandle: SavedStateHandle, +) : BaseMainPagingViewModel(repository, savedStateHandle[MainDestinations.TMDB_SIMILAR_ID]) \ No newline at end of file diff --git a/features/feature-paging/src/main/java/com/sample/tmdb/paging/main/tvshow/SimilarTvSeriesViewModel.kt b/features/feature-paging/src/main/java/com/sample/tmdb/paging/main/tvshow/SimilarTvSeriesViewModel.kt new file mode 100644 index 0000000..d55a47d --- /dev/null +++ b/features/feature-paging/src/main/java/com/sample/tmdb/paging/main/tvshow/SimilarTvSeriesViewModel.kt @@ -0,0 +1,16 @@ +package com.sample.tmdb.paging.main.tvshow + +import androidx.lifecycle.SavedStateHandle +import com.sample.tmdb.common.MainDestinations +import com.sample.tmdb.domain.model.TVShow +import com.sample.tmdb.domain.repository.BasePagingRepository +import com.sample.tmdb.domain.utils.Similar +import com.sample.tmdb.paging.main.BaseMainPagingViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class SimilarTvSeriesViewModel @Inject constructor( + @Similar repository: BasePagingRepository, + savedStateHandle: SavedStateHandle, +) : BaseMainPagingViewModel(repository, savedStateHandle[MainDestinations.TMDB_SIMILAR_ID]) \ No newline at end of file diff --git a/features/feature-paging/src/main/res/values/strings.xml b/features/feature-paging/src/main/res/values/strings.xml index 0d9520c..bf12883 100644 --- a/features/feature-paging/src/main/res/values/strings.xml +++ b/features/feature-paging/src/main/res/values/strings.xml @@ -8,6 +8,7 @@ On the air %s Top Rated %s Discover %s + Similar %s Search Clear \ No newline at end of file