Use ViewModel instead of Callbacks for UI Updates

This commit is contained in:
Fawkes100 2025-01-19 07:22:59 +01:00
parent 7aa30fd4d7
commit 1096be3051
4 changed files with 93 additions and 45 deletions

View File

@ -3,6 +3,8 @@ package com.stormtales.notevault;
import android.os.Bundle; import android.os.Bundle;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.Menu; import android.view.Menu;
import android.widget.Toast;
import androidx.lifecycle.ViewModelProvider;
import com.google.android.material.navigation.NavigationView; import com.google.android.material.navigation.NavigationView;
import androidx.navigation.NavController; import androidx.navigation.NavController;
import androidx.navigation.Navigation; import androidx.navigation.Navigation;
@ -14,11 +16,13 @@ import com.stormtales.notevault.databinding.ActivityMainBinding;
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 com.stormtales.notevault.ui.login.LoginDialog; import com.stormtales.notevault.ui.login.LoginDialog;
import com.stormtales.notevault.ui.login.LoginViewModel;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration; private AppBarConfiguration mAppBarConfiguration;
private ActivityMainBinding binding; private ActivityMainBinding binding;
private LoginViewModel loginViewModel;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -30,11 +34,7 @@ public class MainActivity extends AppCompatActivity {
setSupportActionBar(binding.appBarMain.toolbar); setSupportActionBar(binding.appBarMain.toolbar);
binding.appBarMain.toolbar.setOnMenuItemClickListener(item -> { binding.appBarMain.toolbar.setOnMenuItemClickListener(item -> {
if (item.getItemId() == R.id.auth_action) { if (item.getItemId() == R.id.auth_action) {
if (new AuthService(getApplicationContext()).isLoggedIn()) { showLoginDialog();
//performLogout(); // Logout-Logik aufrufen
} else {
showLoginDialog(); // Zeige das Login-Fenster an
}
return true; return true;
} }
return false; return false;
@ -50,6 +50,12 @@ public class MainActivity extends AppCompatActivity {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main); NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration); NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController); NavigationUI.setupWithNavController(navigationView, navController);
loginViewModel = new ViewModelProvider(this).get(LoginViewModel.class);
loginViewModel.setAuthService(new AuthService(getApplicationContext()));
loginViewModel.getIsLoggedIn().observe(this, isLoggedIn -> {
this.invalidateOptionsMenu();
});
} }
@Override @Override
@ -69,7 +75,7 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public boolean onPrepareOptionsMenu(Menu menu) { public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem loginItem = menu.findItem(R.id.auth_action); MenuItem loginItem = menu.findItem(R.id.auth_action);
if (new AuthService(this).isLoggedIn()) { if (Boolean.TRUE.equals(loginViewModel.getIsLoggedIn().getValue())) {
loginItem.setIcon(R.drawable.logout); // Setze das Logout-Symbol loginItem.setIcon(R.drawable.logout); // Setze das Logout-Symbol
} else { } else {
loginItem.setIcon(R.drawable.login); // Setze das Login-Symbol loginItem.setIcon(R.drawable.login); // Setze das Login-Symbol
@ -78,27 +84,7 @@ public class MainActivity extends AppCompatActivity {
} }
public void showLoginDialog() { public void showLoginDialog() {
LoginDialog loginDialog = LoginDialog.newInstance(new APICallback() { LoginDialog loginDialog = new LoginDialog(loginViewModel);
@Override
public void onSuccess() {
}
@Override
public void onError(String error) {
}
}, new APICallback() {
@Override
public void onSuccess() {
}
@Override
public void onError(String error) {
}
});
loginDialog.show(getSupportFragmentManager(), "login"); loginDialog.show(getSupportFragmentManager(), "login");
} }
} }

View File

@ -18,7 +18,7 @@ public class AuthService {
this.tokenManager = new TokenManager(context); this.tokenManager = new TokenManager(context);
} }
public void performLogin(String email, String password, APICallback callback) { public void performLogin(String email, String password, LoginCallback callback) {
LoginRequest loginRequest = new LoginRequest(email, password); LoginRequest loginRequest = new LoginRequest(email, password);
authAPI.login(loginRequest).enqueue(new Callback<LoginResponse>() { authAPI.login(loginRequest).enqueue(new Callback<LoginResponse>() {
@ -28,7 +28,7 @@ public class AuthService {
String token = response.body().getToken(); String token = response.body().getToken();
saveToken(token); saveToken(token);
// Erfolgsrückmeldung an den Callback senden // Erfolgsrückmeldung an den Callback senden
callback.onSuccess(); callback.onSuccess(response.body());
} else { } else {
// Fehlermeldung an den Callback senden // Fehlermeldung an den Callback senden
callback.onError("Login fehlgeschlagen. Überprüfe Benutzername und Passwort."); callback.onError("Login fehlgeschlagen. Überprüfe Benutzername und Passwort.");
@ -78,4 +78,9 @@ public class AuthService {
public boolean isLoggedIn() { public boolean isLoggedIn() {
return !TextUtils.isEmpty(tokenManager.getToken()); return !TextUtils.isEmpty(tokenManager.getToken());
} }
public interface LoginCallback {
void onSuccess(LoginResponse loginResponse);
void onError(String error);
}
} }

View File

@ -10,35 +10,29 @@ import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; 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.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;
public class LoginDialog extends DialogFragment { public class LoginDialog extends DialogFragment {
private APICallback loginCallback; private LoginViewModel loginViewModel;
private APICallback registerCallback;
private boolean isLoginMode = true; private boolean isLoginMode = true;
private Dialog dialog; private Dialog dialog;
@Override @Override
public void onAttach(Context context) { public void onAttach(Context context) {
super.onAttach(context); super.onAttach(context);
if (loginCallback == null) {
throw new IllegalStateException("LoginDialogFragment must be created using newInstance()");
}
} }
public static LoginDialog newInstance(APICallback loginCallback, APICallback registerCallback) { public LoginDialog(LoginViewModel loginViewModel) {
LoginDialog fragment = new LoginDialog(); this.loginViewModel = loginViewModel;
fragment.loginCallback = loginCallback;
fragment.registerCallback = registerCallback;
return fragment;
} }
@NonNull @NonNull
@ -61,15 +55,14 @@ public class LoginDialog extends DialogFragment {
// Handle login logic // Handle login logic
String email = editTextEmail.getText().toString(); String email = editTextEmail.getText().toString();
String password = editTextPassword.getText().toString(); String password = editTextPassword.getText().toString();
AuthService authRepository = new AuthService(this.getContext()); this.loginViewModel.performLogin(email, password, this::onSuccessFullLogin);
authRepository.performLogin(email, password, loginCallback);
} else { } else {
// Handle registration logic // Handle registration logic
String email = editTextEmail.getText().toString(); String email = editTextEmail.getText().toString();
String password = editTextPassword.getText().toString(); String password = editTextPassword.getText().toString();
String username = editTextUsername.getText().toString(); String username = editTextUsername.getText().toString();
AuthService authRepository = new AuthService(this.getContext()); AuthService authRepository = new AuthService(this.getContext());
authRepository.performRegistration(email, username, password, registerCallback); //authRepository.performRegistration(email, username, password, registerCallback);
} }
}); });
@ -83,7 +76,12 @@ public class LoginDialog extends DialogFragment {
}); });
builder.setView(view); builder.setView(view);
return builder.create(); dialog = builder.create();
return dialog;
}
void onSuccessFullLogin() {
this.dialog.dismiss();
} }
} }

