Skip to content

Instantly share code, notes, and snippets.

@SUPERCILEX
Last active September 13, 2022 12:04
Show Gist options
  • Save SUPERCILEX/21da30a6f73b621b704aba67977af89b to your computer and use it in GitHub Desktop.
Save SUPERCILEX/21da30a6f73b621b704aba67977af89b to your computer and use it in GitHub Desktop.
class StateHolder<T : Any>(state: T) {
private val _liveData = MutableLiveData(state)
val liveData: LiveData<T> get() = _liveData
private var _value: T = state
val value: T get() = _value
fun update(notify: Boolean = true, block: T.() -> T) {
synchronized(LOCK) {
_value = block(value)
if (notify) _liveData.postValue(value)
}
}
private companion object {
val LOCK = Object()
}
}
class VM : ViewModel() {
private val _state = StateHolder(State())
val state: LiveData<State> get() = _state.liveData
private val _actions = Channel<Action>(Channel.CONFLATED)
val actions: Flow<Action> = flow { for (e in _actions) emit(e) }
private val _viewActions = Channel<ViewAction>(Channel.CONFLATED)
val viewActions: Flow<ViewAction> = flow { for (e in _viewActions) emit(e) }
sealed class Action {
data class Navigate(val directions: NavDirections) : Action()
}
sealed class ViewAction {
data class VisitPage(val url: String) : ViewAction()
}
data class State(
val isLoading: Boolean = false
)
}
class Fragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launchWhenStarted {
vm.actions.collect { onActionRequested(it) }
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
viewLifecycleOwner.lifecycleScope.launchWhenCreated {
vm.viewActions.collect { onViewActionRequested(it) }
}
vm.state.observe(viewLifecycleOwner) {
onViewStateChanged(it)
}
}
private fun onActionRequested(action: VM.Action) {
when (action) {
is VM.Action.Navigate -> findNavController().navigate(action.directions)
}
}
private fun onViewActionRequested(action: VM.ViewAction) {
when (action) {
is VM.ViewAction.VisitPage -> binding.web.loadUrl(action.url)
}
}
private fun onViewStateChanged(state: VM.State) {
progress?.isVisible = state.isLoading
binding.web.isVisible = state.isWebViewVisible
binding.finishCheckInHint.isVisible = state.isFinishButtonVisible
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment