Skip to content

Commit

Permalink
Update project
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbel committed Feb 1, 2024
1 parent 831b23c commit fda85cf
Show file tree
Hide file tree
Showing 13 changed files with 47 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,12 @@ class Interactor @Inject constructor(
imageInteractor: ImageInteractor,
movieInteractor: MovieInteractor,
notificationInteractor: NotificationInteractor,
pagingKeyInteractor: PagingKeyInteractor,
searchInteractor: SearchInteractor,
settingsInteractor: SettingsInteractor,
suggestionInteractor: SuggestionInteractor
): AccountInteractor by accountInteractor,
AuthenticationInteractor by authenticationInteractor,
ImageInteractor by imageInteractor,
MovieInteractor by movieInteractor,
NotificationInteractor by notificationInteractor,
PagingKeyInteractor by pagingKeyInteractor,
SearchInteractor by searchInteractor,
SettingsInteractor by settingsInteractor,
SuggestionInteractor by suggestionInteractor
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import androidx.paging.PagingSource
import kotlinx.coroutines.flow.Flow
import org.michaelbel.movies.common.list.MovieList
import org.michaelbel.movies.network.Either
import org.michaelbel.movies.network.model.MovieResponse
import org.michaelbel.movies.persistence.database.entity.MovieDb

interface MovieInteractor {

fun moviesPagingData(movieList: MovieList): Flow<PagingData<MovieDb>>

fun moviesPagingData(searchQuery: String): Flow<PagingData<MovieDb>>

fun moviesPagingSource(pagingKey: String): PagingSource<Int, MovieDb>

fun moviesFlow(pagingKey: String, limit: Int): Flow<List<MovieDb>>
Expand All @@ -24,7 +25,5 @@ interface MovieInteractor {

suspend fun removeMovie(pagingKey: String, movieId: Int)

suspend fun insertMovies(pagingKey: String, movies: List<MovieResponse>)

suspend fun insertMovie(pagingKey: String, movie: MovieDb)
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,13 @@ import org.michaelbel.movies.interactor.AuthenticationInteractor
import org.michaelbel.movies.interactor.ImageInteractor
import org.michaelbel.movies.interactor.MovieInteractor
import org.michaelbel.movies.interactor.NotificationInteractor
import org.michaelbel.movies.interactor.PagingKeyInteractor
import org.michaelbel.movies.interactor.SearchInteractor
import org.michaelbel.movies.interactor.SettingsInteractor
import org.michaelbel.movies.interactor.SuggestionInteractor
import org.michaelbel.movies.interactor.impl.AccountInteractorImpl
import org.michaelbel.movies.interactor.impl.AuthenticationInteractorImpl
import org.michaelbel.movies.interactor.impl.ImageInteractorImpl
import org.michaelbel.movies.interactor.impl.MovieInteractorImpl
import org.michaelbel.movies.interactor.impl.NotificationInteractorImpl
import org.michaelbel.movies.interactor.impl.PagingKeyInteractorImpl
import org.michaelbel.movies.interactor.impl.SearchInteractorImpl
import org.michaelbel.movies.interactor.impl.SettingsInteractorImpl
import org.michaelbel.movies.interactor.impl.SuggestionInteractorImpl

Expand Down Expand Up @@ -58,18 +54,6 @@ internal interface InteractorModule {
interactor: NotificationInteractorImpl
): NotificationInteractor

@Binds
@Singleton
fun providePagingKeyInteractor(
interactor: PagingKeyInteractorImpl
): PagingKeyInteractor

@Binds
@Singleton
fun provideSearchInteractor(
interactor: SearchInteractorImpl
): SearchInteractor

@Binds
@Singleton
fun provideSettingsInteractor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@ import org.michaelbel.movies.common.dispatchers.MoviesDispatchers
import org.michaelbel.movies.common.list.MovieList
import org.michaelbel.movies.interactor.MovieInteractor
import org.michaelbel.movies.interactor.ktx.nameOrLocalList
import org.michaelbel.movies.interactor.remote.MoviesRemoteMediator
import org.michaelbel.movies.interactor.remote.FeedMoviesRemoteMediator
import org.michaelbel.movies.interactor.remote.SearchMoviesRemoteMediator
import org.michaelbel.movies.network.Either
import org.michaelbel.movies.network.model.MovieResponse
import org.michaelbel.movies.persistence.database.AppDatabase
import org.michaelbel.movies.persistence.database.entity.MovieDb
import org.michaelbel.movies.repository.MovieRepository
import org.michaelbel.movies.repository.PagingKeyRepository
import org.michaelbel.movies.repository.SearchRepository

@Singleton
internal class MovieInteractorImpl @Inject constructor(
private val dispatchers: MoviesDispatchers,
private val searchRepository: SearchRepository,
private val movieRepository: MovieRepository,
private val pagingKeyRepository: PagingKeyRepository,
private val database: AppDatabase,
Expand All @@ -33,7 +36,7 @@ internal class MovieInteractorImpl @Inject constructor(
config = PagingConfig(
pageSize = MovieResponse.DEFAULT_PAGE_SIZE
),
remoteMediator = MoviesRemoteMediator(
remoteMediator = FeedMoviesRemoteMediator(
movieRepository = movieRepository,
pagingKeyRepository = pagingKeyRepository,
database = database,
Expand All @@ -43,6 +46,22 @@ internal class MovieInteractorImpl @Inject constructor(
).flow
}

override fun moviesPagingData(searchQuery: String): Flow<PagingData<MovieDb>> {
return Pager(
config = PagingConfig(
pageSize = MovieResponse.DEFAULT_PAGE_SIZE
),
remoteMediator = SearchMoviesRemoteMediator(
pagingKeyRepository = pagingKeyRepository,
searchRepository = searchRepository,
movieRepository = movieRepository,
database = database,
query = searchQuery
),
pagingSourceFactory = { movieRepository.moviesPagingSource(searchQuery) }
).flow
}

override fun moviesPagingSource(pagingKey: String): PagingSource<Int, MovieDb> {
return movieRepository.moviesPagingSource(pagingKey)
}
Expand Down Expand Up @@ -78,12 +97,6 @@ internal class MovieInteractorImpl @Inject constructor(
}
}

override suspend fun insertMovies(pagingKey: String, movies: List<MovieResponse>) {
return withContext(dispatchers.io) {
movieRepository.insertMovies(pagingKey, movies)
}
}

override suspend fun insertMovie(pagingKey: String, movie: MovieDb) {
return withContext(dispatchers.io) {
movieRepository.insertMovie(pagingKey, movie)
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import org.michaelbel.movies.persistence.database.entity.MovieDb
import org.michaelbel.movies.repository.MovieRepository
import org.michaelbel.movies.repository.PagingKeyRepository

class MoviesRemoteMediator(
class FeedMoviesRemoteMediator(
private val pagingKeyRepository: PagingKeyRepository,
private val movieRepository: MovieRepository,
private val database: AppDatabase,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
package org.michaelbel.movies.search.remote
package org.michaelbel.movies.interactor.remote

import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.room.withTransaction
import org.michaelbel.movies.common.exceptions.PageEmptyException
import org.michaelbel.movies.interactor.Interactor
import org.michaelbel.movies.network.ktx.isEmpty
import org.michaelbel.movies.network.ktx.isPaginationReached
import org.michaelbel.movies.network.ktx.nextPage
import org.michaelbel.movies.network.model.MovieResponse
import org.michaelbel.movies.network.model.Result
import org.michaelbel.movies.persistence.database.AppDatabase
import org.michaelbel.movies.persistence.database.entity.MovieDb
import org.michaelbel.movies.repository.MovieRepository
import org.michaelbel.movies.repository.PagingKeyRepository
import org.michaelbel.movies.repository.SearchRepository

class SearchMoviesRemoteMediator(
private val interactor: Interactor,
private val pagingKeyRepository: PagingKeyRepository,
private val movieRepository: MovieRepository,
private val searchRepository: SearchRepository,
private val database: AppDatabase,
private val query: String
): RemoteMediator<Int, MovieDb>() {

Expand All @@ -31,15 +38,15 @@ class SearchMoviesRemoteMediator(
return reachedResult
}
LoadType.APPEND -> {
interactor.page(query) ?: return reachedResult
pagingKeyRepository.page(query) ?: return reachedResult
}
}

if (query.isEmpty()) {
throw PageEmptyException
}

val moviesResult: Result<MovieResponse> = interactor.searchMoviesResult(
val moviesResult: Result<MovieResponse> = searchRepository.searchMoviesResult(
query = query,
page = loadKey ?: 1
)
Expand All @@ -48,15 +55,13 @@ class SearchMoviesRemoteMediator(
throw PageEmptyException
}

if (loadType == LoadType.REFRESH) {
interactor.run {
removePagingKey(query)
removeMovies(query)
database.withTransaction {
if (loadType == LoadType.REFRESH) {
pagingKeyRepository.removePagingKey(query)
movieRepository.removeMovies(query)
}
}
interactor.run {
insertPagingKey(query, moviesResult.nextPage)
insertMovies(query, moviesResult.results)
pagingKeyRepository.insertPagingKey(query, moviesResult.nextPage)
movieRepository.insertMovies(query, moviesResult.results)
}

MediatorResult.Success(endOfPaginationReached = moviesResult.isPaginationReached)
Expand Down
4 changes: 1 addition & 3 deletions feature/search-impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ android {
kotlinOptions {
freeCompilerArgs = freeCompilerArgs + listOf(
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=androidx.compose.material3.ExperimentalMaterial3Api",
"-opt-in=androidx.paging.ExperimentalPagingApi"
"-opt-in=androidx.compose.material3.ExperimentalMaterial3Api"
)
}

Expand Down Expand Up @@ -59,7 +58,6 @@ dependencies {
implementation(project(":core:interactor"))
implementation(project(":core:network"))
implementation(project(":core:notifications"))
implementation(project(":core:persistence"))

testImplementation(libs.junit)
androidTestImplementation(libs.androidx.test.ext.junit.ktx)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.michaelbel.movies.search

import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.cachedIn
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -21,10 +19,8 @@ import org.michaelbel.movies.common.viewmodel.BaseViewModel
import org.michaelbel.movies.interactor.Interactor
import org.michaelbel.movies.network.connectivity.NetworkManager
import org.michaelbel.movies.network.connectivity.NetworkStatus
import org.michaelbel.movies.network.model.MovieResponse
import org.michaelbel.movies.persistence.database.entity.MovieDb
import org.michaelbel.movies.persistence.database.entity.SuggestionDb
import org.michaelbel.movies.search.remote.SearchMoviesRemoteMediator

@HiltViewModel
class SearchViewModel @Inject constructor(
Expand Down Expand Up @@ -66,24 +62,9 @@ class SearchViewModel @Inject constructor(
private val _active: MutableStateFlow<Boolean> = MutableStateFlow(true)
val active: StateFlow<Boolean> = _active.asStateFlow()

val pagingItems: Flow<PagingData<MovieDb>> = query.flatMapLatest { query ->
Pager(
config = PagingConfig(
pageSize = MovieResponse.DEFAULT_PAGE_SIZE
),
remoteMediator = SearchMoviesRemoteMediator(
interactor = interactor,
query = query
),
pagingSourceFactory = { interactor.moviesPagingSource(query) }
).flow
.stateIn(
scope = this,
started = SharingStarted.Lazily,
initialValue = PagingData.empty()
)
.cachedIn(this)
}
val pagingDataFlow: Flow<PagingData<MovieDb>> = query
.flatMapLatest { query -> interactor.moviesPagingData(query) }
.cachedIn(this)

init {
loadSuggestions()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fun SearchRoute(
modifier: Modifier = Modifier,
viewModel: SearchViewModel = hiltViewModel()
) {
val pagingItems: LazyPagingItems<MovieDb> = viewModel.pagingItems.collectAsLazyPagingItems()
val pagingItems: LazyPagingItems<MovieDb> = viewModel.pagingDataFlow.collectAsLazyPagingItems()
val currentFeedView: FeedView by viewModel.currentFeedView.collectAsStateWithLifecycle()
val networkStatus: NetworkStatus by viewModel.networkStatus.collectAsStateWithLifecycle()
val suggestions: List<SuggestionDb> by viewModel.suggestionsFlow.collectAsStateWithLifecycle()
Expand Down

0 comments on commit fda85cf

Please sign in to comment.