Skip to content

Instantly share code, notes, and snippets.

@cbedoy
Last active March 17, 2021 04:38
Show Gist options
  • Select an option

  • Save cbedoy/bc1eb2f85c9e308cfc1a499374d35e1c to your computer and use it in GitHub Desktop.

Select an option

Save cbedoy/bc1eb2f85c9e308cfc1a499374d35e1c to your computer and use it in GitHub Desktop.
Common MVI
class LoginFragment {
val viewModel by viewModel<LoginViewModel>()
override fun onViewCreadted(){
with(binding){
action.setOnClickListener{
viewModel.performIntent(
intent = PerformLoginWith(
username = usernameField.textAsString
)
)
}
}
lifecycleScope.launch{
viewModel.state.collect { state ->
handleState(state)
}
}
}
fun handleState(intent: LoginState){
//.....
}
}
sealed class LoginIntent{
data class PerformLoginWith(username: String, password: String): LoginIntent()
object RequestSupport: LoginIntent()
}
class LoginRepository (
val service: AppService
){
suspend fun getSessionWith(username: String) = service.getSession(username)
}
sealed class LoginState{
object Ilde: LoginState(),
data class ShowMessage(val message:STring): LoginState()
data class ShowOrHideLoader(val isVisible): LoginState()
}
class LoginUseCase(
val repository: LoginRepository
){
fun performLoginWithUserName(username: String) = flow {
emit(ShowLoader(isVisible = true))
when(val response = repository.getSessionWith(username)){
is Success -> {
emit(ShowMessage(message = "Success"))
}
else -> {
emit(ShowMessage(message = "failure"))
}
}
emit(ShowLoader(isVisible = false))
emit(Ilde)
}
// if success then you will get flow state of:
// (ShowLoader(isVisible = true), ShowMessage(message = "Success"), ShowLoader(isVisible = false), Ilde)
// else
// (ShowLoader(isVisible = true), ShowMessage(message = "false"), ShowLoader(isVisible = false), Ilde)
}
class LoginViewModel(
private val useCase: LoginUseCase
) : ViewModel(){
private val channel = Channel<LoginIntent>()
private val _state = MutableStateFlow<LoginState>(Ilde)
val state: StateFlow<LoginState> get() = _state
init {
viewModelScope.launch {
handleIntents()
}
}
suspend fun handleIntents(){
channel.collectAsFlow(){ intent ->
when(intent){
is PerformLoginWith -> {
useCase.performLoginWith(intent.username) {
_state.value = it
}
}
}
}
}
fun performIntent(val intent: LoginIntent) = viewModelScope.launch {
channel.offer(intent)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment