refactoring Login routine

This commit is contained in:
yb 2022-06-30 16:19:13 +02:00
parent 78f4f1cae6
commit 98ea837ad8
13 changed files with 134 additions and 223 deletions

View File

@ -1,6 +1,9 @@
package eu.csc.vehown.ui.base;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.navigation.NavController;
@ -10,7 +13,10 @@ import androidx.navigation.ui.NavigationUI;
import eu.csc.vehown.R;
import eu.csc.vehown.databinding.ActivityBaseRegistrationBinding;
public class BaseRegistrationActivity extends AppCompatActivity {
/**
* @see eu.csc.vehown.ui.registration.vehicle.FragmentVehicleRegistration
*/
public class BaseRegistrationActivity extends AppCompatActivity implements ICallbackInterface {
private ActivityBaseRegistrationBinding binding;
@ -34,4 +40,9 @@ public class BaseRegistrationActivity extends AppCompatActivity {
NavigationUI.setupWithNavController(binding.navView, navController);
}
@Override
public void showIdle(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
}

View File

@ -0,0 +1,5 @@
package eu.csc.vehown.ui.base;
public interface ICallbackInterface {
void showIdle(String msg);
}

View File

@ -6,10 +6,13 @@ import android.content.Intent;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
@ -28,16 +31,22 @@ import eu.csc.vehown.ui.models.LoginResult;
import eu.csc.vehown.ui.register.RegisterCustomerActivity;
import eu.csc.vehown.ui.registration.customer.FragmentCustomerRegistration;
/**
*
*/
public class LoginActivity extends AppCompatActivity {
private LoginViewModel loginViewModel;
Button btnShowRegistration;
private Button btnShowRegistration;
private boolean loginVisible;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
loginViewModel = new ViewModelProvider(this, new LoginViewModelFactory())
.get(LoginViewModel.class);
btnShowRegistration = findViewById(R.id.btnShowRegistration);
btnShowRegistration.setOnClickListener(new View.OnClickListener() {
@ -151,10 +160,10 @@ public class LoginActivity extends AppCompatActivity {
}
private void switchView() {
if(
loginViewModel.isLoginVisible()){
if (
loginVisible) {
showRegistration();
}else
} else
showLogin();
}
@ -165,31 +174,19 @@ public class LoginActivity extends AppCompatActivity {
fragmentTransaction.replace(R.id.content_frame, fragment);
fragmentTransaction.commit();
loginViewModel.setLoginVisible(false);
loginVisible = false;
btnShowRegistration.setText("Login");
}
private void showLogin(){
private void showLogin() {
LoginFragment fragment = new LoginFragment();
fragment.setArguments(new Bundle());
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment);
fragmentTransaction.commit();
loginViewModel.setLoginVisible(true);
loginVisible = true;
btnShowRegistration.setText("Register");
}
private void updateUiWithUser(LoggedInUserView model) {
String welcome = getString(R.string.welcome) + model.getDisplayName();
// TODO : initiate successful logged in experience
Toast.makeText(getApplicationContext(), welcome, Toast.LENGTH_LONG).show();
}
private void showLoginFailed(@StringRes Integer errorString) {
Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_SHORT).show();
}
}

View File

@ -1,41 +0,0 @@
package eu.csc.vehown.ui.login;
import androidx.annotation.Nullable;
/**
* Data validation state of the login form.
*/
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;
}
}

View File

@ -1,77 +0,0 @@
package eu.csc.vehown.ui.login;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import android.util.Patterns;
import eu.csc.vehown.data.LoginRepository;
import eu.csc.vehown.data.Result;
import eu.csc.vehown.R;
import eu.csc.vehown.data.model.LoggedInUser;
import eu.csc.vehown.ui.models.LoggedInUserView;
import eu.csc.vehown.ui.models.LoginResult;
import lombok.Getter;
import lombok.Setter;
public class LoginViewModel extends ViewModel {
private MutableLiveData<LoginFormState> loginFormState = new MutableLiveData<>();
private MutableLiveData<LoginResult> loginResult = new MutableLiveData<>();
private LoginRepository loginRepository;
LoginViewModel(LoginRepository loginRepository) {
this.loginRepository = loginRepository;
}
LiveData<LoginFormState> getLoginFormState() {
return loginFormState;
}
LiveData<LoginResult> getLoginResult() {
return loginResult;
}
public void login(String username, String password) {
// can be launched in a separate asynchronous job
Result<LoggedInUser> result = loginRepository.login(username, password);
if (result instanceof Result.Success) {
LoggedInUser data = ((Result.Success<LoggedInUser>) result).getData();
loginResult.setValue(new LoginResult(new LoggedInUserView(data.getDisplayName())));
} else {
loginResult.setValue(new LoginResult(R.string.login_failed));
}
}
public void loginDataChanged(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));
}
}
// 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;
}
@Getter
@Setter
private boolean loginVisible;
}

