From 1096be30516d4285c578d9df1adedfd4080c4663 Mon Sep 17 00:00:00 2001 From: Fawkes100 Date: Sun, 19 Jan 2025 07:22:59 +0100 Subject: [PATCH] Use ViewModel instead of Callbacks for UI Updates --- .../stormtales/notevault/MainActivity.java | 40 ++++--------- .../notevault/network/auth/AuthService.java | 9 ++- .../notevault/ui/login/LoginDialog.java | 30 +++++----- .../notevault/ui/login/LoginViewModel.java | 59 +++++++++++++++++++ 4 files changed, 93 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/com/stormtales/notevault/MainActivity.java b/app/src/main/java/com/stormtales/notevault/MainActivity.java index e22efed..edd4e25 100644 --- a/app/src/main/java/com/stormtales/notevault/MainActivity.java +++ b/app/src/main/java/com/stormtales/notevault/MainActivity.java @@ -3,6 +3,8 @@ package com.stormtales.notevault; import android.os.Bundle; import android.view.MenuItem; import android.view.Menu; +import android.widget.Toast; +import androidx.lifecycle.ViewModelProvider; import com.google.android.material.navigation.NavigationView; import androidx.navigation.NavController; 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.auth.AuthService; import com.stormtales.notevault.ui.login.LoginDialog; +import com.stormtales.notevault.ui.login.LoginViewModel; public class MainActivity extends AppCompatActivity { private AppBarConfiguration mAppBarConfiguration; private ActivityMainBinding binding; + private LoginViewModel loginViewModel; @Override protected void onCreate(Bundle savedInstanceState) { @@ -30,11 +34,7 @@ public class MainActivity extends AppCompatActivity { setSupportActionBar(binding.appBarMain.toolbar); binding.appBarMain.toolbar.setOnMenuItemClickListener(item -> { if (item.getItemId() == R.id.auth_action) { - if (new AuthService(getApplicationContext()).isLoggedIn()) { - //performLogout(); // Logout-Logik aufrufen - } else { - showLoginDialog(); // Zeige das Login-Fenster an - } + showLoginDialog(); return true; } return false; @@ -50,6 +50,12 @@ public class MainActivity extends AppCompatActivity { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main); NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration); NavigationUI.setupWithNavController(navigationView, navController); + + loginViewModel = new ViewModelProvider(this).get(LoginViewModel.class); + loginViewModel.setAuthService(new AuthService(getApplicationContext())); + loginViewModel.getIsLoggedIn().observe(this, isLoggedIn -> { + this.invalidateOptionsMenu(); + }); } @Override @@ -69,7 +75,7 @@ public class MainActivity extends AppCompatActivity { @Override public boolean onPrepareOptionsMenu(Menu menu) { 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 } else { loginItem.setIcon(R.drawable.login); // Setze das Login-Symbol @@ -78,27 +84,7 @@ public class MainActivity extends AppCompatActivity { } public void showLoginDialog() { - LoginDialog loginDialog = LoginDialog.newInstance(new APICallback() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(String error) { - - } - }, new APICallback() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(String error) { - - } - }); + LoginDialog loginDialog = new LoginDialog(loginViewModel); loginDialog.show(getSupportFragmentManager(), "login"); } } \ No newline at end of file diff --git a/app/src/main/java/com/stormtales/notevault/network/auth/AuthService.java b/app/src/main/java/com/stormtales/notevault/network/auth/AuthService.java index 6260828..de9d6ca 100644 --- a/app/src/main/java/com/stormtales/notevault/network/auth/AuthService.java +++ b/app/src/main/java/com/stormtales/notevault/network/auth/AuthService.java @@ -18,7 +18,7 @@ public class AuthService { 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); authAPI.login(loginRequest).enqueue(new Callback() { @@ -28,7 +28,7 @@ public class AuthService { String token = response.body().getToken(); saveToken(token); // Erfolgsrückmeldung an den Callback senden - callback.onSuccess(); + callback.onSuccess(response.body()); } else { // Fehlermeldung an den Callback senden callback.onError("Login fehlgeschlagen. Überprüfe Benutzername und Passwort."); @@ -78,4 +78,9 @@ public class AuthService { public boolean isLoggedIn() { return !TextUtils.isEmpty(tokenManager.getToken()); } + + public interface LoginCallback { + void onSuccess(LoginResponse loginResponse); + void onError(String error); + } } diff --git a/app/src/main/java/com/stormtales/notevault/ui/login/LoginDialog.java b/app/src/main/java/com/stormtales/notevault/ui/login/LoginDialog.java index b9af4d7..1d9949a 100644 --- a/app/src/main/java/com/stormtales/notevault/ui/login/LoginDialog.java +++ b/app/src/main/java/com/stormtales/notevault/ui/login/LoginDialog.java @@ -10,35 +10,29 @@ import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import androidx.lifecycle.ViewModelProvider; import com.stormtales.notevault.R; import com.stormtales.notevault.network.APICallback; import com.stormtales.notevault.network.auth.AuthService; public class LoginDialog extends DialogFragment { - private APICallback loginCallback; - private APICallback registerCallback; - + private LoginViewModel loginViewModel; private boolean isLoginMode = true; - private Dialog dialog; @Override public void onAttach(Context context) { super.onAttach(context); - if (loginCallback == null) { - throw new IllegalStateException("LoginDialogFragment must be created using newInstance()"); - } + } - public static LoginDialog newInstance(APICallback loginCallback, APICallback registerCallback) { - LoginDialog fragment = new LoginDialog(); - fragment.loginCallback = loginCallback; - fragment.registerCallback = registerCallback; - return fragment; + public LoginDialog(LoginViewModel loginViewModel) { + this.loginViewModel = loginViewModel; } @NonNull @@ -61,15 +55,14 @@ public class LoginDialog extends DialogFragment { // Handle login logic String email = editTextEmail.getText().toString(); String password = editTextPassword.getText().toString(); - AuthService authRepository = new AuthService(this.getContext()); - authRepository.performLogin(email, password, loginCallback); + 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); + //authRepository.performRegistration(email, username, password, registerCallback); } }); @@ -83,7 +76,12 @@ public class LoginDialog extends DialogFragment { }); builder.setView(view); - return builder.create(); + dialog = builder.create(); + return dialog; + } + + void onSuccessFullLogin() { + this.dialog.dismiss(); } } diff --git a/app/src/main/java/com/stormtales/notevault/ui/login/LoginViewModel.java b/app/src/main/java/com/stormtales/notevault/ui/login/LoginViewModel.java index 8169df4..3f3a675 100644 --- a/app/src/main/java/com/stormtales/notevault/ui/login/LoginViewModel.java +++ b/app/src/main/java/com/stormtales/notevault/ui/login/LoginViewModel.java @@ -1,6 +1,65 @@ package com.stormtales.notevault.ui.login; +import android.util.Log; +import android.widget.Toast; +import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import com.stormtales.notevault.network.auth.AuthService; +import com.stormtales.notevault.network.auth.LoginResponse; public class LoginViewModel extends ViewModel { + + private final MutableLiveData username; + private final MutableLiveData 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 getIsLoggedIn() { + return isLoggedIn; + } + + public MutableLiveData 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(); + } }