Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
shunchaki
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Shohboz Qoraboev
shunchaki
Commits
46cfb422
Commit
46cfb422
authored
Jan 06, 2022
by
shohboz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[UPD]
MUS-288
, Feature, updated add card
parent
ff55e2e3
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
913 additions
and
167 deletions
+913
-167
misc.xml
.idea/misc.xml
+2
-0
agr-sdk-pgw-core-release-1.7.0.aar
app/aars/agr-sdk-pgw-core-release-1.7.0.aar
+0
-0
MobiUz.apk
app/release/MobiUz.apk
+0
-0
output-metadata.json
app/release/output-metadata.json
+20
-0
AuthViewModel.kt
...n/java/uz/mobiuz/mobiservice/dev/ui/auth/AuthViewModel.kt
+49
-0
VerificationFragment.kt
...iservice/dev/ui/auth/verification/VerificationFragment.kt
+143
-10
CONSTANTS.kt
...ain/java/uz/mobiuz/mobiservice/dev/ui/global/CONSTANTS.kt
+4
-1
BillingFragment.kt
...java/uz/mobiuz/mobiservice/dev/ui/home/BillingFragment.kt
+1
-14
AddCardFragment.kt
.../uz/mobiuz/mobiservice/dev/ui/sdk/card/AddCardFragment.kt
+15
-5
CardConfirmFragment.kt
...mobiuz/mobiservice/dev/ui/sdk/card/CardConfirmFragment.kt
+261
-6
CardDelegate.kt
...ava/uz/mobiuz/mobiservice/dev/ui/sdk/card/CardDelegate.kt
+12
-9
CardViewModel.kt
...va/uz/mobiuz/mobiservice/dev/ui/sdk/card/CardViewModel.kt
+75
-7
CardsListAdapter.kt
...uz/mobiuz/mobiservice/dev/ui/sdk/card/CardsListAdapter.kt
+12
-10
CardsListFragment.kt
...z/mobiuz/mobiservice/dev/ui/sdk/card/CardsListFragment.kt
+178
-73
fragment_add_card.xml
app/src/main/res/layout/fragment_add_card.xml
+1
-1
fragment_card_confirm.xml
app/src/main/res/layout/fragment_card_confirm.xml
+67
-26
fragment_cards_list.xml
app/src/main/res/layout/fragment_cards_list.xml
+4
-2
fragment_verification.xml
app/src/main/res/layout/fragment_verification.xml
+1
-0
layout_empty.xml
app/src/main/res/layout/layout_empty.xml
+57
-0
mobi_uz_item_card.xml
app/src/main/res/layout/mobi_uz_item_card.xml
+5
-2
nav_graph_home.xml
app/src/main/res/navigation/nav_graph_home.xml
+6
-1
No files found.
.idea/misc.xml
View file @
46cfb422
...
...
@@ -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"
/>
...
...
app/aars/agr-sdk-pgw-core-release-1.7.0.aar
View file @
46cfb422
No preview for this file type
app/release/MobiUz.apk
0 → 100644
View file @
46cfb422
File added
app/release/output-metadata.json
0 → 100644
View file @
46cfb422
{
"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
app/src/main/java/uz/mobiuz/mobiservice/dev/ui/auth/AuthViewModel.kt
View file @
46cfb422
...
...
@@ -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
app/src/main/java/uz/mobiuz/mobiservice/dev/ui/auth/verification/VerificationFragment.kt
View file @
46cfb422
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
()
}
...
...
app/src/main/java/uz/mobiuz/mobiservice/dev/ui/global/CONSTANTS.kt
View file @
46cfb422
...
...
@@ -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
=
6000
0
L
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"
...
...
app/src/main/java/uz/mobiuz/mobiservice/dev/ui/home/BillingFragment.kt
View file @
46cfb422
...
...
@@ -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
()
}))
}
})
}
...
...
app/src/main/java/uz/mobiuz/mobiservice/dev/ui/sdk/card/AddCardFragment.kt
View file @
46cfb422
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
()
...
...
app/src/main/java/uz/mobiuz/mobiservice/dev/ui/sdk/card/CardConfirmFragment.kt
View file @
46cfb422
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
:
Home
ViewModel
by
viewModels
()
private
val
viewModel
:
Card
ViewModel
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
.
mainIndex
UiState
.
collect
{
viewModel
.
cardConfirm
UiState
.
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
()
}
...
...
app/src/main/java/uz/mobiuz/mobiservice/dev/ui/sdk/card/CardDelegate.kt
View file @
46cfb422
...
...
@@ -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
()
+
" "
+
container
View
.
context
.
getString
(
R
.
string
.
agr_mobi_uz_curr
)
containerView
.
tvCardBalance
.
text
=
cardInfo
.
balance
.
formattedMoney
()
+
" "
+
item
View
.
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
app/src/main/java/uz/mobiuz/mobiservice/dev/ui/sdk/card/CardViewModel.kt
View file @
46cfb422
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
{
_
cardRegistration
UiState
.
emit
(
UiStateObject
.
SUCCESS
(
data
))
_
resendSms
UiState
.
emit
(
UiStateObject
.
SUCCESS
(
data
))
}
}
})
...
...
app/src/main/java/uz/mobiuz/mobiservice/dev/ui/sdk/card/CardsListAdapter.kt
View file @
46cfb422
...
...
@@ -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
app/src/main/java/uz/mobiuz/mobiservice/dev/ui/sdk/card/CardsListFragment.kt
View file @
46cfb422
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
}
}
}
...
...
app/src/main/res/layout/fragment_add_card.xml
View file @
46cfb422
...
...
@@ -126,7 +126,7 @@
android:layout_gravity=
"bottom"
android:layout_marginHorizontal=
"16dp"
android:layout_marginBottom=
"40dp"
android:enabled=
"
fals
e"
android:enabled=
"
tru
e"
android:text=
"@string/agr_mobi_uz_add_card"
android:textStyle=
"bold"
/>
</LinearLayout>
app/src/main/res/layout/fragment_card_confirm.xml
View file @
46cfb422
...
...
@@ -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.Colore
d"
android:background=
"?android:selectableItemBackgroun
d"
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_margin
Start
=
"16dp"
android:layout_margin
Horizontal
=
"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"
...
...
app/src/main/res/layout/fragment_cards_list.xml
View file @
46cfb422
...
...
@@ -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"
/>
...
...
app/src/main/res/layout/fragment_verification.xml
View file @
46cfb422
...
...
@@ -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
...
...
app/src/main/res/layout/layout_empty.xml
0 → 100644
View file @
46cfb422
<?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>
app/src/main/res/layout/mobi_uz_item_card.xml
View file @
46cfb422
...
...
@@ -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
app/src/main/res/navigation/nav_graph_home.xml
View file @
46cfb422
...
...
@@ -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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment