Commit 46cfb422 authored by shohboz's avatar shohboz

[UPD] MUS-288, Feature, updated add card

parent ff55e2e3
......@@ -7,6 +7,7 @@
<entry key="../../.gradle/caches/transforms-3/272c6ad3bc9f3b40802fd3a427796f36/transformed/jetified-agr-sdk-mobi-uz-release-1.0.0/res/layout/agr_layout_empty.xml" value="0.25625" />
<entry key="../../.gradle/caches/transforms-3/eea77424a90e1e1097be3e7a9314e37d/transformed/jetified-mobi_uz/res/layout/agr_fragment_fast_pay.xml" value="0.25" />
<entry key="../../.gradle/caches/transforms-3/fd180e2afb980e83e4951f5e21e58af5/transformed/jetified-agr-sdk-coreui-release-1.7.0/res/layout/agr_core_ui_layout_zero.xml" value="0.25625" />
<entry key="../../.gradle/caches/transforms-3/fd180e2afb980e83e4951f5e21e58af5/transformed/jetified-agr-sdk-coreui-release-1.7.0/res/layout/agr_item_card.xml" value="0.25625" />
<entry key="..\:/Users/NEW AGE/StudioProjects/shunchaki/app/src/main/res/layout/fragment_billing.xml" value="0.20520833333333333" />
<entry key="app/src/main/res/drawable/bgn_avatar.xml" value="0.25069444444444444" />
<entry key="app/src/main/res/drawable/bgn_lang.xml" value="0.2796296296296296" />
......@@ -117,6 +118,7 @@
<entry key="app/src/main/res/layout/item_ussd.xml" value="0.22" />
<entry key="app/src/main/res/layout/large.xml" value="0.25625" />
<entry key="app/src/main/res/layout/layout_ask_create_task.xml" value="0.22643442622950818" />
<entry key="app/src/main/res/layout/layout_empty.xml" value="0.25625" />
<entry key="app/src/main/res/layout/layout_exit.xml" value="0.25625" />
<entry key="app/src/main/res/layout/layout_home_header.xml" value="0.25625" />
<entry key="app/src/main/res/layout/layout_offline_bottom_sheet.xml" value="0.266051912568306" />
......
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "uz.mobiuz.mobiservice.dev",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0",
"outputFile": "app-release.apk"
}
],
"elementType": "File"
}
\ No newline at end of file
......@@ -11,6 +11,10 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launch
import uz.agr.sdk.core.entity.card.CardInfo
import uz.agr.sdk.core.entity.card.CardRegistration
import uz.agr.sdk.pgw_core.mobi.BaseListener
import uz.agr.sdk.pgw_core.mobi.MobiUz
import javax.inject.Inject
@HiltViewModel
......@@ -99,4 +103,49 @@ class AuthViewModel @Inject constructor(
}
private val _cardConfirmUiState = MutableSharedFlow<UiStateObject<CardInfo>>()
val cardConfirmUiState: SharedFlow<UiStateObject<CardInfo>> = _cardConfirmUiState
fun cardConfirm(cardId: String, code: String) = viewModelScope.launch {
_cardConfirmUiState.emit(UiStateObject.LOADING)
MobiUz.cardConfirmSms(cardId, code, object : BaseListener<CardInfo> {
override fun error(message: String) {
viewModelScope.launch {
_cardConfirmUiState.emit(UiStateObject.ERROR(message))
}
}
override fun loading(boolean: Boolean) {}
override fun success(data: CardInfo) {
viewModelScope.launch {
_cardConfirmUiState.emit(UiStateObject.SUCCESS(data))
}
}
})
}
private val _resendSmsUiState = MutableSharedFlow<UiStateObject<CardRegistration>>()
val resendSmsUiState: SharedFlow<UiStateObject<CardRegistration>> = _resendSmsUiState
fun resendSms(phoneNumber: String, cardNumber: String, cardExpire: String) = viewModelScope.launch {
_resendSmsUiState.emit(UiStateObject.LOADING)
MobiUz.registerCardResendSms(phoneNumber, cardNumber, cardExpire,object : BaseListener<CardRegistration> {
override fun error(message: String) {
viewModelScope.launch {
_resendSmsUiState.emit(UiStateObject.ERROR(message))
}
}
override fun loading(boolean: Boolean) {}
override fun success(data: CardRegistration) {
viewModelScope.launch {
_resendSmsUiState.emit(UiStateObject.SUCCESS(data))
}
}
})
}
}
\ No newline at end of file
package uz.mobiuz.mobiservice.dev.ui.auth.verification
import android.app.Activity
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
......@@ -10,6 +16,7 @@ import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import com.google.android.gms.auth.api.phone.SmsRetriever
import com.google.android.material.textfield.TextInputEditText
import uz.mobiuz.mobiservice.dev.R
import uz.mobiuz.mobiservice.dev.databinding.FragmentVerificationBinding
......@@ -30,6 +37,10 @@ import uz.mobiuz.mobiservice.dev.utils.hideKeyboard
import uz.mobiuz.mobiservice.dev.utils.showKeyboard
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import uz.agr.mobiuz.extension.SmsBroadcastReceiver
import uz.agr.mobiuz.ui.dialog.MessageDialog
import uz.agr.sdk.coreui.extension.hideSoftInput
import java.util.regex.Pattern
import javax.inject.Inject
......@@ -46,17 +57,25 @@ class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
private val navController: NavController by lazy(LazyThreadSafetyMode.NONE) { NavHostFragment.findNavController(this) }
private var verificationCode = ""
private var code = ""
private var phone = ""
private var type = ""
private var smsBroadcastReceiver: SmsBroadcastReceiver? = null
private var cardNumber = ""
private var cardId = ""
private var cardExpire = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
phone = it.getString(CONSTANTS.PHONE) ?: ""
type = it.getString(CONSTANTS.TYPE_VERIFICATION) ?: ""
verificationCode = it.getString(CONSTANTS.PIN_CODE) ?: ""
//card
cardId = it.getString(CONSTANTS.CARD_ID) ?: ""
cardNumber = it.getString(CONSTANTS.CARD_NUMBER) ?: ""
cardExpire = it.getString(CONSTANTS.CARD_EXPIRE) ?: ""
}
}
......@@ -64,6 +83,8 @@ class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
_bn = FragmentVerificationBinding.bind(view)
setUpUI()
count(true)
startSmsUserConsent()
registerBroadcastReceiver()
collects()
}
......@@ -91,18 +112,27 @@ class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
btnVerification.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
getLinePinCodes()
val auth = UserAuth(phone.replace("+", "").replace(" ", ""), null, code)
if (type == CONSTANTS.TYPE_FORGET) {
viewModel.checkResetCode(auth)
} else {
viewModel.verification(auth)
val auth = UserAuth(phone.filter { it.isDigit() }, null, code)
when (type) {
CONSTANTS.TYPE_FORGET -> {
viewModel.checkResetCode(auth)
}
CONSTANTS.TYPE_ADD_CARD -> {
viewModel.cardConfirm(cardId, getLinePinCodes())
}
else -> {
viewModel.verification(auth)
}
}
}
})
sentCodeAgain.setOnClickListener {
viewModel.resetSmsCode(UserAuth(phone.replace("+", "").replace(" ", "")))
if(type == CONSTANTS.TYPE_ADD_CARD){
viewModel.resendSms("998949125150", cardNumber, cardExpire)
}else
viewModel.resetSmsCode(UserAuth(phone.filter { it.isDigit() }))
}
coutdownView.setOnCountdownEndListener {
count(false)
......@@ -111,7 +141,7 @@ class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
}
}
private fun setVerificationCode() {
private fun setVerificationCode(code:String) {
if(verificationCode.length == 6){
bn.apply {
pin1.setText(verificationCode[0].toString())
......@@ -126,7 +156,7 @@ class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
}
}
private fun getLinePinCodes() {
private fun getLinePinCodes() :String{
bn.apply {
code = ""
code += pin1.text.toString()
......@@ -136,6 +166,7 @@ class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
code += pin5.text.toString()
code += pin6.text.toString()
}
return code
}
private fun setColorPins(color: Int) {
......@@ -286,6 +317,47 @@ class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
}
}
}
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
viewModel.cardConfirmUiState.collect {
when (it) {
is UiStateObject.SUCCESS -> {
showProgressDialog(false)
showSuccessDialog()
}
is UiStateObject.ERROR -> {
showProgressDialog(false)
setColorPins(getColorCompat(R.color.primary100))
bn.txtErrorCode.isVisible = true
bn.pinView.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
showToastMessage(it.message)
}
is UiStateObject.LOADING -> {
showProgressDialog(true)
}
else -> Unit
}
}
}
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
viewModel.resendSmsUiState.collect {
when (it) {
is UiStateObject.SUCCESS -> {
showProgressDialog(false)
count(true)
}
is UiStateObject.ERROR -> {
showProgressDialog(false)
}
is UiStateObject.LOADING -> {
showProgressDialog(true)
}
else -> Unit
}
}
}
}
private fun count(status: Boolean) {
......@@ -297,7 +369,68 @@ class VerificationFragment : BaseFragment(R.layout.fragment_verification) {
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
activity?.hideSoftInput(bn.pinView)
if (requestCode == 200) {
if (resultCode == Activity.RESULT_OK && data != null) { //That gives all message to us.
val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
message?.let {
getOtpFromMessage(message)
}
}
}
}
private fun getOtpFromMessage(message: String) { // This will match any 6 digit number in the message
val matcher = Pattern.compile("(|^)\\d{6}").matcher(message)
if (matcher.find()) {
setVerificationCode(matcher.group(0))
// etConfirmCode.setText(matcher.group(0))
}
}
private fun showSuccessDialog() {
val dialog = MessageDialog(
requireContext(),
getString(uz.agr.mobiuz.R.string.agr_mobi_uz_card_added),
getString(uz.agr.mobiuz.R.string.agr_mobi_uz_close_process)
)
dialog.window!!.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.setCanceledOnTouchOutside(true)
dialog.setOnOkClickListener(object : MessageDialog.OnClickListener {
override fun dialogPositiveClicked() {
dialog.dismiss()
navController.popBackStack(R.id.cardsListFragment, false)
}
})
dialog.show()
}
private fun startSmsUserConsent() {
val client = SmsRetriever.getClient(requireContext())
client.startSmsUserConsent(null)
.addOnSuccessListener { /**/ }
.addOnFailureListener { /**/ }
}
private fun registerBroadcastReceiver() {
smsBroadcastReceiver = SmsBroadcastReceiver()
smsBroadcastReceiver!!.smsBroadcastReceiverListener =
object : SmsBroadcastReceiver.SmsBroadcastReceiverListener {
override fun onSuccess(intent: Intent?) {
startActivityForResult(intent, 200)
}
override fun onFailure() {}
}
val intentFilter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION)
requireActivity().registerReceiver(smsBroadcastReceiver, intentFilter)
}
override fun onDestroy() {
requireActivity().unregisterReceiver(smsBroadcastReceiver)
_bn = null
super.onDestroy()
}
......
......@@ -3,6 +3,8 @@ package uz.mobiuz.mobiservice.dev.ui.global
object CONSTANTS {
const val CARD_ID = "CARD_ID"
const val CARD_NUMBER = "CARD_NUMBER"
const val CARD_EXPIRE = "CARD_EXPIRE"
const val UNAUTHORIZED = "UNAUTHORIZED"
const val BASE_URL = "https://mobileapp.mobi.uz/api/v1/"
......@@ -36,7 +38,7 @@ object CONSTANTS {
const val PHONE2 = "+998 97 130 09 09"
const val PHONE3 = "+998 97 203 10 10"
const val DEFAULT_PHONE = "+998 97 999-99-99"
const val RESEND_CODE_TIME = 60000L
const val RESEND_CODE_TIME = 6000L
const val BLOCKED_TIME = 6000
......@@ -46,6 +48,7 @@ object CONSTANTS {
const val REGISTER = "register"
const val TYPE_VERIFICATION = "type_verification"
const val TYPE_FORGET = "type_forget"
const val TYPE_ADD_CARD = "TYPE_ADD_CARD"
const val PIN_CODE = "PIN_CODE"
const val FIRST = "first"
const val SERVICE = "service"
......
......@@ -43,20 +43,7 @@ class BillingFragment : BaseFragment(R.layout.fragment_billing) {
savedCards.setOnClickListener {
getPhoneNumber(object : LoadPhoneNumber {
override fun invoke(phoneNumber: String) {
// navController.navigate(R.id.cardsListFragment, bundleOf(CONSTANTS.PHONE to pref.userPhone.filter { it.isDigit() }))
MobiUz.registerCard("998990552109", "8600312917291250", "0325", object : BaseListener<CardRegistration> {
override fun error(message: String) {
Log.e("TTT", "Error : $message")
}
override fun loading(boolean: Boolean) {
Log.d("TTT", "Loading : $boolean")
}
override fun success(data: CardRegistration) {
Log.d("TTT", "Data: ${data.maskedPhoneNumber}")
}
})
navController.navigate(R.id.cardsListFragment, bundleOf(CONSTANTS.PHONE to pref.userPhone.filter { it.isDigit() }))
}
})
}
......
package uz.mobiuz.mobiservice.dev.ui.sdk.card
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.text.method.DigitsKeyListener
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
......@@ -12,6 +15,7 @@ import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import uz.agr.mobiuz.ui.dialog.MessageDialog
import uz.agr.mobiuz.ui.fast_action.animation.getColorCompat
import uz.agr.sdk.core.entity.card.CardRegistration
import uz.agr.sdk.coreui.extension.hideSoftInput
......@@ -66,12 +70,12 @@ class AddCardFragment : BaseFragment(R.layout.fragment_add_card) {
btnContinue.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
if (cardNumberValid != null && cardExpiryValid != null) {
viewModel.cardRegistration(pref.userPhone.filter { it.isDigit() }, cardNumberValid!!, cardExpiryValid!!)
// viewModel.cardRegistration(pref.userPhone.filter { it.isDigit() }, cardNumberValid!!, cardExpiryValid!!)
viewModel.cardRegistration("998949125150", cardNumberValid!!, cardExpiryValid!!)
}
}
})
}
}
......@@ -82,7 +86,14 @@ class AddCardFragment : BaseFragment(R.layout.fragment_add_card) {
is UiStateObject.SUCCESS -> {
showProgressDialog(false)
showToastMessage("success:${it.data.maskedPhoneNumber}")
navController.navigate(R.id.cardConfirmFragment, bundleOf(CONSTANTS.CARD_ID to it.data.cardId))
navController.navigate(R.id.verificationFragment,
bundleOf(
CONSTANTS.TYPE_VERIFICATION to CONSTANTS.TYPE_ADD_CARD,
CONSTANTS.CARD_ID to it.data.cardId,
CONSTANTS.CARD_NUMBER to cardNumberValid,
CONSTANTS.CARD_EXPIRE to cardExpiryValid,
)
)
}
is UiStateObject.ERROR -> {
......@@ -91,7 +102,6 @@ class AddCardFragment : BaseFragment(R.layout.fragment_add_card) {
}
is UiStateObject.LOADING -> {
showProgressDialog(true)
}
else -> Unit
......@@ -122,7 +132,7 @@ class AddCardFragment : BaseFragment(R.layout.fragment_add_card) {
tvErrorMsg.visible(false)
} else {
etCardNumber.setBackgroundResource(uz.agr.mobiuz.R.drawable.agr_edit_text_error)
etCardNumber.setTextColor(getColorCompat(uz.agr.mobiuz.R.color.primary100))
etCardNumber.setTextColor(getColorCompat(R.color.primary100))
tvErrorMsg.visible(true)
}
checkValidForm()
......
package uz.mobiuz.mobiservice.dev.ui.sdk.card
import android.app.Activity
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import com.google.android.gms.auth.api.phone.SmsRetriever
import com.google.android.material.textfield.TextInputEditText
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import uz.agr.mobiuz.extension.SmsBroadcastReceiver
import uz.agr.mobiuz.ui.dialog.MessageDialog
import uz.agr.mobiuz.ui.fast_action.animation.getColorCompat
import uz.agr.mobiuz.ui.fast_action.animation.showKeyboard
import uz.agr.sdk.coreui.extension.hideSoftInput
import uz.agr.sdk.coreui.extension.visible
import uz.agr.sdk.coreui.ui.ButtonClick
import uz.agr.sdk.coreui.ui.TextWatcherWrapper
import uz.mobiuz.mobiservice.dev.R
import uz.mobiuz.mobiservice.dev.databinding.FragmentCardConfirmBinding
import uz.mobiuz.mobiservice.dev.model.SharedPref
import uz.mobiuz.mobiservice.dev.network.model.UiStateObject
import uz.mobiuz.mobiservice.dev.ui.base.BaseFragment
import uz.mobiuz.mobiservice.dev.ui.global.CONSTANTS
import uz.mobiuz.mobiservice.dev.ui.home.HomeViewModel
import uz.mobiuz.mobiservice.dev.utils.extensions.clearText
import uz.mobiuz.mobiservice.dev.utils.extensions.isEmpty
import uz.mobiuz.mobiservice.dev.utils.extensions.isNotEmpty
import uz.mobiuz.mobiservice.dev.utils.hideKeyboard
import java.util.regex.Pattern
import javax.inject.Inject
@AndroidEntryPoint
......@@ -25,14 +48,23 @@ class CardConfirmFragment : BaseFragment(R.layout.fragment_card_confirm) {
private var _bn: FragmentCardConfirmBinding? = null
private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
private val viewModel: HomeViewModel by viewModels()
private val viewModel: CardViewModel by viewModels()
private val navController: NavController by lazy(LazyThreadSafetyMode.NONE) { NavHostFragment.findNavController(this) }
private var smsBroadcastReceiver: SmsBroadcastReceiver? = null
private var cardNumber = ""
private var cardId = ""
private var cardExpire = ""
// private val phoneNumber: String by argument(CardConfirmFragment.ARG_PHONE_NUMBER)
// private val maskedPhoneNumber: String by argument(CardConfirmFragment.ARG_MASKED_PHONE_NUMBER)
private var code = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
cardId = it.getString(CONSTANTS.CARD_ID) ?: ""
cardNumber = it.getString(CONSTANTS.CARD_NUMBER) ?: ""
cardExpire = it.getString(CONSTANTS.CARD_EXPIRE) ?: ""
}
}
......@@ -41,41 +73,264 @@ class CardConfirmFragment : BaseFragment(R.layout.fragment_card_confirm) {
_bn = FragmentCardConfirmBinding.bind(view)
setUpUI()
count(true)
startSmsUserConsent()
registerBroadcastReceiver()
collects()
}
override fun setUpUI() {
bn.apply {
btnResend.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
// viewModel.resendSms(pref.userPhone.filter { it.isDigit() },cardNumber,cardExpire)
viewModel.resendSms("998949125150", cardNumber, cardExpire)
}
})
btnConfirm.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
viewModel.cardConfirm(cardId, getLinePinCodes())
}
})
toolbar.setNavigationOnClickListener { navController.navigateUp() }
loadEdited()
frame.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
checkFocus().showKeyboard()
setColorPins(getColorCompat(R.color.black100))
}
})
coutdownView.setOnCountdownEndListener {
count(false)
}
}
}
private fun count(status: Boolean) {
bn.apply {
btnResend.isVisible = !status
coutdownViewHelperText.isVisible = !status
coutdownView.isVisible = status
if (status) coutdownView.start(CONSTANTS.RESEND_CODE_TIME)
}
}
override fun collects() {
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
viewModel.mainIndexUiState.collect {
viewModel.cardConfirmUiState.collect {
when (it) {
is UiStateObject.SUCCESS -> {
showProgressDialog(false)
showSuccessDialog()
}
is UiStateObject.ERROR -> {
showProgressDialog(false)
setColorPins(getColorCompat(R.color.primary100))
bn.txtErrorCode.isVisible = true
bn.pinView.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
showToastMessage(it.message)
}
is UiStateObject.LOADING -> {
showProgressDialog(true)
}
else -> Unit
}
}
}
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
viewModel.resendSmsUiState.collect {
when (it) {
is UiStateObject.SUCCESS -> {
showProgressDialog(false)
count(true)
}
is UiStateObject.ERROR -> {
showProgressDialog(false)
}
is UiStateObject.LOADING -> {
showProgressDialog(true)
}
else -> Unit
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
activity?.hideSoftInput(bn.etConfirmCode)
if (requestCode == 200) {
if (resultCode == Activity.RESULT_OK && data != null) { //That gives all message to us.
val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
message?.let {
getOtpFromMessage(message)
}
}
}
}
private fun getOtpFromMessage(message: String) { // This will match any 6 digit number in the message
val matcher = Pattern.compile("(|^)\\d{6}").matcher(message)
if (matcher.find()) {
setTextPinCodes(matcher.group(0))
// etConfirmCode.setText(matcher.group(0))
}
}
private fun showSuccessDialog() {
val dialog = MessageDialog(
requireContext(),
getString(uz.agr.mobiuz.R.string.agr_mobi_uz_card_added),
getString(uz.agr.mobiuz.R.string.agr_mobi_uz_close_process)
)
dialog.window!!.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.setCanceledOnTouchOutside(true)
dialog.setOnOkClickListener(object : MessageDialog.OnClickListener {
override fun dialogPositiveClicked() {
dialog.dismiss()
navController.popBackStack(R.id.cardsListFragment, false)
}
})
dialog.show()
}
private fun getLinePinCodes(): String {
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()
}
return code.filter { it.isDigit() }
}
private fun setColorPins(color: Int) {
bn.apply {
pin1.setTextColor(color)
pin2.setTextColor(color)
pin3.setTextColor(color)
pin4.setTextColor(color)
pin5.setTextColor(color)
pin6.setTextColor(color)
}
}
private fun checkFocus(): View {
bn.apply {
return when {
pin1.isEmpty() -> pin1
pin2.isEmpty() -> pin2
pin3.isEmpty() -> pin3
pin4.isEmpty() -> pin4
pin5.isEmpty() -> pin5
else -> pin6
}
}
}
private fun clearLatest(): View {
bn.apply {
return when {
pin6.isNotEmpty() -> pin6.clearText()
pin5.isNotEmpty() -> pin5.clearText()
pin4.isNotEmpty() -> pin4.clearText()
pin3.isNotEmpty() -> pin3.clearText()
pin2.isNotEmpty() -> pin2.clearText()
else -> pin1.clearText()
}
}
}
private fun setTextPinCodes(code: String) {
bn.apply {
if (code.length != 6) return
pin1.setText(code[0].toString())
pin2.setText(code[1].toString())
pin3.setText(code[2].toString())
pin4.setText(code[3].toString())
pin5.setText(code[4].toString())
pin6.setText(code[5].toString())
}
}
private fun loadEdited() {
bn.apply {
for (i in 0 until pinView.childCount) {
(pinView.getChildAt(i) as TextInputEditText).apply {
this.addTextChangedListener(object : TextWatcherWrapper() {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
bn.txtErrorCode.isVisible = false
txtErrorCode.visible(false)
if (s.toString().isNotEmpty()) {
if (i == pinView.childCount - 1) {
pin6.hideKeyboard()
btnConfirm.isEnabled = true
} else pinView.getChildAt(i + 1).requestFocus()
this@apply.setBackgroundResource(uz.agr.mobiuz.R.drawable.agr_bgn_ver_checked)
} else {
if (i == pinView.childCount - 1) {
btnConfirm.isEnabled = false
}
this@apply.setBackgroundResource(uz.agr.mobiuz.R.drawable.agr_bgn_ver_unchecked)
}
}
})
}
}
for (i in 0 until pinView.childCount) {
pinView.getChildAt(i).setOnKeyListener { _, keyCode, event ->
if (event.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_DEL) {
clearLatest().requestFocus()
return@setOnKeyListener false
}
else -> Unit
false
}
}
}
}
private fun startSmsUserConsent() {
val client = SmsRetriever.getClient(requireContext())
client.startSmsUserConsent(null)
.addOnSuccessListener { /**/ }
.addOnFailureListener { /**/ }
}
private fun registerBroadcastReceiver() {
smsBroadcastReceiver = SmsBroadcastReceiver()
smsBroadcastReceiver!!.smsBroadcastReceiverListener =
object : SmsBroadcastReceiver.SmsBroadcastReceiverListener {
override fun onSuccess(intent: Intent?) {
startActivityForResult(intent, 200)
}
override fun onFailure() {}
}
val intentFilter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION)
context?.registerReceiver(smsBroadcastReceiver, intentFilter)
}
override fun onDestroy() {
requireActivity().unregisterReceiver(smsBroadcastReceiver)
_bn = null
super.onDestroy()
}
......
......@@ -7,18 +7,19 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.hannesdorfmann.adapterdelegates4.AdapterDelegate
import kotlinx.android.synthetic.main.mobi_uz_item_card.view.*
import timber.log.Timber
import uz.agr.sdk.core.entity.card.CardInfo
import uz.agr.sdk.coreui.extension.*
import uz.agr.sdk.coreui.model.storage.Prefs
import uz.mobiuz.mobiservice.dev.R
import uz.mobiuz.mobiservice.dev.utils.LayoutContainer
import uz.mobiuz.mobiservice.dev.utils.extensions.MultiBlock
class CardDelegate(
private val hideSettingsIcon: (Boolean),
private val clickListener: (CardInfo, Int) -> Unit
) : AdapterDelegate<MutableList<Any>>() {
private var listener: MultiBlock<CardInfo, Int>? = null
private var amount: Long = 0L
private var cardsList: List<String> = emptyList()
......@@ -42,7 +43,7 @@ class CardDelegate(
return (viewHolder as ViewHolder).bind(items[position] as CardInfo, position)
}
private inner class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer {
private inner class ViewHolder(val containerView: View) : RecyclerView.ViewHolder(containerView) {
private lateinit var cardInfo: CardInfo
init {
......@@ -60,7 +61,7 @@ class CardDelegate(
}
if (!hideSettingsIcon) {
containerView.btnSetting.setOnClickListener {
clickListener(cardInfo, adapterPosition)
listener?.invoke(cardInfo, adapterPosition)
}
}
containerView.btnSetting.visible(!hideSettingsIcon)
......@@ -70,12 +71,10 @@ class CardDelegate(
fun bind(cardInfo: CardInfo, position: Int) {
this.cardInfo = cardInfo
containerView.tvCardBalance.text = cardInfo.balance.formattedMoney() + " " + containerView.context.getString(R.string.agr_mobi_uz_curr)
containerView.tvCardBalance.text = cardInfo.balance.formattedMoney() + " " + itemView.context.getString(R.string.agr_mobi_uz_curr)
containerView.tvCardPan.text = cardInfo.pan.formatToMaskedCardPan()
containerView.tvCardExpire.text = cardInfo.getExpiryFormatted()
containerView.tvCardHolderName.text = cardInfo.fullName
Timber.e("PAN: ${cardInfo.pan}")
Timber.e("EXpire: ${cardInfo.expiry}")
val isUzCard = cardInfo.pan.startsWith("8600")
val isHumoCard = cardInfo.pan.startsWith("9860")
if (isHumoCard) {
......@@ -89,7 +88,7 @@ class CardDelegate(
private fun itemClicked() {
if (amount <= cardInfo.balance)
clickListener(cardInfo, adapterPosition)
listener?.invoke(cardInfo, adapterPosition)
else showError()
}
......@@ -103,4 +102,8 @@ class CardDelegate(
dialog.show()
}
}
fun setOnClickListener(block: MultiBlock<CardInfo, Int>) {
listener = block
}
}
\ No newline at end of file
package uz.mobiuz.mobiservice.dev.ui.sdk.card
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launch
import uz.agr.sdk.core.entity.card.CardInfo
import uz.agr.sdk.core.entity.card.CardRegistration
import uz.agr.sdk.pgw_core.mobi.BaseListener
import uz.agr.sdk.pgw_core.mobi.CardListenerMobi
import uz.agr.sdk.pgw_core.mobi.MobiUz
import uz.mobiuz.mobiservice.dev.network.model.UiStateList
import uz.mobiuz.mobiservice.dev.network.model.UiStateObject
import uz.mobiuz.mobiservice.dev.network.repository.MainRepository
import javax.inject.Inject
......@@ -19,29 +21,95 @@ class CardViewModel @Inject constructor(
private val repository: MainRepository
) : ViewModel() {
private val _cardListUiState = MutableSharedFlow<UiStateList<CardInfo>>()
val cardListUiState: SharedFlow<UiStateList<CardInfo>> = _cardListUiState
fun getAllCards() = viewModelScope.launch {
_cardListUiState.emit(UiStateList.LOADING)
MobiUz.getAllCards(object : CardListenerMobi<CardInfo> {
override fun error(message: String) {
viewModelScope.launch {
_cardListUiState.emit(UiStateList.ERROR(message))
}
}
override fun loading(boolean: Boolean) {}
override fun local(localData: List<CardInfo>) {
viewModelScope.launch {
_cardListUiState.emit(UiStateList.SUCCESS(localData))
}
}
override fun server(serverData: List<CardInfo>) {
viewModelScope.launch {
_cardListUiState.emit(UiStateList.SUCCESS(serverData))
}
}
})
}
private val _cardRegistrationUiState = MutableSharedFlow<UiStateObject<CardRegistration>>()
val cardRegistrationUiState: SharedFlow<UiStateObject<CardRegistration>> = _cardRegistrationUiState
fun cardRegistration(phone: String, card: String, expire: String) = viewModelScope.launch {
_cardRegistrationUiState.emit(UiStateObject.LOADING)
MobiUz.registerCard(phone, card, expire, object : BaseListener<CardRegistration> {
override fun error(message: String) {
Log.d("TAG", "error: ")
viewModelScope.launch {
_cardRegistrationUiState.emit(UiStateObject.ERROR(message))
}
}
override fun loading(boolean: Boolean) {
Log.d("TAG", "loading: $boolean ")
override fun loading(boolean: Boolean) {}
override fun success(data: CardRegistration) {
viewModelScope.launch {
_cardRegistrationUiState.emit(UiStateObject.LOADING)
_cardRegistrationUiState.emit(UiStateObject.SUCCESS(data))
}
}
})
}
private val _cardConfirmUiState = MutableSharedFlow<UiStateObject<CardInfo>>()
val cardConfirmUiState: SharedFlow<UiStateObject<CardInfo>> = _cardConfirmUiState
fun cardConfirm(cardId: String, code: String) = viewModelScope.launch {
_cardConfirmUiState.emit(UiStateObject.LOADING)
MobiUz.cardConfirmSms(cardId, code, object : BaseListener<CardInfo> {
override fun error(message: String) {
viewModelScope.launch {
_cardConfirmUiState.emit(UiStateObject.ERROR(message))
}
}
override fun loading(boolean: Boolean) {}
override fun success(data: CardInfo) {
viewModelScope.launch {
_cardConfirmUiState.emit(UiStateObject.SUCCESS(data))
}
}
})
}
private val _resendSmsUiState = MutableSharedFlow<UiStateObject<CardRegistration>>()
val resendSmsUiState: SharedFlow<UiStateObject<CardRegistration>> = _resendSmsUiState
fun resendSms(phoneNumber: String, cardNumber: String, cardExpire: String) = viewModelScope.launch {
_resendSmsUiState.emit(UiStateObject.LOADING)
MobiUz.registerCardResendSms(phoneNumber, cardNumber, cardExpire,object : BaseListener<CardRegistration> {
override fun error(message: String) {
viewModelScope.launch {
_resendSmsUiState.emit(UiStateObject.ERROR(message))
}
}
override fun loading(boolean: Boolean) {}
override fun success(data: CardRegistration) {
Log.d("TAG", "success: ${data.maskedPhoneNumber} ")
viewModelScope.launch {
_cardRegistrationUiState.emit(UiStateObject.SUCCESS(data))
_resendSmsUiState.emit(UiStateObject.SUCCESS(data))
}
}
})
......
......@@ -2,27 +2,25 @@ package uz.mobiuz.mobiservice.dev.ui.sdk.card
import androidx.recyclerview.widget.DiffUtil
import com.hannesdorfmann.adapterdelegates4.ListDelegationAdapter
import uz.agr.mobiuz.ui.card.select.CardDelegate
import uz.agr.sdk.core.entity.card.CardInfo
import uz.agr.sdk.coreui.ui.list.ProgressAdapterDelegate
import uz.agr.sdk.coreui.ui.list.ProgressItem
import uz.mobiuz.mobiservice.dev.utils.extensions.MultiBlock
import uz.mobiuz.mobiservice.dev.utils.extensions.SingleBlock
class CardsListAdapter(
hideSettingsIcon: (Boolean),
clickListener: (CardInfo, Int) -> Unit
private val hideSettingsIcon: Boolean,
) : ListDelegationAdapter<MutableList<Any>>() {
// private var listener: MultiBlock<CardInfo,Int>? = null
//
// fun setOnClickListener(block: MultiBlock<CardInfo,Int>){
// listener = block
// }
private var listener: MultiBlock<CardInfo, Int>? = null
init {
items = mutableListOf()
delegatesManager.addDelegate(CardDelegate(hideSettingsIcon, clickListener))
val delegateAdapter = CardDelegate(hideSettingsIcon)
delegateAdapter.setOnClickListener { cardInfo, i ->
listener?.invoke(cardInfo,i)
}
delegatesManager.addDelegate(delegateAdapter)
delegatesManager.addDelegate(ProgressAdapterDelegate())
}
......@@ -86,4 +84,8 @@ class CardsListAdapter(
}
}
}
fun setOnClickListener(block: MultiBlock<CardInfo, Int>) {
listener = block
}
}
\ No newline at end of file
package uz.mobiuz.mobiservice.dev.ui.sdk.card
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import uz.agr.mobiuz.presentation.card.dialog.MessageDialogFragment
import uz.agr.sdk.core.entity.card.CardInfo
import uz.agr.sdk.core.entity.card.CardRegistration
import uz.agr.sdk.coreui.extension.formattedCardNumber
import uz.agr.sdk.coreui.extension.visible
import uz.agr.sdk.coreui.ui.decoration.EndOffsetItemDecoration
import uz.agr.sdk.coreui.ui.decoration.StartOffsetItemDecoration
import uz.agr.sdk.pgw_core.mobi.BaseListener
import uz.agr.sdk.pgw_core.mobi.CardListenerMobi
import uz.agr.sdk.pgw_core.mobi.MobiUz
import uz.mobiuz.mobiservice.dev.R
import uz.mobiuz.mobiservice.dev.databinding.FragmentCardsListBinding
import uz.mobiuz.mobiservice.dev.model.SharedPref
import uz.mobiuz.mobiservice.dev.network.model.UiStateList
import uz.mobiuz.mobiservice.dev.ui.base.BaseFragment
import uz.mobiuz.mobiservice.dev.ui.global.CONSTANTS
import javax.inject.Inject
......@@ -30,11 +39,14 @@ class CardsListFragment : BaseFragment(R.layout.fragment_cards_list) {
private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
private val viewModel: CardViewModel by viewModels()
private val navController: NavController by lazy(LazyThreadSafetyMode.NONE) { NavHostFragment.findNavController(this) }
private var phone = ""
private var selectedCard: CardInfo? = null
private lateinit var adapter: CardsListAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
adapter = CardsListAdapter(false)
arguments?.let {
phone = it.getString(CONSTANTS.PHONE) ?: ""
}
......@@ -44,14 +56,20 @@ class CardsListFragment : BaseFragment(R.layout.fragment_cards_list) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
_bn = FragmentCardsListBinding.bind(view)
viewModel.getAllCards()
setUpUI()
collects()
}
override fun setUpUI() {
bn.apply {
adapter.setOnClickListener { cardInfo, i ->
onCardClicked(cardInfo)
}
toolbar.setNavigationOnClickListener {
navController.navigateUp()
}
......@@ -60,99 +78,186 @@ class CardsListFragment : BaseFragment(R.layout.fragment_cards_list) {
// addCard()
navController.navigate(R.id.addCardFragment)
}
}
MobiUz.hasCards(object : BaseListener<Boolean> {
override fun error(message: String) {
}
override fun loading(boolean: Boolean) {
}
override fun success(data: Boolean) {
getAllCards()
recyclerView.apply {
layoutManager = LinearLayoutManager(context)
setHasFixedSize(true)
adapter = this@CardsListFragment.adapter
visible(false)
}
})
}
private fun getAllCards() {
MobiUz.getAllCards(object : CardListenerMobi<CardInfo> {
override fun error(message: String) {
}
override fun loading(boolean: Boolean) {
}
override fun local(localData: List<CardInfo>) {
recyclerView.addItemDecoration(
StartOffsetItemDecoration(
resources.getDimensionPixelOffset(
uz.agr.mobiuz.R.dimen.agr_card_list_start_offset
)
)
)
recyclerView.addItemDecoration(
EndOffsetItemDecoration(
resources.getDimensionPixelOffset(
uz.agr.mobiuz.R.dimen.agr_card_list_end_offset
)
)
)
swipeToRefresh.setColorSchemeResources(
uz.agr.mobiuz.R.color.agr_black,
uz.agr.mobiuz.R.color.agr_mobi_uz_colorAccent
)
swipeToRefresh.setOnRefreshListener {
MobiUz.refreshCardsInfo(object : BaseListener<List<CardInfo>>{
override fun error(message: String) {
showToastMessage(message)
}
override fun loading(boolean: Boolean) {
swipeToRefresh.isRefreshing = boolean
}
override fun success(data: List<CardInfo>) {
setData(data)
}
})
}
}
override fun server(serverData: List<CardInfo>) {
}
})
}
private fun addCard() {
MobiUz.registerCard("998990552109", "8600312917291250", "0325", object : BaseListener<CardRegistration> {
override fun error(message: String) {
Log.e("TTT", "error:$message")
}
override fun loading(boolean: Boolean) {
Log.e("TTT", "loading:$boolean")
}
override fun success(data: CardRegistration) {
Log.e("TTT", "success:${data.maskedPhoneNumber}")
}
})
private fun onCardClicked(cardInfo: CardInfo) {
selectedCard = cardInfo
showDeleteCardConfirmDialog(cardInfo.pan.formattedCardNumber())
}
private fun cardConfirm(cardId: String, code: String) {
MobiUz.cardConfirmSms(cardId, code, object : BaseListener<CardInfo> {
override fun error(message: String) {
private fun showDeleteCardConfirmDialog(cardNumber: String) {
val dialog = MessageDialogFragment(requireContext(), getString(uz.agr.mobiuz.R.string.agr_mobi_uz_delete_card_question))
dialog.window!!.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.setCanceledOnTouchOutside(true)
dialog.setOnCancelClickListener {
dialog.dismiss()
}
dialog.setOnOkClickListener {
MobiUz.deleteCard(selectedCard!!,object : BaseListener<Boolean>{
override fun error(message: String) {
}
}
override fun loading(boolean: Boolean) {
override fun loading(boolean: Boolean) {
// showProgressDialog(boolean)
}
}
override fun success(data: Boolean) {
viewModel.getAllCards()
}
})
dialog.dismiss()
}
dialog.show()
}
override fun success(data: CardInfo) {
}
})
}
// private fun hasCards() {
// MobiUz.hasCards(object : BaseListener<Boolean> {
// override fun error(message: String) {
//
// }
//
// override fun loading(boolean: Boolean) {
//
// }
//
// override fun success(data: Boolean) {
// getAllCards()
// }
// })
// }
//
// private fun getAllCards() {
// MobiUz.getAllCards(object : CardListenerMobi<CardInfo> {
// override fun error(message: String) {
//
// }
//
// override fun loading(boolean: Boolean) {
//
// }
//
// override fun local(localData: List<CardInfo>) {
// setData(localData)
// }
//
// override fun server(serverData: List<CardInfo>) {
// setData(serverData)
// }
// })
// }
private fun delete(card: CardInfo) {
MobiUz.deleteCard(card)
private fun setData(data: List<CardInfo>) {
bn.recyclerView.isVisible = data.isNotEmpty()
bn.layoutEmpty.root.isVisible = data.isEmpty()
adapter.setData(data)
}
override fun collects() {
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
// viewModel.mainIndexUiState.collect {
// when (it) {
// is UiStateObject.SUCCESS -> {
// private fun addCard() {
// MobiUz.registerCard("998990552109", "8600312917291250", "0325", object : BaseListener<CardRegistration> {
// override fun error(message: String) {
// Log.e("TTT", "error:$message")
// }
//
// override fun loading(boolean: Boolean) {
// Log.e("TTT", "loading:$boolean")
// }
//
// }
// is UiStateObject.ERROR -> {
// override fun success(data: CardRegistration) {
// Log.e("TTT", "success:${data.maskedPhoneNumber}")
// }
// })
// }
//
// private fun cardConfirm(cardId: String, code: String) {
// MobiUz.cardConfirmSms(cardId, code, object : BaseListener<CardInfo> {
// override fun error(message: String) {
//
// }
// is UiStateObject.LOADING -> {
// }
//
// override fun loading(boolean: Boolean) {
//
// }
//
// override fun success(data: CardInfo) {
//
// }
// else -> Unit
// }
// }
// })
//
//
// }
//
// private fun delete(card: CardInfo) {
// MobiUz.deleteCard(card)
// }
override fun collects() {
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
viewModel.cardListUiState.collect {
when (it) {
is UiStateList.SUCCESS -> {
showProgressDialog(false)
setData(it.data)
}
is UiStateList.ERROR -> {
showToastMessage(it.message)
showProgressDialog(false)
}
is UiStateList.LOADING -> {
showProgressDialog(true)
}
else -> Unit
}
}
}
......
......@@ -126,7 +126,7 @@
android:layout_gravity="bottom"
android:layout_marginHorizontal="16dp"
android:layout_marginBottom="40dp"
android:enabled="false"
android:enabled="true"
android:text="@string/agr_mobi_uz_add_card"
android:textStyle="bold" />
</LinearLayout>
......@@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:layout_height="match_parent"
android:orientation="vertical">
......@@ -130,45 +131,85 @@
android:visibility="gone"
tools:ignore="Autofill,LabelFor" />
<TextView
android:id="@+id/tvTimeOut"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="32dp"
android:layout_marginTop="64dp"
android:layout_marginRight="32dp"
android:gravity="center"
android:textColor="@color/agr_grey110"
android:textSize="14sp"
tools:text="@string/agr_mobi_uz_sms_time_out_info" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="28dp"
android:layout_gravity="center"
android:layout_marginTop="@dimen/_34sdp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/pin_view_group">
<TextView
android:id="@+id/countWaitText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/sent_code_again"
android:textColor="@color/grey110"
android:textSize="16sp" />
<cn.iwgang.countdownview.CountdownView
android:id="@+id/coutdown_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="@dimen/_4sdp"
android:layout_marginTop="2dp"
app:isHideTimeBackground="false"
app:isShowDay="false"
app:isShowHour="false"
app:isShowMillisecond="false"
app:isShowMinute="true"
app:isShowSecond="true"
app:isShowTimeBgBorder="false"
app:isShowTimeBgDivisionLine="false"
app:suffixDay="days"
app:suffixGravity="center"
app:suffixHour=":"
app:suffixMillisecond="ss"
app:suffixMinute=":"
app:suffixSecond=""
app:suffixTextColor="@color/grey100"
app:suffixTextSize="14sp"
app:timeBgColor="@color/white100"
app:timeBgRadius="3dp"
app:timeBgSize="14dp"
app:timeTextSize="14sp" />
<TextView
android:id="@+id/coutdown_view_helper_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="@dimen/_4sdp"
android:text="00:00"
android:textColor="@color/primary100"
android:textSize="16sp"
android:visibility="gone" />
</LinearLayout>
<Button
android:id="@+id/btnConfirm"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_gravity="bottom"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="51dp"
android:background="@drawable/button_selector"
android:enabled="false"
android:text="@string/agr_mobi_uz_next"
android:textAllCaps="false"
android:textColor="@color/agr_white"
android:textSize="15sp"
android:textStyle="bold" />
android:text="@string/agr_mobi_uz_next" />
<Button
<TextView
android:id="@+id/btnResend"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:background="?android:selectableItemBackground"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingVertical="16dp"
android:layout_gravity="center_horizontal"
android:layout_marginStart="16dp"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:text="@string/agr_mobi_uz_sms_resend"
android:textAllCaps="false"
android:textColor="@color/primary100"
android:textSize="14sp"
android:textStyle="bold"
......
......@@ -33,13 +33,15 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:visibility="visible"
android:layout_height="match_parent"
tools:listitem="@layout/agr_item_card"
tools:listitem="@layout/mobi_uz_item_card"
tools:paddingTop="@dimen/agr_card_list_start_offset" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<include
layout="@layout/agr_layout_empty"
android:id="@+id/layout_empty"
layout="@layout/layout_empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
......
......@@ -4,6 +4,7 @@
android:id="@+id/view_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<com.google.android.material.appbar.MaterialToolbar
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/emptyLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/agr_white">
<Space
android:id="@+id/spaceTop"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/agr_white"
app:layout_constraintBottom_toTopOf="@id/ivNoCard"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintVertical_weight="1" />
<ImageView
android:id="@+id/ivNoCard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/_25sdp"
android:contentDescription="@null"
app:layout_constraintBottom_toTopOf="@id/tvNoCard"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/ic_agr_no_cards" />
<TextView
android:id="@+id/tvNoCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:letterSpacing="0.05"
android:lineSpacingExtra="2dp"
android:layout_marginHorizontal="@dimen/_30sdp"
android:text="@string/agr_mobi_uz_no_card"
android:textColor="@color/agr_grey80"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Space
android:id="@+id/spaceBottom"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvNoCard"
app:layout_constraintVertical_weight="1.3" />
</androidx.constraintlayout.widget.ConstraintLayout>
......@@ -4,8 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginHorizontal="16dp"
android:layout_marginBottom="@dimen/_8sdp"
app:cardCornerRadius="@dimen/_6sdp">
......@@ -143,5 +142,9 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tvCardBalance"
app:srcCompat="@drawable/ic_mobi_uz_delete" />
<View
android:layout_width="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_height="1dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
\ No newline at end of file
......@@ -82,8 +82,13 @@
android:label="AddCardFragment" />
<fragment
android:id="@+id/cardConfirmFragment"
tools:layout=""
tools:layout="@layout/fragment_card_confirm"
android:name="uz.mobiuz.mobiservice.dev.ui.sdk.card.CardConfirmFragment"
android:label="CardConfirmFragment" />
<fragment
android:id="@+id/verificationFragment"
android:name="uz.mobiuz.mobiservice.dev.ui.auth.verification.VerificationFragment"
android:label="MyVerificationFragment" />
</navigation>
\ 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