Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@GuilhE
Last active February 16, 2024 01:05
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 GuilhE/7385d9f9b8cf970d94272a54a8d31db3 to your computer and use it in GitHub Desktop.
Save GuilhE/7385d9f9b8cf970d94272a54a8d31db3 to your computer and use it in GitHub Desktop.
Medium articles - MVI+FSM
class TimerViewModel : ViewModel(), ContainerHost<TimerUiState, Nothing> {
override val container = viewModelScope.container<TimerUiState, Nothing>(TimerUiState())
private val stateMachine = StateMachine.create<TimerState.State, TimerState.Event, TimerState.SideEffect> {
initialState(TimerState.State.Idle)
state<TimerState.State.Idle> {
on<TimerState.Event.OnSetTimer> {
transitionTo(TimerState.State.SettingTimer, TimerState.SideEffect.SetTimer)
}
}
state<TimerState.State.SettingTimer> {
on<TimerState.Event.OnTimerSet> {
transitionTo(TimerState.State.Idle, TimerState.SideEffect.TimerReady(it.value))
}
}
onTransition {
val validTransition = it as? StateMachine.Transition.Valid ?: return@onTransition
when (val effect = validTransition.sideEffect as TimerState.SideEffect) {
is TimerState.SideEffect.SetTimer -> intent { reduce { state.copy(isSettingTimer = true, isCountingDown = false, isRestarting = false) } }
is TimerState.SideEffect.TimerReady -> intent { reduce { TimerUiState(effect.value) } }
}
}
}
fun settingTime() {
stateMachine.transition(TimerState.Event.OnSetTimer)
}
fun setTime(seconds: Int) {
stateMachine.transition(TimerState.Event.OnTimerSet(seconds))
}
}
//Collecting state changes in the View
@Composable
fun TimerScreen(viewModel: TimerViewModel) {
with(viewModel.collectAsState().value) { /*...*/ }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment