Skip to content

Instantly share code, notes, and snippets.

@PaulWoitaschek
Created July 17, 2019 14:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PaulWoitaschek/7e6318614307556fae6770556f83c570 to your computer and use it in GitHub Desktop.
Save PaulWoitaschek/7e6318614307556fae6770556f83c570 to your computer and use it in GitHub Desktop.
@file:Suppress("EXPERIMENTAL_API_USAGE")
package my.something.t
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking
import kotlinx.io.IOException
data class ViewState(val content: String?, val loading: Boolean, val showError: Boolean)
fun contentFlow(): Flow<String> {
return flow {
var index = 0
while (true) {
index++
if (index == 10) {
throw IOException()
}
delay(250)
emit(index.toString())
}
}
}
fun viewState(repeat: Flow<Unit>): Flow<ViewState> {
val initialState = ViewState(content = null, loading = true, showError = false)
return flow {
emit(initialState)
var lastState = initialState
suspend fun updateAndEmit(update: ViewState.() -> ViewState) {
lastState = update(lastState)
emit(lastState)
}
repeat.startContentFlow(::updateAndEmit)
}
}
suspend fun <T> Flow<T>.startContentFlow(updateAndEmit: suspend (ViewState.() -> ViewState) ->Unit) {
try {
contentFlow().collect {
updateAndEmit { copy(content = it, loading = false) }
}
} catch (t: IOException) {
updateAndEmit { copy(loading = false, showError = true) }
take(1).collect {
updateAndEmit { copy(loading = true, showError = false) }
startContentFlow(updateAndEmit)
}
}
}
fun main(){
runBlocking {
val repeatAfterOneSecond = flowOf(Unit).delayFlow(1000)
viewState(repeatAfterOneSecond).collect {
println(it)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment