package org.mercury_im.messenger.ui.login; import android.app.Application; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.stringprep.XmppStringprepException; import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.Messenger; import org.mercury_im.messenger.R; import org.mercury_im.messenger.entity.Account; import org.mercury_im.messenger.entity.IAccount; import javax.inject.Inject; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; public class LoginViewModel extends AndroidViewModel { private MutableLiveData usernameError = new MutableLiveData<>(new Error()); private MutableLiveData passwordError = new MutableLiveData<>(new Error()); private MutableLiveData loginEnabled = new MutableLiveData<>(false); private MutableLiveData loginSuccessful = new MutableLiveData<>(false); private EntityBareJid username; private String password; @Inject Messenger messenger; public LoginViewModel(@NonNull Application application) { super(application); ((MercuryImApplication) application).getAppComponent().inject(this); } public void setUsername(String username) { if (username == null || username.isEmpty()) { usernameError.setValue(new Error(getApplication().getResources().getString(R.string.error_field_required))); this.username = null; updateLoginEnabled(); return; } try { this.username = JidCreate.entityBareFrom(username); updateLoginEnabled(); } catch (XmppStringprepException e) { usernameError.setValue(new Error(getApplication().getResources().getString(R.string.error_invalid_username))); this.username = null; updateLoginEnabled(); } } public void setPassword(String password) { this.password = password; updateLoginEnabled(); if (password == null || password.isEmpty()) { passwordError.setValue(new Error(getApplication().getResources().getString(R.string.error_field_required))); } } private void updateLoginEnabled() { loginEnabled.setValue(username != null && !(password == null || password.isEmpty())); } public void login() { Account account = new IAccount(); account.setAddress(username.asUnescapedString()); account.setPassword(password); account.setEnabled(true); loginEnabled.setValue(false); messenger.addAccount().enableAccountAndLogin(account) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .map(result -> { switch (result) { case success: loginSuccessful.setValue(true); break; case credential_error: passwordError.setValue(new Error(getApplication().getResources().getString(R.string.error_incorrect_password))); loginEnabled.setValue(true); break; case server_error: case other_error: Toast.makeText(getApplication(), "A connection error occurred", Toast.LENGTH_LONG); loginEnabled.setValue(true); } return true; }) .ignoreElement() .subscribe(); } public LiveData getPasswordError() { return passwordError; } public LiveData getUsernameError() { return usernameError; } public LiveData isLoginSuccessful() { return loginSuccessful; } public LiveData isLoginEnabled() { return loginEnabled; } public static class Error { private String message; public Error() { } public Error(String errorMessage) { this.message = errorMessage; } public boolean isError() { return message != null; } public String getErrorMessage() { return message; } } }