View File

@ -1,26 +0,0 @@
package eu.csc.vehown.ui.login;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import androidx.annotation.NonNull;
import eu.csc.vehown.data.LoginDataSource;
import eu.csc.vehown.data.LoginRepository;
/**
* ViewModel provider factory to instantiate LoginViewModel.
* Required given LoginViewModel has a non-empty constructor
*/
public class LoginViewModelFactory implements ViewModelProvider.Factory {
@NonNull
@Override
@SuppressWarnings("unchecked")
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (modelClass.isAssignableFrom(LoginViewModel.class)) {
return (T) new LoginViewModel(LoginRepository.getInstance(new LoginDataSource()));
} else {
throw new IllegalArgumentException("Unknown ViewModel class");
}
}
}

View File

@ -22,6 +22,8 @@ import com.google.android.material.navigation.NavigationView;
import eu.csc.log.CSCLog4jFactory;
import eu.csc.vehown.R;
import eu.csc.vehown.broadcast.VehicleEventReceivedReceiver;
import eu.csc.vehown.persist.sharedPreferences.LocalStorageClient;
import eu.csc.vehown.persist.sharedPreferences.SharedPreferencesFactory;
import eu.csc.vehown.services.mqtt.MqttClient;
import eu.csc.vehown.services.notifications.NotificationService;
import eu.csc.vehown.services.rest.vehownserver.VehOwnApiClientFactory;
@ -41,9 +43,10 @@ public class MainActivity extends AppCompatActivity {
// private static final int PERMISSIONS_REQUESTED = 1;
private static final String CONNECTIVITY_CHANGE = "android.net.conn.CONNECTIVITY_CHANGE";
private static final String TAG = MainActivity.class.getSimpleName();
// private CSCLog log;
// private Handler handler;
// private Handler handler;
private AppBarConfiguration mAppBarConfiguration;
@Override
@ -78,6 +81,7 @@ public class MainActivity extends AppCompatActivity {
//FIXME MqttClient.receiveMessages(getApplicationContext());
setup();
checkRegistration();
for (int i = 0; i < 10; ++i) {
//DataServiceIntent.startUploadingRequestHelp(this, i + "", "");
@ -86,6 +90,15 @@ public class MainActivity extends AppCompatActivity {
}
private void checkRegistration() {
if(SharedPreferencesFactory.isLoggedIn(getApplicationContext())){
Log.d(TAG, "NOT LOGGED IN");
}else{
}
}
private void setup() {
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(VehicleEventReceivedReceiver.EVENT_INTENT_NAME);
@ -112,7 +125,7 @@ public class MainActivity extends AppCompatActivity {
Intent intent = null;
switch (item.getItemId()) {
case R.id.nav_login:
intent = new Intent(this, LoginActivity.class);
showLogin();
break;
case R.id.nav_list_content:
@ -164,6 +177,10 @@ public class MainActivity extends AppCompatActivity {
}
}
private Intent showLogin() {
return new Intent(this, LoginActivity.class);
}
// public void onRequestPermissionsResult(int requestCode, @NotNull String[] permissions, @NotNull int[] grantResults) {
// if (requestCode == PERMISSIONS_REQUESTED) {// If request is cancelled, the result arrays are empty.
// if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

View File

@ -2,6 +2,7 @@ package eu.csc.vehown.ui.registration.vehicle;
import androidx.lifecycle.ViewModelProvider;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@ -30,6 +31,7 @@ import eu.csc.vehown.databinding.FragmentVehicleRegistrationFragmentBinding;
import eu.csc.vehown.ui.adapters.PropulsionTypeAdapter;
import eu.csc.vehown.ui.adapters.VehicleBrandAdapter;
import eu.csc.vehown.ui.adapters.VehicleModelAdapter;
import eu.csc.vehown.ui.base.ICallbackInterface;
import eu.csc.vehown.ui.md.ItemDetailFragment;
import eu.csc.vehown.ui.modal.Helper;
import eu.csc.vehown.ui.pub.UIUtils;
@ -42,11 +44,12 @@ import eu.csc.vehown.ui.viewmodels.AppViewModelFactory;
public class FragmentVehicleRegistration extends Fragment {
private FragmentVehicleRegistrationViewModel mViewModel;
private FragmentVehicleRegistrationFragmentBinding binding;
private FragmentVehicleRegistrationViewModel mViewModel;
private List<View> mandatoryFields;
private ICallbackInterface mCallback;
public static FragmentVehicleRegistration newInstance() {
return new FragmentVehicleRegistration();
@ -55,7 +58,7 @@ public class FragmentVehicleRegistration extends Fragment {
public static FragmentVehicleRegistration editCurrentItem(String id) {
Bundle args = new Bundle();
;
args.putString(ItemDetailFragment.ARG_ITEM_ID, id);
FragmentVehicleRegistration result = new FragmentVehicleRegistration();
@ -74,7 +77,13 @@ public class FragmentVehicleRegistration extends Fragment {
String id = null;
Bundle args = getArguments();
if (args != null)
{
id = args.getString(ItemDetailFragment.ARG_ITEM_ID, null);
}else{
}
mViewModel = new ViewModelProvider(this, new AppViewModelFactory(getContext())).get(FragmentVehicleRegistrationViewModel.class);
@ -83,10 +92,8 @@ public class FragmentVehicleRegistration extends Fragment {
mViewModel.getCurrentVehicle().observe(getViewLifecycleOwner(), vehicle -> {
binding.editPowertrain.setText(vehicle.getPowertrain());
binding.editVariant.setText(vehicle.getVariant());
binding.editVIN.setText(vehicle.getVin());
binding.editLicensePlate.setText(vehicle.getLicensePlate());
setVehicle(vehicle);
//ToDo set Spinner Content
//binding.spModel.
@ -163,7 +170,12 @@ public class FragmentVehicleRegistration extends Fragment {
}
binding.btnStore.setOnClickListener(v -> {
mViewModel.storeVehicle(getVehicle());
if(mCallback != null){
mCallback.showIdle("RUNNING");
}
//mViewModel.storeVehicle(getVehicle());
//Helper.infoDialog(handler, getApplicationContext(), "success");
});
@ -177,16 +189,13 @@ public class FragmentVehicleRegistration extends Fragment {
binding.btnRegisterVehicle.setOnClickListener(v -> {
Vehicle vehicle = getVehicle();
/*
private Date registrationDate;
*/
mViewModel
.getRepository()
.storeCustomerVehicle(vehicle);
//ToDo run RestCall
/*
try {
@ -220,7 +229,7 @@ public class FragmentVehicleRegistration extends Fragment {
});
binding.btnUnregisterVehicle.setOnClickListener(v -> {
mViewModel.unregisterVehicle();
});
// mandatoryFields = new ArrayList<>(Arrays.asList(binding.spBrand, binding.spModel, binding.editPowertrain, binding.editVariant,
@ -242,6 +251,16 @@ public class FragmentVehicleRegistration extends Fragment {
return root;
}
private void setVehicle(Vehicle vehicle) {
binding.editPowertrain.setText(vehicle.getPowertrain());
binding.editVariant.setText(vehicle.getVariant());
binding.editVIN.setText(vehicle.getVin());
binding.editLicensePlate.setText(vehicle.getLicensePlate());
//binding.datePickerRegistration
}
private Vehicle getVehicle() {
Vehicle vehicle = new Vehicle();
@ -256,4 +275,16 @@ public class FragmentVehicleRegistration extends Fragment {
return vehicle;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (ICallbackInterface) activity;
} catch (ClassCastException e) {
}
}
}

View File

@ -32,10 +32,6 @@ public class FragmentVehicleRegistrationViewModel extends AbstractBaseViewModel
private final CustomerRegistrationRepository repository;
private final Context context;
ExecutorService executorService = Executors.newFixedThreadPool(4);
private final MutableLiveData<List<Language>> languages;
@Getter
private final MutableLiveData<List<VehicleBrand>> vehicleBrands;
@Getter
@ -52,7 +48,6 @@ public class FragmentVehicleRegistrationViewModel extends AbstractBaseViewModel
public FragmentVehicleRegistrationViewModel(CustomerRegistrationRepository repository, Context context, LocalStorageClient localStorageClient) {
super(localStorageClient);
languages = new MutableLiveData<>();
vehicleBrands = new MutableLiveData<>();
vehiclePropulsionTypes = new MutableLiveData<>();
vehicleModels = new MutableLiveData<>();
@ -65,42 +60,6 @@ public class FragmentVehicleRegistrationViewModel extends AbstractBaseViewModel
}
public List<Language> getLanguages() {
if (languages.getValue() == null) {
List<Language> langs = new ArrayList<>();
try {
VehOwnApiClientFactory.getDataClient().listLanguages()
.execute()
.body()
.forEach(languageDto -> {
Language lang = new Language();
lang.setId(languageDto.getLocale());
lang.setName(languageDto.getName());
langs.add(lang);
});
} catch (IOException e) {
e.printStackTrace();
langs.add(new Language("en", "English"));
}
languages.setValue(langs);
}
return languages.getValue();
}
public String[] getLanguageNames() {
List<Language> languages = getLanguages();
String[] languageNames = new String[languages.size()];
for (int i = 0; i < languages.size(); i++) {
languageNames[i] = languages.get(i).getName();
}
return languageNames;
}
public void fetchData() {
executorService.execute(new Runnable() {
@Override
@ -152,7 +111,7 @@ public class FragmentVehicleRegistrationViewModel extends AbstractBaseViewModel
}
public void storeVehicle(Vehicle vehicle) {
Helper.infoToast(context, "Storing vehicle");
Helper.infoToast(context, "Storing vehicle data local");
getRepository().storeCustomerVehicle(vehicle);
Helper.infoToast(context, "success");
@ -165,4 +124,7 @@ public class FragmentVehicleRegistrationViewModel extends AbstractBaseViewModel
Helper.infoToast(context, "success");
}
public void unregisterVehicle() {
}
}

View File

@ -13,6 +13,7 @@ public abstract class AbstractBaseViewModel extends ViewModel {
protected final LocalStorageClient localStorageClient;
protected ExecutorService executorService = Executors.newFixedThreadPool(4);
protected AbstractBaseViewModel(LocalStorageClient localStorage) {

View File

@ -44,4 +44,22 @@
app:navGraph="@navigation/mobile_navigation2"
/>
<!-- <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"/>-->
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -2,7 +2,15 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:scrollbarFadeDuration="0"
android:scrollbarSize="5dip"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -8,4 +8,9 @@ public class SharedPreferencesFactory {
return new LocalStorageClientImpl(context);
}
public static boolean isLoggedIn(Context context){
return getInstance(context).getIsLoggedIn();
}
}