Commit ae72f928 authored by shohboz's avatar shohboz

[ADD] MUS-125 Feature, add check-phone api and handle login api response

parent be0a3fe1
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="$USER_HOME$/.android/avd/Pixel_3_API_30.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2021-12-06T08:51:27.847367Z" />
</component>
</project>
\ No newline at end of file
......@@ -25,6 +25,7 @@
<entry key="app/src/main/res/drawable/ic_group_12.xml" value="0.2796296296296296" />
<entry key="app/src/main/res/drawable/ic_russia.xml" value="0.2796296296296296" />
<entry key="app/src/main/res/drawable/ic_vector_error.xml" value="0.20694444444444443" />
<entry key="app/src/main/res/drawable/text_handle.xml" value="1.4214285714285715" />
<entry key="app/src/main/res/layout/activity_auth.xml" value="0.3416666666666667" />
<entry key="app/src/main/res/layout/activity_language.xml" value="0.25" />
<entry key="app/src/main/res/layout/activity_main.xml" value="0.22" />
......@@ -34,21 +35,28 @@
<entry key="app/src/main/res/layout/fragment_base.xml" value="0.23497267759562843" />
<entry key="app/src/main/res/layout/fragment_biometric.xml" value="0.23497267759562843" />
<entry key="app/src/main/res/layout/fragment_blank.xml" value="0.18385416666666668" />
<entry key="app/src/main/res/layout/fragment_check_phone.xml" value="0.25625" />
<entry key="app/src/main/res/layout/fragment_enter_password.xml" value="0.22" />
<entry key="app/src/main/res/layout/fragment_forget_password.xml" value="0.21174863387978143" />
<entry key="app/src/main/res/layout/fragment_home.xml" value="0.18385416666666668" />
<entry key="app/src/main/res/layout/fragment_login.xml" value="0.2" />
<entry key="app/src/main/res/layout/fragment_password.xml" value="0.2" />
<entry key="app/src/main/res/layout/fragment_pin.xml" value="0.23497267759562843" />
<entry key="app/src/main/res/layout/fragment_pin_dialog.xml" value="0.25625" />
<entry key="app/src/main/res/layout/fragment_pin_lock.xml" value="0.23497267759562843" />
<entry key="app/src/main/res/layout/fragment_progress.xml" value="0.33242753623188404" />
<entry key="app/src/main/res/layout/fragment_register.xml" value="0.33242753623188404" />
<entry key="app/src/main/res/layout/fragment_verification.xml" value="0.2" />
<entry key="app/src/main/res/layout/home_home.xml" value="0.25625" />
<entry key="app/src/main/res/layout/home_motion.xml" value="0.10951008645533142" />
<entry key="app/src/main/res/layout/item_confirm.xml" value="0.23497267759562843" />
<entry key="app/src/main/res/layout/item_home.xml" value="0.29936594202898553" />
<entry key="app/src/main/res/layout/item_pin.xml" value="0.23497267759562843" />
<entry key="app/src/main/res/layout/layout_ask_create_task.xml" value="0.22643442622950818" />
<entry key="app/src/main/res/layout/layout_exit.xml" value="0.25625" />
<entry key="app/src/main/res/layout/motion_layout.xml" value="0.266796875" />
<entry key="app/src/main/res/menu/bottom_nav_menu.xml" value="0.3416666666666667" />
<entry key="app/src/main/res/xml/layout_description.xml" value="0.25625" />
</map>
</option>
</component>
......
......@@ -93,6 +93,8 @@ dependencies {
implementation "com.github.iwgang:countdownview:2.1.6"
implementation 'com.poovam:pin-edittext-field:1.2.3'
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="uz.ssd.mobiuz">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".app.App"
......@@ -14,8 +15,10 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/Theme.MobiUzAndroid"
android:usesCleartextTraffic="true">
android:usesCleartextTraffic="true"
tools:targetApi="m">
<activity
android:name=".LanguageActivity"
android:screenOrientation="portrait"
......
......@@ -3,29 +3,37 @@ package uz.ssd.mobiuz
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricPrompt
import androidx.core.hardware.fingerprint.FingerprintManagerCompat
import androidx.navigation.NavController
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import dagger.hilt.android.AndroidEntryPoint
import uz.ssd.mobiuz.databinding.ActivityAuthBinding
import uz.ssd.mobiuz.utils.extensions.customLog
import uz.ssd.mobiuz.utils.CONSTANTS
import uz.ssd.mobiuz.utils.Utils
@AndroidEntryPoint
class AuthActivity : AppCompatActivity() {
private var _bn: ActivityAuthBinding? = null
private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
private lateinit var navController : NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_bn = ActivityAuthBinding.inflate(layoutInflater)
setContentView(bn.root)
val fragment = supportFragmentManager.findFragmentById(R.id.auth_container) as NavHostFragment
navController = NavHostFragment.findNavController(fragment)
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
// val bio = BiometricManager.from(this).canAuthenticate()
// val man = FingerprintManagerCompat.from(this)
// val manager = man.isHardwareDetected && man.hasEnrolledFingerprints()
// customLog("bio:$bio $manager")
intent?.let {
val type = it.getStringExtra(CONSTANTS.TYPE_AUTH)
if (type == CONSTANTS.PIN_CODE) {
navController.popBackStack()
navController.navigate(R.id.pinFragment,null,Utils.navOptions())
}
}
}
override fun onDestroy() {
......
package uz.ssd.mobiuz
import uz.ssd.mobiuz.ui.base.BaseFragment
class MotionFragment: BaseFragment(R.layout.home_motion) {
override fun setUpUI() {
}
override fun collects() {
}
}
\ No newline at end of file
......@@ -6,6 +6,7 @@ import uz.ssd.mobiuz.model.SharedPref
import uz.ssd.mobiuz.model.UserAuth
import uz.ssd.mobiuz.network.api.ApiService
import uz.ssd.mobiuz.network.model.Action
import uz.ssd.mobiuz.network.model.Customer
import uz.ssd.mobiuz.network.model.UiStateObject
import uz.ssd.mobiuz.utils.extensions.userMessage
import javax.inject.Inject
......@@ -18,19 +19,18 @@ class AuthRepository @Inject constructor(
@ApplicationContext val context: Context
) {
suspend fun loginUser(data: UserAuth): UiStateObject<Action> {
suspend fun checkPhone(data: UserAuth): UiStateObject<Action> {
return try {
val res = apiService.checkPhone(data)
if (res.status)
UiStateObject.SUCCESS(res.data ?: Action())
else{
var error = ""
res.errors.forEach {
error += it.message
when {
res.status -> UiStateObject.SUCCESS(res.data ?: Action())
res.errors.isNotEmpty() -> {
UiStateObject.ERRORS(res.errors)
}
UiStateObject.ERROR(error)
else -> UiStateObject.ERROR(res.message)
}
} catch (e: Exception) {
UiStateObject.ERROR(e.userMessage(context))
}
......@@ -39,9 +39,13 @@ class AuthRepository @Inject constructor(
suspend fun registerUser(data: UserAuth): UiStateObject<String> {
return try {
val res = apiService.register(data)
if (res.status)
UiStateObject.SUCCESS(res.message)
else UiStateObject.ERROR(res.message)
when {
res.status -> UiStateObject.SUCCESS(res.message)
res.errors.isNotEmpty() -> {
UiStateObject.ERRORS(res.errors)
}
else -> UiStateObject.ERROR(res.message)
}
} catch (e: Exception) {
UiStateObject.ERROR(e.userMessage(context))
......@@ -51,12 +55,54 @@ class AuthRepository @Inject constructor(
suspend fun checkSMSCode(data: UserAuth): UiStateObject<String> {
return try {
val res = apiService.checkSMSCode(data)
if (res.status){
pref.setUserToken(res.data?.token)
UiStateObject.SUCCESS(res.message)
when {
res.status -> {
pref.setUserToken(res.data?.token)
pref.isRegistered = true
UiStateObject.SUCCESS(res.message)
}
res.errors.isNotEmpty() -> {
UiStateObject.ERRORS(res.errors)
}
else -> UiStateObject.ERROR(res.message)
}
else UiStateObject.ERROR(res.message)
} catch (e: Exception) {
UiStateObject.ERROR(e.userMessage(context))
}
}
suspend fun loginUser(data: UserAuth): UiStateObject<String> {
return try {
val res = apiService.login(data)
when {
res.status -> {
UiStateObject.SUCCESS(res.message)
}
res.errors.isNotEmpty() -> {
UiStateObject.ERRORS(res.errors)
}
else -> UiStateObject.ERROR(res.message)
}
} catch (e: Exception) {
UiStateObject.ERROR(e.userMessage(context))
}
}
suspend fun mainIndex(): UiStateObject<Customer> {
return try {
val res = apiService.mainIndex()
when {
res.status && res.data != null -> {
UiStateObject.SUCCESS(res.data!!)
}
res.errors.isNotEmpty() -> {
UiStateObject.ERRORS(res.errors)
}
else -> UiStateObject.ERROR(res.message)
}
} catch (e: Exception) {
UiStateObject.ERROR(e.userMessage(context))
}
......
......@@ -17,13 +17,13 @@ class AuthViewModel @Inject constructor(
private val repository: AuthRepository
) : ViewModel() {
private val _loginUiState = MutableStateFlow<UiStateObject<Action>>(UiStateObject.EMPTY)
val loginUiState: StateFlow<UiStateObject<Action>> = _loginUiState
private val _checkPhoneUiState = MutableStateFlow<UiStateObject<Action>>(UiStateObject.EMPTY)
val checkPhoneUiState: StateFlow<UiStateObject<Action>> = _checkPhoneUiState
fun login(data: UserAuth) = viewModelScope.launch {
_loginUiState.value = UiStateObject.LOADING
_loginUiState.value = repository.loginUser(data)
_loginUiState.value = UiStateObject.EMPTY
fun checkPhone(data: UserAuth) = viewModelScope.launch {
_checkPhoneUiState.value = UiStateObject.LOADING
_checkPhoneUiState.value = repository.checkPhone(data)
_checkPhoneUiState.value = UiStateObject.EMPTY
}
private val _registerUiState = MutableStateFlow<UiStateObject<String>>(UiStateObject.EMPTY)
......@@ -32,6 +32,7 @@ class AuthViewModel @Inject constructor(
fun register(data: UserAuth) = viewModelScope.launch {
_registerUiState.value = UiStateObject.LOADING
_registerUiState.value = repository.registerUser(data)
_registerUiState.value = UiStateObject.EMPTY
}
private val _verificationUiState = MutableStateFlow<UiStateObject<String>>(UiStateObject.EMPTY)
......@@ -40,5 +41,15 @@ class AuthViewModel @Inject constructor(
fun verification(data: UserAuth) = viewModelScope.launch {
_verificationUiState.value = UiStateObject.LOADING
_verificationUiState.value = repository.checkSMSCode(data)
_verificationUiState.value = UiStateObject.EMPTY
}
private val _loginUiState = MutableStateFlow<UiStateObject<String>>(UiStateObject.EMPTY)
val loginUiState: StateFlow<UiStateObject<String>> = _loginUiState
fun login(data: UserAuth) = viewModelScope.launch {
_loginUiState.value = UiStateObject.LOADING
_loginUiState.value = repository.loginUser(data)
_loginUiState.value = UiStateObject.EMPTY
}
}
\ No newline at end of file
......@@ -35,9 +35,6 @@ class BiometricFragment : BaseFragment(R.layout.fragment_biometric) {
private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
private val navController: NavController by lazy(LazyThreadSafetyMode.NONE) { NavHostFragment.findNavController(this) }
var phone = ""
var phoneRaw = ""
private val viewModel: AuthViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
......@@ -69,19 +66,13 @@ class BiometricFragment : BaseFragment(R.layout.fragment_biometric) {
txtSkip.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
val intent = Intent(requireContext(), MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
startActivity(intent)
requireActivity().finish()
navigate()
}
})
btnNext.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
val intent = Intent(requireContext(), MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
startActivity(intent)
requireActivity().finish()
navigate()
}
})
......@@ -93,6 +84,14 @@ class BiometricFragment : BaseFragment(R.layout.fragment_biometric) {
}
}
private fun navigate() {
val intent = Intent(requireContext(), MainActivity::class.java)
intent.putExtra(CONSTANTS.FIRST,CONSTANTS.FIRST)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
startActivity(intent)
requireActivity().finish()
}
override fun collects() {}
override fun onDestroy() {
......
......@@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.View
import android.view.animation.AnimationUtils
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
......@@ -48,6 +49,7 @@ class CheckPhoneFragment : BaseFragment(R.layout.fragment_check_phone) {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
customLog("s=${s?.toString()?.length}")
bn.helperPhone.isVisible = false
btnLogin.isEnabled = inputPhone.text.toString().trim().length == 17
}
})
......@@ -60,7 +62,7 @@ class CheckPhoneFragment : BaseFragment(R.layout.fragment_check_phone) {
phone.length < 13 -> {
inputPhone.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
}
else -> viewModel.login(UserAuth(phone, null))
else -> viewModel.checkPhone(UserAuth(phone.replace("+",""), null))
}
}
......@@ -73,10 +75,11 @@ class CheckPhoneFragment : BaseFragment(R.layout.fragment_check_phone) {
override fun collects() {
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
viewModel.loginUiState.collect {
viewModel.checkPhoneUiState.collect {
when (it) {
is UiStateObject.SUCCESS -> {
showProgressDialog(false)
bn.helperPhone.isVisible = false
if (it.data.action == "login") {
navController.navigate(R.id.loginFragment, bundleOf(CONSTANTS.PHONE to phoneRaw), Utils.navOptions())
} else if (it.data.action == "register") {
......@@ -84,10 +87,24 @@ class CheckPhoneFragment : BaseFragment(R.layout.fragment_check_phone) {
}
}
is UiStateObject.ERROR -> {
bn.helperPhone.isVisible = false
showProgressDialog(false)
showMessage(it.message)
}
is UiStateObject.ERRORS -> {
it.errors.forEach {
if(it.key == "phone"){
bn.layoutInput.startAnimation(AnimationUtils.loadAnimation(requireContext(),R.anim.shake))
bn.helperPhone.isVisible = true
bn.helperPhone.text = it.message
}
}
showProgressDialog(false)
}
is UiStateObject.LOADING -> {
bn.helperPhone.isVisible = false
showProgressDialog(true)
}
else -> Unit
......
......@@ -3,6 +3,7 @@ package uz.ssd.mobiuz.ui.auth
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.animation.AnimationUtils
import android.widget.TextView
import androidx.core.hardware.fingerprint.FingerprintManagerCompat
import androidx.core.view.isVisible
......@@ -19,6 +20,7 @@ import uz.ssd.mobiuz.databinding.FragmentPinBinding
import uz.ssd.mobiuz.model.PinData
import uz.ssd.mobiuz.model.SharedPref
import uz.ssd.mobiuz.ui.base.BaseFragment
import uz.ssd.mobiuz.utils.CONSTANTS
import uz.ssd.mobiuz.utils.Utils
import javax.inject.Inject
......@@ -69,6 +71,7 @@ class ConfirmPinFragment : BaseFragment(R.layout.fragment_pin) {
txtNotPin.isVisible = false
navigate()
} else {
cardPin.startAnimation(AnimationUtils.loadAnimation(requireContext(),R.anim.shake))
txtNotPin.isVisible = true
}
}
......@@ -94,13 +97,14 @@ class ConfirmPinFragment : BaseFragment(R.layout.fragment_pin) {
}
private fun navigate() {
pref.pin_code = pinCode
val manager = FingerprintManagerCompat.from(requireContext())
val isEnabled = manager.isHardwareDetected && manager.hasEnrolledFingerprints()
if (isEnabled) {
navController.navigate(R.id.biometricFragment, null, Utils.navOptions())
} else {
startActivity(Intent(requireContext(), MainActivity::class.java))
startActivity(Intent(requireContext(), MainActivity::class.java).putExtra(CONSTANTS.FIRST,CONSTANTS.FIRST))
requireActivity().finish()
}
}
......
......@@ -3,6 +3,7 @@ package uz.ssd.mobiuz.ui.auth
import android.os.Bundle
import android.view.View
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
......@@ -58,6 +59,7 @@ class LoginFragment : BaseFragment(R.layout.fragment_login) {
inputPassword.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
bn.helperPassword.isVisible = false
btnLogin.isEnabled = (s.toString().length > 5)
}
})
......@@ -77,7 +79,7 @@ class LoginFragment : BaseFragment(R.layout.fragment_login) {
)
}
else -> {
viewModel.login(UserAuth(phone.replace(" ", ""), password))
viewModel.login(UserAuth(phone.replace(" ", "").replace("+", ""), password))
}
}
......@@ -96,19 +98,37 @@ class LoginFragment : BaseFragment(R.layout.fragment_login) {
when (it) {
is UiStateObject.SUCCESS -> {
showProgressDialog(false)
navController.navigate(R.id.verificationFragment, null, Utils.navOptions())
bn.helperPassword.isVisible = false
bn.helperPhone.isVisible = false
navController.navigate(R.id.verificationFragment, bundleOf(CONSTANTS.PHONE to phone), Utils.navOptions())
}
is UiStateObject.ERROR -> {
showProgressDialog(false)
bn.inputPassword.startAnimation(
android.view.animation.AnimationUtils.loadAnimation(
requireContext(),
R.anim.shake
)
)
showMessage(it.message)
bn.helperPassword.isVisible = false
bn.helperPhone.isVisible = false
}
is UiStateObject.ERRORS -> {
showProgressDialog(false)
it.errors.forEach {
if (it.key == "phone") {
bn.helperPhone.isVisible = true
bn.helperPhone.text = it.message
} else {
bn.helperPhone.isVisible = false
}
if (it.key == "password") {
bn.helperPassword.isVisible = true
bn.helperPassword.text = it.message
} else {
bn.helperPassword.isVisible = false
}
}
}
is UiStateObject.LOADING -> {
bn.helperPassword.isVisible = false
bn.helperPhone.isVisible = false
showProgressDialog(true)
}
else -> Unit
......
......@@ -39,6 +39,13 @@ class PinAdapter : RecyclerView.Adapter<PinAdapter.VHolder>() {
list[index].count = id
notifyItemChanged(index)
if (index == 3) checkDone()
}else{
list.forEach {
it.count = -1
}
notifyDataSetChanged()
list[0].count = id
notifyItemChanged(0)
}
}
......
package uz.ssd.mobiuz.ui.auth
import android.app.AlertDialog
import android.content.Context
import android.view.LayoutInflater
import android.view.animation.AnimationUtils
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import uz.ssd.mobiuz.R
import uz.ssd.mobiuz.databinding.FragmentPinDialogBinding
import uz.ssd.mobiuz.model.PinData
import uz.ssd.mobiuz.model.SharedPref
import uz.ssd.mobiuz.utils.extensions.SingleBlock
class PinDialogFragment(context: Context) : AlertDialog(context,R.style.FullScreenDialog) {
lateinit var pref: SharedPref
private var _bn: FragmentPinDialogBinding? = null
private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
private val data = ArrayList<PinData>()
private val pinAdapter = PinAdapter()
private var listener: SingleBlock<Unit>? = null
init {
_bn = FragmentPinDialogBinding.inflate(LayoutInflater.from(context))
pref = SharedPref(context)
setView(bn.root)
setCancelable(false)
setUpUI()
}
fun setUpUI() {
bn.apply {
loadData()
rvPin.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
rvPin.setHasFixedSize(true)
rvPin.adapter = pinAdapter
txtNotPin.isVisible = false
pinAdapter.setOnDoneListener {
if (pref.pin_code == it) {
listener?.invoke(Unit)
txtNotPin.isVisible = false
dismiss()
} else {
cardPin.startAnimation(AnimationUtils.loadAnimation(context, R.anim.shake))
txtNotPin.isVisible = true
}
}
for (i in 0 until btnViewGroup.childCount) {
btnViewGroup.getChildAt(i).setOnClickListener {
if (it.id == R.id.btn_remove) {
pinAdapter.removeItem()
txtNotPin.isVisible = false
} else {
val text = it as TextView
pinAdapter.addItem(text.text.toString().toInt())
}
}
}
}
}
fun setOnPinDoneListener(block: SingleBlock<Unit>) {
listener = block
}
private fun loadData() {
data.clear()
for (i in 0..3) {
data.add(PinData(-1))
}
pinAdapter.submitList(data)
}
}
\ No newline at end of file
......@@ -18,7 +18,6 @@ import uz.ssd.mobiuz.model.PinData
import uz.ssd.mobiuz.model.SharedPref
import uz.ssd.mobiuz.ui.base.BaseFragment
import uz.ssd.mobiuz.utils.Utils
import uz.ssd.mobiuz.utils.extensions.showMessage
import javax.inject.Inject
@AndroidEntryPoint
......
package uz.ssd.mobiuz.ui.auth
import android.graphics.Color
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.view.animation.AnimationUtils
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
......@@ -13,6 +12,7 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import uz.ssd.mobiuz.R
import uz.ssd.mobiuz.databinding.FragmentVerificationBinding
import uz.ssd.mobiuz.model.SharedPref
import uz.ssd.mobiuz.model.UserAuth
import uz.ssd.mobiuz.network.model.UiStateObject
import uz.ssd.mobiuz.ui.base.BaseFragment
......@@ -21,12 +21,15 @@ import uz.ssd.mobiuz.utils.ButtonClick
import uz.ssd.mobiuz.utils.CONSTANTS
import uz.ssd.mobiuz.utils.Utils
import uz.ssd.mobiuz.utils.extensions.hideKeyboard
import uz.ssd.mobiuz.utils.extensions.showKeyboard
import uz.ssd.mobiuz.utils.extensions.showMessage
import javax.inject.Inject
@AndroidEntryPoint
class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
@Inject
lateinit var pref: SharedPref
private var _bn: FragmentVerificationBinding? = null
private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
private val viewModel: AuthViewModel by viewModels()
......@@ -42,6 +45,7 @@ class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
phone = it.getString(CONSTANTS.PHONE) ?: ""
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
_bn = FragmentVerificationBinding.bind(view)
setUpUI()
......@@ -56,35 +60,29 @@ class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
navController.navigateUp()
}
loadEdited()
viewGroup.setOnClickListener(object : ButtonClick(){
viewGroup.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
v?.hideKeyboard()
}
})
frame.setOnClickListener(object : ButtonClick(){
override fun onSingleClick(v: View?) {
clearPins()
lineField.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
btnLogin.isEnabled = (s.toString().length == 6)
}
})
btnLogin.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
getLinePinCodes()
if(code.length == 6){
viewModel.verification(UserAuth(phone, null,code))
}else{
clearPins()
if (code.length == 6) {
viewModel.verification(UserAuth(phone.replace("+", "").replace(" ", ""), null, code))
}
}
})
countWaitText.setTextColor(Color.parseColor("#97ADB6"))
sentCodeAgain.setTextColor(Color.parseColor("#FF9500"))
sentCodeAgain.setOnClickListener {
count(true)
}
......@@ -95,152 +93,7 @@ class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
}
private fun getLinePinCodes() {
bn.apply {
code = ""
code += pin1.text.toString()
code += pin2.text.toString()
code += pin3.text.toString()
code += pin4.text.toString()
code += pin5.text.toString()
code += pin6.text.toString()
}
}
private fun clearPins() {
bn.apply {
pin1.text?.clear()
pin2.text?.clear()
pin3.text?.clear()
pin4.text?.clear()
pin5.text?.clear()
pin6.text?.clear()
pin1.showKeyboard()
}
}
private fun loadEdited() {
bn.apply {
pin1.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
if (s.toString().isNotEmpty()) {
pin2.requestFocus()
pin1.setBackgroundResource(R.drawable.bgn_ver_checked)
} else {
pin1.setBackgroundResource(R.drawable.bgn_ver_unchecked)
}
}
})
pin2.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
if (s.toString().isNotEmpty()) {
pin3.requestFocus()
pin2.setBackgroundResource(R.drawable.bgn_ver_checked)
} else {
pin1.requestFocus()
pin2.setBackgroundResource(R.drawable.bgn_ver_unchecked)
}
}
})
pin3.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
if (s.toString().isNotEmpty()) {
pin4.requestFocus()
pin3.setBackgroundResource(R.drawable.bgn_ver_checked)
} else {
pin2.requestFocus()
pin3.setBackgroundResource(R.drawable.bgn_ver_unchecked)
}
}
})
pin4.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
if (s.toString().isNotEmpty()) {
pin5.requestFocus()
pin4.setBackgroundResource(R.drawable.bgn_ver_checked)
} else {
pin3.requestFocus()
pin4.setBackgroundResource(R.drawable.bgn_ver_unchecked)
}
}
})
pin5.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
if (s.toString().isNotEmpty()) {
pin6.requestFocus()
pin5.setBackgroundResource(R.drawable.bgn_ver_checked)
} else {
pin4.requestFocus()
pin5.setBackgroundResource(R.drawable.bgn_ver_unchecked)
}
}
})
pin6.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
if (s.toString().isNotEmpty()) {
pin6.setBackgroundResource(R.drawable.bgn_ver_checked)
pin6.hideKeyboard()
btnLogin.isEnabled = true
} else {
pin5.requestFocus()
btnLogin.isEnabled = false
pin6.setBackgroundResource(R.drawable.bgn_ver_unchecked)
}
}
})
for (i in 0 until pinView.childCount){
pinView.getChildAt(i).setOnKeyListener { _, keyCode, _ ->
if (keyCode == KeyEvent.KEYCODE_DEL) {
checkFocus().requestFocus()
}
false
}
}
}
}
private fun checkFocus(): View {
bn.apply {
return when {
pin6.text.toString().trim().isNotEmpty() -> {
pin6.text?.clear()
return pin6
}
pin5.text.toString().trim().isNotEmpty() -> {
pin5.text?.clear()
return pin5
}
pin4.text.toString().trim().isNotEmpty() -> {
pin4.text?.clear()
return pin4
}
pin3.text.toString().trim().isNotEmpty() -> {
pin3.text?.clear()
return pin3
}
pin2.text.toString().trim().isNotEmpty() -> {
pin2.text?.clear()
return pin2
}
else -> {
pin1.text?.clear()
pin1
}
}
}
code = bn.lineField.text.toString()
}
override fun collects() {
......@@ -249,13 +102,29 @@ class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
when (it) {
is UiStateObject.SUCCESS -> {
showProgressDialog(false)
bn.helperLineField.isVisible = false
pref.userPhone = phone
navController.navigate(R.id.pinFragment, null, Utils.navOptions())
}
is UiStateObject.ERROR -> {
showProgressDialog(false)
bn.lineField.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
bn.helperLineField.isVisible = false
showMessage(it.message)
}
is UiStateObject.ERRORS -> {
showProgressDialog(false)
it.errors.forEach {
if (it.key == "code") {
bn.helperLineField.isVisible = true
bn.helperLineField.text = it.message
} else bn.helperLineField.isVisible = false
}
bn.lineField.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
// showMessage(it.message)
}
is UiStateObject.LOADING -> {
bn.helperLineField.isVisible = false
showProgressDialog(true)
}
else -> Unit
......
package uz.ssd.mobiuz.ui.base
import android.graphics.Color
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.snackbar.Snackbar
import uz.ssd.mobiuz.R
import androidx.fragment.app.Fragment
import uz.ssd.mobiuz.ui.global.ProgressDialog
abstract class BaseFragment(private val layoutId:Int) : Fragment() {
abstract class BaseFragment(private val layoutId: Int) : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(layoutId,container,false)
return inflater.inflate(layoutId, container, false)
}
protected abstract fun setUpUI()
......
......@@ -3,7 +3,6 @@ package uz.ssd.mobiuz.ui.forget
import android.graphics.Color
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
......@@ -18,12 +17,10 @@ import uz.ssd.mobiuz.model.UserAuth
import uz.ssd.mobiuz.network.model.UiStateObject
import uz.ssd.mobiuz.ui.auth.AuthViewModel
import uz.ssd.mobiuz.ui.base.BaseFragment
import uz.ssd.mobiuz.ui.global.TextWatcherWrapper
import uz.ssd.mobiuz.utils.ButtonClick
import uz.ssd.mobiuz.utils.CONSTANTS
import uz.ssd.mobiuz.utils.Utils
import uz.ssd.mobiuz.utils.extensions.hideKeyboard
import uz.ssd.mobiuz.utils.extensions.showKeyboard
import uz.ssd.mobiuz.utils.extensions.showMessage
@AndroidEntryPoint
......@@ -66,9 +63,6 @@ class ForgetVerificationFragment : BaseFragment(R.layout.fragment_verification)
loadEdited()
frame.setOnClickListener {
clearPins()
}
btnLogin.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
......@@ -95,155 +89,19 @@ class ForgetVerificationFragment : BaseFragment(R.layout.fragment_verification)
}
private fun loadEdited() {
bn.apply {
pin1.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
if (s.toString().isNotEmpty()) {
pin2.requestFocus()
pin1.setBackgroundResource(R.drawable.bgn_ver_checked)
} else {
pin1.setBackgroundResource(R.drawable.bgn_ver_unchecked)
}
}
})
pin2.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
if (s.toString().isNotEmpty()) {
pin3.requestFocus()
pin2.setBackgroundResource(R.drawable.bgn_ver_checked)
} else {
pin1.requestFocus()
pin2.setBackgroundResource(R.drawable.bgn_ver_unchecked)
}
}
})
pin3.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
if (s.toString().isNotEmpty()) {
pin4.requestFocus()
pin3.setBackgroundResource(R.drawable.bgn_ver_checked)
} else {
pin2.requestFocus()
pin3.setBackgroundResource(R.drawable.bgn_ver_unchecked)
}
}
})
pin4.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
if (s.toString().isNotEmpty()) {
pin5.requestFocus()
pin4.setBackgroundResource(R.drawable.bgn_ver_checked)
} else {
pin3.requestFocus()
pin4.setBackgroundResource(R.drawable.bgn_ver_unchecked)
}
}
})
pin5.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
if (s.toString().isNotEmpty()) {
pin6.requestFocus()
pin5.setBackgroundResource(R.drawable.bgn_ver_checked)
} else {
pin4.requestFocus()
pin5.setBackgroundResource(R.drawable.bgn_ver_unchecked)
}
}
})
pin6.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
if (s.toString().isNotEmpty()) {
pin6.setBackgroundResource(R.drawable.bgn_ver_checked)
pin6.hideKeyboard()
btnLogin.isEnabled = true
} else {
pin5.requestFocus()
btnLogin.isEnabled = false
pin6.setBackgroundResource(R.drawable.bgn_ver_unchecked)
}
}
})
for (i in 0 until pinView.childCount){
pinView.getChildAt(i).setOnKeyListener { _, keyCode, _ ->
if (keyCode == KeyEvent.KEYCODE_DEL) {
checkFocus().requestFocus()
}
false
}
}
}
}
private fun getLinePinCodes() {
bn.apply {
code = ""
code += pin1.text.toString()
code += pin2.text.toString()
code += pin3.text.toString()
code += pin4.text.toString()
code += pin5.text.toString()
code += pin6.text.toString()
}
}
private fun clearPins() {
bn.apply {
pin1.text?.clear()
pin2.text?.clear()
pin3.text?.clear()
pin4.text?.clear()
pin5.text?.clear()
pin6.text?.clear()
pin1.showKeyboard()
}
}
private fun checkFocus(): View {
bn.apply {
return when {
pin6.text.toString().trim().isNotEmpty() -> {
pin6.text?.clear()
return pin6
}
pin5.text.toString().trim().isNotEmpty() -> {
pin5.text?.clear()
return pin5
}
pin4.text.toString().trim().isNotEmpty() -> {
pin4.text?.clear()
return pin4
}
pin3.text.toString().trim().isNotEmpty() -> {
pin3.text?.clear()
return pin3
}
pin2.text.toString().trim().isNotEmpty() -> {
pin2.text?.clear()
return pin2
}
else -> {
pin1.text?.clear()
pin1
}
}
}
}
override fun collects() {
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
viewModel.loginUiState.collect {
......
......@@ -2,32 +2,16 @@ package uz.ssd.mobiuz.utils
object CONSTANTS {
const val BASE_URL = "http://10.160.45.60/api/v1/"
const val BASE_URL_WITHOUT_API = "http://157.230.7.9:9098"
const val IMAGE_URL = "http://157.230.7.9:9098/api/attach/"
const val IMAGE_URL_GET = "http://157.230.7.9:9098/api/attach/get/"
const val ROOM = "room"
const val RU = "ru"
const val UZ = "uz"
const val EN = "en"
const val DES_POINT = "des_point"
const val PHONE = "phone"
const val TYPE_REPORT = "type_report"
const val TYPE_CREATE_SELF = "type_create_self"
const val TYPE_REPORT_102 = "type_report_102"
const val TYPE_REPORT_SELF = "type_report_self"
const val LOGO = "LOGO"
const val PIN_CODE = "pin_code"
const val TYPE_AUTH = "type_auth"
const val FIRST = "first"
const val LONGITUDE = 69.2602108116081
const val LATITUDE = 41.34823322480444
const val LONGITUDE2 = 69.26776391206731
const val LATITUDE2 = 41.29976097420951
//history
const val INCIDENT_CARD = "INCIDENT_CARD"
const val CAMERA = "CAMERA"
const val SELF_EMPLOYMENT = "SELF_EMPLOYMENT"
const val ID_TASK = "ID_TASK"
const val TICKET_ID = "TICKET_ID"
}
\ No newline at end of file
package uz.ssd.mobiuz.utils
import android.os.Build
import android.text.TextUtils
import androidx.navigation.NavOptions
import uz.ssd.mobiuz.R
......@@ -13,4 +15,34 @@ object Utils {
.setPopExitAnim(R.anim.slide_out_right)
.build()
}
fun getDeviceName(): String {
val manufacturer = Build.MANUFACTURER
val model = Build.MODEL
return if (model.toLowerCase().startsWith(manufacturer.toLowerCase())) {
capitalize(model)
} else {
capitalize(manufacturer) + " " + model
}
}
private fun capitalize(str: String): String {
if (TextUtils.isEmpty(str)) {
return str
}
val arr = str.toCharArray()
var capitalizeNext = true
val phrase = StringBuilder()
for (c in arr) {
if (capitalizeNext && Character.isLetter(c)) {
phrase.append(Character.toUpperCase(c))
capitalizeNext = false
continue
} else if (Character.isWhitespace(c)) {
capitalizeNext = true
}
phrase.append(c)
}
return phrase.toString()
}
}
\ No newline at end of file
......@@ -9,6 +9,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.google.gson.JsonSyntaxException
import retrofit2.HttpException
import uz.ssd.mobiuz.R
import uz.ssd.mobiuz.ui.base.ExitDialog
import java.io.IOException
import java.net.ConnectException
......@@ -59,6 +60,14 @@ fun Throwable.userMessage(context: Context) = when (this) {
else -> context.getString(R.string.ex_nothing)
}
fun Fragment.showCustomExitDialog(block: () -> Unit) {
val dialog = ExitDialog()
dialog.setOnDoneListener {
block()
}
dialog.show(childFragmentManager, "childFragmentManager")
}
typealias SingleBlock<T> = (T) -> Unit
typealias MultiBlock<T, K> = (T, K) -> Unit
typealias ThreeBlock<T, K, M> = (T, K, M) -> Unit
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<size
android:height="0dp"
android:width="0dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:fitsSystemWindows="true"
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/auth_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/auth_container"
app:navGraph="@navigation/nav_graph_auth"
app:defaultNavHost="true"
android:name="androidx.navigation.fragment.NavHostFragment"
tools:context=".AuthActivity">
</androidx.fragment.app.FragmentContainerView>
app:navGraph="@navigation/nav_graph_auth"
tools:context=".AuthActivity"/>
</LinearLayout>
......@@ -61,6 +61,19 @@
android:background="@drawable/edit_text_bgn"
android:layout_height="match_parent"/>
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/helper_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/phone"
android:visibility="gone"
android:textStyle="bold"
android:layout_marginTop="@dimen/_4sdp"
android:layout_marginStart="@dimen/_12sdp"
android:layout_gravity="start"
android:textColor="@color/red"
/>
</LinearLayout>
<LinearLayout
......
......@@ -67,6 +67,21 @@
android:paddingStart="@dimen/_12sdp" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/helper_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/phone"
android:visibility="gone"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="@id/layout_input_password"
app:layout_constraintTop_toBottomOf="@id/layout_input_password"
android:layout_marginTop="@dimen/_4sdp"
android:layout_marginStart="@dimen/_12sdp"
android:layout_gravity="start"
android:textColor="@color/red"
/>
<TextView
android:id="@+id/txt_hint_confirm"
......@@ -96,14 +111,27 @@
android:layout_height="match_parent"
android:background="@drawable/edit_text_bgn"
android:imeOptions="actionDone"
android:inputType="number"
android:inputType="numberPassword"
android:maxLength="7"
android:textSize="@dimen/_12sdp"
android:paddingVertical="@dimen/_12sdp"
android:paddingStart="@dimen/_12sdp"
tools:ignore="RtlSymmetry" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/helper_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/phone"
android:visibility="gone"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="@id/layout_input_confirm"
app:layout_constraintTop_toBottomOf="@id/layout_input_confirm"
android:layout_marginTop="@dimen/_4sdp"
android:layout_marginStart="@dimen/_12sdp"
android:layout_gravity="start"
android:textColor="@color/red"
/>
<TextView
android:id="@+id/txt_forget_password"
......
......@@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
......@@ -44,6 +45,7 @@
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:id="@+id/card_pin"
android:layout_height="wrap_content"
android:layout_gravity="center">
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:fitsSystemWindows="true"
android:orientation="vertical">
<TextView
android:id="@+id/txt_enter_pin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/_14sdp"
android:layout_marginTop="@dimen/_44sdp"
android:text="@string/enter_pin_code"
android:textSize="@dimen/_16sdp"
android:textStyle="bold" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TextView
android:id="@+id/txt_not_pin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center"
android:layout_marginTop="@dimen/_20sdp"
android:layout_marginBottom="@dimen/_20sdp"
android:text="@string/pin_not_same"
android:textColor="@color/red"
android:textSize="@dimen/_10sdp"
android:textStyle="bold"
android:visibility="gone" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/card_pin"
android:layout_width="wrap_content"
android:minWidth="@dimen/_80sdp"
android:minHeight="@dimen/_25sdp"
android:layout_height="wrap_content"
android:layout_gravity="center">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_pin"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_gravity="center"
android:paddingHorizontal="18dp"
android:layout_marginTop="2dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="4"
tools:listitem="@layout/item_pin" />
</com.google.android.material.card.MaterialCardView>
</FrameLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/btn_view_group"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2.5">
<TextView
android:id="@+id/btn_1"
android:layout_height="@dimen/_44sdp"
android:layout_width="@dimen/_48sdp"
style="@style/BtnStyle"
android:background="@drawable/bgn_pin_btn"
android:text="@string/_1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_2"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/btn_2"
style="@style/BtnStyle"
android:background="@drawable/bgn_pin_btn"
android:text="@string/_2"
android:layout_height="@dimen/_44sdp"
android:layout_width="@dimen/_48sdp"
app:layout_constraintEnd_toStartOf="@id/btn_3"
app:layout_constraintStart_toEndOf="@id/btn_1"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/btn_3"
style="@style/BtnStyle"
android:background="@drawable/bgn_pin_btn"
android:text="@string/_3"
android:layout_height="@dimen/_44sdp"
android:layout_width="@dimen/_48sdp"
app:layout_constraintStart_toEndOf="@id/btn_2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/btn_4"
style="@style/BtnStyle"
android:layout_marginTop="@dimen/_16sdp"
android:background="@drawable/bgn_pin_btn"
android:text="@string/_4"
android:layout_height="@dimen/_44sdp"
android:layout_width="@dimen/_48sdp"
app:layout_constraintEnd_toStartOf="@id/btn_5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_1" />
<TextView
android:id="@+id/btn_5"
style="@style/BtnStyle"
android:background="@drawable/bgn_pin_btn"
android:text="@string/_5"
android:layout_height="@dimen/_44sdp"
android:layout_width="@dimen/_48sdp"
app:layout_constraintEnd_toStartOf="@id/btn_3"
app:layout_constraintStart_toEndOf="@id/btn_1"
app:layout_constraintTop_toTopOf="@id/btn_4" />
<TextView
android:id="@+id/btn_6"
style="@style/BtnStyle"
android:background="@drawable/bgn_pin_btn"
android:text="@string/_6"
android:layout_height="@dimen/_44sdp"
android:layout_width="@dimen/_48sdp"
app:layout_constraintStart_toEndOf="@id/btn_5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/btn_4" />
<TextView
android:id="@+id/btn_7"
style="@style/BtnStyle"
android:layout_marginTop="@dimen/_16sdp"
android:background="@drawable/bgn_pin_btn"
android:text="@string/_7"
android:layout_height="@dimen/_44sdp"
android:layout_width="@dimen/_48sdp"
app:layout_constraintEnd_toStartOf="@id/btn_8"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_4" />
<TextView
android:id="@+id/btn_8"
style="@style/BtnStyle"
android:background="@drawable/bgn_pin_btn"
android:text="@string/_8"
android:layout_height="@dimen/_44sdp"
android:layout_width="@dimen/_48sdp"
app:layout_constraintEnd_toStartOf="@id/btn_3"
app:layout_constraintStart_toEndOf="@id/btn_1"
app:layout_constraintTop_toTopOf="@id/btn_7" />
<TextView
android:id="@+id/btn_9"
style="@style/BtnStyle"
android:background="@drawable/bgn_pin_btn"
android:text="@string/_9"
android:layout_height="@dimen/_44sdp"
android:layout_width="@dimen/_48sdp"
app:layout_constraintStart_toEndOf="@id/btn_8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/btn_7" />
<TextView
android:id="@+id/btn_0"
style="@style/BtnStyle"
android:layout_marginTop="@dimen/_16sdp"
android:background="@drawable/bgn_pin_btn"
android:text="@string/_0"
android:layout_height="@dimen/_44sdp"
android:layout_width="@dimen/_48sdp"
app:layout_constraintStart_toStartOf="@id/btn_8"
app:layout_constraintTop_toBottomOf="@id/btn_7" />
<ImageView
android:id="@+id/btn_remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/remove"
android:padding="@dimen/_12sdp"
android:src="@drawable/ic_vector_remove"
app:layout_constraintBottom_toBottomOf="@id/btn_0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_0"
app:layout_constraintTop_toTopOf="@id/btn_0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
\ No newline at end of file
......@@ -26,77 +26,58 @@
app:layout_constraintTop_toBottomOf="@id/toolbar" />
<FrameLayout
android:id="@+id/pin_view_group"
android:layout_width="match_parent"
<com.poovam.pinedittextfield.SquarePinField
android:id="@+id/line_field"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/_12sdp"
android:layout_marginTop="@dimen/_80sdp"
android:hint="******"
android:orientation="horizontal"
android:textColorHint="@color/black"
android:textSize="@dimen/_14sdp"
android:textStyle="bold"
android:textSelectHandle="@drawable/text_handle"
android:inputType="number"
app:highlightType="allFields"
app:cornerRadius="@dimen/_6sdp"
app:isCursorEnabled="true"
app:fieldColor="@color/black"
app:highlightColor="@color/red"
app:isCustomBackground="false"
app:lineThickness="1dp"
android:imeOptions="actionDone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/txt_enter_phone">
<LinearLayout
android:id="@+id/pin_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/pin_1"
style="@style/PinStyle"
android:background="@drawable/bgn_ver_unchecked" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/pin_2"
style="@style/PinStyle"
android:background="@drawable/bgn_ver_unchecked" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/pin_3"
style="@style/PinStyle"
android:background="@drawable/bgn_ver_unchecked" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/pin_4"
style="@style/PinStyle"
android:background="@drawable/bgn_ver_unchecked" />
app:layout_constraintTop_toBottomOf="@id/txt_enter_phone"
app:noOfFields="6" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/pin_5"
style="@style/PinStyle"
android:background="@drawable/bgn_ver_unchecked" />
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/pin_6"
style="@style/PinStyle"
android:background="@drawable/bgn_ver_unchecked"
android:imeOptions="actionDone" />
</LinearLayout>
<TextView
android:id="@+id/helper_line_field"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="error"
android:visibility="invisible"
android:layout_margin="@dimen/_4sdp"
android:textStyle="bold"
android:textColor="@color/red"
app:layout_constraintStart_toStartOf="@id/line_field"
app:layout_constraintTop_toBottomOf="@id/line_field" />
<FrameLayout
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible" />
</FrameLayout>
<TextView
android:id="@+id/countWaitText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="38dp"
android:layout_marginTop="@dimen/_34sdp"
android:text="@string/sent_code_again"
android:textSize="16sp"
android:textColor="#97ADB6"
app:layout_constraintEnd_toStartOf="@id/coutdown_view"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/pin_view_group" />
app:layout_constraintTop_toBottomOf="@+id/line_field" />
<TextView
android:id="@+id/sent_code_again"
......@@ -107,28 +88,28 @@
android:background="?selectableItemBackground"
android:text="@string/sent_code_again"
android:textSize="14sp"
android:textColor="#FF9500"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/pin_view_group" />
app:layout_constraintTop_toBottomOf="@+id/line_field" />
<cn.iwgang.countdownview.CountdownView
android:id="@+id/coutdown_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/_12sdp"
android:layout_marginTop="4dp"
android:visibility="visible"
android:layout_marginStart="@dimen/_10sdp"
app:isHideTimeBackground="false"
app:isShowDay="false"
app:isShowHour="false"
app:isShowMillisecond="false"
app:isShowMinute="true"
app:isShowSecond="true"
app:suffixTextColor="#97ADB6"
android:layout_marginTop="4dp"
app:isShowTimeBgBorder="false"
app:isShowTimeBgDivisionLine="false"
app:isTimeTextBold="true"
app:layout_constraintBottom_toBottomOf="@id/countWaitText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/countWaitText"
......@@ -139,11 +120,11 @@
app:suffixMillisecond="ss"
app:suffixMinute=":"
app:suffixSecond=""
app:suffixTextSize="12sp"
app:suffixTextSize="16sp"
app:timeBgColor="#00FF5000"
app:timeBgRadius="3dp"
app:timeBgSize="14dp"
app:timeTextSize="14dp" />
app:timeBgSize="16dp"
app:timeTextSize="16dp" />
<Button
......@@ -157,7 +138,7 @@
android:text="@string/continuoue"
android:textSize="@dimen/_12sdp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/pin_view_group" />
app:layout_constraintTop_toBottomOf="@id/line_field" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="12dp">
<LinearLayout
android:layout_width="@dimen/_200sdp"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/text_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center"
android:layout_marginTop="32dp"
android:textStyle="bold"
android:layout_marginHorizontal="22dp"
android:gravity="center"
android:text="@string/exit"
android:textSize="16sp" />
<TextView
android:id="@+id/text_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center"
android:gravity="center"
android:layout_marginHorizontal="22dp"
android:layout_marginTop="12dp"
android:text="@string/are_you_sure"
android:textSize="16sp" />
<View
android:layout_width="match_parent"
android:layout_marginTop="32dp"
android:background="@color/light"
android:layout_height="1dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:elevation="2dp"
android:orientation="horizontal">
<TextView
android:id="@+id/btn_cancel"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:background="?android:selectableItemBackground"
android:textStyle="bold"
android:paddingVertical="14dp"
android:layout_height="wrap_content"
android:text="@string/no"
android:textAllCaps="false"
android:textColor="@color/black"
app:cornerRadius="24dp" />
<View
android:layout_width="1dp"
android:background="@color/light"
android:layout_height="match_parent"/>
<TextView
android:id="@+id/btn_done"
android:layout_width="0dp"
android:layout_weight="1"
android:paddingVertical="14dp"
android:gravity="center"
android:background="?android:selectableItemBackground"
android:textStyle="bold"
android:layout_gravity="center"
android:layout_height="wrap_content"
android:text="@string/yes"
android:textAllCaps="false"
android:textColor="@color/black"
app:cornerRadius="24dp" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:layoutDescription="@xml/home_motion_scene"
android:layout_height="match_parent">
</androidx.constraintlayout.motion.widget.MotionLayout>
\ No newline at end of file
......@@ -10,4 +10,5 @@
android:name="uz.ssd.mobiuz.ui.home.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" />
</navigation>
\ No newline at end of file
......@@ -2,13 +2,13 @@
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:startDestination="@id/homeFragment"
app:startDestination="@id/motionFragment"
android:id="@+id/nav_graph_profile">
<fragment
android:id="@+id/homeFragment"
android:name="uz.ssd.mobiuz.ui.home.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" />
android:id="@+id/motionFragment"
tools:layout="@layout/home_motion"
android:name="uz.ssd.mobiuz.MotionFragment"
android:label="MotionFragment" />
</navigation>
\ No newline at end of file
......@@ -68,5 +68,10 @@
<string name="remove">remove</string>
<string name="password_same">Пароли совпали</string>
<string name="password_not_same">Пароли не совпали</string>
<string name="enter_pin_code">Enter pin code</string>
<string name="exit">Exit</string>
<string name="are_you_sure">Do you want to exit?</string>
<string name="no">No</string>
<string name="yes">Yes</string>
</resources>
\ No newline at end of file
......@@ -31,9 +31,10 @@
<item name="android:windowBackground">@android:color/transparent</item>
</style>
<style name="FullScreenDialog" parent="Theme.AppCompat.Light.Dialog">
<style name="FullScreenDialog" parent="ThemeOverlay.AppCompat.Dialog">
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:padding">0dp</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowBackground">@android:color/transparent</item>
......@@ -87,4 +88,14 @@
<item name="android:maxLength">1</item>
</style>
<style name="CustomDialog" parent="Theme.MaterialComponents.DayNight.Dialog">
<item name="android:windowAnimationStyle">@style/MaterialDialogAnimation</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
<style name="MaterialDialogAnimation" tools:ignore="ResourceName">
<item name="android:windowEnterAnimation">@anim/agr_grow_in</item>
<item name="android:windowExitAnimation">@anim/agr_fade_out</item>
</style>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<MotionScene>
</MotionScene>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment