Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package travel.footsteps.city
- import android.databinding.ObservableArrayList
- import android.databinding.ObservableField
- import io.reactivex.Completable
- import io.reactivex.Observable
- import io.reactivex.ObservableSource
- import io.reactivex.ObservableTransformer
- import io.reactivex.internal.operators.completable.CompletableFromCallable
- import io.reactivex.schedulers.Schedulers
- import io.reactivex.subjects.PublishSubject
- import travel.footsteps.parseobjects.City
- import travel.footsteps.parseobjects.Track
- import travel.footsteps.ui.base.BaseViewModel
- import travel.footsteps.utils.usecase.*
- import travel.footsteps.waypoint.Waypoint
- import javax.inject.Inject
- class CityViewModel
- @Inject
- constructor(
- private val getCityUsecase: GetCityUsecase,
- private val getRoutesUsecase: GetRoutesUsecase,
- private val getWaypointsUsecase: GetWaypointsUsecase
- ) : BaseViewModel(), ObservableTransformer<UiEvent, UiEventResults> {
- private val eventSubject = PublishSubject.create<UiEvent>()
- val city = ObservableField<City>()
- val routes = ObservableArrayList<Track>()
- val waypoints = ObservableArrayList<Waypoint>()
- val uiStateObservable: Observable<CityUiState> = eventSubject
- .compose(this)
- .onErrorReturn { UiEventResults.Error(it) }
- .scan(INITIAL_UI_STATE, this::reduceUiState)
- .replay(1)
- .autoConnect()
- override fun apply(upstream: Observable<UiEvent>): ObservableSource<UiEventResults> {
- return upstream.switchMap { event ->
- when (event) {
- UiEvent.LOAD_DATA -> loadData()
- }
- }
- }
- fun sendUiEvent(uiEvent: UiEvent) {
- eventSubject.onNext(uiEvent)
- }
- private fun loadData(): Observable<UiEventResults> {
- return Completable.concatArray(loadCity(), loadRecommendedRoutes(), loadRecommendedWaypoints())
- .subscribeOn(Schedulers.io())
- .toSingleDefault(UiEventResults.Success as UiEventResults)
- .toObservable()
- .startWith(UiEventResults.Pending)
- }
- private fun loadCity(): Completable {
- return getCityUsecase
- .doOnSuccess { city.set(it) }
- .toCompletable()
- }
- private fun loadRecommendedRoutes(): Completable {
- return Observable.just(GetRoutesAction.GetRecommendedRoutes)
- .compose(getRoutesUsecase)
- .flatMapCompletable {
- Completable.fromCallable {
- routes.clear()
- routes.addAll(it)
- }
- }
- }
- private fun loadRecommendedWaypoints(): Completable {
- return Observable.just(GetWaypointsAction.GetWaypointsForRoutes(routes))
- .compose(getWaypointsUsecase)
- .flatMapCompletable {
- CompletableFromCallable {
- waypoints.clear()
- waypoints.addAll(it)
- }
- }
- }
- private fun reduceUiState(previousUiState: CityUiState, uiEventResults: UiEventResults): CityUiState {
- return when (uiEventResults) {
- UiEventResults.Success -> previousUiState.copy(false, true, null)
- UiEventResults.Pending -> previousUiState.copy(true, false, null)
- is UiEventResults.Error -> previousUiState.copy(false, false, null)
- UiEventResults.Default -> INITIAL_UI_STATE
- }
- }
- companion object {
- private val INITIAL_UI_STATE = CityUiState(false, false, null)
- }
- }
- sealed class UiAction {
- object LoadCityAction : UiAction()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement