Skip to content

Instantly share code, notes, and snippets.

@KonstantinBerkow
Created January 29, 2018 17:21
Show Gist options
  • Save KonstantinBerkow/42cd40751df4c5e952a63487653028f6 to your computer and use it in GitHub Desktop.
Save KonstantinBerkow/42cd40751df4c5e952a63487653028f6 to your computer and use it in GitHub Desktop.
FrankensteinPresenter
@Singleton
class ImagePresentationPresenter
@Inject constructor(private val client: OkHttpClient) {
private val resultsRelay = PublishRelay.create<Result>().toSerialized()
private val states: Observable<UiState>
private val loadTransformer = ObservableTransformer<LoadImage, Result> {
it.flatMap { event ->
val url = event.url
when {
url.isBlank() -> {
val errors = singletonMap(Field.IMAGE_URL, FieldError.EMPTY_INPUT)
Observable.just(InputError(url, errors))
}
HttpUrl.parse(url) == null -> {
val errors = singletonMap(Field.IMAGE_URL, FieldError.ILLEGAL_URL_ADDRESS)
Observable.just(InputError(url, errors))
}
else -> performRequest(url).subscribeOn(Schedulers.io())
.map { LoadSuccessful as Result }
.onErrorReturn { error -> LoadFailed(error) }
.startWith(LoadInFlight(url))
}
}
}
init {
val initial = UiState(url = null)
states = resultsRelay
.scan(initial) { old, result -> result.alterState(old) }
.replay(1)
.autoConnect()
}
fun attachEvents(events: Observable<LoadImage>) {
events.observeOn(Schedulers.computation())
.ofType(LoadImage::class.java)
.compose(loadTransformer)
.subscribe(resultsRelay)
}
private fun performRequest(url: String) = Observable.create<Response> {
val request = Request.Builder().url(url).get().build()
val call = client.newCall(request)
call.enqueue(object : Callback {
override fun onFailure(call: Call, error: IOException) {
it.onError(error)
}
override fun onResponse(call: Call, response: Response) {
it.onNext(response)
it.onComplete()
}
})
it.setCancellable { call.cancel() }
}
fun states(): Observable<UiState> = states
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment