merge
This commit is contained in:
		
						commit
						b6ff473ae1
					
				| @ -7,21 +7,25 @@ import androidx.annotation.Nullable; | |||||||
| import androidx.security.crypto.EncryptedSharedPreferences; | import androidx.security.crypto.EncryptedSharedPreferences; | ||||||
| import androidx.security.crypto.MasterKeys; | 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.displaynone.acss.components.auth.models.user.repository.dto.UserDTO; | ||||||
| import com.google.gson.Gson; | import com.google.gson.Gson; | ||||||
| 
 | 
 | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.security.GeneralSecurityException; | import java.security.GeneralSecurityException; | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.Optional; |  | ||||||
| 
 | 
 | ||||||
| public class UserManager { | public class UserManager { | ||||||
|  |     // Preferences | ||||||
|     private static final String _PREFERENCES_FILENAME = "userData"; |     private static final String _PREFERENCES_FILENAME = "userData"; | ||||||
|     private final SharedPreferences _preferences; |     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 UserDTO userDTO; | ||||||
|     private static final String ACCESS_KEY = "user"; |  | ||||||
|     private Gson gson = new Gson(); |  | ||||||
| 
 | 
 | ||||||
|     public UserManager(Context context) { |     public UserManager(Context context) { | ||||||
|         this._preferences = this._createEncryptedPreferences(context); |         this._preferences = this._createEncryptedPreferences(context); | ||||||
| @ -40,23 +44,24 @@ public class UserManager { | |||||||
|             throw new RuntimeException(e); |             throw new RuntimeException(e); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     public void saveDto(UserDTO userDTO) { |     public void saveDto(UserDTO userDTO) { | ||||||
|         this.userDTO = userDTO; |         this.userDTO = userDTO; | ||||||
|         _preferences.edit() |         _preferences.edit() | ||||||
|                 .putString(ACCESS_KEY,toJson(userDTO)) |                 .putString(_KEY_USER, toJson(userDTO)) | ||||||
|                 .apply(); |                 .apply(); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     public @Nullable UserDTO getDto() { |     public @Nullable UserDTO getDto() { | ||||||
|         if (this.userDTO != null) return this.userDTO; |         if (this.userDTO != null) return this.userDTO; | ||||||
|         UserDTO userDTO = fromJson( _preferences.getString(ACCESS_KEY, null)); |         return fromJson(_preferences.getString(_KEY_USER, null)); | ||||||
|         return userDTO; |  | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     private UserDTO fromJson(String userJSON) { |     private UserDTO fromJson(String userJSON) { | ||||||
|         UserDTO userDTO = gson.fromJson(userJSON, UserDTO.class); |         return gson.fromJson(userJSON, UserDTO.class); | ||||||
|         return userDTO; |  | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     private String toJson(UserDTO userDTO) { |     private String toJson(UserDTO userDTO) { | ||||||
|         return gson.toJson(userDTO); |         return gson.toJson(userDTO); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| package com.displaynone.acss.config | package com.displaynone.acss.config | ||||||
| 
 | 
 | ||||||
| object Constants { | object Constants { | ||||||
|     const val serverUrl = "http://192.168.136.38:8086" |     const val serverUrl = "http://192.168.56.1:8086" | ||||||
| } | } | ||||||
|  | |||||||
| @ -46,7 +46,7 @@ class AdminFragment : Fragment(R.layout.fragment_admin) { | |||||||
|             } |             } | ||||||
|             if (state is AdminViewModel.State.Error){ |             if (state is AdminViewModel.State.Error){ | ||||||
|                 val errorMessage = state.errorMessage |                 val errorMessage = state.errorMessage | ||||||
|                 binding.loginSearch.setError(errorMessage) |                 binding.loginSearch.error = errorMessage | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -56,18 +56,17 @@ class AuthFragment: Fragment(R.layout.fragment_auth) { | |||||||
|             @SuppressLint("ResourceAsColor") |             @SuppressLint("ResourceAsColor") | ||||||
|             override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { |             override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { | ||||||
|                 binding.error.visibility = View.GONE |                 binding.error.visibility = View.GONE | ||||||
|                 val username = s.toString() | //                val username = s.toString() | ||||||
|                 val valid = isUsernameValid(username) | //                val valid = isUsernameValid(username) | ||||||
| 
 | // | ||||||
|                 if (valid) { | //                if (valid) { | ||||||
|                     binding.hint.visibility = View.INVISIBLE | //                    binding.hint.visibility = View.INVISIBLE | ||||||
|                 }else{ | //                }else{ | ||||||
|                     binding.login.error = getString(R.string.login_hint) | //                    binding.login.error = getString(R.string.login_hint) | ||||||
|                 } | //                } | ||||||
| //                binding.hint.visibility = if(valid) View.INVISIBLE else View.VISIBLE | //                binding.hint.visibility = if(valid) View.INVISIBLE else View.VISIBLE | ||||||
|                 binding.next.isEnabled = valid | //                binding.next.isEnabled = valid | ||||||
|                 val color = if (valid) R.color.primary else R.color.secondary | 
 | ||||||
|                 binding.next.backgroundTintList = ContextCompat.getColorStateList(requireContext(), color) |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             override fun afterTextChanged(s: Editable?) {} |             override fun afterTextChanged(s: Editable?) {} | ||||||
| @ -94,37 +93,95 @@ class AuthFragment: Fragment(R.layout.fragment_auth) { | |||||||
| //        }) | //        }) | ||||||
|     } |     } | ||||||
|     private fun getPasswordValidError(password: String): String { |     private fun getPasswordValidError(password: String): String { | ||||||
|         if (password.length < 8){ return "LenError" } |         if (password.length < 8) { | ||||||
|         val letterRegex = Regex("^(?=.*[A-Z]).+$") |             return "LenError" | ||||||
|         if(!letterRegex.matches(password)){ return "UpperCaseError"} |         } | ||||||
|         val digitRegex = Regex("^(?=.*\\\\d).+$") |  | ||||||
|         if(!digitRegex.matches(password)){ return "DigitCaseError"} |  | ||||||
| 
 |  | ||||||
|         return "NoErrors" |         return "NoErrors" | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun isUsernameValid(username: String): Boolean { |     private fun validatePasswordAndSetError(password: String) { | ||||||
|  |         val errorType = getPasswordValidError(password) | ||||||
|  | 
 | ||||||
|  |         when (errorType) { | ||||||
|  |             "LenError" -> { | ||||||
|  |                 binding.password.error = getString(R.string.error_password_too_short) | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             "NoErrors" -> { | ||||||
|  |                 binding.password.error = null | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     private fun getLoginValidError(username: String): String { | ||||||
|         val alf = "^[a-zA-Z0-9_]+$".toRegex() |         val alf = "^[a-zA-Z0-9_]+$".toRegex() | ||||||
|         return username.isNotEmpty() && |         if (username.isEmpty()) { | ||||||
|                 username.length >= 3 && |             return "EmptyError" | ||||||
|                 !username[0].isDigit() && |  | ||||||
|                 alf.matches(username) |  | ||||||
|         } |         } | ||||||
|     private fun isPasswordValid(password: String): Boolean { |         if (username.length < 3) { | ||||||
|         return password.isNotEmpty() && |             return "LenError" | ||||||
|                 password.length >= 8 |  | ||||||
|         } |         } | ||||||
|  |         if (username[0].isDigit()) { | ||||||
|  |             return "StartsWithDigitError" | ||||||
|  |         } | ||||||
|  |         if (!alf.matches(username)) { | ||||||
|  |             return "InvalidCharactersError" | ||||||
|  |         } | ||||||
|  |         return "NoErrors" | ||||||
|  |     } | ||||||
|  | //    private fun isPasswordValid(password: String): Boolean { | ||||||
|  | //        return password.isNotEmpty() && | ||||||
|  | //                password.length >= 8 | ||||||
|  | //    } | ||||||
| 
 | 
 | ||||||
| //    private fun subscribe() { | //    private fun subscribe() { | ||||||
| //        viewModel.state.collectWhenStarted(this) { state -> | //        viewModel.state.collectWhenStarted(this) { state -> | ||||||
| //            binding.login.setOnClickListener(this::onLoginButtonClicked) | //            binding.login.setOnClickListener(this::onLoginButtonClicked) | ||||||
| //        } | //        } | ||||||
| //    } | //    } | ||||||
|  | private fun validateLoginAndSetError(username: String) { | ||||||
|  |     val errorType = getLoginValidError(username) | ||||||
| 
 | 
 | ||||||
|  |     when (errorType) { | ||||||
|  |         "EmptyError" -> { | ||||||
|  |             binding.login.error = getString(R.string.error_login_empty) | ||||||
|  |         } | ||||||
|  |         "LenError" -> { | ||||||
|  |             binding.login.error = getString(R.string.error_login_too_short) | ||||||
|  |         } | ||||||
|  |         "StartsWithDigitError" -> { | ||||||
|  |             binding.login.error = getString(R.string.error_login_starts_with_digit) | ||||||
|  |         } | ||||||
|  |         "InvalidCharactersError" -> { | ||||||
|  |             binding.login.error = getString(R.string.error_login_invalid_characters) | ||||||
|  |         } | ||||||
|  |         "NoErrors" -> { | ||||||
|  |             binding.login.error = null | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|     private fun onLoginButtonClicked(view: View) { |     private fun onLoginButtonClicked(view: View) { | ||||||
|         val login = binding.login.text.toString() |         val login = binding.login.text.toString() | ||||||
|         val password = binding.password.text.toString() |         val password = binding.password.text.toString() | ||||||
|         if (login.isEmpty()) return |         if (getPasswordValidError(password) != "NoErrors") { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             val color = R.color.secondary | ||||||
|  |             binding.next.backgroundTintList = ContextCompat.getColorStateList(requireContext(), color) | ||||||
|  |             validatePasswordAndSetError(password) | ||||||
|  |         }else{ | ||||||
|  |             val color = R.color.primary | ||||||
|  |             binding.next.backgroundTintList = ContextCompat.getColorStateList(requireContext(), color) | ||||||
|  |         } | ||||||
|  | //        if (login.isEmpty()) return | ||||||
|  |         if (getLoginValidError(login) != "NoErrors") { | ||||||
|  |             val color = R.color.secondary | ||||||
|  |             binding.next.backgroundTintList = ContextCompat.getColorStateList(requireContext(), color) | ||||||
|  |             validateLoginAndSetError(login) | ||||||
|  |         }else{ | ||||||
|  |             val color = R.color.primary | ||||||
|  |             binding.next.backgroundTintList = ContextCompat.getColorStateList(requireContext(), color) | ||||||
|  | 
 | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         viewModel.login(login, password) |         viewModel.login(login, password) | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -109,4 +109,9 @@ class InitFragment : Fragment(R.layout.fragment_init) { | |||||||
|     private fun handleError(errorMessage: String) { |     private fun handleError(errorMessage: String) { | ||||||
|         binding.error.text = errorMessage |         binding.error.text = errorMessage | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     override fun onDestroyView() { | ||||||
|  |         super.onDestroyView() | ||||||
|  |         _binding = null | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -11,8 +11,8 @@ import androidx.navigation.fragment.findNavController | |||||||
| import androidx.recyclerview.widget.LinearLayoutManager | import androidx.recyclerview.widget.LinearLayoutManager | ||||||
| import com.bumptech.glide.Glide | import com.bumptech.glide.Glide | ||||||
| import com.displaynone.acss.R | 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.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.components.auth.models.user.repository.dto.UserDTO | ||||||
| import com.displaynone.acss.databinding.FragmentProfileBinding | import com.displaynone.acss.databinding.FragmentProfileBinding | ||||||
| import com.displaynone.acss.ui.profile.ProfileViewModel.Action | import com.displaynone.acss.ui.profile.ProfileViewModel.Action | ||||||
| @ -33,27 +33,26 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) { | |||||||
|         checkForAdmin() |         checkForAdmin() | ||||||
| 
 | 
 | ||||||
|         binding.swipeRefresh.setOnRefreshListener { |         binding.swipeRefresh.setOnRefreshListener { | ||||||
|             if (getIsMe()){ |             if (getIsMe()) refreshData() else showData(getUserDto()!!); | ||||||
|                 refreshData() |  | ||||||
|             } else{ |  | ||||||
|                 showData(getUserDto()!!) |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         binding.logout.setOnClickListener { |         binding.logout.setOnClickListener { | ||||||
|             logout() |             logout() | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         binding.scan.setOnClickListener { |         binding.scan.setOnClickListener { | ||||||
|             navigateTo(view, R.id.action_profileFragment_to_qrScanFragment) |             navigateTo(view, R.id.action_profileFragment_to_qrScanFragment) | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         binding.buttonSearch.setOnClickListener { |         binding.buttonSearch.setOnClickListener { | ||||||
|             navigateTo(view, R.id.action_profileFragment_to_adminFragment) |             navigateTo(view, R.id.action_profileFragment_to_adminFragment) | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         binding.recyclerViewLogs.adapter = adapter |         binding.recyclerViewLogs.adapter = adapter | ||||||
|  | 
 | ||||||
|         if (getIsMe()) { |         if (getIsMe()) { | ||||||
|             refreshData() |             refreshData() | ||||||
|             viewModel.visitListState.collectWithLifecycle(this) { data -> |             viewModel.visitListState.collectWithLifecycle(this) { data -> adapter.submitData(data) } | ||||||
|                 adapter.submitData(data) |  | ||||||
|             } |  | ||||||
|             waitForQRScanResult() |             waitForQRScanResult() | ||||||
|         } else { |         } else { | ||||||
|             showData(getUserDto()!!) |             showData(getUserDto()!!) | ||||||
| @ -67,40 +66,34 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) { | |||||||
|         } |         } | ||||||
|         subscribe() |         subscribe() | ||||||
|         binding.recyclerViewLogs.layoutManager = LinearLayoutManager(requireContext()) |         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() |     private fun checkForAdmin() { | ||||||
|         if (userDTO != null) { |         val userDTO = UserServiceST.getInstance().getUserDTO() ?: return | ||||||
|  | 
 | ||||||
|         if (userDTO.roles.any { it.name == "ROLE_ADMIN" }) { |         if (userDTO.roles.any { it.name == "ROLE_ADMIN" }) { | ||||||
|                 Log.d("adminlog", "i'm admin") |  | ||||||
|             binding.buttonSearch.visibility = View.VISIBLE |             binding.buttonSearch.visibility = View.VISIBLE | ||||||
|             binding.rightsUsingSmartphone.text = "Пропуск действителен" |             binding.rightsUsingSmartphone.text = "Пропуск действителен" | ||||||
|         } |         } | ||||||
|         if (userDTO.roles.any { it.name == "ROLE_USER" }) { |         if (userDTO.roles.any { it.name == "ROLE_USER" }) { | ||||||
|                 Log.d("userlog", "i'm user") |  | ||||||
| 
 |  | ||||||
|             binding.rightsUsingSmartphone.text = "Пропуск действителен" |             binding.rightsUsingSmartphone.text = "Пропуск действителен" | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     } | 
 | ||||||
|     private fun hideButtons() { |     private fun hideButtons() { | ||||||
|         binding.logout.visibility = View.GONE |         binding.logout.visibility = View.GONE | ||||||
|         binding.scan.visibility = View.GONE |         binding.scan.visibility = View.GONE | ||||||
|         binding.buttonSearch.visibility = View.GONE |         binding.buttonSearch.visibility = View.GONE | ||||||
|         binding.changeRights.visibility = View.VISIBLE |         binding.changeRights.visibility = View.VISIBLE | ||||||
|     } |     } | ||||||
|     fun showMyData(userDTO: UserDTO){ | 
 | ||||||
|  |     private fun showMyData(userDTO: UserDTO) { | ||||||
|         binding.fio.text = userDTO.name |         binding.fio.text = userDTO.name | ||||||
|         binding.position.text = userDTO.position |         binding.position.text = userDTO.position | ||||||
|         setAvatar(userDTO.photo) |         setAvatar(userDTO.photo) | ||||||
|     } |     } | ||||||
|     fun showData(userDTO: UserDTO){ | 
 | ||||||
|  |     private fun showData(userDTO: UserDTO) { | ||||||
|         binding.fio.text = userDTO.name |         binding.fio.text = userDTO.name | ||||||
|         binding.position.text = userDTO.position |         binding.position.text = userDTO.position | ||||||
|         binding.changeRights.text = if(userDTO.isACSBlocked) "Разблокировать пользователя" else "Заблокировать пользователя" |         binding.changeRights.text = if(userDTO.isACSBlocked) "Разблокировать пользователя" else "Заблокировать пользователя" | ||||||
| @ -114,30 +107,34 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) { | |||||||
| 
 | 
 | ||||||
|         setAvatar(userDTO.photo) |         setAvatar(userDTO.photo) | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     private fun refreshData() { |     private fun refreshData() { | ||||||
|         Log.d("ProfileFragment", "Refreshed") |  | ||||||
|         viewModel.getInfo() |         viewModel.getInfo() | ||||||
|         subscribeToGetData() |         subscribeToGetData() | ||||||
|     } |     } | ||||||
|     fun subscribe() { | 
 | ||||||
|  |     private fun subscribe() { | ||||||
|         viewModel.action.collectWithLifecycle(this) { action -> |         viewModel.action.collectWithLifecycle(this) { action -> | ||||||
|             if (action is Action.GoToAuth) { |             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) { |             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? { |     private fun getUserDto(): UserDTO? { | ||||||
|         return arguments?.getSerializable("user") as? UserDTO |         return arguments?.getSerializable("user") as? UserDTO | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     private fun getIsMe(): Boolean { |     private fun getIsMe(): Boolean { | ||||||
|         return arguments?.getBoolean("isMe", true) ?: true |         return arguments?.getBoolean("isMe", true) ?: true | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun waitForQRScanResult() { |     private fun waitForQRScanResult() { | ||||||
| 
 |  | ||||||
|         requireActivity().onBackPressedDispatcher.addCallback( |         requireActivity().onBackPressedDispatcher.addCallback( | ||||||
|             viewLifecycleOwner, |             viewLifecycleOwner, | ||||||
|             object : OnBackPressedCallback(true) { |             object : OnBackPressedCallback(true) { | ||||||
| @ -151,13 +148,12 @@ class ProfileFragment: Fragment(R.layout.fragment_profile) { | |||||||
|         )?.observe(viewLifecycleOwner) { bundle -> |         )?.observe(viewLifecycleOwner) { bundle -> | ||||||
|             val qrCode = bundle.getString("key_qr") |             val qrCode = bundle.getString("key_qr") | ||||||
|             if (!qrCode.isNullOrEmpty()) view?.let { |             if (!qrCode.isNullOrEmpty()) view?.let { | ||||||
|                 val bundle = Bundle().apply { |                 val newBundle = Bundle().apply { putString("qrCode", qrCode) } | ||||||
|                     putString("qrCode", qrCode) |                 navigateTo(it, R.id.action_profileFragment_to_qrResultFragment, newBundle) | ||||||
|                 } |  | ||||||
|                 navigateTo(it, R.id.action_profileFragment_to_qrResultFragment, bundle) |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     private fun logout() { |     private fun logout() { | ||||||
|         viewModel.logout() |         viewModel.logout() | ||||||
|         viewModel.openAuth() |         viewModel.openAuth() | ||||||
|  | |||||||
| @ -1,13 +1,9 @@ | |||||||
| package com.displaynone.acss.ui.result | package com.displaynone.acss.ui.result | ||||||
| 
 | 
 | ||||||
| import android.content.Context |  | ||||||
| import android.content.SharedPreferences |  | ||||||
| import android.os.Bundle | import android.os.Bundle | ||||||
| import android.util.Log |  | ||||||
| import android.view.View | import android.view.View | ||||||
| import androidx.fragment.app.Fragment | import androidx.fragment.app.Fragment | ||||||
| import androidx.fragment.app.viewModels | import androidx.fragment.app.viewModels | ||||||
| import androidx.navigation.fragment.findNavController |  | ||||||
| import com.displaynone.acss.R | import com.displaynone.acss.R | ||||||
| import com.displaynone.acss.databinding.FragmentQrResultBinding | import com.displaynone.acss.databinding.FragmentQrResultBinding | ||||||
| import com.displaynone.acss.util.collectWithLifecycle | import com.displaynone.acss.util.collectWithLifecycle | ||||||
| @ -21,7 +17,6 @@ class QrResultFragment : Fragment(R.layout.fragment_qr_result) { | |||||||
| 
 | 
 | ||||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||||
|         super.onViewCreated(view, savedInstanceState) |         super.onViewCreated(view, savedInstanceState) | ||||||
|         Log.d("QrResultFragment", getQrCode()) |  | ||||||
|         _binding = FragmentQrResultBinding.bind(view) |         _binding = FragmentQrResultBinding.bind(view) | ||||||
|         binding.close.setOnClickListener(this::closeQrScanFragment) |         binding.close.setOnClickListener(this::closeQrScanFragment) | ||||||
| 
 | 
 | ||||||
| @ -29,26 +24,30 @@ class QrResultFragment : Fragment(R.layout.fragment_qr_result) { | |||||||
| 
 | 
 | ||||||
|         viewModel.state.collectWithLifecycle(this) { state -> |         viewModel.state.collectWithLifecycle(this) { state -> | ||||||
|             if (state is QrResultViewModel.State.Result) { |             if (state is QrResultViewModel.State.Result) { | ||||||
|                 if (state.resultCode == 200) { |                 when (state.resultCode) { | ||||||
|  |                     200 -> { | ||||||
|                         setResult(getString(R.string.success)) |                         setResult(getString(R.string.success)) | ||||||
|                 } else if (state.resultCode == 400) { |                     } | ||||||
|  | 
 | ||||||
|  |                     400 -> { | ||||||
|                         setResult(getString(R.string.wrong)) |                         setResult(getString(R.string.wrong)) | ||||||
|                 } else if (state.resultCode == 401) { |                     } | ||||||
|  | 
 | ||||||
|  |                     401 -> { | ||||||
|                         setResult(getString(R.string.cancel)) |                         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() { |     private fun openDoor() { | ||||||
|  |         val qrValue = getQrCode() ?: return | ||||||
| 
 | 
 | ||||||
|         val qrCodeValueLong: Long |         val qrCodeValueLong: Long | ||||||
| 
 |  | ||||||
|         try { |         try { | ||||||
|             qrCodeValueLong = getQrCode().toLong() |             qrCodeValueLong = qrValue.toLong() | ||||||
|         } catch (exception: Exception) { |         } catch (exception: Exception) { | ||||||
|             when (exception) { |             when (exception) { | ||||||
|                 is NumberFormatException, is IllegalArgumentException -> setResult(getString(R.string.wrong)) |                 is NumberFormatException, is IllegalArgumentException -> setResult(getString(R.string.wrong)) | ||||||
| @ -60,8 +59,8 @@ class QrResultFragment : Fragment(R.layout.fragment_qr_result) { | |||||||
|         viewModel.openDoor(qrCodeValueLong) |         viewModel.openDoor(qrCodeValueLong) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun getQrCode(): String { |     private fun getQrCode(): String? { | ||||||
|         return arguments?.getString("qrCode") ?: "No QR Code Provided" |         return arguments?.getString("qrCode") | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun closeQrScanFragment(view: View) { |     private fun closeQrScanFragment(view: View) { | ||||||
|  | |||||||
| @ -61,9 +61,7 @@ class QrScanFragment : Fragment(R.layout.fragment_qr_scan) { | |||||||
|         viewModel.action.collectWhenStarted(this) { action -> |         viewModel.action.collectWhenStarted(this) { action -> | ||||||
|             when (action) { |             when (action) { | ||||||
|                 is QrScanViewModel.Action.RequestPermission -> requestPermission(action.permission) |                 is QrScanViewModel.Action.RequestPermission -> requestPermission(action.permission) | ||||||
|                 is QrScanViewModel.Action.CloseWithCancel -> { |                 is QrScanViewModel.Action.CloseWithCancel -> goBack() | ||||||
|                     goBack() |  | ||||||
|                 } |  | ||||||
|                 is QrScanViewModel.Action.CloseWithResult -> { |                 is QrScanViewModel.Action.CloseWithResult -> { | ||||||
|                     sendResult(QrScanDestination.packToBundle(action.result)) |                     sendResult(QrScanDestination.packToBundle(action.result)) | ||||||
|                     goBack() |                     goBack() | ||||||
| @ -82,9 +80,7 @@ class QrScanFragment : Fragment(R.layout.fragment_qr_scan) { | |||||||
|         val previewView: PreviewView = binding.viewFinder |         val previewView: PreviewView = binding.viewFinder | ||||||
|         val executor = ContextCompat.getMainExecutor(context) |         val executor = ContextCompat.getMainExecutor(context) | ||||||
| 
 | 
 | ||||||
|         val options = BarcodeScannerOptions.Builder() |         val options = BarcodeScannerOptions.Builder().setBarcodeFormats(Barcode.FORMAT_QR_CODE).build() | ||||||
|             .setBarcodeFormats(Barcode.FORMAT_QR_CODE) |  | ||||||
|             .build() |  | ||||||
|         val barcodeScanner = BarcodeScanning.getClient(options) |         val barcodeScanner = BarcodeScanning.getClient(options) | ||||||
|         this.barcodeScanner = barcodeScanner |         this.barcodeScanner = barcodeScanner | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,7 +1,5 @@ | |||||||
| package com.displaynone.acss.ui.scan | package com.displaynone.acss.ui.scan | ||||||
| 
 | 
 | ||||||
| import androidx.lifecycle.ViewModel |  | ||||||
| 
 |  | ||||||
| import android.Manifest | import android.Manifest | ||||||
| import android.app.Application | import android.app.Application | ||||||
| import android.content.pm.PackageManager | import android.content.pm.PackageManager | ||||||
| @ -80,6 +78,7 @@ class QrScanViewModel( | |||||||
|         data class RequestPermission( |         data class RequestPermission( | ||||||
|             val permission: String |             val permission: String | ||||||
|         ) : Action |         ) : Action | ||||||
|  | 
 | ||||||
|         data object CloseWithCancel : Action |         data object CloseWithCancel : Action | ||||||
|         data class CloseWithResult( |         data class CloseWithResult( | ||||||
|             val result: String |             val result: String | ||||||
|  | |||||||
| @ -36,19 +36,29 @@ | |||||||
|                 android:orientation="vertical" |                 android:orientation="vertical" | ||||||
|                 android:gravity="center_horizontal" |                 android:gravity="center_horizontal" | ||||||
|                 android:paddingTop="50dp"> |                 android:paddingTop="50dp"> | ||||||
|  |                 <androidx.cardview.widget.CardView | ||||||
|  |                     android:layout_width="wrap_content" | ||||||
|  |                     android:layout_height="wrap_content" | ||||||
|  |                     app:cardCornerRadius="80dp" | ||||||
|  | 
 | ||||||
|  |                     android:layout_margin="5dp" | ||||||
|  |                     android:elevation="10dp"> | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|                 <ImageView |                 <ImageView | ||||||
|                     android:layout_margin="10dp" |                     android:layout_margin="10dp" | ||||||
|                     android:id="@+id/avatar" |                     android:id="@+id/avatar" | ||||||
|                     android:layout_marginTop="10dp" |                     android:layout_marginTop="10dp" | ||||||
|                     android:layout_width="match_parent" |                     android:layout_width="150dp" | ||||||
|                     android:layout_height="150dp" |                     android:layout_height="150dp" | ||||||
|                     android:foregroundGravity="center" |                     android:foregroundGravity="center" | ||||||
|                     android:importantForAccessibility="no" |                     android:importantForAccessibility="no" | ||||||
|                     android:src="@drawable/_user_" |                     android:src="@drawable/_user_" | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|                     app:layout_constraintBottom_toTopOf="@+id/title" |                     app:layout_constraintBottom_toTopOf="@+id/title" | ||||||
|                     app:layout_constraintTop_toTopOf="parent" /> |                     app:layout_constraintTop_toTopOf="parent" /> | ||||||
|  |                 </androidx.cardview.widget.CardView> | ||||||
| 
 | 
 | ||||||
|                 <androidx.constraintlayout.helper.widget.Flow |                 <androidx.constraintlayout.helper.widget.Flow | ||||||
|                     android:id="@+id/flow" |                     android:id="@+id/flow" | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ | |||||||
|     <fragment |     <fragment | ||||||
|         android:id="@+id/nav_profile" |         android:id="@+id/nav_profile" | ||||||
|         android:name="com.displaynone.acss.ui.profile.ProfileFragment" |         android:name="com.displaynone.acss.ui.profile.ProfileFragment" | ||||||
|         android:label="@string/profile" |         android:label="@string/title_profile" | ||||||
|         tools:layout="@layout/fragment_profile"> |         tools:layout="@layout/fragment_profile"> | ||||||
|         <action |         <action | ||||||
|             android:id="@+id/action_profileFragment_to_authFragment" |             android:id="@+id/action_profileFragment_to_authFragment" | ||||||
|  | |||||||
| @ -26,4 +26,11 @@ | |||||||
|     <string name="profile">Profile</string> |     <string name="profile">Profile</string> | ||||||
|     <string name="serverIsUnabailable">Server is unavailable</string> |     <string name="serverIsUnabailable">Server is unavailable</string> | ||||||
|     <string name="AdminFragment">Checking the session employee</string> |     <string name="AdminFragment">Checking the session employee</string> | ||||||
|  |     <string name="error_password_too_short">The password must contain at least 8 characters</string> | ||||||
|  |     <string name="error_password_no_uppercase">The password must contain at least one uppercase letter</string> | ||||||
|  |     <string name="error_password_no_digit">The password must contain at least one digit</string> | ||||||
|  |     <string name="error_login_empty">The username cannot be empty</string> | ||||||
|  |     <string name="error_login_too_short">Login must contain at least 3 characters</string> | ||||||
|  |     <string name="error_login_starts_with_digit">Login cannot start with a digit</string> | ||||||
|  |     <string name="error_login_invalid_characters">Login can contain only letters, numbers, and underscores</string> | ||||||
| </resources> | </resources> | ||||||
| @ -25,7 +25,12 @@ | |||||||
|     <string name="qrScanFragment">QR code scanning</string> |     <string name="qrScanFragment">QR code scanning</string> | ||||||
|     <string name="qrResultFragment">Scan result</string> |     <string name="qrResultFragment">Scan result</string> | ||||||
|     <string name="profile">Profile</string> |     <string name="profile">Profile</string> | ||||||
| 
 |     <string name="error_password_too_short">The password must contain at least 8 characters</string> | ||||||
|  |     <string name="error_password_no_uppercase">The password must contain at least one uppercase letter</string> | ||||||
|  |     <string name="error_password_no_digit">The password must contain at least one digit</string> | ||||||
|     <string name="AdminFragment">Checking the session employee</string> |     <string name="AdminFragment">Checking the session employee</string> | ||||||
| 
 |     <string name="error_login_empty">The username cannot be empty</string> | ||||||
|  |     <string name="error_login_too_short">Login must contain at least 3 characters</string> | ||||||
|  |     <string name="error_login_starts_with_digit">Login cannot start with a digit</string> | ||||||
|  |     <string name="error_login_invalid_characters">Login can contain only letters, numbers, and underscores</string> | ||||||
| </resources> | </resources> | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user