WIP: LoginFormValidation
This commit is contained in:
parent
1096be3051
commit
83a6c27c56
@ -4,20 +4,23 @@ import android.app.AlertDialog;
|
|||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.widget.EditText;
|
import android.widget.*;
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import com.stormtales.notevault.R;
|
import com.stormtales.notevault.R;
|
||||||
import com.stormtales.notevault.network.APICallback;
|
import com.stormtales.notevault.network.APICallback;
|
||||||
import com.stormtales.notevault.network.auth.AuthService;
|
import com.stormtales.notevault.network.auth.AuthService;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class LoginDialog extends DialogFragment {
|
public class LoginDialog extends DialogFragment {
|
||||||
|
|
||||||
@ -25,6 +28,12 @@ public class LoginDialog extends DialogFragment {
|
|||||||
private boolean isLoginMode = true;
|
private boolean isLoginMode = true;
|
||||||
private Dialog dialog;
|
private Dialog dialog;
|
||||||
|
|
||||||
|
private Button loginButton;
|
||||||
|
private ProgressBar loadingProgressBar;
|
||||||
|
private EditText editTextUsername;
|
||||||
|
private EditText editTextPassword;
|
||||||
|
private EditText editTextEmail;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
@ -43,43 +52,93 @@ public class LoginDialog extends DialogFragment {
|
|||||||
View view = inflater.inflate(R.layout.fragment_login_dialog, null);
|
View view = inflater.inflate(R.layout.fragment_login_dialog, null);
|
||||||
|
|
||||||
TextView textViewTitle = view.findViewById(R.id.textViewTitle);
|
TextView textViewTitle = view.findViewById(R.id.textViewTitle);
|
||||||
EditText editTextUsername = view.findViewById(R.id.editTextUsername);
|
editTextUsername = view.findViewById(R.id.editTextUsername);
|
||||||
EditText editTextEmail = view.findViewById(R.id.editTextEmail);
|
editTextEmail = view.findViewById(R.id.editTextEmail);
|
||||||
EditText editTextPassword = view.findViewById(R.id.editTextPassword);
|
editTextPassword = view.findViewById(R.id.editTextPassword);
|
||||||
Button buttonAction = view.findViewById(R.id.buttonAction);
|
loginButton = view.findViewById(R.id.buttonAction);
|
||||||
TextView textViewSwitch = view.findViewById(R.id.textViewSwitch);
|
TextView textViewSwitch = view.findViewById(R.id.textViewSwitch);
|
||||||
|
loadingProgressBar = view.findViewById(R.id.loading);
|
||||||
// Handle action button click
|
// Handle action button click
|
||||||
buttonAction.setOnClickListener(v -> {
|
|
||||||
if (isLoginMode) {
|
|
||||||
// Handle login logic
|
|
||||||
String email = editTextEmail.getText().toString();
|
|
||||||
String password = editTextPassword.getText().toString();
|
|
||||||
this.loginViewModel.performLogin(email, password, this::onSuccessFullLogin);
|
|
||||||
} else {
|
|
||||||
// Handle registration logic
|
|
||||||
String email = editTextEmail.getText().toString();
|
|
||||||
String password = editTextPassword.getText().toString();
|
|
||||||
String username = editTextUsername.getText().toString();
|
|
||||||
AuthService authRepository = new AuthService(this.getContext());
|
|
||||||
//authRepository.performRegistration(email, username, password, registerCallback);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Toggle between Login and Registration
|
// Toggle between Login and Registration
|
||||||
textViewSwitch.setOnClickListener(v -> {
|
textViewSwitch.setOnClickListener(v -> {
|
||||||
isLoginMode = !isLoginMode;
|
isLoginMode = !isLoginMode;
|
||||||
textViewTitle.setText(isLoginMode ? "Login" : "Register");
|
textViewTitle.setText(isLoginMode ? "Login" : "Register");
|
||||||
editTextUsername.setVisibility(isLoginMode ? View.GONE : View.VISIBLE);
|
editTextUsername.setVisibility(isLoginMode ? View.GONE : View.VISIBLE);
|
||||||
buttonAction.setText(isLoginMode ? "Login" : "Register");
|
loginButton.setText(isLoginMode ? "Login" : "Register");
|
||||||
textViewSwitch.setText(isLoginMode ? "Don't have an account? Register" : "Already have an account? Login");
|
textViewSwitch.setText(isLoginMode ? "Don't have an account? Register" : "Already have an account? Login");
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.setView(view);
|
builder.setView(view);
|
||||||
dialog = builder.create();
|
dialog = builder.create();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TextWatcher afterTextChangedListener = new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
loginViewModel.updateLoginData(editTextUsername.getText().toString(), editTextPassword.getText().toString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
editTextUsername.addTextChangedListener(afterTextChangedListener);
|
||||||
|
editTextPassword.addTextChangedListener(afterTextChangedListener);
|
||||||
|
editTextPassword.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
|
if(actionId == EditorInfo.IME_ACTION_DONE) {
|
||||||
|
loginViewModel.performLogin(editTextUsername.getText().toString(), editTextPassword.getText().toString(), LoginDialog.this::onSuccessFullLogin);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
loginButton.setOnClickListener(v -> {
|
||||||
|
loadingProgressBar.setVisibility(View.VISIBLE);
|
||||||
|
String email = editTextEmail.getText().toString();
|
||||||
|
String password = editTextPassword.getText().toString();
|
||||||
|
if (isLoginMode) {
|
||||||
|
// Handle login logic
|
||||||
|
this.loginViewModel.performLogin(email, password, this::onSuccessFullLogin);
|
||||||
|
} else {
|
||||||
|
// Handle registration logic
|
||||||
|
String username = editTextUsername.getText().toString();
|
||||||
|
AuthService authRepository = new AuthService(this.getContext());
|
||||||
|
//authRepository.performRegistration(email, username, password, registerCallback);
|
||||||
|
}
|
||||||
|
});
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
loginViewModel.getLoginFormState().observe(getViewLifecycleOwner(), new Observer<LoginFormState>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(LoginFormState loginFormState) {
|
||||||
|
if(loginFormState == null) return;
|
||||||
|
loginButton.setEnabled(loginFormState.isDataValid());
|
||||||
|
if(loginFormState.getUsernameError() != null) {
|
||||||
|
editTextUsername.setError(getString(loginFormState.getUsernameError()));
|
||||||
|
}
|
||||||
|
if(loginFormState.getPasswordError() != null) {
|
||||||
|
editTextPassword.setError(getString(loginFormState.getPasswordError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void onSuccessFullLogin() {
|
void onSuccessFullLogin() {
|
||||||
this.dialog.dismiss();
|
this.dialog.dismiss();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.stormtales.notevault.ui.login;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
public class LoginFormState {
|
||||||
|
@Nullable
|
||||||
|
private Integer usernameError;
|
||||||
|
@Nullable
|
||||||
|
private Integer passwordError;
|
||||||
|
private boolean isDataValid;
|
||||||
|
|
||||||
|
LoginFormState(@Nullable Integer usernameError, @Nullable Integer passwordError) {
|
||||||
|
this.usernameError = usernameError;
|
||||||
|
this.passwordError = passwordError;
|
||||||
|
this.isDataValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoginFormState(boolean isDataValid) {
|
||||||
|
this.usernameError = null;
|
||||||
|
this.passwordError = null;
|
||||||
|
this.isDataValid = isDataValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Integer getUsernameError() {
|
||||||
|
return usernameError;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Integer getPasswordError() {
|
||||||
|
return passwordError;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isDataValid() {
|
||||||
|
return isDataValid;
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,11 @@
|
|||||||
package com.stormtales.notevault.ui.login;
|
package com.stormtales.notevault.ui.login;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.Patterns;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
import androidx.lifecycle.ViewModel;
|
import androidx.lifecycle.ViewModel;
|
||||||
|
import com.stormtales.notevault.R;
|
||||||
import com.stormtales.notevault.network.auth.AuthService;
|
import com.stormtales.notevault.network.auth.AuthService;
|
||||||
import com.stormtales.notevault.network.auth.LoginResponse;
|
import com.stormtales.notevault.network.auth.LoginResponse;
|
||||||
|
|
||||||
@ -11,6 +13,7 @@ public class LoginViewModel extends ViewModel {
|
|||||||
|
|
||||||
private final MutableLiveData<String> username;
|
private final MutableLiveData<String> username;
|
||||||
private final MutableLiveData<Boolean> isLoggedIn;
|
private final MutableLiveData<Boolean> isLoggedIn;
|
||||||
|
private MutableLiveData<LoginFormState> loginFormState = new MutableLiveData<>();
|
||||||
private AuthService authService;
|
private AuthService authService;
|
||||||
|
|
||||||
public LoginViewModel() {
|
public LoginViewModel() {
|
||||||
@ -38,6 +41,16 @@ public class LoginViewModel extends ViewModel {
|
|||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateLoginData(String username, String password) {
|
||||||
|
if(!isUserNameValid(username)) {
|
||||||
|
loginFormState.setValue(new LoginFormState(R.string.invalid_username, null));
|
||||||
|
} else if(!isPasswordValid(password)) {
|
||||||
|
loginFormState.setValue(new LoginFormState(null, R.string.invalid_password));
|
||||||
|
} else {
|
||||||
|
loginFormState.setValue(new LoginFormState(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class LoginCallBackImpl implements AuthService.LoginCallback {
|
public class LoginCallBackImpl implements AuthService.LoginCallback {
|
||||||
|
|
||||||
private final SuccessFullLoginCallback successFullLoginCallback;
|
private final SuccessFullLoginCallback successFullLoginCallback;
|
||||||
@ -62,4 +75,25 @@ public class LoginViewModel extends ViewModel {
|
|||||||
public interface SuccessFullLoginCallback {
|
public interface SuccessFullLoginCallback {
|
||||||
void onSuccess();
|
void onSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MutableLiveData<LoginFormState> getLoginFormState() {
|
||||||
|
return loginFormState;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A placeholder username validation check
|
||||||
|
private boolean isUserNameValid(String username) {
|
||||||
|
if (username == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (username.contains("@")) {
|
||||||
|
return Patterns.EMAIL_ADDRESS.matcher(username).matches();
|
||||||
|
} else {
|
||||||
|
return !username.trim().isEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A placeholder password validation check
|
||||||
|
private boolean isPasswordValid(String password) {
|
||||||
|
return password != null && password.trim().length() > 5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="16dp"
|
android:padding="16dp"
|
||||||
android:background="@drawable/dialog_background"
|
android:background="@drawable/dialog_background"
|
||||||
@ -65,4 +65,20 @@
|
|||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true" />
|
android:focusable="true" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/loading"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginTop="64dp"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:layout_marginBottom="64dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/password"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/password"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="0.3"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
Loading…
Reference in New Issue
Block a user