Skip to content

Instantly share code, notes, and snippets.

@zsoltk
Created November 7, 2018 16:41
Show Gist options
  • Save zsoltk/26444678bbb7b20c14ea47ae7d1d53d0 to your computer and use it in GitHub Desktop.
Save zsoltk/26444678bbb7b20c14ea47ae7d1d53d0 to your computer and use it in GitHub Desktop.
sealed class Lce<out T> {
open val content: T? = null
open val error: Throwable? = null
open val isLoading: Boolean = false
object Loading : Lce<Nothing>() { override val isLoading: Boolean = true }
data class Content<out T>(override val content: T) : Lce<T>()
data class Error(override val error: Throwable) : Lce<Nothing>()
}
class Executor {
private val service = CatApi.service
fun loadRandomImage(): Observable<Lce<String>> {
return service.getRandomImage()
.map { Content(it) as Lce<String> }
.onErrorReturn { Error(it) }
.startWith(just(Loading))
.observeOn(AndroidSchedulers.mainThread())
}
}
class AsyncFeature : ActorReducerFeature<Wish, Effect, State, Nothing>(
initialState = State(),
actor = ActorImpl(),
reducer = ReducerImpl()
) {
data class State(
val image: Lce<String>? = null
)
sealed class Wish {
object LoadNewImage : Wish()
}
sealed class Effect {
data class ImageUpdate(val image: Lce<String>) : Effect()
}
class ActorImpl : Actor<State, Wish, Effect> {
private val executor = Executor()
override fun invoke(state: State, wish: Wish): Observable<Effect> = when (wish) {
is LoadNewImage -> executor
.loadRandomImage()
.map { Effect.ImageUpdate(it) }
}
}
class ReducerImpl : Reducer<State, Effect> {
override fun invoke(state: State, effect: Effect): State = when (effect) {
is Effect.ImageUpdate -> state.copy(
image = effect.image
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment