Removed butterknife from login activity (#5380)

* Removed butterknife view bindings

* Migrated click listeners to view binding

* Migrate onEditorAction to use ViewBinding

* Finally, removed butterknife
This commit is contained in:
Paul Hawke 2023-11-11 07:54:08 -06:00 committed by GitHub
parent 9620f6eee0
commit 861d2b9bf6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 110 deletions

View file

@ -14,10 +14,8 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView;
import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -27,8 +25,7 @@ import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.app.NavUtils;
import androidx.core.content.ContextCompat;
import com.google.android.material.textfield.TextInputLayout;
import fr.free.nrw.commons.databinding.ActivityLoginBinding;
import fr.free.nrw.commons.utils.ActivityUtils;
import java.util.Locale;
import org.wikipedia.AppAdapter;
@ -42,15 +39,9 @@ import org.wikipedia.login.LoginResult;
import javax.inject.Inject;
import javax.inject.Named;
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.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.WelcomeActivity;
import fr.free.nrw.commons.contributions.MainActivity;
import fr.free.nrw.commons.di.ApplicationlessInjection;
import fr.free.nrw.commons.kvstore.JsonKvStore;
@ -87,30 +78,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
@Inject
SystemThemeUtils systemThemeUtils;
@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;
private ActivityLoginBinding binding;
ProgressDialog progressDialog;
private AppCompatDelegate delegate;
private LoginTextWatcher textWatcher = new LoginTextWatcher();
@ -120,6 +88,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
final String saveErrorMessage ="errorMessage";
final String saveUsername="username";
final String savePassword="password";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -133,18 +102,26 @@ public class LoginActivity extends AccountAuthenticatorActivity {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
binding = ActivityLoginBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
ButterKnife.bind(this);
binding.loginUsername.addTextChangedListener(textWatcher);
binding.loginPassword.addTextChangedListener(textWatcher);
binding.loginTwoFactor.addTextChangedListener(textWatcher);
usernameEdit.addTextChangedListener(textWatcher);
passwordEdit.addTextChangedListener(textWatcher);
twoFactorEdit.addTextChangedListener(textWatcher);
binding.skipLogin.setOnClickListener(view -> skipLogin());
binding.forgotPassword.setOnClickListener(view -> forgotPassword());
binding.aboutPrivacyPolicy.setOnClickListener(view -> onPrivacyPolicyClicked());
binding.signUpButton.setOnClickListener(view -> signUp());
binding.loginButton.setOnClickListener(view -> performLogin());
binding.loginPassword.setOnEditorActionListener(this::onEditorAction);
binding.loginPassword.setOnFocusChangeListener(this::onPasswordFocusChanged);
if (ConfigUtils.isBetaFlavour()) {
loginCredentials.setText(getString(R.string.login_credential));
binding.loginCredentials.setText(getString(R.string.login_credential));
} else {
loginCredentials.setVisibility(View.GONE);
binding.loginCredentials.setVisibility(View.GONE);
}
}
/**
@ -152,16 +129,14 @@ public class LoginActivity extends AccountAuthenticatorActivity {
* @param view The keyboard
* @param hasFocus Set to true if the keyboard has focus
*/
@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()) {
boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
if (binding.loginButton.isEnabled()) {
if (actionId == IME_ACTION_DONE) {
performLogin();
return true;
@ -174,8 +149,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
}
@OnClick(R.id.skip_login)
void skipLogin() {
protected void skipLogin() {
new AlertDialog.Builder(this).setTitle(R.string.skip_login_title)
.setMessage(R.string.skip_login_message)
.setCancelable(false)
@ -187,18 +161,15 @@ public class LoginActivity extends AccountAuthenticatorActivity {
.show();
}
@OnClick(R.id.forgot_password)
void forgotPassword() {
protected void forgotPassword() {
Utils.handleWebUrl(this, Uri.parse(BuildConfig.FORGOT_PASSWORD_URL));
}
@OnClick(R.id.about_privacy_policy)
void onPrivacyPolicyClicked() {
protected void onPrivacyPolicyClicked() {
Utils.handleWebUrl(this, Uri.parse(BuildConfig.PRIVACY_POLICY_URL));
}
@OnClick(R.id.sign_up_button)
void signUp() {
protected void signUp() {
Intent intent = new Intent(this, SignupActivity.class);
startActivity(intent);
}
@ -236,23 +207,23 @@ public class LoginActivity extends AccountAuthenticatorActivity {
} catch (Exception e) {
e.printStackTrace();
}
usernameEdit.removeTextChangedListener(textWatcher);
passwordEdit.removeTextChangedListener(textWatcher);
twoFactorEdit.removeTextChangedListener(textWatcher);
binding.loginUsername.removeTextChangedListener(textWatcher);
binding.loginPassword.removeTextChangedListener(textWatcher);
binding.loginTwoFactor.removeTextChangedListener(textWatcher);
delegate.onDestroy();
if(null!=loginClient) {
loginClient.cancel();
}
binding = null;
super.onDestroy();
}
@OnClick(R.id.login_button)
public void performLogin() {
Timber.d("Login to start!");
final String username = usernameEdit.getText().toString();
final String rawUsername = usernameEdit.getText().toString().trim();
final String password = passwordEdit.getText().toString();
String twoFactorCode = twoFactorEdit.getText().toString();
final String username = binding.loginUsername.getText().toString();
final String rawUsername = binding.loginUsername.getText().toString().trim();
final String password = binding.loginPassword.getText().toString();
String twoFactorCode = binding.loginTwoFactor.getText().toString();
showLoggingProgressBar();
doLogin(username, password, twoFactorCode);
@ -389,9 +360,9 @@ public class LoginActivity extends AccountAuthenticatorActivity {
public void askUserForTwoFactorAuth() {
progressDialog.dismiss();
twoFactorContainer.setVisibility(VISIBLE);
twoFactorEdit.setVisibility(VISIBLE);
twoFactorEdit.requestFocus();
binding.twoFactorContainer.setVisibility(VISIBLE);
binding.loginTwoFactor.setVisibility(VISIBLE);
binding.loginTwoFactor.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
showMessageAndCancelDialog(R.string.login_failed_2fa_needed);
@ -422,15 +393,15 @@ public class LoginActivity extends AccountAuthenticatorActivity {
}
private void showMessage(@StringRes int resId, @ColorRes int colorResId) {
errorMessage.setText(getString(resId));
errorMessage.setTextColor(ContextCompat.getColor(this, colorResId));
errorMessageContainer.setVisibility(VISIBLE);
binding.errorMessage.setText(getString(resId));
binding.errorMessage.setTextColor(ContextCompat.getColor(this, colorResId));
binding.errorMessageContainer.setVisibility(VISIBLE);
}
private void showMessage(String message, @ColorRes int colorResId) {
errorMessage.setText(message);
errorMessage.setTextColor(ContextCompat.getColor(this, colorResId));
errorMessageContainer.setVisibility(VISIBLE);
binding.errorMessage.setText(message);
binding.errorMessage.setTextColor(ContextCompat.getColor(this, colorResId));
binding.errorMessageContainer.setVisibility(VISIBLE);
}
private AppCompatDelegate getDelegate() {
@ -451,9 +422,11 @@ public class LoginActivity extends AccountAuthenticatorActivity {
@Override
public void afterTextChanged(Editable editable) {
boolean enabled = usernameEdit.getText().length() != 0 && passwordEdit.getText().length() != 0
&& (BuildConfig.DEBUG || twoFactorEdit.getText().length() != 0 || twoFactorEdit.getVisibility() != VISIBLE);
loginButton.setEnabled(enabled);
boolean enabled = binding.loginUsername.getText().length() != 0 &&
binding.loginPassword.getText().length() != 0 &&
(BuildConfig.DEBUG || binding.loginTwoFactor.getText().length() != 0 ||
binding.loginTwoFactor.getVisibility() != VISIBLE);
binding.loginButton.setEnabled(enabled);
}
}
@ -471,22 +444,22 @@ public class LoginActivity extends AccountAuthenticatorActivity {
} else {
outState.putBoolean(saveProgressDailog,false);
}
outState.putString(saveErrorMessage,errorMessage.getText().toString()); //Save the errorMessage
outState.putString(saveErrorMessage,binding.errorMessage.getText().toString()); //Save the errorMessage
outState.putString(saveUsername,getUsername()); // Save the username
outState.putString(savePassword,getPassword()); // Save the password
}
private String getUsername() {
return usernameEdit.getText().toString();
return binding.loginUsername.getText().toString();
}
private String getPassword(){
return passwordEdit.getText().toString();
return binding.loginPassword.getText().toString();
}
@Override
protected void onRestoreInstanceState(final Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
usernameEdit.setText(savedInstanceState.getString(saveUsername));
passwordEdit.setText(savedInstanceState.getString(savePassword));
binding.loginUsername.setText(savedInstanceState.getString(saveUsername));
binding.loginPassword.setText(savedInstanceState.getString(savePassword));
if(savedInstanceState.getBoolean(saveProgressDailog)) {
performLogin();
}

View file

@ -10,6 +10,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.Button
import android.widget.TextView
import androidx.test.core.app.ApplicationProvider
import fr.free.nrw.commons.R
import fr.free.nrw.commons.TestAppAdapter
@ -55,7 +56,7 @@ class LoginActivityUnitTests {
private lateinit var keyEvent: KeyEvent
@Mock
private lateinit var loginButton: Button
private lateinit var textView: TextView
@Mock
private lateinit var bundle: Bundle
@ -95,40 +96,12 @@ class LoginActivityUnitTests {
fun testOnEditorActionCaseDefault() {
val method: Method = LoginActivity::class.java.getDeclaredMethod(
"onEditorAction",
TextView::class.java,
Int::class.java,
KeyEvent::class.java
)
method.isAccessible = true
method.invoke(activity, 0, keyEvent)
}
@Test
@Throws(Exception::class)
fun testOnEditorActionCaseLoginEnabledFirstCase() {
Whitebox.setInternalState(activity, "loginButton", loginButton)
`when`(loginButton.isEnabled).thenReturn(true)
val method: Method = LoginActivity::class.java.getDeclaredMethod(
"onEditorAction",
Int::class.java,
KeyEvent::class.java
)
method.isAccessible = true
method.invoke(activity, EditorInfo.IME_ACTION_DONE, keyEvent)
}
@Test
@Throws(Exception::class)
fun testOnEditorActionCaseLoginEnabledSecondCase() {
Whitebox.setInternalState(activity, "loginButton", loginButton)
`when`(loginButton.isEnabled).thenReturn(true)
`when`(keyEvent.keyCode).thenReturn(KeyEvent.KEYCODE_ENTER)
val method: Method = LoginActivity::class.java.getDeclaredMethod(
"onEditorAction",
Int::class.java,
KeyEvent::class.java
)
method.isAccessible = true
method.invoke(activity, 0, keyEvent)
method.invoke(activity, textView, 0, keyEvent)
}
@Test