View File

@ -1,6 +1,65 @@
package com.stormtales.notevault.ui.login; package com.stormtales.notevault.ui.login;
import android.util.Log;
import android.widget.Toast;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
import com.stormtales.notevault.network.auth.AuthService;
import com.stormtales.notevault.network.auth.LoginResponse;
public class LoginViewModel extends ViewModel { public class LoginViewModel extends ViewModel {
private final MutableLiveData<String> username;
private final MutableLiveData<Boolean> isLoggedIn;
private AuthService authService;
public LoginViewModel() {
username = new MutableLiveData<>("Not Logged In");
isLoggedIn = new MutableLiveData<>(false);
}
public void performLogin(String email, String password, SuccessFullLoginCallback successFullLoginCallback) {
if(authService != null) {
authService.performLogin(email, password, new LoginCallBackImpl(successFullLoginCallback));
} else {
throw new RuntimeException("AuthService is not provided to LoginViewModel");
}
}
public void setAuthService(AuthService authService) {
this.authService = authService;
}
public MutableLiveData<Boolean> getIsLoggedIn() {
return isLoggedIn;
}
public MutableLiveData<String> getUsername() {
return username;
}
public class LoginCallBackImpl implements AuthService.LoginCallback {
private final SuccessFullLoginCallback successFullLoginCallback;
public LoginCallBackImpl(SuccessFullLoginCallback successFullLoginCallback) {
this.successFullLoginCallback = successFullLoginCallback;
}
@Override
public void onSuccess(LoginResponse loginResponse) {
username.setValue(loginResponse.getUsername());
isLoggedIn.setValue(true);
successFullLoginCallback.onSuccess();
}
@Override
public void onError(String error) {
Log.d("LoginService", error);
}
}
public interface SuccessFullLoginCallback {
void onSuccess();
}
} }