From 277db36d797b46f4423645d907c5424b1e617677 Mon Sep 17 00:00:00 2001 From: Universall Date: Thu, 20 Feb 2025 11:41:48 +0300 Subject: [PATCH] Refactor --- .../auth/internal_utils/UserManager.java | 35 ++++---- .../com/displaynone/acss/config/Constants.kt | 2 +- .../acss/ui/admin/AdminFragment.kt | 2 +- .../displaynone/acss/ui/init/InitFragment.kt | 9 +- .../acss/ui/profile/ProfileFragment.kt | 86 +++++++++---------- .../acss/ui/result/QrResultFragment.kt | 39 ++++----- .../acss/ui/scan/QrScanFragment.kt | 8 +- .../acss/ui/scan/QrScanViewModel.kt | 3 +- app/src/main/res/navigation/nav_graph.xml | 2 +- 9 files changed, 89 insertions(+), 97 deletions(-) diff --git a/app/src/main/java/com/displaynone/acss/components/auth/internal_utils/UserManager.java b/app/src/main/java/com/displaynone/acss/components/auth/internal_utils/UserManager.java index 2c9397c..24cdfa1 100644 --- a/app/src/main/java/com/displaynone/acss/components/auth/internal_utils/UserManager.java +++ b/app/src/main/java/com/displaynone/acss/components/auth/internal_utils/UserManager.java @@ -7,21 +7,25 @@ import androidx.annotation.Nullable; import androidx.security.crypto.EncryptedSharedPreferences; import androidx.security.crypto.MasterKeys; -import com.displaynone.acss.components.auth.models.AuthTokenPair; import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO; import com.google.gson.Gson; import java.io.IOException; import java.security.GeneralSecurityException; -import java.util.Collections; -import java.util.Optional; public class UserManager { + // Preferences private static final String _PREFERENCES_FILENAME = "userData"; private final SharedPreferences _preferences; + + // Utils + private static final Gson gson = new Gson(); + + // Keys + private static final String _KEY_USER = "user"; + + // Cache private UserDTO userDTO; - private static final String ACCESS_KEY = "user"; - private Gson gson = new Gson(); public UserManager(Context context) { this._preferences = this._createEncryptedPreferences(context); @@ -40,23 +44,24 @@ public class UserManager { throw new RuntimeException(e); } } + public void saveDto(UserDTO userDTO) { this.userDTO = userDTO; _preferences.edit() - .putString(ACCESS_KEY,toJson(userDTO)) + .putString(_KEY_USER, toJson(userDTO)) .apply(); } + public @Nullable UserDTO getDto() { if (this.userDTO != null) return this.userDTO; - UserDTO userDTO = fromJson( _preferences.getString(ACCESS_KEY, null)); - return userDTO; - } - private UserDTO fromJson(String userJSON){ - UserDTO userDTO = gson.fromJson(userJSON, UserDTO.class); - return userDTO; - } - private String toJson(UserDTO userDTO){ - return gson.toJson(userDTO); + return fromJson(_preferences.getString(_KEY_USER, null)); } + private UserDTO fromJson(String userJSON) { + return gson.fromJson(userJSON, UserDTO.class); + } + + private String toJson(UserDTO userDTO) { + return gson.toJson(userDTO); + } } diff --git a/app/src/main/java/com/displaynone/acss/config/Constants.kt b/app/src/main/java/com/displaynone/acss/config/Constants.kt index 5fb94b1..350a0dc 100644 --- a/app/src/main/java/com/displaynone/acss/config/Constants.kt +++ b/app/src/main/java/com/displaynone/acss/config/Constants.kt @@ -1,5 +1,5 @@ package com.displaynone.acss.config object Constants { - const val serverUrl = "http://192.168.136.38:8086" + const val serverUrl = "http://192.168.56.1:8086" } diff --git a/app/src/main/java/com/displaynone/acss/ui/admin/AdminFragment.kt b/app/src/main/java/com/displaynone/acss/ui/admin/AdminFragment.kt index 8b4db77..b910c1e 100644 --- a/app/src/main/java/com/displaynone/acss/ui/admin/AdminFragment.kt +++ b/app/src/main/java/com/displaynone/acss/ui/admin/AdminFragment.kt @@ -46,7 +46,7 @@ class AdminFragment : Fragment(R.layout.fragment_admin) { } if (state is AdminViewModel.State.Error){ val errorMessage = state.errorMessage - binding.loginSearch.setError(errorMessage) + binding.loginSearch.error = errorMessage } } } diff --git a/app/src/main/java/com/displaynone/acss/ui/init/InitFragment.kt b/app/src/main/java/com/displaynone/acss/ui/init/InitFragment.kt index a08fedd..567c01d 100644 --- a/app/src/main/java/com/displaynone/acss/ui/init/InitFragment.kt +++ b/app/src/main/java/com/displaynone/acss/ui/init/InitFragment.kt @@ -80,10 +80,6 @@ class InitFragment : Fragment(R.layout.fragment_init) { return false } - private fun getCachedUser(): UserDTO? { - return UserServiceST.getInstance().getUserDTO(); - } - private fun isUserAuthenticated(): Boolean { return UserServiceST.getInstance().hasTokens() } @@ -91,4 +87,9 @@ class InitFragment : Fragment(R.layout.fragment_init) { private fun handleError(string: Int) { binding.error.text = requireContext().getString(string) } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } } \ No newline at end of file diff --git a/app/src/main/java/com/displaynone/acss/ui/profile/ProfileFragment.kt b/app/src/main/java/com/displaynone/acss/ui/profile/ProfileFragment.kt index 57fee69..8dc9166 100644 --- a/app/src/main/java/com/displaynone/acss/ui/profile/ProfileFragment.kt +++ b/app/src/main/java/com/displaynone/acss/ui/profile/ProfileFragment.kt @@ -11,8 +11,8 @@ import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import com.bumptech.glide.Glide import com.displaynone.acss.R -import com.displaynone.acss.components.auth.models.user.UserServiceST import com.displaynone.acss.components.acs.models.visit.VisitAdapter +import com.displaynone.acss.components.auth.models.user.UserServiceST import com.displaynone.acss.components.auth.models.user.repository.dto.UserDTO import com.displaynone.acss.databinding.FragmentProfileBinding import com.displaynone.acss.ui.profile.ProfileViewModel.Action @@ -20,7 +20,7 @@ import com.displaynone.acss.ui.scan.QrScanDestination import com.displaynone.acss.util.collectWithLifecycle import com.displaynone.acss.util.navigateTo -class ProfileFragment: Fragment(R.layout.fragment_profile) { +class ProfileFragment : Fragment(R.layout.fragment_profile) { private var _binding: FragmentProfileBinding? = null private val binding: FragmentProfileBinding get() = _binding!! @@ -33,29 +33,28 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) { checkForAdmin() binding.swipeRefresh.setOnRefreshListener { - if (getIsMe()){ - refreshData() - } else{ - showData(getUserDto()!!) - } + if (getIsMe()) refreshData() else showData(getUserDto()!!); } - binding.logout.setOnClickListener{ + + binding.logout.setOnClickListener { logout() } - binding.scan.setOnClickListener{ + + binding.scan.setOnClickListener { navigateTo(view, R.id.action_profileFragment_to_qrScanFragment) } - binding.buttonSearch.setOnClickListener{ + + binding.buttonSearch.setOnClickListener { navigateTo(view, R.id.action_profileFragment_to_adminFragment) } + binding.recyclerViewLogs.adapter = adapter + if (getIsMe()) { refreshData() - viewModel.visitListState.collectWithLifecycle(this) { data -> - adapter.submitData(data) - } + viewModel.visitListState.collectWithLifecycle(this) { data -> adapter.submitData(data) } waitForQRScanResult() - } else{ + } else { showData(getUserDto()!!) Log.d("ProfileFragment", "set login") viewModel.visitListStateFromLogin.collectWithLifecycle(this) { data -> @@ -66,72 +65,66 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) { } subscribe() binding.recyclerViewLogs.layoutManager = LinearLayoutManager(requireContext()) -// viewModel.visitListStateFromLogin.collectWithLifecycle(this) { data -> -// adapter.submitData(data) -// } - } + private fun checkForAdmin() { - Log.d("check", "cheking for roles") + val userDTO = UserServiceST.getInstance().getUserDTO() ?: return - val userDTO = UserServiceST.getInstance().getUserDTO() - if (userDTO != null) { - if (userDTO.roles.any { it.name == "ROLE_ADMIN" }) { - Log.d("adminlog", "i'm admin") - binding.buttonSearch.visibility = View.VISIBLE - binding.rightsUsingSmartphone.text = "Пропуск действителен" - } - if (userDTO.roles.any { it.name == "ROLE_USER" }) { - Log.d("userlog", "i'm user") - - binding.rightsUsingSmartphone.text = "Пропуск действителен" - } + if (userDTO.roles.any { it.name == "ROLE_ADMIN" }) { + binding.buttonSearch.visibility = View.VISIBLE + binding.rightsUsingSmartphone.text = "Пропуск действителен" + } + if (userDTO.roles.any { it.name == "ROLE_USER" }) { + binding.rightsUsingSmartphone.text = "Пропуск действителен" } } + private fun hideButtons() { binding.logout.visibility = View.GONE binding.scan.visibility = View.GONE binding.buttonSearch.visibility = View.GONE } - fun showMyData(userDTO: UserDTO){ + + private fun showMyData(userDTO: UserDTO) { binding.fio.text = userDTO.name binding.position.text = userDTO.position setAvatar(userDTO.photo) } - fun showData(userDTO: UserDTO){ + + private fun showData(userDTO: UserDTO) { binding.fio.text = userDTO.name binding.position.text = userDTO.position viewModel.setLogin(login1 = userDTO.login) - Log.d("ProfileFragment", userDTO.login) - -// binding.lastEntry.text = userDTO.lastVisit - setAvatar(userDTO.photo) } + private fun refreshData() { - Log.d("ProfileFragment", "Refreshed") viewModel.getInfo() subscribeToGetData() } - fun subscribe() { + + private fun subscribe() { viewModel.action.collectWithLifecycle(this) { action -> if (action is Action.GoToAuth) { - view?.let { navigateTo(it, R.id.action_profileFragment_to_authFragment) } ?: throw IllegalStateException("View is null") + view?.let { navigateTo(it, R.id.action_profileFragment_to_authFragment) } + ?: throw IllegalStateException("View is null") } if (action is Action.GoToScan) { - view?.let { navigateTo(it, R.id.action_profileFragment_to_qrResultFragment) }?: throw IllegalStateException("View is null") + view?.let { navigateTo(it, R.id.action_profileFragment_to_qrResultFragment) } + ?: throw IllegalStateException("View is null") } } } + private fun getUserDto(): UserDTO? { return arguments?.getSerializable("user") as? UserDTO } + private fun getIsMe(): Boolean { return arguments?.getBoolean("isMe", true) ?: true } private fun waitForQRScanResult() { - requireActivity().onBackPressedDispatcher.addCallback( viewLifecycleOwner, object : OnBackPressedCallback(true) { @@ -145,20 +138,19 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) { )?.observe(viewLifecycleOwner) { bundle -> val qrCode = bundle.getString("key_qr") if (!qrCode.isNullOrEmpty()) view?.let { - val bundle = Bundle().apply { - putString("qrCode", qrCode) - } - navigateTo(it, R.id.action_profileFragment_to_qrResultFragment, bundle) + val newBundle = Bundle().apply { putString("qrCode", qrCode) } + navigateTo(it, R.id.action_profileFragment_to_qrResultFragment, newBundle) } } } + private fun logout() { viewModel.logout() viewModel.openAuth() Toast.makeText(activity, "LOGOUT", Toast.LENGTH_SHORT).show() } - private fun subscribeToGetData(){ + private fun subscribeToGetData() { viewModel.state.collectWithLifecycle(this) { state -> if (state is ProfileViewModel.State.Show) { val userDto: UserDTO = state.item diff --git a/app/src/main/java/com/displaynone/acss/ui/result/QrResultFragment.kt b/app/src/main/java/com/displaynone/acss/ui/result/QrResultFragment.kt index 4f47f45..34de52b 100644 --- a/app/src/main/java/com/displaynone/acss/ui/result/QrResultFragment.kt +++ b/app/src/main/java/com/displaynone/acss/ui/result/QrResultFragment.kt @@ -1,13 +1,9 @@ package com.displaynone.acss.ui.result -import android.content.Context -import android.content.SharedPreferences import android.os.Bundle -import android.util.Log import android.view.View import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels -import androidx.navigation.fragment.findNavController import com.displaynone.acss.R import com.displaynone.acss.databinding.FragmentQrResultBinding import com.displaynone.acss.util.collectWithLifecycle @@ -21,34 +17,37 @@ class QrResultFragment : Fragment(R.layout.fragment_qr_result) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - Log.d("QrResultFragment", getQrCode()) _binding = FragmentQrResultBinding.bind(view) binding.close.setOnClickListener(this::closeQrScanFragment) this.openDoor() - viewModel.state.collectWithLifecycle(this){ state -> - if (state is QrResultViewModel.State.Result){ - if (state.resultCode == 200) { - setResult(getString(R.string.success)) - } else if (state.resultCode == 400) { - setResult(getString(R.string.wrong)) - } else if (state.resultCode == 401) { - setResult(getString(R.string.cancel)) + viewModel.state.collectWithLifecycle(this) { state -> + if (state is QrResultViewModel.State.Result) { + when (state.resultCode) { + 200 -> { + setResult(getString(R.string.success)) + } + + 400 -> { + setResult(getString(R.string.wrong)) + } + + 401 -> { + setResult(getString(R.string.cancel)) + } } } - if (state is QrResultViewModel.State.Error){ - setResult(state.errorMessage) - } + if (state is QrResultViewModel.State.Error) setResult(state.errorMessage) } } private fun openDoor() { + val qrValue = getQrCode() ?: return val qrCodeValueLong: Long - try { - qrCodeValueLong = getQrCode().toLong() + qrCodeValueLong = qrValue.toLong() } catch (exception: Exception) { when (exception) { is NumberFormatException, is IllegalArgumentException -> setResult(getString(R.string.wrong)) @@ -60,8 +59,8 @@ class QrResultFragment : Fragment(R.layout.fragment_qr_result) { viewModel.openDoor(qrCodeValueLong) } - private fun getQrCode(): String { - return arguments?.getString("qrCode") ?: "No QR Code Provided" + private fun getQrCode(): String? { + return arguments?.getString("qrCode") } private fun closeQrScanFragment(view: View) { diff --git a/app/src/main/java/com/displaynone/acss/ui/scan/QrScanFragment.kt b/app/src/main/java/com/displaynone/acss/ui/scan/QrScanFragment.kt index b1f3c2a..ca6d1d0 100644 --- a/app/src/main/java/com/displaynone/acss/ui/scan/QrScanFragment.kt +++ b/app/src/main/java/com/displaynone/acss/ui/scan/QrScanFragment.kt @@ -61,9 +61,7 @@ class QrScanFragment : Fragment(R.layout.fragment_qr_scan) { viewModel.action.collectWhenStarted(this) { action -> when (action) { is QrScanViewModel.Action.RequestPermission -> requestPermission(action.permission) - is QrScanViewModel.Action.CloseWithCancel -> { - goBack() - } + is QrScanViewModel.Action.CloseWithCancel -> goBack() is QrScanViewModel.Action.CloseWithResult -> { sendResult(QrScanDestination.packToBundle(action.result)) goBack() @@ -82,9 +80,7 @@ class QrScanFragment : Fragment(R.layout.fragment_qr_scan) { val previewView: PreviewView = binding.viewFinder val executor = ContextCompat.getMainExecutor(context) - val options = BarcodeScannerOptions.Builder() - .setBarcodeFormats(Barcode.FORMAT_QR_CODE) - .build() + val options = BarcodeScannerOptions.Builder().setBarcodeFormats(Barcode.FORMAT_QR_CODE).build() val barcodeScanner = BarcodeScanning.getClient(options) this.barcodeScanner = barcodeScanner diff --git a/app/src/main/java/com/displaynone/acss/ui/scan/QrScanViewModel.kt b/app/src/main/java/com/displaynone/acss/ui/scan/QrScanViewModel.kt index 6961085..18537f9 100644 --- a/app/src/main/java/com/displaynone/acss/ui/scan/QrScanViewModel.kt +++ b/app/src/main/java/com/displaynone/acss/ui/scan/QrScanViewModel.kt @@ -1,7 +1,5 @@ package com.displaynone.acss.ui.scan -import androidx.lifecycle.ViewModel - import android.Manifest import android.app.Application import android.content.pm.PackageManager @@ -80,6 +78,7 @@ class QrScanViewModel( data class RequestPermission( val permission: String ) : Action + data object CloseWithCancel : Action data class CloseWithResult( val result: String diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index 7f9ec69..2a2aca1 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -17,7 +17,7 @@