diff --git a/ring-android/app/src/main/java/cx/ring/account/RingAccountCreationFragment.java b/ring-android/app/src/main/java/cx/ring/account/RingAccountCreationFragment.java index 181be0edcf07abb74d457455d73a0f05c6a8ce24..f25283d117db87790ca659e9df1038e9fe619ffe 100644 --- a/ring-android/app/src/main/java/cx/ring/account/RingAccountCreationFragment.java +++ b/ring-android/app/src/main/java/cx/ring/account/RingAccountCreationFragment.java @@ -22,7 +22,6 @@ package cx.ring.account; import android.app.Activity; import android.content.Context; import android.os.Bundle; -import com.google.android.material.textfield.TextInputLayout; import android.text.Editable; import android.text.InputFilter; import android.view.View; @@ -31,9 +30,14 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.EditText; +import android.widget.ImageView; +import android.widget.ProgressBar; import android.widget.Switch; import androidx.annotation.NonNull; + +import com.google.android.material.textfield.TextInputLayout; + import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnCheckedChanged; @@ -42,11 +46,12 @@ import butterknife.OnEditorAction; import butterknife.OnTextChanged; import cx.ring.R; import cx.ring.dependencyinjection.RingInjectionComponent; -import cx.ring.mvp.BaseSupportFragment; import cx.ring.mvp.AccountCreationModel; +import cx.ring.mvp.BaseSupportFragment; import cx.ring.utils.RegisteredNameFilter; -public class RingAccountCreationFragment extends BaseSupportFragment<RingAccountCreationPresenter> implements RingAccountCreationView { +public class RingAccountCreationFragment extends BaseSupportFragment<RingAccountCreationPresenter> + implements RingAccountCreationView { @BindView(R.id.switch_ring_username) protected Switch mUsernameSwitch; @@ -78,6 +83,12 @@ public class RingAccountCreationFragment extends BaseSupportFragment<RingAccount @BindView(R.id.create_account) protected Button mCreateAccountButton; + @BindView(R.id.ring_username_availability_image_view) + protected ImageView mUsernameAvailabilityImageView; + + @BindView(R.id.ring_username_availability_spinner) + protected ProgressBar mUsernameAvailabilitySpinner; + private AccountCreationModel model; public static RingAccountCreationFragment newInstance(AccountCreationModelImpl ringAccountViewModel) { @@ -111,7 +122,8 @@ public class RingAccountCreationFragment extends BaseSupportFragment<RingAccount super.onResume(); if (mUsernameBox.getVisibility() == View.VISIBLE) { mUsernameTxt.requestFocus(); - InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); + InputMethodManager imm = (InputMethodManager) requireActivity(). + getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(mUsernameTxt, InputMethodManager.SHOW_IMPLICIT); } } @@ -136,11 +148,6 @@ public class RingAccountCreationFragment extends BaseSupportFragment<RingAccount presenter.createAccount(); } - @OnTextChanged(value = R.id.ring_username, callback = OnTextChanged.Callback.TEXT_CHANGED) - public void onUsernameChanged() { - mUsernameTxt.setError(null); - } - @OnTextChanged(value = R.id.ring_password, callback = OnTextChanged.Callback.TEXT_CHANGED) public void afterPasswordChanged(Editable txt) { presenter.passwordChanged(txt.toString()); @@ -165,27 +172,46 @@ public class RingAccountCreationFragment extends BaseSupportFragment<RingAccount } @Override - public void enableTextError() { - mUsernameTxtBox.setErrorEnabled(true); - mUsernameTxtBox.setError(getString(R.string.looking_for_username_availability)); - } - - @Override - public void disableTextError() { - mUsernameTxtBox.setErrorEnabled(false); - mUsernameTxtBox.setError(null); - } - - @Override - public void showExistingNameError() { - mUsernameTxtBox.setErrorEnabled(true); - mUsernameTxtBox.setError(getString(R.string.username_already_taken)); - } - - @Override - public void showInvalidNameError() { - mUsernameTxtBox.setErrorEnabled(true); - mUsernameTxtBox.setError(getString(R.string.invalid_username)); + public void updateUsernameAvailability(UsernameAvailabilityStatus status) { + mUsernameAvailabilitySpinner.setVisibility(View.GONE); + mUsernameAvailabilityImageView.setVisibility(View.VISIBLE); + switch (status){ + case ERROR: + mUsernameTxtBox.setErrorEnabled(true); + mUsernameTxtBox.setError(getString(R.string.unknown_error)); + mUsernameAvailabilityImageView.setImageDrawable(getResources(). + getDrawable(R.drawable.ic_error_red)); + break; + case ERROR_USERNAME_INVALID: + mUsernameTxtBox.setErrorEnabled(true); + mUsernameTxtBox.setError(getString(R.string.invalid_username)); + mUsernameAvailabilityImageView.setImageDrawable(getResources(). + getDrawable(R.drawable.ic_error_red)); + break; + case ERROR_USERNAME_TAKEN: + mUsernameTxtBox.setErrorEnabled(true); + mUsernameTxtBox.setError(getString(R.string.username_already_taken)); + mUsernameAvailabilityImageView.setImageDrawable(getResources(). + getDrawable(R.drawable.ic_error_red)); + break; + case LOADING: + mUsernameTxtBox.setErrorEnabled(false); + mUsernameAvailabilityImageView.setVisibility(View.INVISIBLE); + mUsernameAvailabilitySpinner.setVisibility(View.VISIBLE); + break; + case AVAILABLE: + mUsernameTxtBox.setErrorEnabled(false); + mUsernameAvailabilityImageView.setImageDrawable(getResources(). + getDrawable(R.drawable.ic_good_green)); + break; + case RESET: + mUsernameTxtBox.setErrorEnabled(false); + mUsernameAvailabilityImageView.setVisibility(View.INVISIBLE); + enableNextButton(false); + default: + mUsernameAvailabilityImageView.setVisibility(View.INVISIBLE); + break; + } } @Override diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/RingGuidedStepFragment.java b/ring-android/app/src/main/java/cx/ring/tv/account/RingGuidedStepFragment.java index baed08e5ca9c237da148718ce6279fa98e324563..737fc181f4063f43f3a8a6087541c65f5d814491 100644 --- a/ring-android/app/src/main/java/cx/ring/tv/account/RingGuidedStepFragment.java +++ b/ring-android/app/src/main/java/cx/ring/tv/account/RingGuidedStepFragment.java @@ -72,6 +72,18 @@ public abstract class RingGuidedStepFragment<T extends RootPresenter> extends Gu .icon(icon) .build()); } + + protected static void addDisabledNonFocusableAction(Context context, List<GuidedAction> actions, long id, String title, String desc, Drawable icon) { + actions.add(new GuidedAction.Builder(context) + .id(id) + .title(title) + .description(desc) + .enabled(false) + .focusable(false) + .icon(icon) + .build()); + } + protected static void addDisabledAction(Context context, List<GuidedAction> actions, long id, String title, String desc, Drawable icon,boolean next) { actions.add(new GuidedAction.Builder(context) .id(id) diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/TVRingAccountCreationFragment.java b/ring-android/app/src/main/java/cx/ring/tv/account/TVRingAccountCreationFragment.java index fd0f1c6267ac6d40d848e778d6013b74a604823b..e79d2f6e89716fdd49e61d97aa4ce0c19d6bc848 100644 --- a/ring-android/app/src/main/java/cx/ring/tv/account/TVRingAccountCreationFragment.java +++ b/ring-android/app/src/main/java/cx/ring/tv/account/TVRingAccountCreationFragment.java @@ -62,10 +62,14 @@ public class TVRingAccountCreationFragment @Override public void afterTextChanged(Editable s) { String newName = s.toString(); - boolean empty = newName.isEmpty(); - presenter.ringCheckChanged(!empty); - if (!empty) + if (!newName.equals(getResources().getString(R.string.register_username))) { + boolean empty = newName.isEmpty(); + /** If the username is empty make sure to set isRegisterUsernameChecked + * to False, this allows to create an account with an empty username */ + presenter.ringCheckChanged(!empty); + /** Send the newName even when empty (in order to reset the views) */ presenter.userNameChanged(newName); + } } }; @@ -108,7 +112,7 @@ public class TVRingAccountCreationFragment @Override public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) { addEditTextAction(getActivity(), actions, USERNAME, R.string.register_username, R.string.prompt_new_username); - addDisabledAction(getActivity(), actions, CHECK, "", "", null); + addDisabledNonFocusableAction(getActivity(), actions, CHECK, "", "", null); addPasswordAction(getActivity(), actions, PASSWORD, getString(R.string.prompt_new_password_optional), getString(R.string.enter_password), ""); addPasswordAction(getActivity(), actions, PASSWORD_CONFIRMATION, getString(R.string.prompt_new_password_repeat), getString(R.string.enter_password), ""); addDisabledAction(getActivity(), actions, CONTINUE, getString(R.string.action_create), "", null, true); @@ -128,30 +132,45 @@ public class TVRingAccountCreationFragment @Override public long onGuidedActionEditedAndProceed(GuidedAction action) { - if (action.getId() == PASSWORD) { - passwordChanged(action); - } else if (action.getId() == PASSWORD_CONFIRMATION) { - confirmPasswordChanged(action); - } else if (action.getId() == USERNAME) { - ViewGroup view = (ViewGroup) getActionItemView(findActionPositionById(USERNAME)); - if (view != null) { - EditText text = view.findViewById(R.id.guidedactions_item_title); - text.removeTextChangedListener(mUsernameWatcher); - } - String username = action.getEditTitle().toString(); - boolean empty = username.isEmpty(); - if (empty) { - action.setTitle(getString(R.string.register_username)); - } else { - action.setTitle(username); - } - GuidedAction a = findActionById(CHECK); - a.setEnabled(!empty); - notifyActionChanged(findActionPositionById(CHECK)); - } + onGuidedActionChange(action); return GuidedAction.ACTION_ID_NEXT; } + @Override + public void onGuidedActionEditCanceled(GuidedAction action) { + onGuidedActionChange(action); + } + + private void onGuidedActionChange(GuidedAction action){ + switch ((int) action.getId()){ + case USERNAME: + usernameChanged(action); + break; + case PASSWORD: + passwordChanged(action); + break; + case PASSWORD_CONFIRMATION: + confirmPasswordChanged(action); + break; + } + } + + private void usernameChanged(GuidedAction action) { + String username = action.getEditTitle().toString(); + ViewGroup view = (ViewGroup) getActionItemView(findActionPositionById(USERNAME)); + if (view != null) { + EditText text = view.findViewById(R.id.guidedactions_item_title); + text.removeTextChangedListener(mUsernameWatcher); + } + + if(username.isEmpty()) + action.setTitle(getString(R.string.register_username)); + else + action.setTitle(username); + + notifyActionChanged(findActionPositionById(PASSWORD)); + } + private void passwordChanged(GuidedAction action) { String password = action.getEditDescription().toString(); if (password.length() > 0) { @@ -180,59 +199,66 @@ public class TVRingAccountCreationFragment } @Override - public void enableTextError() { - GuidedAction action = findActionById(CHECK); - action.setIcon(null); - action.setTitle(getString(R.string.looking_for_username_availability)); - notifyActionChanged(findActionPositionById(CHECK)); - } - - @Override - public void disableTextError() { - GuidedAction action = findActionById(CHECK); - action.setIcon(null); - action.setDescription(""); - notifyActionChanged(findActionPositionById(CHECK)); - } - - @Override - public void showExistingNameError() { - GuidedAction action = findActionById(CHECK); - action.setIcon(getResources().getDrawable(R.drawable.ic_error_red)); - action.setDescription(getString(R.string.username_already_taken)); - notifyActionChanged(findActionPositionById(CHECK)); - } + public void updateUsernameAvailability(UsernameAvailabilityStatus status) { + GuidedAction actionCheck = findActionById(CHECK); + switch (status){ + case ERROR: + actionCheck.setTitle(getResources().getString(R.string.generic_error)); + displayErrorIconTitle(actionCheck, getString(R.string.unknown_error)); + break; + case ERROR_USERNAME_INVALID: + displayErrorIconTitle(actionCheck,getString(R.string.invalid_username)); + break; + case ERROR_USERNAME_TAKEN: + displayErrorIconTitle(actionCheck, + getString(R.string.username_already_taken)); + break; + case LOADING: + actionCheck.setIcon(null); + actionCheck.setTitle(getResources(). + getString(R.string.looking_for_username_availability)); + break; + case AVAILABLE: + actionCheck.setTitle(getString(R.string.username_available)); + actionCheck.setIcon(getResources().getDrawable(R.drawable.ic_good_green)); + break; + case RESET: + actionCheck.setIcon(null); + actionCheck.setTitle(""); + enableNextButton(false); + default: + actionCheck.setIcon(null); + break; + } - @Override - public void showInvalidNameError() { - GuidedAction action = findActionById(CHECK); - action.setIcon(getResources().getDrawable(R.drawable.ic_error_red)); - action.setDescription(getString(R.string.invalid_username)); notifyActionChanged(findActionPositionById(CHECK)); } @Override public void showInvalidPasswordError(boolean display) { + GuidedAction action = findActionById(CONTINUE); if (display) { - GuidedAction action = findActionById(CONTINUE); - action.setIcon(getResources().getDrawable(R.drawable.ic_error_red)); - action.setDescription(getString(R.string.error_password_char_count)); + displayErrorIconDescription(action,getString(R.string.error_password_char_count)); action.setEnabled(false); + } else { + action.setDescription(""); } notifyActionChanged(findActionPositionById(CONTINUE)); } @Override public void showNonMatchingPasswordError(boolean display) { + GuidedAction action = findActionById(CONTINUE); if (display) { - GuidedAction action = findActionById(CONTINUE); - action.setIcon(getResources().getDrawable(R.drawable.ic_error_red)); - action.setDescription(getString(R.string.error_passwords_not_equals)); + displayErrorIconDescription(action,getString(R.string.error_passwords_not_equals)); action.setEnabled(false); + } else { + action.setDescription(""); } notifyActionChanged(findActionPositionById(CONTINUE)); } + @Override public void displayUsernameBox(boolean display) { } @@ -240,17 +266,10 @@ public class TVRingAccountCreationFragment @Override public void enableNextButton(boolean enabled) { Log.d(TAG, "enableNextButton: " + enabled); - GuidedAction actionCheck = findActionById(CHECK); GuidedAction actionContinue = findActionById(CONTINUE); - if (enabled) { - actionCheck.setIcon(getResources().getDrawable(R.drawable.ic_good_green)); - actionCheck.setTitle(getString(R.string.no_registered_name_for_account)); - actionCheck.setDescription(""); + if (enabled) actionContinue.setIcon(null); - actionCheck.setDescription(""); - } actionContinue.setEnabled(enabled); - notifyActionChanged(findActionPositionById(CHECK)); notifyActionChanged(findActionPositionById(CONTINUE)); } @@ -270,4 +289,15 @@ public class TVRingAccountCreationFragment } } + private void displayErrorIconTitle(GuidedAction action, String title) { + action.setIcon(getResources().getDrawable(R.drawable.ic_error_red)); + action.setTitle(title); + } + + private void displayErrorIconDescription(GuidedAction action, String description) { + action.setIcon(getResources().getDrawable(R.drawable.ic_error_red)); + action.setDescription(description); + } + + } diff --git a/ring-android/app/src/main/res/layout/frag_acc_ring_create.xml b/ring-android/app/src/main/res/layout/frag_acc_ring_create.xml index 8b35449fe155a98dfd1d524ad922ae87cf0f4817..41a2ac94d1d6356fcaba4d32b6bf7ba0e0ba4192 100644 --- a/ring-android/app/src/main/res/layout/frag_acc_ring_create.xml +++ b/ring-android/app/src/main/res/layout/frag_acc_ring_create.xml @@ -45,7 +45,7 @@ android:text="@string/register_username" android:textColor="@color/text_color_primary" /> - <LinearLayout + <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/ring_username_box" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -53,9 +53,12 @@ <com.google.android.material.textfield.TextInputLayout android:id="@+id/ring_username_txt_box" - android:layout_width="match_parent" + android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginBottom="16dp"> + android:layout_marginBottom="16dp" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toLeftOf="@id/ring_username_availability_image_view" + app:layout_constraintTop_toTopOf="parent"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/ring_username" @@ -75,7 +78,26 @@ </com.google.android.material.textfield.TextInputEditText> </com.google.android.material.textfield.TextInputLayout> - </LinearLayout> + <androidx.appcompat.widget.AppCompatImageView + android:id="@+id/ring_username_availability_image_view" + android:layout_width="24dp" + android:layout_height="24dp" + android:visibility="invisible" + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toTopOf="@id/ring_username_txt_box" + android:layout_marginTop="16dp"/> + + <ProgressBar + android:id="@+id/ring_username_availability_spinner" + style="?android:attr/progressBarStyle" + android:layout_width="24dp" + android:layout_height="24dp" + android:visibility="gone" + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toTopOf="@id/ring_username_txt_box" + android:layout_marginTop="16dp"/> + + </androidx.constraintlayout.widget.ConstraintLayout> <Switch android:id="@+id/ring_password_switch" diff --git a/ring-android/app/src/main/res/values/strings_account.xml b/ring-android/app/src/main/res/values/strings_account.xml index 2cb52dd3d2607da514504d45c337e4f17943d11d..54bccc5d05a978578e1e591b9529262ece494a1b 100644 --- a/ring-android/app/src/main/res/values/strings_account.xml +++ b/ring-android/app/src/main/res/values/strings_account.xml @@ -204,12 +204,14 @@ along with this program; if not, write to the Free Software <!-- Name registration --> <string name="error_username_empty">Enter a username</string> <string name="no_registered_name_for_account">No registered name found for this account</string> + <string name="username_available">Username available !</string> <string name="register_name">Register name</string> <string name="trying_to_register_name">Trying to register name</string> <string name="registered_username">Registered username</string> <string name="register_username">Register public username (recommended)</string> <string name="username_already_taken">Username already taken</string> <string name="invalid_username">Invalid username</string> + <string name="unknown_error">Unknown error. Please check your network connection!</string> <string name="looking_for_username_availability">Looking for username availability…</string> <string name="account_status_connecting">Connecting</string> <string name="account_status_connection_error">Connection error</string> diff --git a/ring-android/libringclient/src/main/java/cx/ring/account/RingAccountCreationPresenter.java b/ring-android/libringclient/src/main/java/cx/ring/account/RingAccountCreationPresenter.java index a6b2ba9cbaf81c471b8c6a01572d7913598ec207..7d278b4b4bf9c7b6ecb4add8d443f43dd5163957 100644 --- a/ring-android/libringclient/src/main/java/cx/ring/account/RingAccountCreationPresenter.java +++ b/ring-android/libringclient/src/main/java/cx/ring/account/RingAccountCreationPresenter.java @@ -34,24 +34,21 @@ import io.reactivex.subjects.PublishSubject; public class RingAccountCreationPresenter extends RootPresenter<RingAccountCreationView> { public static final String TAG = RingAccountCreationPresenter.class.getSimpleName(); - public static final int PASSWORD_MIN_LENGTH = 6; - + private static final int PASSWORD_MIN_LENGTH = 6; + private static final long TYPING_DELAY = 350L; + private final PublishSubject<String> contactQuery = PublishSubject.create(); protected AccountService mAccountService; - @Inject @Named("UiScheduler") protected Scheduler mUiScheduler; - private AccountCreationModel mAccountCreationModel; - private boolean isRingUserNameCorrect = false; private boolean isPasswordCorrect = true; private boolean isConfirmCorrect = true; private boolean isRegisterUsernameChecked = true; + private boolean startUsernameAvailabitlityProgressBarAnimation = true; private String mPasswordConfirm = ""; - private final PublishSubject<String> contactQuery = PublishSubject.create(); - @Inject public RingAccountCreationPresenter(AccountService accountService) { this.mAccountService = accountService; @@ -61,28 +58,34 @@ public class RingAccountCreationPresenter extends RootPresenter<RingAccountCreat public void bindView(RingAccountCreationView view) { super.bindView(view); mCompositeDisposable.add(contactQuery - .debounce(350, TimeUnit.MILLISECONDS) - .switchMapSingle(q -> mAccountService.findRegistrationByName("", "", q)) + .debounce(TYPING_DELAY, TimeUnit.MILLISECONDS) + .switchMapSingle(q -> mAccountService. + findRegistrationByName("", "", q)) .observeOn(mUiScheduler) .subscribe(q -> handleBlockchainResult(q.name, q.address, q.state))); - } public void init(AccountCreationModel accountCreationModel) { mAccountCreationModel = accountCreationModel; } + /** + * Called everytime the provided username for the new account changes + * Sends the new value of the username to the ContactQuery subjet and shows the loading + * animation if it has not been started before + * @param userName + */ public void userNameChanged(String userName) { - if (!userName.isEmpty()) { - mAccountCreationModel.setUsername(userName); - contactQuery.onNext(userName); - isRingUserNameCorrect = false; - getView().enableTextError(); - } else { - mAccountCreationModel.setUsername(""); - getView().disableTextError(); + mAccountCreationModel.setUsername(userName); + contactQuery.onNext(userName); + isRingUserNameCorrect = false; + RingAccountCreationView view = getView(); + + if (startUsernameAvailabitlityProgressBarAnimation) { + view.updateUsernameAvailability(RingAccountCreationView. + UsernameAvailabilityStatus.LOADING); + startUsernameAvailabitlityProgressBarAnimation = false; } - checkForms(); } public void ringCheckChanged(boolean isChecked) { @@ -96,19 +99,19 @@ public class RingAccountCreationPresenter extends RootPresenter<RingAccountCreat public void passwordChanged(String password) { mAccountCreationModel.setPassword(password); - if (!password.equals(mPasswordConfirm)) { - getView().showNonMatchingPasswordError(true); - isConfirmCorrect = false; - } else { - getView().showNonMatchingPasswordError(false); - isConfirmCorrect = true; - } if (!password.isEmpty() && password.length() < PASSWORD_MIN_LENGTH) { getView().showInvalidPasswordError(true); isPasswordCorrect = false; } else { getView().showInvalidPasswordError(false); isPasswordCorrect = true; + if (!password.equals(mPasswordConfirm)) { + getView().showNonMatchingPasswordError(true); + isConfirmCorrect = false; + } else { + getView().showNonMatchingPasswordError(false); + isConfirmCorrect = true; + } } checkForms(); } @@ -140,38 +143,50 @@ public class RingAccountCreationPresenter extends RootPresenter<RingAccountCreat } private void checkForms() { - getView().enableNextButton(isInputValid()); + boolean valid = isInputValid(); + getView().enableNextButton(valid); + if(valid && isRingUserNameCorrect) + getView().updateUsernameAvailability(RingAccountCreationView. + UsernameAvailabilityStatus.AVAILABLE); } private void handleBlockchainResult(String name, String address, int state) { RingAccountCreationView view = getView(); + //Once we get the result, we can show the loading animation again when the user types + startUsernameAvailabitlityProgressBarAnimation = true; if (view == null) { return; } if (name == null || name.isEmpty()) { - view.disableTextError(); + + view.updateUsernameAvailability(RingAccountCreationView. + UsernameAvailabilityStatus.RESET); isRingUserNameCorrect = false; } else { switch (state) { case 0: // on found - view.showExistingNameError(); + view.updateUsernameAvailability(RingAccountCreationView. + UsernameAvailabilityStatus.ERROR_USERNAME_TAKEN); isRingUserNameCorrect = false; break; case 1: // invalid name - view.showInvalidNameError(); + view.updateUsernameAvailability(RingAccountCreationView. + UsernameAvailabilityStatus.ERROR_USERNAME_INVALID); isRingUserNameCorrect = false; break; case 2: // available - view.disableTextError(); + view.updateUsernameAvailability(RingAccountCreationView. + UsernameAvailabilityStatus.AVAILABLE); mAccountCreationModel.setUsername(name); isRingUserNameCorrect = true; break; default: // on error - view.disableTextError(); + view.updateUsernameAvailability(RingAccountCreationView. + UsernameAvailabilityStatus.ERROR); isRingUserNameCorrect = false; break; } diff --git a/ring-android/libringclient/src/main/java/cx/ring/account/RingAccountCreationView.java b/ring-android/libringclient/src/main/java/cx/ring/account/RingAccountCreationView.java index e08ca8661f9893296fa85c407004723c1dae0332..65de5eafef636709d2a8308db160f83f1f045414 100644 --- a/ring-android/libringclient/src/main/java/cx/ring/account/RingAccountCreationView.java +++ b/ring-android/libringclient/src/main/java/cx/ring/account/RingAccountCreationView.java @@ -23,13 +23,16 @@ import cx.ring.mvp.AccountCreationModel; public interface RingAccountCreationView { - void enableTextError(); - - void disableTextError(); - - void showExistingNameError(); - - void showInvalidNameError(); + enum UsernameAvailabilityStatus { + ERROR_USERNAME_TAKEN, + ERROR_USERNAME_INVALID, + ERROR, + LOADING, + AVAILABLE, + RESET + } + + void updateUsernameAvailability(UsernameAvailabilityStatus status); void showInvalidPasswordError(boolean display); diff --git a/ring-android/libringclient/src/main/java/cx/ring/services/AccountService.java b/ring-android/libringclient/src/main/java/cx/ring/services/AccountService.java index 8fa603496d5829e4575b5a83fed78f0b3c2e2c0d..e76ff58d4c651f83f7d3757b23e6f88485b5a747 100644 --- a/ring-android/libringclient/src/main/java/cx/ring/services/AccountService.java +++ b/ring-android/libringclient/src/main/java/cx/ring/services/AccountService.java @@ -59,12 +59,12 @@ import cx.ring.utils.SwigNativeConverter; import cx.ring.utils.VCardUtils; import ezvcard.VCard; import io.reactivex.Completable; +import io.reactivex.Observable; import io.reactivex.Single; import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.BehaviorSubject; import io.reactivex.subjects.PublishSubject; import io.reactivex.subjects.Subject; -import io.reactivex.Observable; /** * This service handles the accounts (Ring and SIP) @@ -970,7 +970,7 @@ public class AccountService { public Single<RegisteredName> findRegistrationByName(final String account, final String nameserver, final String name) { if (name == null || name.isEmpty()) { - return Single.create(l -> l.onError(new IllegalArgumentException())); + return Single.just(new RegisteredName()); } return getRegisteredNames() .filter(r -> account.equals(r.accountId) && name.equals(r.name))