Commit be371d26 authored by shohboz's avatar shohboz

[UPD] MUS-278 Feature, updated biometric check and add roaming and other changes

parent df4b3022
......@@ -66,7 +66,14 @@ dependencies {
// Firebase
implementation 'com.google.firebase:firebase-core:20.0.1'
implementation 'com.google.firebase:firebase-core:20.0.2'
// Import the BoM for the Firebase platform
implementation platform('com.google.firebase:firebase-bom:29.0.3')
// Declare the dependencies for the Crashlytics and Analytics libraries
// When using the BoM, you don't specify versions in Firebase library dependencies
implementation 'com.google.firebase:firebase-crashlytics-ktx'
implementation 'com.google.firebase:firebase-analytics-ktx'
// Navigation
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
......
......@@ -79,6 +79,7 @@ class MainActivity : AppCompatActivity() {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
FirebaseApp.initializeApp(this@MainActivity)
// throw java.lang.NullPointerException("cannot")
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this@MainActivity)
FirebaseMessaging.getInstance().token.addOnCompleteListener {
......@@ -165,11 +166,19 @@ class MainActivity : AppCompatActivity() {
}
})
txtRedactData.setOnClickListener {
navigateUri(CONSTANTS.MAIN_URL1)
navigateUri(when(pref.language){
CONSTANTS.UZ -> CONSTANTS.LICENSE_UZ
CONSTANTS.RU -> CONSTANTS.LICENSE_RU
else -> CONSTANTS.LICENSE_EN
})
}
txtPublicOferta.setOnClickListener {
navigateUri(CONSTANTS.MAIN_URL2)
navigateUri(when(pref.language){
CONSTANTS.UZ -> CONSTANTS.PRIVACY_POLICY_UZ
CONSTANTS.RU -> CONSTANTS.PRIVACY_POLICY_RU
else -> CONSTANTS.PRIVACY_POLICY_EN
})
}
}
}
......@@ -306,7 +315,6 @@ class MainActivity : AppCompatActivity() {
override fun onDestroy() {
_bn = null
unregisterReceiver(receiver)
pref.blockedTime = 0
super.onDestroy()
}
}
\ No newline at end of file
......@@ -5,8 +5,11 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Rect
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.Window
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
......@@ -20,10 +23,12 @@ import com.mobiuz.app.dev.ui.auth.AuthActivity
import com.mobiuz.app.dev.ui.global.ButtonClick
import com.mobiuz.app.dev.ui.global.CONSTANTS
import com.mobiuz.app.dev.utils.NetworkUtil
import com.mobiuz.app.dev.utils.extensions.customLog
import com.mobiuz.app.dev.utils.extensions.showMessage
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import java.lang.RuntimeException
import javax.inject.Inject
@SuppressLint("CustomSplashScreen")
......@@ -44,6 +49,8 @@ class SplashActivity : AppCompatActivity() {
setContentView(bn.root)
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
// customLog("rect.top: ${getStatusBarHeight() / resources.displayMetrics.density}")
receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val type = NetworkUtil.getConnectivityStatus(this@SplashActivity)
......@@ -96,6 +103,8 @@ class SplashActivity : AppCompatActivity() {
}
fun navigate() {
when {
pref.language.isEmpty() -> {
......
......@@ -69,5 +69,8 @@ interface ApiService {
@POST(CONSTANTS.API_SERVICE_INDEX)
suspend fun getServices(): ResponseList<ServiceData>
@POST(CONSTANTS.API_MAIN_ROAMING)
suspend fun mainRoaming(): ResponseObject<Roaming>
}
\ No newline at end of file
......@@ -13,7 +13,9 @@ data class CustomerData(
data class TarifCodeName(
var code: String,
var name: Any
var name: String,
var total_price: Int,
var next_tariffication_date: String
)
data class CustomerInfo(
......
package com.mobiuz.app.dev.network.model
data class Roaming(
val name: String?
)
......@@ -7,6 +7,7 @@ import com.mobiuz.app.dev.model.UserAuth
import com.mobiuz.app.dev.network.api.ApiService
import com.mobiuz.app.dev.network.model.ChangePassword
import com.mobiuz.app.dev.network.model.Customer
import com.mobiuz.app.dev.network.model.Roaming
import com.mobiuz.app.dev.network.model.UiStateObject
import com.mobiuz.app.dev.utils.extensions.getMessage
import com.mobiuz.app.dev.utils.extensions.userMessage
......@@ -68,6 +69,22 @@ class MainRepository @Inject constructor(
UiStateObject.ERROR(e.userMessage(context))
}
}
suspend fun mainRoaming(): UiStateObject<Roaming> {
return try {
val res = apiService.mainRoaming()
when {
res.status -> {
UiStateObject.SUCCESS(res.data!!)
}
res.errors.isNotEmpty() -> UiStateObject.ERROR(res.errors.getMessage())
else -> UiStateObject.ERROR(res.message)
}
} catch (e: Exception) {
UiStateObject.ERROR(e.userMessage(context))
}
}
}
\ No newline at end of file
package com.mobiuz.app.dev.ui.auth.check
import android.os.Bundle
import android.telephony.PhoneNumberFormattingTextWatcher
import android.text.Editable
import android.view.View
import android.view.animation.AnimationUtils
import androidx.core.os.bundleOf
......@@ -19,7 +21,9 @@ import com.mobiuz.app.dev.ui.global.ButtonClick
import com.mobiuz.app.dev.ui.global.CONSTANTS
import com.mobiuz.app.dev.ui.global.TextWatcherWrapper
import com.mobiuz.app.dev.utils.Utils
import com.mobiuz.app.dev.utils.extensions.checkChangedPosition
import com.mobiuz.app.dev.utils.extensions.customLog
import com.mobiuz.app.dev.utils.extensions.maskedTextMobi
import com.mobiuz.app.dev.utils.extensions.showCustomDialog
import com.mobiuz.app.dev.utils.hideKeyboard
import dagger.hilt.android.AndroidEntryPoint
......@@ -32,6 +36,8 @@ class CheckPhoneFragment : BaseFragment(R.layout.fragment_check_phone) {
private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
private val navController: NavController by lazy(LazyThreadSafetyMode.NONE) { NavHostFragment.findNavController(this) }
var phone = ""
var oldText = ""
var newText = ""
var phoneRaw = ""
private val viewModel: AuthViewModel by viewModels()
......@@ -47,24 +53,41 @@ class CheckPhoneFragment : BaseFragment(R.layout.fragment_check_phone) {
override fun setUpUI() {
bn.apply {
viewGroup.setOnClickListener(object : ButtonClick(){
viewGroup.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
bn.viewGroup.hideKeyboard()
}
})
inputPhone.addTextChangedListener(object : TextWatcherWrapper() {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
super.beforeTextChanged(s, start, count, after)
oldText = s.toString()
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
super.onTextChanged(s, start, before, count)
customLog("s=${s?.toString()?.length}")
btnLogin.isEnabled = inputPhone.text.toString().trim().length == 17
try {
inputPhone.removeTextChangedListener(this)
newText = s.toString().replace(" ","").maskedTextMobi()
inputPhone.setText(newText)
inputPhone.setSelection(oldText.checkChangedPosition(newText))
inputPhone.addTextChangedListener(this)
btnLogin.isEnabled = inputPhone.text.toString().trim().length == 12
}catch (e: Exception){
inputPhone.text.clear()
}
}
})
btnLogin.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
phone = "+998" + inputPhone.unmaskedText.toString().trim()
phoneRaw = inputPhone.text.toString().trim()
phone = "+998" + inputPhone.text.toString().trim().replace(" ","")
phoneRaw = "+998 " + inputPhone.text.toString().trim()
when {
phone.length < 13 -> {
inputPhone.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
......@@ -86,10 +109,10 @@ class CheckPhoneFragment : BaseFragment(R.layout.fragment_check_phone) {
when (it) {
is UiStateObject.SUCCESS -> {
showProgressDialog(false)
if (it.data.action == "login") {
navController.navigate(R.id.loginFragment, bundleOf(CONSTANTS.PHONE to phoneRaw), Utils.navOptions())
} else if (it.data.action == "register") {
if (it.data.action == "register") {
navController.navigate(R.id.registerFragment, bundleOf(CONSTANTS.PHONE to phone), Utils.navOptions())
} else {
navController.navigate(R.id.loginFragment, bundleOf(CONSTANTS.PHONE to phoneRaw), Utils.navOptions())
}
}
is UiStateObject.ERROR -> {
......
......@@ -64,7 +64,7 @@ class LoginFragment : BaseFragment(R.layout.fragment_login) {
}
})
txtHelperMobiuz.makeLinks(Pair("www.mobi.uz", View.OnClickListener {
val uri = Uri.parse("https://www.mobi.uz/")
val uri = Uri.parse(CONSTANTS.HTTP_MOBI_UZ)
val intent = Intent(Intent.ACTION_VIEW)
intent.data = uri
startActivity(intent)
......
......@@ -6,6 +6,7 @@ import android.os.Bundle
import android.view.View
import android.view.animation.AnimationUtils
import android.widget.TextView
import androidx.biometric.BiometricManager
import androidx.core.hardware.fingerprint.FingerprintManagerCompat
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
......@@ -42,6 +43,8 @@ class PinFragment : BaseFragment(R.layout.fragment_pin) {
private var titleText = ""
private var pinCode = ""
private var count = 3
private lateinit var biometricManager: BiometricManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
......@@ -54,6 +57,7 @@ class PinFragment : BaseFragment(R.layout.fragment_pin) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
_bn = FragmentPinBinding.bind(view)
biometricManager = BiometricManager.from(requireContext())
setUpUI()
collects()
......@@ -80,9 +84,11 @@ class PinFragment : BaseFragment(R.layout.fragment_pin) {
rvPin.adapter = pinAdapter
titleText = when (type) {
CONSTANTS.NEW_PIN -> {
topDiv.isVisible = false
getString(R.string.install_pin)
}
CONSTANTS.CONFIRM_NEW_PIN -> {
topDiv.isVisible = false
getString(R.string.confirm_pin)
}
CONSTANTS.CURRENT_PIN -> {
......@@ -169,6 +175,13 @@ class PinFragment : BaseFragment(R.layout.fragment_pin) {
}
}
private fun checkBiometric() : Boolean {
return when (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG or BiometricManager.Authenticators.BIOMETRIC_WEAK)) {
BiometricManager.BIOMETRIC_SUCCESS -> true
else -> false
}
}
private fun loadError(){
bn.apply {
......@@ -196,8 +209,8 @@ class PinFragment : BaseFragment(R.layout.fragment_pin) {
}
private fun navigate() {
val golfing = Goldfinger.Builder(requireContext()).build()
if (golfing.canAuthenticate()) {
if (checkBiometric()) {
navController.navigate(R.id.biometricFragment, null, Utils.navOptions())
} else {
val intent = Intent(requireContext(), MainActivity::class.java)
......
......@@ -12,6 +12,7 @@ import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import com.mobiuz.app.R
import com.mobiuz.app.databinding.FragmentRegisterBinding
import com.mobiuz.app.dev.model.SharedPref
import com.mobiuz.app.dev.model.UserAuth
import com.mobiuz.app.dev.network.model.UiStateObject
import com.mobiuz.app.dev.ui.auth.AuthViewModel
......@@ -25,10 +26,13 @@ import com.mobiuz.app.dev.utils.extensions.showCustomDialog
import com.mobiuz.app.dev.utils.hideKeyboard
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import javax.inject.Inject
@AndroidEntryPoint
class RegisterFragment : BaseFragment(R.layout.fragment_register) {
@Inject
lateinit var pref: SharedPref
private var _bn: FragmentRegisterBinding? = null
private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
private val navController: NavController by lazy(LazyThreadSafetyMode.NONE) { NavHostFragment.findNavController(this) }
......@@ -74,14 +78,23 @@ class RegisterFragment : BaseFragment(R.layout.fragment_register) {
txtAgree.makeLinks(
Pair("Terms of Use", View.OnClickListener {
val uri = Uri.parse(CONSTANTS.TERMS_OF_USE)
val uri = Uri.parse(when(pref.language){
CONSTANTS.UZ -> CONSTANTS.LICENSE_UZ
CONSTANTS.RU -> CONSTANTS.LICENSE_RU
else -> CONSTANTS.LICENSE_EN
})
val intent = Intent(Intent.ACTION_VIEW)
intent.data = uri
startActivity(intent)
}),
Pair("Privacy Policy", View.OnClickListener {
val uri = Uri.parse(CONSTANTS.PRIVACY_POLICY)
val uri = Uri.parse(when(pref.language){
CONSTANTS.UZ -> CONSTANTS.PRIVACY_POLICY_UZ
CONSTANTS.RU -> CONSTANTS.PRIVACY_POLICY_RU
else -> CONSTANTS.PRIVACY_POLICY_EN
})
val intent = Intent(Intent.ACTION_VIEW)
intent.data = uri
startActivity(intent)
......
......@@ -11,12 +11,22 @@ object CONSTANTS {
// safety data
const val HELP_BOT = "@MobiuzHelpBot"
const val TERMS_OF_USE = "https://ip.mobi.uz/selfcare/"
const val PRIVACY_POLICY = "https://www.mobi.uz/"
const val HTTP_MOBI_UZ = "https://www.mobi.uz/"
const val HTTP_MOBI_UZ = "https://mobi.uz/"
const val FEEDBACK = "https://company.mobi.uz/ru/feedback/"
const val MAIN_URL1 = "https://www.mobi.uz/"
const val MAIN_URL2 = "https://www.mobi.uz/"
const val LICENSE_UZ = "http://10.160.45.60/uploads/licenses/license_uz.html"
const val LICENSE_RU = "http://10.160.45.60/uploads/licenses/license_ru.html"
const val LICENSE_EN = "http://10.160.45.60/uploads/licenses/license_en.html"
const val PRIVACY_POLICY_UZ = "http://10.160.45.60/uploads/privacy/privacy_policy_uz.html"
const val PRIVACY_POLICY_RU = "http://10.160.45.60/uploads/privacy/privacy_policy_ru.html"
const val PRIVACY_POLICY_EN = "http://10.160.45.60/uploads/privacy/privacy_policy_en.html"
const val PAYSYS_LICENSE_UZ = "http://10.160.45.60/uploads/paysys/license_uz.html"
const val PAYSYS_LICENSE_RU = "http://10.160.45.60/uploads/paysys/license_ru.html"
const val PAYSYS_LICENSE_EN = "http://10.160.45.60/uploads/paysys/license_en.html"
const val MAIN_URL2 = "https://mobi.uz/"
const val PHONE1 = "0890"
const val PHONE2 = "+998 97 130 09 09"
const val PHONE3 = "+998 97 203 10 10"
......@@ -39,7 +49,6 @@ object CONSTANTS {
const val FULL_SCREEN_DIALOG = "full_screen_dialog"
const val CONNECTIVITY_CHANGE = "android.net.conn.CONNECTIVITY_CHANGE"
const val MY_CONNECTIVITY_CHANGE = "MY_CONNECTIVITY_CHANGE"
const val USSD_ACTION_REFRESH = "com.times.ussd.action.REFRESH"
//password types
......@@ -76,5 +85,6 @@ object CONSTANTS {
const val API_CHECK_PASSWORD = "customer/check-password"
const val API_CHANGE_PASSWORD = "customer/change-password"
const val API_SERVICE_INDEX = "service/index"
const val API_MAIN_ROAMING = "main/roaming"
}
......@@ -7,8 +7,7 @@ import android.view.animation.AnimationUtils
import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK
import androidx.biometric.BiometricManager.Authenticators.*
import androidx.biometric.BiometricPrompt
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
......@@ -47,7 +46,6 @@ class FullScreenFragment : BaseFragment(R.layout.fragment_pin_dialog) {
private lateinit var mainViewModel: MainViewModel
private var type = ""
private var errorCount = 3
private lateinit var goldfinger: Goldfinger
private lateinit var biometricManager: BiometricManager
private lateinit var biometricPrompt: BiometricPrompt
private lateinit var promptInfo: BiometricPrompt.PromptInfo
......@@ -71,8 +69,6 @@ class FullScreenFragment : BaseFragment(R.layout.fragment_pin_dialog) {
setUpUI()
goldfinger = Goldfinger.Builder(requireContext()).build()
biometricManager = BiometricManager.from(requireContext())
checkBiometric()
......@@ -119,27 +115,6 @@ class FullScreenFragment : BaseFragment(R.layout.fragment_pin_dialog) {
}
private fun loadFingerPrint() {
if (goldfinger.canAuthenticate()) {
val params = Goldfinger.PromptParams.Builder(this)
.title(getString(R.string.biometric_enter))
.description(getString(R.string.enter_from_finger_or_face))
.negativeButtonText(getString(R.string.cancel))
.build()
goldfinger.authenticate(params, object : Goldfinger.Callback {
override fun onResult(result: Goldfinger.Result) {
if (result.type() == Goldfinger.Type.SUCCESS) {
navigate()
}
}
override fun onError(e: Exception) {}
})
}
}
override fun setUpUI() {
bn.apply {
loadData()
......
......@@ -7,14 +7,15 @@ import android.os.Bundle
import android.view.View
import android.widget.FrameLayout
import android.widget.LinearLayout
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.tabs.TabLayoutMediator
import com.mobiuz.app.dev.BillingActivity
import com.mobiuz.app.R
import com.mobiuz.app.databinding.FragmentHomeBinding
import com.mobiuz.app.dev.BillingActivity
import com.mobiuz.app.dev.MainViewModel
import com.mobiuz.app.dev.model.SharedPref
import com.mobiuz.app.dev.network.model.Customer
......@@ -24,8 +25,6 @@ import com.mobiuz.app.dev.utils.extensions.*
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import java.text.SimpleDateFormat
import java.util.*
import javax.inject.Inject
......@@ -41,16 +40,20 @@ class HomeFragment : BaseFragment(R.layout.fragment_home) {
private lateinit var mainViewModel: MainViewModel
private var isFirstProgressing = true
private var jobAutoSlide: Job? = null
private var jobToMatch: Job? = null
private var customer: Customer? = null
private var overScroll = 0
private val sliderAdapter = SliderAdapter()
private var lastUpdateTime = 0L
private lateinit var matchParam: FrameLayout.LayoutParams
private lateinit var changedParam: FrameLayout.LayoutParams
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mainViewModel = ViewModelProvider(requireActivity())[MainViewModel::class.java]
viewModel.mainIndex()
viewModel.mainRoaming()
lastUpdateTime = System.currentTimeMillis()
}
......@@ -67,6 +70,8 @@ class HomeFragment : BaseFragment(R.layout.fragment_home) {
override fun setUpUI() {
bn.apply {
matchParam = FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
changedParam = FrameLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
slider.adapter = sliderAdapter
......@@ -106,27 +111,31 @@ class HomeFragment : BaseFragment(R.layout.fragment_home) {
mainViewModel.openDrawer(System.currentTimeMillis())
}
val params0 = FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
val params = FrameLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
bounceScrollView.setOnOverScrollListener { fromStart, overScrolledDistance ->
if (fromStart && overScrolledDistance > 140.52632 && (lastUpdateTime < System.currentTimeMillis() - 3000)) {
// customLog("fromStart:$fromStart, overScroll:$overScroll, overScrolledDistance: $overScrolledDistance")
if (!fromStart) {
lastUpdateTime = System.currentTimeMillis()
}
if (fromStart && overScrolledDistance > 140.52632 && (lastUpdateTime < System.currentTimeMillis() - 2000)) {
vibrate(requireContext())
viewModel.mainIndex()
lastUpdateTime = System.currentTimeMillis()
}
if (fromStart && overScroll < overScrolledDistance) {
params.width = homeImage.width + (overScrolledDistance - overScroll)
params.height = homeImage.height + (overScrolledDistance - overScroll)
homeImage.layoutParams = params
changedParam.width = homeImage.width + (overScrolledDistance - overScroll)
changedParam.height = homeImage.height + (overScrolledDistance - overScroll)
homeImage.layoutParams = changedParam
} else {
params.width = homeImage.width - (overScroll - overScrolledDistance)
params.height = homeImage.height - (overScroll - overScrolledDistance)
homeImage.layoutParams = params0
changedParam.width = homeImage.width - (overScroll - overScrolledDistance)
changedParam.height = homeImage.height - (overScroll - overScrolledDistance)
homeImage.layoutParams = matchParam
}
overScroll = overScrolledDistance
}
bounceScrollView.setOnScrollListener { _, scrollY ->
......@@ -174,6 +183,28 @@ class HomeFragment : BaseFragment(R.layout.fragment_home) {
}
}
}
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
viewModel.mainRoamingUiState.collect {
when (it) {
is UiStateObject.SUCCESS -> {
showProgressDialog(false)
bn.cardRoaming.isVisible = it.data.name != null
customLog("mainRoamingUiState SUCCESS${it.data}")
}
is UiStateObject.ERROR -> {
customLog("mainRoamingUiState ERROR${it.message}")
showProgressDialog(false)
bn.cardRoaming.isVisible = false
}
is UiStateObject.LOADING -> {
bn.cardRoaming.isVisible = false
customLog("mainRoamingUiState LOADING")
}
else -> Unit
}
}
}
}
@SuppressLint("SetTextI18n")
......@@ -184,19 +215,17 @@ class HomeFragment : BaseFragment(R.layout.fragment_home) {
txtBalance.text = "${it.balance?.amount?.toMoneyFormat()} ${it.balance?.currency}"
pref.userBirthday = customer?.customer?.date_of_birth ?: ""
it.counters?.let {
txtCountMb.text = it.BYTE?.value?.toMoneyFormat() ?: "0"
txtTypeMb.text = it.BYTE?.unit ?: "mb"
txtSumTariff.text = getString(R.string.sum_month,it.SECOND?.value?.toMoneyFormat() ?: "0")
txtCountMinut.text = it.SECOND?.value?.toMoneyFormat() ?: "0"
txtTypeMinut.text = it.SECOND?.unit ?: "min"
txtTarif.text = it.SECOND?.name ?: "My tarif"
val strDate = it.SECOND?.date_to
val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm")
val date: Date = dateFormat.parse(strDate)
val d = SimpleDateFormat("dd MMMM")
txtTarifTo.text = d.format(date)
txtTarif.text = customer?.customer?.tariff?.name
txtSumTariff.text = getString(R.string.sum_month, customer?.customer?.tariff?.total_price?.toMoneyFormat() ?: "0")
txtTarifTo.text = customer?.customer?.tariff?.next_tariffication_date
txtCountSms.text = it.ITEM?.value?.toMoneyFormat() ?: "0"
txtTypeSms.text = it.ITEM?.unit ?: "sms"
......
......@@ -3,6 +3,7 @@ package com.mobiuz.app.dev.ui.home
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.mobiuz.app.dev.network.model.Customer
import com.mobiuz.app.dev.network.model.Roaming
import com.mobiuz.app.dev.network.model.UiStateObject
import com.mobiuz.app.dev.network.repository.AuthRepository
import com.mobiuz.app.dev.network.repository.MainRepository
......@@ -25,5 +26,13 @@ class HomeViewModel @Inject constructor(
_mainIndexUiState.value = repository.mainIndex()
}
private val _mainRoamingUiState = MutableStateFlow<UiStateObject<Roaming>>(UiStateObject.EMPTY)
val mainRoamingUiState: StateFlow<UiStateObject<Roaming>> = _mainRoamingUiState
fun mainRoaming() = viewModelScope.launch {
_mainRoamingUiState.value = UiStateObject.LOADING
_mainRoamingUiState.value = repository.mainRoaming()
}
}
\ No newline at end of file
......@@ -29,7 +29,7 @@ class SliderAdapter : RecyclerView.Adapter<SliderAdapter.SliderViewHolder>() {
fun onBind(position: Int) {
view.apply {
if(position % 2 != 0){
imageSlider.setBackgroundResource(R.drawable.image_slider2)
imageSlider.setImageResource(R.drawable.image_slider2)
txtDescription.setTextColor(Color.WHITE)
txtDescription.text = itemView.context.getString(R.string.misic_all_with_you)
}
......
package com.mobiuz.app.dev.ui.home
import android.content.Context
import android.util.AttributeSet
import android.view.View
import com.mobiuz.app.dev.utils.extensions.getStatusBarHeight
class StatusBarSpacer @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
View(context, attrs) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) =
setMeasuredDimension(widthMeasureSpec, (getStatusBarHeight()))
}
\ No newline at end of file
package com.mobiuz.app.dev.ui.settings.safety
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.provider.Settings.ACTION_BIOMETRIC_ENROLL
import android.view.View
import android.widget.SeekBar
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators.*
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import com.mobiuz.app.BuildConfig
import com.mobiuz.app.R
import com.mobiuz.app.databinding.FragmentSafetyBinding
import com.mobiuz.app.dev.model.SharedPref
......@@ -13,8 +20,15 @@ import com.mobiuz.app.dev.ui.base.BaseFragment
import com.mobiuz.app.dev.ui.global.ButtonClick
import com.mobiuz.app.dev.ui.global.CONSTANTS
import com.mobiuz.app.dev.utils.Utils
import com.mobiuz.app.dev.utils.extensions.customLog
import com.mobiuz.app.dev.utils.extensions.showMessage
import dagger.hilt.android.AndroidEntryPoint
import uz.agr.sdk.core.entity.synxron.VersionSdk
// 35
// 93 320 36 00 = 30
import javax.inject.Inject
@AndroidEntryPoint
......@@ -23,6 +37,8 @@ class SafetyFragment : BaseFragment(R.layout.fragment_safety) {
@Inject
lateinit var pref: SharedPref
private lateinit var biometricManager: BiometricManager
private var _bn: FragmentSafetyBinding? = null
private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
private val navController: NavController by lazy(LazyThreadSafetyMode.NONE) { NavHostFragment.findNavController(this) }
......@@ -32,6 +48,8 @@ class SafetyFragment : BaseFragment(R.layout.fragment_safety) {
_bn = FragmentSafetyBinding.bind(view)
setUpUI()
collects()
biometricManager = BiometricManager.from(requireContext())
checkBiometricAfter(false)
}
......@@ -42,32 +60,97 @@ class SafetyFragment : BaseFragment(R.layout.fragment_safety) {
navController.navigateUp()
}
val text = getString(R.string.settings_safety)
val myText = text.replace(CONSTANTS.DEFAULT_PHONE,pref.userPhone)
val myText = text.replace(CONSTANTS.DEFAULT_PHONE, pref.userPhone)
txtPhoneSafety.text = myText
switchBiometria.isChecked = pref.isUseFingerPrint
switchBiometria.setOnCheckedChangeListener { _, isChecked ->
val message = if(isChecked) getString(R.string.biometric_enabled) else getString(R.string.biometric_disabled)
showToastMessage(message)
pref.isUseFingerPrint = isChecked
if(isChecked && checkBiometric()){
showToastMessage(getString(R.string.biometric_enabled))
pref.isUseFingerPrint = true
}else{
if(checkBiometric()){
pref.isUseFingerPrint = false
showToastMessage(getString(R.string.biometric_disabled))
}else{
checkBiometricAfter(true)
}
}
switchBiometria.isChecked = checkBiometric() && isChecked
}
btn1.setOnClickListener(object : ButtonClick(){
btnBiometric.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
switchBiometria.isChecked = !switchBiometria.isChecked
}
})
btnChangePin.setOnClickListener(object : ButtonClick(){
btnChangePin.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
navController.navigate(R.id.pinFragment, bundleOf(CONSTANTS.TYPE_PIN to CONSTANTS.CURRENT_PIN), Utils.navOptions())
navController.navigate(R.id.pinFragment, bundleOf(CONSTANTS.TYPE_PIN to CONSTANTS.CURRENT_PIN), Utils.navOptions())
}
})
btnChangePassword.setOnClickListener(object : ButtonClick(){
btnChangePassword.setOnClickListener(object : ButtonClick() {
override fun onSingleClick(v: View?) {
navController.navigate(R.id.changePasswordFragment, bundleOf(CONSTANTS.TYPE_PASSWORD to CONSTANTS.CURRENT_PASSWORD),Utils.navOptions())
navController.navigate(R.id.changePasswordFragment, bundleOf(CONSTANTS.TYPE_PASSWORD to CONSTANTS.CURRENT_PASSWORD), Utils.navOptions())
}
})
}
}
private fun checkBiometricAfter(toSettings:Boolean) {
when (biometricManager.canAuthenticate(BIOMETRIC_STRONG or BIOMETRIC_WEAK)) {
BiometricManager.BIOMETRIC_SUCCESS -> {
customLog("BIOMETRIC_SUCCESS")
bn.btnBiometric.isVisible = true
}
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> {
customLog("BIOMETRIC_ERROR_NO_HARDWARE")
pref.isUseFingerPrint = false
bn.btnBiometric.isVisible = false
}
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
customLog("BIOMETRIC_ERROR_NONE_ENROLLED")
customLog("${Build.VERSION.SDK_INT} >= ${Build.VERSION_CODES.R}")
if (toSettings){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
val enrollIntent = Intent(ACTION_BIOMETRIC_ENROLL).apply {
putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, BIOMETRIC_STRONG or BIOMETRIC_WEAK)
}
pref.isShowPin = false
customLog("BIOMETRIC_ERROR_NONE_ENROLLED INTENT")
startActivityForResult(enrollIntent, 1)
}else{
showMessage(getString(R.string.to_settings))
}
}
pref.isUseFingerPrint = false
}
else -> Unit
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
}
private fun checkBiometric(): Boolean {
return when (biometricManager.canAuthenticate(BIOMETRIC_STRONG or BIOMETRIC_WEAK)) {
BiometricManager.BIOMETRIC_SUCCESS -> true
else -> false
}
}
override fun collects() {}
......
......@@ -128,6 +128,47 @@ fun FragmentActivity.showCustomExitDialog(block: () -> Unit) {
dialog.show(supportFragmentManager, "childFragmentManager")
}
fun String.checkChangedPosition(new:String):Int{
for (i in this.indices){
if(i == new.length){
return new.length
}else if (this[i] != new[i]){
return i
}
}
return new.length
}
fun View.getStatusBarHeight(): Int {
var result = 0
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
if (resourceId > 0) {
result = resources.getDimensionPixelSize(resourceId)
}
resources.displayMetrics.heightPixels
return result
}
fun String.maskedTextMobi():String{
var newText = ""
for (i in this.indices){
if(i == 2){
newText += " "
}
if(i == 5){
newText += " "
}
if(i == 7){
newText += " "
}
newText += this[i]
}
return newText
}
//fun Fragment.showCustomDialog(string: String, status: Boolean, block: () -> Unit) {
// val snackBar = Snackbar.make(this.requireView(),string, Snackbar.LENGTH_LONG)
// .setBackgroundTint(Color.GRAY)
......
......@@ -195,7 +195,6 @@
android:layout_gravity="center"
android:src="@drawable/ic_baseline_keyboard_arrow_right" />
</LinearLayout>
<View
......@@ -256,7 +255,7 @@
android:layout_marginStart="12dp"
android:layout_weight="1"
android:text="@string/exit"
android:textSize="20sp"
android:textSize="17sp"
android:textStyle="bold" />
<TextView
......
......@@ -8,12 +8,12 @@
android:fitsSystemWindows="false"
android:orientation="vertical">
<View
android:layout_width="match_parent"
<com.mobiuz.app.dev.ui.home.StatusBarSpacer
android:id="@+id/div"
app:layout_constraintTop_toTopOf="parent"
android:background="@android:color/transparent"
android:layout_height="24dp"/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent" />
<FrameLayout
android:layout_width="match_parent"
......
......@@ -38,27 +38,44 @@
android:textColor="@color/black75"
/>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/layout_input"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="@dimen/_12sdp"
android:layout_marginEnd="@dimen/_12sdp">
android:background="@drawable/edit_text_unchecked"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="6dp"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:text="+998 "
android:visibility="visible"
android:layout_marginStart="@dimen/_16sdp"
android:paddingVertical="@dimen/_14sdp"
android:textStyle="bold"
android:layout_gravity="center"
android:textColor="@color/black80"
android:textSize="17sp"
android:layout_height="wrap_content"/>
<com.github.pinball83.maskededittext.MaskedEditText
<EditText
android:layout_width="match_parent"
android:id="@+id/input_phone"
android:inputType="phone"
app:allowed_chars="1234567890"
android:longClickable="false"
app:mask="+998 ## ### ## ##"
android:maxLength="12"
android:paddingVertical="@dimen/_14sdp"
android:textStyle="bold"
android:layout_gravity="center"
android:imeOptions="actionDone"
app:mask="+998 ** *** ** **"
app:notMaskedSymbol="*"
android:textSize="17sp"
android:padding="@dimen/_14sdp"
android:background="@drawable/edit_text_unchecked"
android:layout_height="match_parent"/>
</com.google.android.material.textfield.TextInputLayout>
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
......
......@@ -6,22 +6,35 @@
android:layout_height="match_parent"
android:fitsSystemWindows="false">
<ImageView
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:id="@+id/home_image"
android:src="@drawable/bgn_home" />
android:layout_height="wrap_content">
<ImageView
android:id="@+id/home_image2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="@drawable/bgn_home" />
<ImageView
android:id="@+id/home_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="@drawable/bgn_home" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
<com.mobiuz.app.dev.ui.home.StatusBarSpacer
android:id="@+id/top_div"
android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_height="wrap_content"
android:background="@android:color/transparent" />
<com.google.android.material.appbar.MaterialToolbar
......@@ -57,20 +70,21 @@
</LinearLayout>
</com.google.android.material.appbar.MaterialToolbar>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottie"
android:layout_width="@dimen/_90sdp"
android:layout_height="@dimen/_90sdp"
android:adjustViewBounds="true"
app:lottie_autoPlay="true"
android:id="@+id/lottie"
android:visibility="invisible"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/_24sdp"
android:adjustViewBounds="true"
android:visibility="invisible"
app:lottie_autoPlay="true"
app:lottie_loop="true"
app:lottie_rawRes="@raw/rifki_loading"
app:lottie_speed="1"
......@@ -78,9 +92,9 @@
<com.xw.repo.widget.BounceScrollView
android:id="@+id/bounce_scrollView"
android:clipToPadding="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:clipToPadding="true">
<LinearLayout
android:layout_width="match_parent"
......@@ -190,20 +204,20 @@
android:id="@+id/txt_tarif"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_tarif"
android:textSize="20sp"
android:textStyle="bold" />
android:textStyle="bold"
tools:text="@string/my_tarif" />
<TextView
android:id="@+id/txt_sum_tariff"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="end"
android:id="@+id/txt_sum_tariff"
android:text="@string/sum_month"
android:textColor="@color/grey70"
android:textSize="14sp" />
android:textSize="14sp"
tools:text="@string/sum_month" />
</LinearLayout>
<View
......@@ -350,45 +364,80 @@
android:textSize="14sp" />
<TextView
android:id="@+id/txt_tarif_to"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/txt_tarif_to"
android:layout_gravity="end"
tools:text="22 Декабря" />
</FrameLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/card_roaming"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="@dimen/_12sdp"
android:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginStart="16dp"
android:text="@string/rouming"
android:textColor="@color/grey80"
android:textSize="14sp" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginHorizontal="16dp"
android:layout_weight="1"
android:gravity="end"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold"
tools:text="Light Роуминг" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/slider"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_marginStart="16dp"
android:layout_marginTop="@dimen/_16sdp"
android:layout_height="180dp" />
android:layout_marginTop="@dimen/_16sdp" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabIndicator"
android:backgroundTint="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="24dp"
app:tabPaddingStart="8dp"
android:layout_gravity="center"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="@dimen/_20sdp"
app:tabPaddingEnd="8dp"
app:tabIndicatorHeight="0dp"
android:backgroundTint="@android:color/transparent"
app:layout_constraintEnd_toEndOf="parent"
app:tabBackground="@drawable/tab_indicator"
app:tabGravity="center" />
app:tabGravity="center"
app:tabIndicatorHeight="0dp"
app:tabPaddingEnd="8dp"
app:tabPaddingStart="8dp" />
</LinearLayout>
</com.xw.repo.widget.BounceScrollView>
</FrameLayout>
</LinearLayout>
</FrameLayout>
\ No newline at end of file
......@@ -5,11 +5,16 @@
android:layout_height="match_parent"
android:orientation="vertical">
<com.mobiuz.app.dev.ui.home.StatusBarSpacer
android:id="@+id/top_div"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent" />
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
app:navigationIcon="@drawable/ic_baseline_arrow_back"
app:title="@string/language_app" />
......
......@@ -133,7 +133,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/_6sdp"
android:textSize="17sp"
android:textSize="15sp"
android:text="@string/forget_password"
android:background="?android:selectableItemBackground"
android:textColor="@color/grey110"
......
......@@ -7,11 +7,12 @@
android:background="@color/white"
android:fitsSystemWindows="false"
android:orientation="vertical">
<View
android:layout_width="match_parent"
<com.mobiuz.app.dev.ui.home.StatusBarSpacer
android:id="@+id/top_div"
android:visibility="gone"
android:layout_height="24dp"/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent" />
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
......
......@@ -7,10 +7,16 @@
android:fitsSystemWindows="false"
android:orientation="vertical">
<com.mobiuz.app.dev.ui.home.StatusBarSpacer
android:id="@+id/top_div"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent" />
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_marginTop="24dp"
android:layout_height="wrap_content"
app:navigationIcon="@drawable/ic_baseline_arrow_back"
app:title="@string/profile" />
......
......@@ -7,11 +7,16 @@
android:fitsSystemWindows="false"
android:orientation="vertical">
<com.mobiuz.app.dev.ui.home.StatusBarSpacer
android:id="@+id/top_div"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent" />
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="34dp"
app:navigationIcon="@drawable/ic_baseline_arrow_back"
app:title="@string/safety" />
......@@ -38,7 +43,8 @@
android:orientation="vertical">
<LinearLayout
android:id="@+id/btn_1"
android:id="@+id/btn_biometric"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
......
......@@ -10,10 +10,15 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/_30sdp"
android:fitsSystemWindows="false"
android:orientation="vertical">
<com.mobiuz.app.dev.ui.home.StatusBarSpacer
android:id="@+id/top_div"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent" />
<LinearLayout
android:id="@+id/layout_offline"
android:layout_width="match_parent"
......
......@@ -6,11 +6,16 @@
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.mobiuz.app.dev.ui.home.StatusBarSpacer
android:id="@+id/top_div"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent" />
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
app:title="@string/support"
android:layout_marginTop="24dp"
android:layout_height="wrap_content"
app:navigationIcon="@drawable/ic_baseline_arrow_back"
/>
......
......@@ -11,11 +11,16 @@
android:layout_height="wrap_content"
android:background="@color/white100">
<com.mobiuz.app.dev.ui.home.StatusBarSpacer
android:id="@+id/top_div"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent" />
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:background="@color/white100"
android:elevation="0dp"
app:navigationIcon="@drawable/ic_baseline_arrow_back"
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:id="@+id/image_slider"
android:scaleType="centerCrop"
android:layout_marginEnd="16dp"
android:src="@drawable/image_slider1"
android:layout_height="200dp"/>
<LinearLayout
android:layout_width="match_parent"
android:paddingVertical="@dimen/_16sdp"
android:layout_height="180dp"
android:layout_marginEnd="16dp"
android:id="@+id/image_slider"
android:layout_height="200dp"
android:paddingHorizontal="12dp"
android:background="@drawable/image_slider1"
android:orientation="vertical">
<ImageView
......@@ -67,4 +72,4 @@
</LinearLayout>
</LinearLayout>
\ No newline at end of file
</FrameLayout>
\ No newline at end of file
......@@ -138,6 +138,7 @@
<string name="pay_balance">Update balance</string>
<string name="more_know">To learn more</string>
<string name="check_internet_and_try_again">Check your internet connection and try again</string>
<string name="to_settings">To use the biometric data, you need to configure it from the settings section</string>
</resources>
\ No newline at end of file
......@@ -138,6 +138,7 @@
<string name="pay_balance">Пополнить баланс</string>
<string name="more_know">Узнать больше</string>
<string name="check_internet_and_try_again">Проверьте подключение к Интернету и попробуйте еще раз</string>
<string name="to_settings">Чтобы использовать биометрические данные, вам необходимо настроить их в разделе настроек.</string>
</resources>
\ No newline at end of file
......@@ -138,5 +138,6 @@
<string name="pay_balance">Hisobni to\'ldirish</string>
<string name="more_know">Ko\'proq bilish</string>
<string name="check_internet_and_try_again">Internet ulanishini tekshirib qayta urinib ko\'ring</string>
<string name="to_settings">Biometric ma\'lumotlardan foydalanish uchun sozlanmalar bo\'limidan sozlashingiz kerak</string>
</resources>
\ No newline at end of file
<resources>
<string name="app_name" translatable="false">MobiUz-Android</string>
<string name="app_name" translatable="false">Mobiuz</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment" translatable="false">Hello blank fragment</string>
<string name="login">Login</string>
......@@ -163,5 +163,7 @@
<string name="powered_by" translatable="false">Powered by</string>
<string name="more_know">Узнать больше</string>
<string name="check_internet_and_try_again">Internet ulanishini tekshirib qayta urinib ko\'ring</string>
<string name="to_settings">Biometric ma\'lumotlardan foydalanish uchun sozlanmalar bo\'limidan sozlashingiz kerak</string>
<string name="rouming">Роуминг</string>
</resources>
\ 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