@@ -3,6 +3,10 @@ package team.aliens.dms.android.feature.resetpassword
33import androidx.lifecycle.viewModelScope
44import dagger.hilt.android.lifecycle.HiltViewModel
55import kotlinx.coroutines.Dispatchers
6+ import kotlinx.coroutines.FlowPreview
7+ import kotlinx.coroutines.flow.debounce
8+ import kotlinx.coroutines.flow.distinctUntilChanged
9+ import kotlinx.coroutines.flow.map
610import kotlinx.coroutines.launch
711import team.aliens.dms.android.core.ui.mvi.BaseMviViewModel
812import team.aliens.dms.android.core.ui.mvi.Intent
@@ -11,10 +15,13 @@ import team.aliens.dms.android.core.ui.mvi.UiState
1115import team.aliens.dms.android.data.auth.model.EmailVerificationType
1216import team.aliens.dms.android.data.auth.repository.AuthRepository
1317import team.aliens.dms.android.data.student.repository.StudentRepository
18+ import team.aliens.dms.android.shared.validator.checkIfEmailValid
1419import team.aliens.dms.android.shared.validator.checkIfPasswordValid
1520import java.util.UUID
1621import javax.inject.Inject
1722
23+ const val SEARCH_DEBOUNCE_MILLIS = 1000L
24+
1825@HiltViewModel
1926class ResetPasswordViewModel @Inject constructor(
2027 private val studentRepository : StudentRepository ,
@@ -27,6 +34,10 @@ class ResetPasswordViewModel @Inject constructor(
2734 ๊ฒ์ฌ์์ ๊ฐ๋ฅ์ด ๋จ๊ฒ ๋๋ค๋ฉด "์ด๋ฉ์ผ ์ธ์ฆ๋ฒํธ ๋ณด๋ด๊ธฐ APi"๋ฅผ ์ฌ์ฉํด์ ์ฌ์ฉ์ ์ด๋ฉ์ผ์ ์ด๋ฉ์ผ์ ๋ฐ์กํฉ๋๋ค.
2835 ๊ทธ๋ฆฌ๊ณ ์ด๋ฉ์ผ ์ธ์ฆ๋ฒํธ ํ์ธ Api๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์ฆ์ ์๋ฃํ๊ณ Students์ ๋น๋ฐ๋ฒํธ ์ฌ์ค์ Api๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ค์ ํฉ๋๋ค.*/
2936
37+ init {
38+ debounceName()
39+ }
40+
3041 override fun processIntent (intent : ResetPasswordIntent ) {
3142 when (intent) {
3243 ResetPasswordIntent .SetPassword -> resetPassword()
@@ -43,6 +54,17 @@ class ResetPasswordViewModel @Inject constructor(
4354 }
4455 }
4556
57+ @OptIn(FlowPreview ::class )
58+ private fun debounceName () {
59+ viewModelScope.launch {
60+ stateFlow.map { it.accountId }.distinctUntilChanged().debounce(SEARCH_DEBOUNCE_MILLIS ).collect {
61+ if (it.isNotBlank()) {
62+ checkIdExists()
63+ }
64+ }
65+ }
66+ }
67+
4668 private fun resetPassword () = viewModelScope.launch(Dispatchers .IO ) {
4769 val capturedState = stateFlow.value
4870 if (capturedState.newPassword != capturedState.newPasswordRepeat) {
@@ -82,30 +104,40 @@ class ResetPasswordViewModel @Inject constructor(
82104 reduce(
83105 newState = stateFlow.value.copy(
84106 hashedEmail = it,
107+ isAccountIdError = false ,
85108 ),
86109 )
87110 postSideEffect(ResetPasswordSideEffect .AccountIdExists )
88111 }.onFailure {
112+ reduce(
113+ newState = stateFlow.value.copy(
114+ isAccountIdError = true ,
115+ ),
116+ )
89117 postSideEffect(ResetPasswordSideEffect .AccountIdNotExists )
90118 }
91119 }
92120
93121 private fun sendEmailVerificationCode (email : String ) =
94- runCatching {
95- viewModelScope.launch(Dispatchers .IO ) {
122+ viewModelScope.launch(Dispatchers .IO ) {
123+ if (! checkIfEmailValid(email)) {
124+ postSideEffect(ResetPasswordSideEffect .InvalidEmailFormat )
125+ return @launch
126+ }
127+ runCatching {
96128 authRepository.sendEmailVerificationCode(
97129 email = email,
98130 type = EmailVerificationType .PASSWORD ,
99131 )
132+ }.onSuccess {
133+ postSideEffect(ResetPasswordSideEffect .SendEmailVerificationCodeSuccess )
134+ }.onFailure {
135+ postSideEffect(ResetPasswordSideEffect .EmailVerificationUserNotFound )
100136 }
101- }.onSuccess {
102- postSideEffect(ResetPasswordSideEffect .SendEmailVerificationCodeSuccess )
103- }.onFailure {
104- postSideEffect(ResetPasswordSideEffect .EmailVerificationTooManyRequest )
105137 }
106138
107139 private fun updateEmailVerificationCode (value : String ) = run {
108- if (value.length > ResetPasswordViewModel . EMAIL_VERIFICATION_CODE_LENGTH ) {
140+ if (value.length > EMAIL_VERIFICATION_CODE_LENGTH ) {
109141 return @run false
110142 }
111143 reduce(newState = stateFlow.value.copy(emailVerificationCode = value))
@@ -182,6 +214,7 @@ data class ResetPasswordUiState(
182214 val newPasswordRepeat : String ,
183215 val hashedEmail : String ,
184216 val sessionId : UUID ,
217+ val isAccountIdError : Boolean ,
185218) : UiState() {
186219 companion object {
187220 fun initial () = ResetPasswordUiState (
@@ -193,6 +226,7 @@ data class ResetPasswordUiState(
193226 newPasswordRepeat = " " ,
194227 hashedEmail = " " ,
195228 sessionId = UUID .randomUUID(),
229+ isAccountIdError = false
196230 )
197231 }
198232}
@@ -223,5 +257,6 @@ sealed class ResetPasswordSideEffect : SideEffect() {
223257 data object EmailVerificationCodeIncorrect : ResetPasswordSideEffect ()
224258 data object EmailVerificationSessionReset : ResetPasswordSideEffect ()
225259 data object EmailVerificationSessionResetFailed : ResetPasswordSideEffect ()
226- data object EmailVerificationTooManyRequest : ResetPasswordSideEffect ()
260+ data object EmailVerificationUserNotFound : ResetPasswordSideEffect ()
261+ data object InvalidEmailFormat : ResetPasswordSideEffect ()
227262}
0 commit comments