Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[🚮] Removing deprecated calls to pipeErrorsTo in Reset Password #448

Merged
merged 1 commit into from
Jan 28, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 103 additions & 85 deletions app/src/main/java/com/kickstarter/viewmodels/ResetPasswordViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<Boolean>

/** Emits a boolean that determines if the form validation is passing. */
fun isFormValid(): Observable<Boolean>

/** Emits when password reset is completed successfully. */
fun resetSuccess(): Observable<Void>

/** Emits when password reset fails. */
fun resetError(): Observable<String>
}

class ViewModel(val environment: Environment) : ActivityViewModel<ResetPasswordActivity>(environment), Inputs, Outputs {
private val client: ApiClientType = environment.apiClient()

private val email = PublishSubject.create<String>()
private val resetPasswordClick = PublishSubject.create<Void>()

private val isFormSubmitting = PublishSubject.create<Boolean>()
private val isFormValid = PublishSubject.create<Boolean>()
private val resetSuccess = PublishSubject.create<Void>()
private val resetError = PublishSubject.create<ErrorEnvelope>()

val inputs: Inputs = this
val outputs: Outputs = this

init {
this.email
.map(StringUtils::isEmail)
.compose(bindToLifecycle())
.subscribe(this.isFormValid)

this.email
.compose<String>(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<Boolean>

private fun submitEmail(email: String) : Observable<User> {
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<Boolean>

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<Void>

override fun isFormSubmitting(): Observable<Boolean> {
return this.isFormSubmitting
}
override fun isFormValid(): Observable<Boolean> {
return this.isFormValid
/** Emits when password reset fails. */
fun resetError(): Observable<String>
}
override fun resetSuccess(): Observable<Void> {
return this.resetSuccess
}
override fun resetError(): Observable<String> {
return this.resetError
.takeUntil(this.resetSuccess)
.map { it.errorMessage() }

class ViewModel(val environment: Environment) : ActivityViewModel<ResetPasswordActivity>(environment), Inputs, Outputs {
private val client: ApiClientType = environment.apiClient()

private val email = PublishSubject.create<String>()
private val resetPasswordClick = PublishSubject.create<Void>()

private val isFormSubmitting = PublishSubject.create<Boolean>()
private val isFormValid = PublishSubject.create<Boolean>()
private val resetSuccess = PublishSubject.create<Void>()
private val resetError = PublishSubject.create<ErrorEnvelope>()

val inputs: Inputs = this
val outputs: Outputs = this

init {
this.email
.map(StringUtils::isEmail)
.compose(bindToLifecycle())
.subscribe(this.isFormValid)

val resetPasswordNotification = this.email
.compose<String>(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<Notification<User>> {
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<Boolean> {
return this.isFormSubmitting
}

override fun isFormValid(): Observable<Boolean> {
return this.isFormValid
}

override fun resetSuccess(): Observable<Void> {
return this.resetSuccess
}

override fun resetError(): Observable<String> {
return this.resetError
.takeUntil(this.resetSuccess)
.map { it.errorMessage() }
}
}
}
}