package org.mercury_im.messenger.android.ui.account.login; import android.app.Application; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import org.mercury_im.messenger.R; import org.mercury_im.messenger.android.MercuryImApplication; import org.mercury_im.messenger.android.ui.base.MercuryAndroidViewModel; import org.mercury_im.messenger.android.util.TextChangedListener; import org.mercury_im.messenger.core.account.error.PasswordError; import org.mercury_im.messenger.core.account.error.UsernameError; import org.mercury_im.messenger.core.util.Optional; import org.mercury_im.messenger.core.viewmodel.account.LoginViewModel; import org.mercury_im.messenger.entity.Account; import javax.inject.Inject; import io.reactivex.ObservableTransformer; public class AndroidLoginViewModel extends AndroidViewModel implements MercuryAndroidViewModel { private final MutableLiveData loginUsernameError = new MutableLiveData<>(); private final MutableLiveData loginPasswordError = new MutableLiveData<>(); private final MutableLiveData loginButtonEnabled = new MutableLiveData<>(true); private final MutableLiveData> loginFinished = new MutableLiveData<>(new Optional<>()); private final MutableLiveData displayProgressBar = new MutableLiveData<>(false); @Inject LoginViewModel commonViewModel; @Inject public AndroidLoginViewModel(Application application) { super(application); reset(); } public void reset() { MercuryImApplication.getApplication().getAppComponent().inject(this); commonViewModel.reset(); addDisposable(getCommonViewModel().getLoginUsernameError() .compose(usernameErrorToErrorMessage) .subscribe(e -> loginUsernameError.setValue(e.isPresent() ? e.getItem() : null))); addDisposable(getCommonViewModel().getLoginPasswordError() .compose(passwordErrorToErrorMessage) .subscribe(e -> loginPasswordError.setValue(e.isPresent() ? e.getItem() : null))); addDisposable(getCommonViewModel().isLoginPossible() .subscribe(loginButtonEnabled::setValue)); addDisposable(getCommonViewModel().isLoginSuccessful() .subscribe(loginFinished::setValue)); addDisposable(getCommonViewModel().isDisplayProgressBar() .subscribe(displayProgressBar::setValue)); } private final ObservableTransformer, Optional> usernameErrorToErrorMessage = upstream -> upstream.map(optional -> { if (!optional.isPresent()){ return new Optional<>(null); } UsernameError error = optional.getItem(); int resourceId; switch (error) { case emptyUsername: resourceId = R.string.error_field_required; break; case invalidUsername: resourceId = R.string.error_invalid_username; break; case unreachableServer: resourceId = R.string.error_unreachable_server; break; default: resourceId = R.string.error_uknown_error; } return new Optional<>(getApplication().getResources().getString(resourceId)); }); private final ObservableTransformer, Optional> passwordErrorToErrorMessage = upstream -> upstream.map(optional -> { if (!optional.isPresent()) { return new Optional<>(null); } PasswordError error = optional.getItem(); int resourceId; switch (error) { case emptyPassword: resourceId = R.string.error_field_required; break; case incorrectPassword: resourceId = R.string.error_incorrect_password; break; default: resourceId = R.string.error_uknown_error; } return new Optional<>(getApplication().getResources().getString(resourceId)); }); @Override protected void onCleared() { super.onCleared(); getCommonViewModel().dispose(); } public Account onLoginButtonClicked() { return getCommonViewModel().login(); } public LiveData getLoginUsernameError() { return loginUsernameError; } public LiveData getLoginPasswordError() { return loginPasswordError; } public LiveData isLoginButtonEnabled() { return loginButtonEnabled; } public LiveData> isLoginFinished() { return loginFinished; } public LiveData isDisplayProgressBar() { return displayProgressBar; } @Override public LoginViewModel getCommonViewModel() { return commonViewModel; } public TextChangedListener getUsernameTextChangedListener() { return usernameTextChangedListener; } public TextChangedListener getPasswordTextChangedListener() { return passwordTextChangedListener; } private final TextChangedListener usernameTextChangedListener = new TextChangedListener() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { getCommonViewModel().onLoginUsernameChanged(s.toString()); } }; private final TextChangedListener passwordTextChangedListener = new TextChangedListener() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { getCommonViewModel().onLoginPasswordChanged(s.toString()); } }; }