Untitled
unknown
kotlin
2 years ago
2.2 kB
2
Indexable
Never
package com.voraapp.vora.base import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.launch abstract class BaseViewModel<S : State, A : Action, E : Effect, H : ActionHandler<S, A>>( private val actionHandler: H, ) : ViewModel() { abstract val initialState: S private val _states: MutableStateFlow<S> by lazy { MutableStateFlow(initialState) } val states: StateFlow<S> get() = _states private val actions = Channel<A>() val effects = Channel<E>() fun offer(action: A) { viewModelScope.launch { actions.send(action) } } @Suppress("UNCHECKED_CAST") protected fun observeActions() { viewModelScope.launch { actions.receiveAsFlow().onEach { when (val action = actionHandler.handle(states.value, it)) { is EffectResult -> { sendEffects(action.effects as List<E>) } is StateResult -> { println("sinan: state: ${action.state}") _states.emit(action.state as S) } } }.collect() } } private suspend fun sendEffects(effects: List<E>) { effects.forEach { this.effects.send(it) } } } abstract class ActionHandler<S : State, A : Action> { abstract suspend fun handle(state: S, action: A): Result } fun <E : Effect> ActionHandler<*, *>.effect(e: E): Result = EffectResult(listOf(e)) fun <E : Effect> ActionHandler<*, *>.effects(e: List<E>): Result = EffectResult(e) fun <S : State> ActionHandler<S, *>.state(s: S): Result = StateResult(s) interface Action interface State interface Effect sealed class Result internal data class EffectResult(val effects: List<Effect>) : Result() internal data class StateResult(val state: State) : Result()