commonMain.com.eygraber.vice.sources.LoadableFlowSource.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vice-sources-jvm Show documentation
Show all versions of vice-sources-jvm Show documentation
Implementations of ViceSource for use with vice-core
The newest version!
package com.eygraber.vice.sources
import androidx.compose.runtime.Stable
import com.eygraber.vice.loadable.ViceLoadable
import com.eygraber.vice.loadable.isLoading
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
import kotlin.time.TimeSource
@Stable
public abstract class LoadableFlowSource : StateFlowSource>() {
private val mutableFlow by lazy {
MutableStateFlow>(ViceLoadable.Loading(placeholder))
}
override val flow: StateFlow> by lazy { mutableFlow }
protected abstract val dataFlow: Flow
protected abstract val placeholder: T
protected open val initialLoadingThreshold: Duration = 200.milliseconds
protected open val minLoadingDuration: Duration = 1.seconds
protected open val isBufferingEmissionsWhileLoading: Boolean = false
override suspend fun onAttached(scope: CoroutineScope) {
val initialLoadingThreshold = TimeSource.Monotonic.markNow() + initialLoadingThreshold
val minLoadingThreshold = initialLoadingThreshold + minLoadingDuration
val collector: suspend (T) -> Unit = { value ->
if(flow.value.isLoading) {
val now = TimeSource.Monotonic.markNow()
if(now in initialLoadingThreshold.. dataFlow.collect(collector)
else -> dataFlow.collectLatest(collector)
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy