Skip to content

Instantly share code, notes, and snippets.

@enyciaa
Last active April 6, 2024 12:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enyciaa/9c333b75be5f8c9fd90be8956cbf0fb5 to your computer and use it in GitHub Desktop.
Save enyciaa/9c333b75be5f8c9fd90be8956cbf0fb5 to your computer and use it in GitHub Desktop.
class MviViewModel(
private val answerService: AnswerService,
) {
private val coroutineScope = MainScope()
private val _viewState: MutableStateFlow<ViewState> = MutableStateFlow(ViewState())
val viewState = _viewState.asStateFlow()
// See https://proandroiddev.com/android-singleliveevent-redux-with-kotlin-flow-b755c70bb055
// For why channel > SharedFlow/StateFlow in this case
private val _oneShotEvents = Channel<OneShotEvent>(Channel.BUFFERED)
val oneShotEvents = _oneShotEvents.receiveAsFlow()
fun onAction(uiAction: UiAction) {
when (uiAction) {
is UiAction.AnswerConfirmed -> {
coroutineScope.launch {
_viewState.value = _viewState.value.copy(isLoading = true)
withContext(Dispatchers.IO) { answerService.save(uiAction.answer) }
val text = if (uiAction.answer == "Nacho cheese") {
"You've heard too many cheese jokes"
} else {
"Nacho cheese"
}
_viewState.value = _viewState.value.copy(textToDisplay = text)
_oneShotEvents.send(OneShotEvent.NavigateToResults)
_viewState.value = _viewState.value.copy(isLoading = false)
}
}
}
}
data class ViewState(
val isLoading: Boolean = false,
val textToDisplay: String = "",
)
sealed class OneShotEvent {
object NavigateToResults : OneShotEvent()
}
sealed class UiAction {
class AnswerConfirmed(val answer: String) : UiAction()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment