Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removed butterknife from login activity #5380

Merged
merged 4 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 52 additions & 79 deletions app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@
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;
Expand All @@ -27,8 +25,7 @@
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;
Expand All @@ -42,15 +39,9 @@
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;
Expand Down Expand Up @@ -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();
Expand All @@ -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);
Expand All @@ -133,35 +102,41 @@ public void onCreate(Bundle savedInstanceState) {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);

setContentView(R.layout.activity_login);
binding = ActivityLoginBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());

binding.loginUsername.addTextChangedListener(textWatcher);
binding.loginPassword.addTextChangedListener(textWatcher);
binding.loginTwoFactor.addTextChangedListener(textWatcher);

ButterKnife.bind(this);
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());

usernameEdit.addTextChangedListener(textWatcher);
passwordEdit.addTextChangedListener(textWatcher);
twoFactorEdit.addTextChangedListener(textWatcher);
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);
}
}
/**
* Hides the keyboard if the user's focus is not on the password (hasFocus is false).
* @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;
Expand All @@ -174,8 +149,7 @@ boolean onEditorAction(int actionId, KeyEvent keyEvent) {
}


@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)
Expand All @@ -187,18 +161,15 @@ void skipLogin() {
.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);
}
Expand Down Expand Up @@ -236,23 +207,23 @@ protected void onDestroy() {
} 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);
Expand Down Expand Up @@ -389,9 +360,9 @@ public MenuInflater getMenuInflater() {

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);
Expand Down Expand Up @@ -422,15 +393,15 @@ public void startMainActivity() {
}

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() {
Expand All @@ -451,9 +422,11 @@ public void onTextChanged(CharSequence charSequence, int start, int count, int a

@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);
}
}

Expand All @@ -471,22 +444,22 @@ protected void onSaveInstanceState(Bundle outState) {
} 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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down