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){
|
|
||||||
UserDTO userDTO = gson.fromJson(userJSON, UserDTO.class);
|
|
||||||
return userDTO;
|
|
||||||
}
|
|
||||||
private String toJson(UserDTO userDTO){
|
|
||||||
return gson.toJson(userDTO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private UserDTO fromJson(String userJSON) {
|
||||||
|
return gson.fromJson(userJSON, UserDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toJson(UserDTO 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)
|
if (username.length < 3) {
|
||||||
}
|
return "LenError"
|
||||||
private fun isPasswordValid(password: String): Boolean {
|
}
|
||||||
return password.isNotEmpty() &&
|
if (username[0].isDigit()) {
|
||||||
password.length >= 8
|
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
|
||||||
@ -20,7 +20,7 @@ import com.displaynone.acss.ui.scan.QrScanDestination
|
|||||||
import com.displaynone.acss.util.collectWithLifecycle
|
import com.displaynone.acss.util.collectWithLifecycle
|
||||||
import com.displaynone.acss.util.navigateTo
|
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 var _binding: FragmentProfileBinding? = null
|
||||||
private val binding: FragmentProfileBinding get() = _binding!!
|
private val binding: FragmentProfileBinding get() = _binding!!
|
||||||
|
|
||||||
@ -33,29 +33,28 @@ 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()!!)
|
||||||
|
|
||||||
Log.d("ProfileFragment", "set login")
|
Log.d("ProfileFragment", "set login")
|
||||||
@ -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() {
|
private fun checkForAdmin() {
|
||||||
Log.d("check", "cheking for roles")
|
val userDTO = UserServiceST.getInstance().getUserDTO() ?: return
|
||||||
|
|
||||||
val userDTO = UserServiceST.getInstance().getUserDTO()
|
if (userDTO.roles.any { it.name == "ROLE_ADMIN" }) {
|
||||||
if (userDTO != null) {
|
binding.buttonSearch.visibility = View.VISIBLE
|
||||||
if (userDTO.roles.any { it.name == "ROLE_ADMIN" }) {
|
binding.rightsUsingSmartphone.text = "Пропуск действителен"
|
||||||
Log.d("adminlog", "i'm admin")
|
}
|
||||||
binding.buttonSearch.visibility = View.VISIBLE
|
if (userDTO.roles.any { it.name == "ROLE_USER" }) {
|
||||||
binding.rightsUsingSmartphone.text = "Пропуск действителен"
|
binding.rightsUsingSmartphone.text = "Пропуск действителен"
|
||||||
}
|
|
||||||
if (userDTO.roles.any { it.name == "ROLE_USER" }) {
|
|
||||||
Log.d("userlog", "i'm user")
|
|
||||||
|
|
||||||
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,20 +148,19 @@ 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()
|
||||||
Toast.makeText(activity, "LOGOUT", Toast.LENGTH_SHORT).show()
|
Toast.makeText(activity, "LOGOUT", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun subscribeToGetData(){
|
private fun subscribeToGetData() {
|
||||||
viewModel.state.collectWithLifecycle(this) { state ->
|
viewModel.state.collectWithLifecycle(this) { state ->
|
||||||
if (state is ProfileViewModel.State.Show) {
|
if (state is ProfileViewModel.State.Show) {
|
||||||
val userDto: UserDTO = state.item
|
val userDto: UserDTO = state.item
|
||||||
|
@ -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,34 +17,37 @@ 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)
|
||||||
|
|
||||||
this.openDoor()
|
this.openDoor()
|
||||||
|
|
||||||
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) {
|
||||||
setResult(getString(R.string.success))
|
200 -> {
|
||||||
} else if (state.resultCode == 400) {
|
setResult(getString(R.string.success))
|
||||||
setResult(getString(R.string.wrong))
|
}
|
||||||
} else if (state.resultCode == 401) {
|
|
||||||
setResult(getString(R.string.cancel))
|
400 -> {
|
||||||
|
setResult(getString(R.string.wrong))
|
||||||
|
}
|
||||||
|
|
||||||
|
401 -> {
|
||||||
|
setResult(getString(R.string.cancel))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (state is QrResultViewModel.State.Error){
|
if (state is QrResultViewModel.State.Error) setResult(state.errorMessage)
|
||||||
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