problem solved related to count down timer of resend otp with viewmodel architect

This commit is contained in:
2024-05-08 13:27:53 +05:30
parent 7e1062f94e
commit 8ca11f3421
4 changed files with 87 additions and 66 deletions

View File

@@ -49,8 +49,6 @@ class GetCodeFragment : Fragment() {
private lateinit var viewModel: OnboardViewModel
private lateinit var progressView: ProgressView
private lateinit var countDownTimer: CountDownTimer
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
@@ -81,21 +79,22 @@ class GetCodeFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// count down timer
startCountDown()
// observing live data
viewModel.sendOTPLiveData.observe(viewLifecycleOwner){
when(it){
is ApiResult.Error -> {
progressView.hide()
Toast.makeText(activity, "${it.errorMessage}", Toast.LENGTH_SHORT).show()
// stating null status for otp sent live data so that when user goes back to the otp screen
// they do not encounter a success status again
viewModel.clearSendOTPData()
}
is ApiResult.Loading -> {
progressView.show("Sending OTP...")
}
is ApiResult.Success -> {
startCountDown()
viewModel.startOTPTimeCountDown()
Toast.makeText(activity, "OTP sent successfully", Toast.LENGTH_SHORT).show()
progressView.hide()
uniqueString = it.data?.unique_string?:""
@@ -130,14 +129,30 @@ class GetCodeFragment : Fragment() {
null -> {}
}
}
viewModel.otpResendTimeLiveData.observe(viewLifecycleOwner){
if (it == 0L){
// no time is ticking
binding.countdown.visibility = GONE
binding.resend.visibility = VISIBLE
}else{
// time is ticking
binding.countdown.visibility = VISIBLE
binding.resend.visibility = GONE
val rms = (it)/1000 // remaining time in second
val time = "%02d:%02d".format(rms/60, rms%60)
val text = "OTP is valid for $time Min"
Log.d("aditya_testing", "onTick: $it")
binding.countdown.text = text
}
}
}
override fun onDestroyView() {
super.onDestroyView()
viewModel.clearValidateOTP()
viewModel.clearSendOTPData()
countDownTimer.cancel()
}
private fun initViews() {
@@ -205,25 +220,6 @@ class GetCodeFragment : Fragment() {
}
}
private fun startCountDown(){
binding.countdown.visibility = VISIBLE
binding.resend.visibility = GONE
countDownTimer = object :CountDownTimer(OTP_RESEND_COUNT_DOWN_TIME, 1000){
override fun onTick(millisUntilFinished: Long) {
val rms = (millisUntilFinished)/1000 // remaining time in second
val time = "%02d:%02d".format(rms/60, rms%60)
val text = "OTP is valid for $time Min"
binding.countdown.text = text
}
override fun onFinish() {
binding.countdown.visibility = GONE
binding.resend.visibility = VISIBLE
}
}.start()
}
private fun getOTP(): String {
binding.apply {
return "${et1.text}${et2.text}${et3.text}${et4.text}"

View File

@@ -90,50 +90,12 @@ class GetEmailFragment : Fragment() {
null -> {}
}
}
viewModel.sendOTPLiveData.observe(viewLifecycleOwner) {
when (it) {
is ApiResult.Error -> {
progressView.hide()
Toast.makeText(activity, "${it.errorMessage}", Toast.LENGTH_SHORT).show()
}
is ApiResult.Loading -> {
progressView.show(title = "Sending OTP")
}
is ApiResult.Success -> {
viewModel.clearSendOTPData()
progressView.hide()
val args = if (isResetPasswordIntent) {
Bundle().apply {
putBoolean(IS_RESET_PASSWORD_INTENT, isResetPasswordIntent)
}
} else {
Bundle().apply {
putBoolean(IS_UNDER_16, isUnder16)
putString(UNIQUE_STRING_ARG, it.data?.unique_string)
putString(EMAIL_ARG, binding.email.text.toString())
}
}
findNavController().navigate(
R.id.action_getEmailFragment_to_getCodeFragment,
args
)
}
null -> {}
}
}
}
override fun onDestroyView() {
super.onDestroyView()
// removing values from live data for a fresh data when new instance is created
viewModel.clearCheckEmailExist()
viewModel.clearSendOTPData()
}
private fun initViews() {
@@ -167,6 +129,43 @@ class GetEmailFragment : Fragment() {
return@setOnClickListener
}
// listening to otp live data
viewModel.sendOTPLiveData.observe(viewLifecycleOwner) {
when (it) {
is ApiResult.Error -> {
progressView.hide()
Toast.makeText(activity, "${it.errorMessage}", Toast.LENGTH_SHORT).show()
}
is ApiResult.Loading -> {
progressView.show(title = "Sending OTP")
}
is ApiResult.Success -> {
progressView.hide()
val args = if (isResetPasswordIntent) {
Bundle().apply {
putBoolean(IS_RESET_PASSWORD_INTENT, isResetPasswordIntent)
}
} else {
Bundle().apply {
putBoolean(IS_UNDER_16, isUnder16)
putString(UNIQUE_STRING_ARG, it.data?.unique_string)
putString(EMAIL_ARG, binding.email.text.toString())
}
}
findNavController().navigate(
R.id.action_getEmailFragment_to_getCodeFragment,
args
)
}
null -> {}
}
}
if (!isUnder16) {
// parent
viewModel.checkEmailExist(binding.email.text.toString(), PARENT_TYPE)

View File

@@ -1,5 +1,6 @@
package com.woka.onboard.mvvm
import android.os.CountDownTimer
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
@@ -106,4 +107,29 @@ class OnboardViewModel: ViewModel(){
_checkUserNameExistLiveData.postValue(response)
}
}
// otp count down timer
private val OTP_RESEND_COUNT_DOWN_TIME = 10 * 60 * 1000L // 10 min
private var countDownTimer: CountDownTimer? = null
private var _otpResendTimeLiveData = MutableLiveData<Long>()
val otpResendTimeLiveData: LiveData<Long>
get() = _otpResendTimeLiveData
fun startOTPTimeCountDown(){
countDownTimer?.cancel()
countDownTimer = object : CountDownTimer(OTP_RESEND_COUNT_DOWN_TIME, 1000){
override fun onTick(millisUntilFinished: Long) {
_otpResendTimeLiveData.postValue(millisUntilFinished)
}
override fun onFinish() {
_otpResendTimeLiveData.postValue(0)
}
}.start()
}
override fun onCleared() {
super.onCleared()
countDownTimer?.cancel()
}
}

View File

@@ -216,7 +216,7 @@
android:id="@+id/countdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
android:visibility="gone"
tools:text="OTP is valid for 10:00 Min"
android:textColor="@color/color_primary"