diff --git a/app/src/main/java/com/kickstarter/viewmodels/ResetPasswordViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/ResetPasswordViewModel.kt index 17755bc708..961a1506e0 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/ResetPasswordViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/ResetPasswordViewModel.kt @@ -3,107 +3,125 @@ package com.kickstarter.viewmodels import com.kickstarter.libs.ActivityViewModel import com.kickstarter.libs.Environment import com.kickstarter.libs.rx.transformers.Transformers +import com.kickstarter.libs.rx.transformers.Transformers.errors +import com.kickstarter.libs.rx.transformers.Transformers.values +import com.kickstarter.libs.utils.ObjectUtils import com.kickstarter.libs.utils.StringUtils import com.kickstarter.models.User import com.kickstarter.services.ApiClientType import com.kickstarter.services.apiresponses.ErrorEnvelope import com.kickstarter.ui.activities.ResetPasswordActivity +import rx.Notification import rx.Observable import rx.subjects.PublishSubject interface ResetPasswordViewModel { - interface Inputs { - /** Call when the email field changes. */ - fun email(emailInput: String) + interface Inputs { + /** Call when the email field changes. */ + fun email(emailInput: String) - /** Call when the reset password button is clicked. */ - fun resetPasswordClick() - } - - interface Outputs { - /** Emits a boolean that determines if the form is in the progress of being submitted. */ - fun isFormSubmitting(): Observable - - /** Emits a boolean that determines if the form validation is passing. */ - fun isFormValid(): Observable - - /** Emits when password reset is completed successfully. */ - fun resetSuccess(): Observable - - /** Emits when password reset fails. */ - fun resetError(): Observable - } - - class ViewModel(val environment: Environment) : ActivityViewModel(environment), Inputs, Outputs { - private val client: ApiClientType = environment.apiClient() - - private val email = PublishSubject.create() - private val resetPasswordClick = PublishSubject.create() - - private val isFormSubmitting = PublishSubject.create() - private val isFormValid = PublishSubject.create() - private val resetSuccess = PublishSubject.create() - private val resetError = PublishSubject.create() - - val inputs: Inputs = this - val outputs: Outputs = this - - init { - this.email - .map(StringUtils::isEmail) - .compose(bindToLifecycle()) - .subscribe(this.isFormValid) - - this.email - .compose(Transformers.takeWhen(this.resetPasswordClick)) - .switchMap(this::submitEmail) - .compose(bindToLifecycle()) - .subscribe { success() } - - this.resetError - .compose(bindToLifecycle()) - .subscribe { this.koala.trackResetPasswordError() } - - this.resetSuccess - .compose(bindToLifecycle()) - .subscribe { this.koala.trackResetPasswordSuccess() } - - this.koala.trackResetPasswordFormView() + /** Call when the reset password button is clicked. */ + fun resetPasswordClick() } - private fun success() { - this.resetSuccess.onNext(null) - } + interface Outputs { + /** Emits a boolean that determines if the form is in the progress of being submitted. */ + fun isFormSubmitting(): Observable - private fun submitEmail(email: String) : Observable { - return this.client.resetPassword(email) - .compose(Transformers.pipeApiErrorsTo(this.resetError)) - .compose(Transformers.neverError()) - .doOnSubscribe { this.isFormSubmitting.onNext(true) } - .doAfterTerminate { this.isFormSubmitting.onNext(false) } - } + /** Emits a boolean that determines if the form validation is passing. */ + fun isFormValid(): Observable - override fun email(emailInput: String) { - this.email.onNext(emailInput) - } - override fun resetPasswordClick() { - this.resetPasswordClick.onNext(null) - } + /** Emits when password reset is completed successfully. */ + fun resetSuccess(): Observable - override fun isFormSubmitting(): Observable { - return this.isFormSubmitting - } - override fun isFormValid(): Observable { - return this.isFormValid + /** Emits when password reset fails. */ + fun resetError(): Observable } - override fun resetSuccess(): Observable { - return this.resetSuccess - } - override fun resetError(): Observable { - return this.resetError - .takeUntil(this.resetSuccess) - .map { it.errorMessage() } + + class ViewModel(val environment: Environment) : ActivityViewModel(environment), Inputs, Outputs { + private val client: ApiClientType = environment.apiClient() + + private val email = PublishSubject.create() + private val resetPasswordClick = PublishSubject.create() + + private val isFormSubmitting = PublishSubject.create() + private val isFormValid = PublishSubject.create() + private val resetSuccess = PublishSubject.create() + private val resetError = PublishSubject.create() + + val inputs: Inputs = this + val outputs: Outputs = this + + init { + this.email + .map(StringUtils::isEmail) + .compose(bindToLifecycle()) + .subscribe(this.isFormValid) + + val resetPasswordNotification = this.email + .compose(Transformers.takeWhen(this.resetPasswordClick)) + .switchMap(this::submitEmail) + + resetPasswordNotification + .compose(values()) + .compose(bindToLifecycle()) + .subscribe { success() } + + resetPasswordNotification + .compose(errors()) + .map { ErrorEnvelope.fromThrowable(it) } + .filter { ObjectUtils.isNotNull(it) } + .compose(bindToLifecycle()) + .subscribe(this.resetError) + + this.resetError + .compose(bindToLifecycle()) + .subscribe { this.koala.trackResetPasswordError() } + + this.resetSuccess + .compose(bindToLifecycle()) + .subscribe { this.koala.trackResetPasswordSuccess() } + + this.koala.trackResetPasswordFormView() + } + + private fun success() { + this.resetSuccess.onNext(null) + } + + private fun submitEmail(email: String): Observable> { + return this.client.resetPassword(email) + .doOnSubscribe { this.isFormSubmitting.onNext(true) } + .doAfterTerminate { this.isFormSubmitting.onNext(false) } + .materialize() + .share() + } + + override fun email(emailInput: String) { + this.email.onNext(emailInput) + } + + override fun resetPasswordClick() { + this.resetPasswordClick.onNext(null) + } + + override fun isFormSubmitting(): Observable { + return this.isFormSubmitting + } + + override fun isFormValid(): Observable { + return this.isFormValid + } + + override fun resetSuccess(): Observable { + return this.resetSuccess + } + + override fun resetError(): Observable { + return this.resetError + .takeUntil(this.resetSuccess) + .map { it.errorMessage() } + } } - } }