From 7c77530c2e598f5f440ed74d08a2ab1fc60f24de Mon Sep 17 00:00:00 2001 From: Madhur Gupta <30932899+madhurgupta10@users.noreply.github.com> Date: Thu, 28 Mar 2019 17:49:49 +0530 Subject: [PATCH] Refactor LoginActivity #2690 (#2775) * Refactor LoginActivity #2690 * Fixed Error cannot find symbol --- app/build.gradle | 4 +- .../java/fr/free/nrw/commons/SignupTest.kt | 2 +- .../java/fr/free/nrw/commons/UITestHelper.kt | 6 +- .../free/nrw/commons/auth/LoginActivity.java | 212 ++++++++++-------- .../main/res/layout-land/activity_login.xml | 18 +- .../main/res/layout-xlarge/activity_login.xml | 16 +- app/src/main/res/layout/activity_login.xml | 16 +- 7 files changed, 149 insertions(+), 125 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 84f929c36..8cbb6eb2f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -195,7 +195,7 @@ android { buildConfigField "String", "SIGNUP_LANDING_URL", "\"https://commons.m.wikimedia.org/w/index.php?title=Special:CreateAccount&returnto=Main+Page&returntoquery=welcome%3Dyes\"" buildConfigField "String", "SIGNUP_SUCCESS_REDIRECTION_URL", "\"https://commons.m.wikimedia.org/w/index.php?title=Main_Page&welcome=yes\"" buildConfigField "String", "FORGOT_PASSWORD_URL", "\"https://commons.wikimedia.org/wiki/Special:PasswordReset\"" - + buildConfigField "String", "PRIVACY_POLICY_URL", "\"https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\"" buildConfigField "String", "ACCOUNT_TYPE", "\"fr.free.nrw.commons\"" buildConfigField "String", "CONTRIBUTION_AUTHORITY", "\"fr.free.nrw.commons.contributions.contentprovider\"" buildConfigField "String", "MODIFICATION_AUTHORITY", "\"fr.free.nrw.commons.modifications.contentprovider\"" @@ -227,7 +227,7 @@ android { buildConfigField "String", "SIGNUP_LANDING_URL", "\"https://commons.m.wikimedia.beta.wmflabs.org/w/index.php?title=Special:CreateAccount&returnto=Main+Page&returntoquery=welcome%3Dyes\"" buildConfigField "String", "SIGNUP_SUCCESS_REDIRECTION_URL", "\"https://commons.m.wikimedia.beta.wmflabs.org/w/index.php?title=Main_Page&welcome=yes\"" buildConfigField "String", "FORGOT_PASSWORD_URL", "\"https://commons.wikimedia.beta.wmflabs.org/wiki/Special:PasswordReset\"" - + buildConfigField "String", "PRIVACY_POLICY_URL", "\"https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\"" buildConfigField "String", "ACCOUNT_TYPE", "\"fr.free.nrw.commons.beta\"" buildConfigField "String", "CONTRIBUTION_AUTHORITY", "\"fr.free.nrw.commons.beta.contributions.contentprovider\"" buildConfigField "String", "MODIFICATION_AUTHORITY", "\"fr.free.nrw.commons.beta.modifications.contentprovider\"" diff --git a/app/src/androidTest/java/fr/free/nrw/commons/SignupTest.kt b/app/src/androidTest/java/fr/free/nrw/commons/SignupTest.kt index 7259d0977..c80dfc550 100644 --- a/app/src/androidTest/java/fr/free/nrw/commons/SignupTest.kt +++ b/app/src/androidTest/java/fr/free/nrw/commons/SignupTest.kt @@ -37,7 +37,7 @@ class SignupTest { } - Espresso.onView(withId(R.id.signupButton)) + Espresso.onView(withId(R.id.sign_up_button)) .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) .perform(click()) intended(hasComponent(SignupActivity::class.java.name)) diff --git a/app/src/androidTest/java/fr/free/nrw/commons/UITestHelper.kt b/app/src/androidTest/java/fr/free/nrw/commons/UITestHelper.kt index 66aeff3f8..406280382 100644 --- a/app/src/androidTest/java/fr/free/nrw/commons/UITestHelper.kt +++ b/app/src/androidTest/java/fr/free/nrw/commons/UITestHelper.kt @@ -22,12 +22,12 @@ class UITestHelper { fun loginUser() { try { //Perform Login - onView(ViewMatchers.withId(R.id.loginUsername)) + onView(ViewMatchers.withId(R.id.login_username)) .perform(ViewActions.clearText(), ViewActions.typeText(getTestUsername())) - onView(ViewMatchers.withId(R.id.loginPassword)) + onView(ViewMatchers.withId(R.id.login_password)) .perform(ViewActions.clearText(), ViewActions.typeText(getTestUserPassword())) closeSoftKeyboard() - onView(ViewMatchers.withId(R.id.loginButton)) + onView(ViewMatchers.withId(R.id.login_button)) .perform(ViewActions.click()) sleep(5000) } catch (ignored: NoMatchingViewException) { diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java index 464f6feb6..57d804827 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java @@ -9,16 +9,9 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import androidx.annotation.ColorRes; -import androidx.annotation.NonNull; -import androidx.annotation.StringRes; -import com.google.android.material.textfield.TextInputLayout; -import androidx.core.app.NavUtils; -import androidx.core.content.ContextCompat; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatDelegate; import android.text.Editable; import android.text.TextWatcher; +import android.view.KeyEvent; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; @@ -27,15 +20,26 @@ import android.widget.Button; import android.widget.EditText; import android.widget.TextView; +import com.google.android.material.textfield.TextInputLayout; + import java.io.IOException; import java.util.Locale; import javax.inject.Inject; import javax.inject.Named; +import androidx.annotation.ColorRes; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.core.app.NavUtils; +import androidx.core.content.ContextCompat; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; +import butterknife.OnEditorAction; +import butterknife.OnFocusChange; import fr.free.nrw.commons.BuildConfig; import fr.free.nrw.commons.PageTitle; import fr.free.nrw.commons.R; @@ -47,7 +51,6 @@ import fr.free.nrw.commons.explore.categories.ExploreActivity; import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.theme.NavigationBaseActivity; -import fr.free.nrw.commons.ui.widget.HtmlTextView; import fr.free.nrw.commons.utils.ConfigUtils; import fr.free.nrw.commons.utils.ViewUtil; import io.reactivex.Observable; @@ -63,23 +66,39 @@ import static fr.free.nrw.commons.auth.AccountUtil.AUTH_TOKEN_TYPE; public class LoginActivity extends AccountAuthenticatorActivity { - @Inject MediaWikiApi mwApi; - @Inject SessionManager sessionManager; + @Inject + MediaWikiApi mwApi; + + @Inject + SessionManager sessionManager; + @Inject @Named("default_preferences") JsonKvStore applicationKvStore; - @BindView(R.id.loginButton) Button loginButton; - @BindView(R.id.signupButton) Button signupButton; - @BindView(R.id.loginUsername) EditText usernameEdit; - @BindView(R.id.loginPassword) EditText passwordEdit; - @BindView(R.id.loginTwoFactor) EditText twoFactorEdit; - @BindView(R.id.error_message_container) ViewGroup errorMessageContainer; - @BindView(R.id.error_message) TextView errorMessage; - @BindView(R.id.login_credentials) TextView loginCredentials; - @BindView(R.id.two_factor_container) TextInputLayout twoFactorContainer; - @BindView(R.id.forgotPassword) HtmlTextView forgotPasswordText; - @BindView(R.id.skipLogin) HtmlTextView skipLoginText; + @BindView(R.id.login_button) + Button loginButton; + + @BindView(R.id.login_username) + EditText usernameEdit; + + @BindView(R.id.login_password) + EditText passwordEdit; + + @BindView(R.id.login_two_factor) + EditText twoFactorEdit; + + @BindView(R.id.error_message_container) + ViewGroup errorMessageContainer; + + @BindView(R.id.error_message) + TextView errorMessage; + + @BindView(R.id.login_credentials) + TextView loginCredentials; + + @BindView(R.id.two_factor_container) + TextInputLayout twoFactorContainer; ProgressDialog progressDialog; private AppCompatDelegate delegate; @@ -88,7 +107,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { private Boolean loginCurrentlyInProgress = false; private Boolean errorMessageShown = false; - private String resultantError; + private String resultantError; private static final String RESULTANT_ERROR = "resultantError"; private static final String ERROR_MESSAGE_SHOWN = "errorMessageShown"; private static final String LOGGING_IN = "loggingIn"; @@ -111,35 +130,50 @@ public class LoginActivity extends AccountAuthenticatorActivity { ButterKnife.bind(this); usernameEdit.addTextChangedListener(textWatcher); - usernameEdit.setOnFocusChangeListener((v, hasFocus) -> { - if (!hasFocus) { - ViewUtil.hideKeyboard(v); - } - }); - passwordEdit.addTextChangedListener(textWatcher); - passwordEdit.setOnFocusChangeListener((v, hasFocus) -> { - if (!hasFocus) { - ViewUtil.hideKeyboard(v); - } - }); - twoFactorEdit.addTextChangedListener(textWatcher); - passwordEdit.setOnEditorActionListener(newLoginInputActionListener()); + } - loginButton.setOnClickListener(view -> performLogin()); - signupButton.setOnClickListener(view -> signUp()); + @OnFocusChange(R.id.login_username) + void onUsernameFocusChanged(View view, boolean hasFocus) { + if (!hasFocus) { + ViewUtil.hideKeyboard(view); + } + } - forgotPasswordText.setOnClickListener(view -> forgotPassword()); - skipLoginText.setOnClickListener(view -> new AlertDialog.Builder(this).setTitle(R.string.skip_login_title) + @OnFocusChange(R.id.login_password) + void onPasswordFocusChanged(View view, boolean hasFocus) { + if (!hasFocus) { + ViewUtil.hideKeyboard(view); + } + } + + @OnEditorAction(R.id.login_password) + boolean onEditorAction(int actionId, KeyEvent keyEvent) { + if (loginButton.isEnabled()) { + if (actionId == IME_ACTION_DONE) { + performLogin(); + return true; + } else if ((keyEvent != null) && keyEvent.getKeyCode() == KEYCODE_ENTER) { + performLogin(); + return true; + } + } + return false; + } + + + @OnClick(R.id.skip_login) + void skipLogin() { + new AlertDialog.Builder(this).setTitle(R.string.skip_login_title) .setMessage(R.string.skip_login_message) .setCancelable(false) .setPositiveButton(R.string.yes, (dialog, which) -> { dialog.cancel(); - skipLogin(); + performSkipLogin(); }) .setNegativeButton(R.string.no, (dialog, which) -> dialog.cancel()) - .show()); + .show(); if (ConfigUtils.isBetaFlavour()) { loginCredentials.setText(getString(R.string.login_credential)); @@ -148,24 +182,36 @@ public class LoginActivity extends AccountAuthenticatorActivity { } } - /** - * This function is called when user skips the login. - * It redirects the user to Explore Activity. - */ - private void skipLogin() { - applicationKvStore.putBoolean("login_skipped", true); - ExploreActivity.startYourself(this); - finish(); - - } - - private void forgotPassword() { + @OnClick(R.id.forgot_password) + void forgotPassword() { Utils.handleWebUrl(this, Uri.parse(BuildConfig.FORGOT_PASSWORD_URL)); } @OnClick(R.id.about_privacy_policy) void onPrivacyPolicyClicked() { - Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\\")); + Utils.handleWebUrl(this, Uri.parse(BuildConfig.PRIVACY_POLICY_URL)); + } + + @OnClick(R.id.login_button) + void performLogin() { + loginCurrentlyInProgress = true; + Timber.d("Login to start!"); + final String username = canonicializeUsername(usernameEdit.getText().toString()); + final String rawUsername = Utils.capitalize(usernameEdit.getText().toString().trim()); + final String password = passwordEdit.getText().toString(); + String twoFactorCode = twoFactorEdit.getText().toString(); + + showLoggingProgressBar(); + compositeDisposable.add(Observable.fromCallable(() -> login(username, password, twoFactorCode)) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(result -> handleLogin(username, rawUsername, password, result))); + } + + @OnClick(R.id.sign_up_button) + void signUp() { + Intent intent = new Intent(this, SignupActivity.class); + startActivity(intent); } @Override @@ -190,7 +236,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { } if (applicationKvStore.getBoolean("login_skipped", false)) { - skipLogin(); + performSkipLogin(); } } @@ -213,21 +259,6 @@ public class LoginActivity extends AccountAuthenticatorActivity { super.onDestroy(); } - private void performLogin() { - loginCurrentlyInProgress = true; - Timber.d("Login to start!"); - final String username = canonicializeUsername(usernameEdit.getText().toString()); - final String rawUsername = Utils.capitalize(usernameEdit.getText().toString().trim()); - final String password = passwordEdit.getText().toString(); - String twoFactorCode = twoFactorEdit.getText().toString(); - - showLoggingProgressBar(); - compositeDisposable.add(Observable.fromCallable(() -> login(username, password, twoFactorCode)) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(result -> handleLogin(username, rawUsername, password, result))); - } - private String login(String username, String password, String twoFactorCode) { try { if (twoFactorCode.isEmpty()) { @@ -241,10 +272,20 @@ public class LoginActivity extends AccountAuthenticatorActivity { } } + /** + * This function is called when user skips the login. + * It redirects the user to Explore Activity. + */ + private void performSkipLogin() { + applicationKvStore.putBoolean("login_skipped", true); + ExploreActivity.startYourself(this); + finish(); + } + private void handleLogin(String username, String rawUsername, String password, String result) { Timber.d("Login done!"); if (result.equals("PASS")) { - handlePassResult(username, rawUsername , password); + handlePassResult(username, rawUsername, password); } else { loginCurrentlyInProgress = false; errorMessageShown = true; @@ -325,6 +366,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { /** * Because Mediawiki is upercase-first-char-then-case-sensitive :) + * * @param username String * @return String canonicial username */ @@ -389,7 +431,9 @@ public class LoginActivity extends AccountAuthenticatorActivity { } if (errorMessageShown) { resultantError = savedInstanceState.getString(RESULTANT_ERROR); - handleOtherResults(resultantError); + if (resultantError != null) { + handleOtherResults(resultantError); + } } } @@ -402,7 +446,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { public void showMessageAndCancelDialog(@StringRes int resId) { showMessage(resId, R.color.secondaryDarkColor); - if (progressDialog != null){ + if (progressDialog != null) { progressDialog.cancel(); } } @@ -422,26 +466,6 @@ public class LoginActivity extends AccountAuthenticatorActivity { finish(); } - private void signUp() { - Intent intent = new Intent(this, SignupActivity.class); - startActivity(intent); - } - - private TextView.OnEditorActionListener newLoginInputActionListener() { - return (textView, actionId, keyEvent) -> { - if (loginButton.isEnabled()) { - if (actionId == IME_ACTION_DONE) { - performLogin(); - return true; - } else if ((keyEvent != null) && keyEvent.getKeyCode() == KEYCODE_ENTER) { - performLogin(); - return true; - } - } - return false; - }; - } - private void showMessage(@StringRes int resId, @ColorRes int colorResId) { errorMessage.setText(getString(resId)); errorMessage.setTextColor(ContextCompat.getColor(this, colorResId)); diff --git a/app/src/main/res/layout-land/activity_login.xml b/app/src/main/res/layout-land/activity_login.xml index 9c739144c..52463ca92 100644 --- a/app/src/main/res/layout-land/activity_login.xml +++ b/app/src/main/res/layout-land/activity_login.xml @@ -95,7 +95,7 @@ android:layout_marginTop="@dimen/standard_gap">