Skip to content

Commit

Permalink
Merge pull request #76 from sheikh-20/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
sheikh-20 authored Jun 16, 2024
2 parents 0647d41 + d235bb9 commit 6092096
Show file tree
Hide file tree
Showing 13 changed files with 457 additions and 62 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ android {
applicationId = "com.application.moviesapp"
minSdk = 24
targetSdk = 33
versionCode = 14
versionName = "1.0.13"
versionCode = 16
versionName = "1.0.15"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.application.moviesapp.data.api.response.TvSeriesTrailerDto
import com.application.moviesapp.data.remote.MovieNewReleasesDto
import com.application.moviesapp.data.remote.MovieUpcomingDto
import com.application.moviesapp.data.remote.MoviesDiscoverDto
import com.application.moviesapp.data.remote.TvSeriesFavouriteDto
import okhttp3.RequestBody
import retrofit2.Response
import retrofit2.http.Body
Expand Down Expand Up @@ -111,6 +112,10 @@ interface MoviesApi {
@GET("/3/account/{account_id}/favorite/movies")
suspend fun getMovieFavourite(@Path("account_id") accountId: Int = 20210857, @Query("language") language: String = "en-US", @Query("page") page: Int = 1): Response<MovieFavouriteDto>

@GET("/3/account/{account_id}/favorite/tv")
suspend fun getTvSeriesFavourite(@Path("account_id") accountId: Int = 20210857, @Query("language") language: String = "en-US", @Query("page") page: Int = 1): Response<TvSeriesFavouriteDto>


@POST("/3/account/{account_id}/favorite")
suspend fun updateMovieFavourite(@Path("account_id") accountId: Int = 20210857, @Body body: RequestBody): Response<MovieUpdateFavouriteDto>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.application.moviesapp.data.mappers

import com.application.moviesapp.data.remote.TvSeriesFavouriteDto
import com.application.moviesapp.domain.model.TvSeriesFavourite

fun TvSeriesFavouriteDto.Result.toDomain(): TvSeriesFavourite {
return TvSeriesFavourite(
adult, backdropPath, firstAirDate, genreIds, id, name, originCountry, originalLanguage, originalName, overview, popularity, posterPath, voteAverage, voteCount
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.application.moviesapp.data.remote

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer


@Serializable
data class TvSeriesFavouriteDto(
@SerialName("page")
val page: Int?,

@SerialName("results")
val results: List<Result?>?,

@SerialName("total_pages")
val totalPages: Int?,

@SerialName("total_results")
val totalResults: Int?
) {

@Serializable
data class Result(

@SerialName("adult")
val adult: Boolean?,

@SerialName("backdrop_path")
val backdropPath: String?,

@SerialName("first_air_date")
val firstAirDate: String?,

@SerialName("genre_ids")
val genreIds: List<Int?>?,

@SerialName("id")
val id: Int?,

@SerialName("name")
val name: String?,

@SerialName("origin_country")
val originCountry: List<String?>?,

@SerialName("original_language")
val originalLanguage: String?,

@SerialName("original_name")
val originalName: String?,

@SerialName("overview")
val overview: String?,

@SerialName("popularity")
val popularity: Double?,

@SerialName("poster_path")
val posterPath: String?,

@SerialName("vote_average")
val voteAverage: Double?,

@SerialName("vote_count")
val voteCount: Int?
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.application.moviesapp.data.remote

import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.application.moviesapp.data.api.MoviesApi

class TvSeriesFavouritePagingSource(private val moviesApi: MoviesApi): PagingSource<Int, TvSeriesFavouriteDto.Result>() {
override fun getRefreshKey(state: PagingState<Int, TvSeriesFavouriteDto.Result>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, TvSeriesFavouriteDto.Result> {

return try {
val page = params.key ?: 1

val apiResult = moviesApi.getTvSeriesFavourite(page = page)
val movies = if (apiResult.isSuccessful) {
apiResult.body()
} else if (apiResult.code() == 400 || apiResult.code() == 401 || apiResult.code() == 403) {
throw Throwable()
} else {
throw Throwable()
}

LoadResult.Page(
data = movies?.results?.map { it ?: TvSeriesFavouriteDto.Result(null, null, null, null, null, null, null, null, null, null, null, null, null, null)} ?: listOf(),
prevKey = if (page == 1) null else page.minus(1),
nextKey = if (movies?.results?.isEmpty() == true) null else page.plus(1),
)
} catch (throwable: Throwable) {
LoadResult.Error(throwable)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import com.application.moviesapp.data.remote.MovieUpcomingDto
import com.application.moviesapp.data.remote.MoviesDiscoverDto
import com.application.moviesapp.data.remote.MoviesDiscoverPagingSource
import com.application.moviesapp.data.remote.TvSeriesDiscoverPagingSource
import com.application.moviesapp.data.remote.TvSeriesFavouriteDto
import com.application.moviesapp.data.remote.TvSeriesFavouritePagingSource
import com.application.moviesapp.data.remote.TvSeriesNowPlayingPagingSource
import com.application.moviesapp.data.remote.TvSeriesSearchPagingSource
import kotlinx.coroutines.flow.Flow
Expand Down Expand Up @@ -72,6 +74,8 @@ interface MoviesRepository {

fun getFavouriteMoviesPagingFlow(): Flow<PagingData<MovieFavouriteDto.Result>>

fun getFavouriteTvSeriesPagingFlow(): Flow<PagingData<TvSeriesFavouriteDto.Result>>

suspend fun getMoviesUpcoming(): MovieUpcomingDto

fun getTvSeriesNowPlayingPagingFlow(): Flow<PagingData<TvSeriesNowPlayingDto.Result>>
Expand Down Expand Up @@ -185,6 +189,13 @@ class MoviesRepositoryImpl @Inject constructor(private val movies: MoviesApi,
}
).flow

override fun getFavouriteTvSeriesPagingFlow(): Flow<PagingData<TvSeriesFavouriteDto.Result>> = Pager(
config = PagingConfig(pageSize = 20),
pagingSourceFactory = {
TvSeriesFavouritePagingSource(movies)
}
).flow

override suspend fun getMoviesDetailById(movieId: Int): Response<MovieDetailsDto> = movies.getMovieDetailsById(movieId)

override suspend fun getTvSeriesDetailById(tvSeriesId: Int): Response<TvSeriesDetailsDto> = movies.getTvSeriesDetailsId(tvSeriesId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import com.application.moviesapp.domain.usecase.GetPasswordResetInteractors
import com.application.moviesapp.domain.usecase.GetSettingsInteractor
import com.application.moviesapp.domain.usecase.GetTvSeriesDetailsInteractor
import com.application.moviesapp.domain.usecase.GetTvSeriesEpisodesUseCase
import com.application.moviesapp.domain.usecase.GetTvSeriesFavouriteInteractor
import com.application.moviesapp.domain.usecase.GetTvSeriesGenreInteractor
import com.application.moviesapp.domain.usecase.GetTvSeriesNowPlayingInteractor
import com.application.moviesapp.domain.usecase.GetTvSeriesSearchInteractor
Expand Down Expand Up @@ -69,6 +70,7 @@ import com.application.moviesapp.domain.usecase.SignUpEmailInteractor
import com.application.moviesapp.domain.usecase.SignUpEmailUseCase
import com.application.moviesapp.domain.usecase.TvSeriesDetailsUseCase
import com.application.moviesapp.domain.usecase.TvSeriesEpisodesUseCase
import com.application.moviesapp.domain.usecase.TvSeriesFavouriteUseCase
import com.application.moviesapp.domain.usecase.TvSeriesGenreUseCase
import com.application.moviesapp.domain.usecase.TvSeriesNowPlayingUseCase
import com.application.moviesapp.domain.usecase.TvSeriesSearchUseCase
Expand Down Expand Up @@ -190,6 +192,12 @@ class UseCaseModule {
}


@Provides
@Singleton
fun providesTvSeriesFavouriteUseCase(moviesRepository: MoviesRepository): TvSeriesFavouriteUseCase {
return GetTvSeriesFavouriteInteractor(moviesRepository)
}

@Provides
@Singleton
fun providesMovieUpdateFavouriteUseCase(moviesRepository: MoviesRepository): MovieUpdateFavouriteUseCase {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.application.moviesapp.domain.model


data class TvSeriesFavourite(
val adult: Boolean?,
val backdropPath: String?,
val firstAirDate: String?,
val genreIds: List<Int?>?,
val id: Int?,
val name: String?,
val originCountry: List<String?>?,
val originalLanguage: String?,
val originalName: String?,
val overview: String?,
val popularity: Double?,
val posterPath: String?,
val voteAverage: Double?,
val voteCount: Int?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.application.moviesapp.domain.usecase

import androidx.paging.PagingData
import androidx.paging.map
import com.application.moviesapp.data.mappers.toDomain
import com.application.moviesapp.data.mappers.toMovie
import com.application.moviesapp.data.remote.TvSeriesFavouriteDto
import com.application.moviesapp.data.repository.MoviesRepository
import com.application.moviesapp.domain.model.MovieFavourite
import com.application.moviesapp.domain.model.TvSeriesFavourite
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject

interface TvSeriesFavouriteUseCase {
operator fun invoke(): Flow<PagingData<TvSeriesFavourite>>
}

class GetTvSeriesFavouriteInteractor @Inject constructor(private val repository: MoviesRepository): TvSeriesFavouriteUseCase {

private companion object {
const val TAG = "GetTvSeriesFavouriteInteractor"
}

override fun invoke(): Flow<PagingData<TvSeriesFavourite>> = repository.getFavouriteTvSeriesPagingFlow().map {
it.map { tvSeries -> tvSeries.toDomain() }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ fun DetailScreen(modifier: Modifier = Modifier,
IconButton(onClick = {
isFavorite = bookmarkUiState.data.favorite != true

onBookmarkClicked("movie", tvSeriesUIState.data.id ?: 0, bookmarkUiState.data.favorite != true)
onBookmarkClicked("tv", tvSeriesUIState.data.id ?: 0, bookmarkUiState.data.favorite != true)
coroutineScope.launch {
snackbarHostState.showSnackbar(message = "Bookmark updated")
}
Expand Down
15 changes: 7 additions & 8 deletions app/src/main/java/com/application/moviesapp/ui/home/HomeApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Divider
import androidx.compose.material.Snackbar
import androidx.compose.material.TextButton
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Tune
import androidx.compose.material.icons.rounded.Bookmark
Expand All @@ -46,7 +44,6 @@ import androidx.compose.material.icons.rounded.NotificationsNone
import androidx.compose.material.icons.rounded.Person
import androidx.compose.material.icons.rounded.PlayCircle
import androidx.compose.material.icons.rounded.Search
import androidx.compose.material3.AssistChip
import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.Button
import androidx.compose.material3.Card
Expand Down Expand Up @@ -82,7 +79,6 @@ import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
Expand Down Expand Up @@ -143,9 +139,7 @@ import com.application.moviesapp.ui.viewmodel.OnboardingViewModel
import com.application.moviesapp.ui.viewmodel.ProfileViewModel
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import timber.log.Timber
import java.io.File

private const val TAG = "HomeApp"
Expand Down Expand Up @@ -196,7 +190,8 @@ fun HomeApp(modifier: Modifier = Modifier,

val moviesSearchFlowState = exploreViewModel.getMovieBySearch(searchUiState.search).collectAsLazyPagingItems()

val myListFlowState = myListViewModel.getMovieFavouritePagingFlow.collectAsLazyPagingItems()
val myListMoviesFlowState = myListViewModel.getMovieFavouritePagingFlow.collectAsLazyPagingItems()
val myListTvSeriesFlowState = myListViewModel.getTvSeriesFavouritePagingFlow.collectAsLazyPagingItems()

val coroutineScope = rememberCoroutineScope()
var showBottomSheet by remember { mutableStateOf(BottomSheet.Default) }
Expand Down Expand Up @@ -357,6 +352,8 @@ fun HomeApp(modifier: Modifier = Modifier,
}

val myListScrollState = rememberLazyGridState()
val myListTvSeriesScrollState = rememberLazyGridState()

val myListHideTopAppBar by remember(myListScrollState) {
derivedStateOf {
myListScrollState.firstVisibleItemIndex == 0
Expand Down Expand Up @@ -467,8 +464,10 @@ fun HomeApp(modifier: Modifier = Modifier,
composable(route = BottomNavigationScreens.MyList.route) {
MyListScreen(
modifier = modifier,
moviesFavouriteFlow = myListFlowState,
moviesFavouriteFlow = myListMoviesFlowState,
tvSeriesFavouriteFlow = myListTvSeriesFlowState,
lazyGridState = myListScrollState,
lazyTvSeriesGridState = myListTvSeriesScrollState,
bottomPadding = paddingValues)
}
composable(route = BottomNavigationScreens.Download.route) {
Expand Down
Loading

0 comments on commit 6092096

Please sign in to comment.