158 lines
5.9 KiB
Kotlin
158 lines
5.9 KiB
Kotlin
package com.tarkvaraprojekt.mobileauthapp
|
|
|
|
import android.app.AlertDialog
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.os.Bundle
|
|
import android.util.Log
|
|
import android.util.TypedValue
|
|
import android.view.LayoutInflater
|
|
import android.view.View
|
|
import android.view.ViewGroup
|
|
import android.widget.TextView
|
|
import android.widget.Toast
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
import androidx.fragment.app.Fragment
|
|
import androidx.fragment.app.activityViewModels
|
|
import androidx.navigation.fragment.findNavController
|
|
import androidx.navigation.fragment.navArgs
|
|
import com.google.android.material.snackbar.Snackbar
|
|
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentPinBinding
|
|
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
|
|
|
/**
|
|
* Fragment that deals with asking the user for PIN 1. If the user has already saved the PIN 1 then it is not asked again
|
|
* and the fragment is skipped and if the PIN 1 is not saved then the user is asked whether it should be saved or
|
|
* not before continuing.
|
|
*/
|
|
class PinFragment : Fragment() {
|
|
|
|
private val viewModel: SmartCardViewModel by activityViewModels()
|
|
|
|
private var _binding: FragmentPinBinding? = null
|
|
private val binding get() = _binding!!
|
|
|
|
// Navigation arguments:
|
|
// saving = true means that the user must be returned to the settings menu
|
|
private val args: PinFragmentArgs by navArgs()
|
|
|
|
private var saveToggle = true
|
|
|
|
override fun onCreateView(
|
|
inflater: LayoutInflater,
|
|
container: ViewGroup?,
|
|
savedInstanceState: Bundle?
|
|
): View? {
|
|
_binding = FragmentPinBinding.inflate(inflater, container, false)
|
|
return binding.root
|
|
}
|
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
super.onViewCreated(view, savedInstanceState)
|
|
checkIfSkip()
|
|
// Switch should be not visible when user is in savings mode
|
|
if (args.saving) {
|
|
binding.savePinQuestion.visibility = View.GONE
|
|
binding.saveLayout.visibility = View.GONE
|
|
} else {
|
|
saveToggle =
|
|
activity?.getPreferences(Context.MODE_PRIVATE)?.getBoolean("saveToggle", true) == true //Android Studio recommendation to get rid of Boolean?.
|
|
if (!saveToggle) {
|
|
binding.saveSwitch.isChecked = false
|
|
}
|
|
binding.saveSwitch.setOnCheckedChangeListener { _, isChecked ->
|
|
if (isChecked) {
|
|
binding.saveStatus.text = getString(R.string.pin_save_on)
|
|
activity?.getPreferences(Context.MODE_PRIVATE)?.edit()?.putBoolean("saveToggle", true)?.apply()
|
|
} else {
|
|
binding.saveStatus.text = getString(R.string.pin_save_off)
|
|
activity?.getPreferences(Context.MODE_PRIVATE)?.edit()?.putBoolean("saveToggle", false)?.apply()
|
|
}
|
|
saveToggle = !saveToggle
|
|
}
|
|
}
|
|
binding.buttonContinue.setOnClickListener { checkEnteredPin() }
|
|
binding.buttonCancel.setOnClickListener { goToTheStart() }
|
|
}
|
|
|
|
/**
|
|
* Takes user to the next fragment, which is AuthFragment.
|
|
*/
|
|
private fun goToTheNextFragment() {
|
|
val action = PinFragmentDirections.actionPinFragmentToAuthFragment(auth = args.auth, mobile = args.mobile)
|
|
findNavController().navigate(action)
|
|
}
|
|
|
|
/**
|
|
* Returns user to the start. If the user arrived from the settings menu then the start is
|
|
* settings menu not the HomeFragment.
|
|
*/
|
|
private fun goToTheStart() {
|
|
if (args.saving) {
|
|
findNavController().navigate(R.id.action_pinFragment_to_settingsFragment)
|
|
} else if (args.auth || args.mobile) {
|
|
if (args.mobile) {
|
|
val resultIntent = Intent()
|
|
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
|
|
requireActivity().finish()
|
|
} else {
|
|
(activity as MainActivity).returnError(444)
|
|
requireActivity().finishAndRemoveTask()
|
|
}
|
|
} else {
|
|
findNavController().navigate(R.id.action_canFragment_to_homeFragment)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if the current fragment can be skipped or not.
|
|
* If the user has PIN 1 saved on the device or PIN 1 is not required
|
|
* then the PIN 1 won't be asked.
|
|
*/
|
|
private fun checkIfSkip() {
|
|
if (viewModel.userPin.length in 4..12) {
|
|
goToTheNextFragment()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Method that creates and shows a snackbar that tells the user that PIN 1 has been saved
|
|
*/
|
|
private fun showSnackbar() {
|
|
val snackbar = Snackbar.make(requireView(), R.string.pin_status_saved, Snackbar.LENGTH_SHORT)
|
|
val snackbarText: TextView = snackbar.view.findViewById(R.id.snackbar_text)
|
|
snackbarText.setTextSize(TypedValue.COMPLEX_UNIT_SP, resources.getDimension(R.dimen.small_text))
|
|
snackbar.show()
|
|
}
|
|
|
|
/**
|
|
* Checks whether the user has entered a PIN 1 with length between [4, 12] in the
|
|
* input field. If yes then the user is allowed to continue otherwise the user is
|
|
* allowed to modify the entered PIN 1.
|
|
*/
|
|
private fun checkEnteredPin() {
|
|
val enteredPin = binding.pinTextField.editText?.text.toString()
|
|
if (enteredPin.length in 4..12) {
|
|
viewModel.setUserPin(enteredPin)
|
|
if (args.saving) {
|
|
viewModel.storePin(requireContext())
|
|
showSnackbar()
|
|
goToTheStart()
|
|
} else {
|
|
if (saveToggle) {
|
|
viewModel.storePin(requireContext())
|
|
showSnackbar()
|
|
}
|
|
goToTheNextFragment()
|
|
}
|
|
} else {
|
|
Toast.makeText(requireContext(), getString(R.string.pin_helper_text), Toast.LENGTH_SHORT)
|
|
.show()
|
|
}
|
|
}
|
|
|
|
override fun onDestroy() {
|
|
super.onDestroy()
|
|
_binding = null
|
|
}
|
|
} |