-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathBaseViewModel.kt
More file actions
66 lines (56 loc) · 2.01 KB
/
Copy pathBaseViewModel.kt
File metadata and controls
66 lines (56 loc) · 2.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package com.getcode.view
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.coroutines.CoroutineContext
abstract class BaseViewModel<ViewState : Any, Event : Any>(
initialState: ViewState,
private val updateStateForEvent: (Event) -> (ViewState.() -> ViewState),
private val defaultDispatcher: CoroutineContext = Dispatchers.Default,
) : ViewModel() {
private val _eventFlow: MutableSharedFlow<Event> = MutableSharedFlow()
val eventFlow: SharedFlow<Event> = _eventFlow.asSharedFlow()
private val _stateFlow: MutableStateFlow<ViewState> = MutableStateFlow(initialState)
val stateFlow: StateFlow<ViewState> = _stateFlow.asStateFlow()
fun dispatchEvent(event: Event) {
setState(updateStateForEvent(event))
viewModelScope.launch(defaultDispatcher) {
_eventFlow.emit(event)
}
}
suspend fun dispatchEvent(context: CoroutineContext, event: Event) {
withContext(context) {
dispatchEvent(event)
}
}
private fun setState(update: ViewState.() -> ViewState) {
_stateFlow.value = _stateFlow.value.update()
}
}
data class LoadingSuccessState(
val loading: Boolean = false,
val success: Boolean = false,
val error: Boolean = false,
) {
sealed interface State {
data object Idle: State
data object Loading : State
data object Success : State
data object Error : State
}
val state: State = when {
loading -> State.Loading
success -> State.Success
error -> State.Error
else -> State.Idle
}
val isIdle: Boolean = state is State.Idle
}