Skip to content

Commit

Permalink
fix login screen's logic error.
Browse files Browse the repository at this point in the history
  • Loading branch information
qingmei2 committed Apr 15, 2019
1 parent 9857b45 commit a0f4bb9
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 87 deletions.
3 changes: 2 additions & 1 deletion app/src/main/java/com/qingmei2/sample/ui/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.qingmei2.sample.ui

import android.content.Intent
import androidx.fragment.app.FragmentActivity
import androidx.navigation.Navigation
import com.qingmei2.rhine.base.view.activity.BaseActivity
import com.qingmei2.sample.R
Expand All @@ -14,7 +15,7 @@ class MainActivity : BaseActivity() {

companion object {

fun launch(activity: androidx.fragment.app.FragmentActivity) =
fun launch(activity: FragmentActivity) =
activity.apply {
startActivity(Intent(this, MainActivity::class.java))
finish()
Expand Down
11 changes: 7 additions & 4 deletions app/src/main/java/com/qingmei2/sample/ui/login/LoginFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.qingmei2.rhine.base.view.fragment.BaseFragment
import com.qingmei2.rhine.ext.livedata.map
import com.qingmei2.rhine.ext.livedata.toReactiveStream
import com.qingmei2.rhine.ext.reactivex.clicksThrottleFirst
import com.qingmei2.rhine.util.RxSchedulers
import com.qingmei2.sample.R
import com.qingmei2.sample.ui.MainActivity
import com.uber.autodispose.autoDisposable
Expand All @@ -24,7 +25,7 @@ class LoginFragment : BaseFragment() {

override val layoutId: Int = R.layout.fragment_login

val mViewModel: LoginViewModel by instance()
private val mViewModel: LoginViewModel by instance()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Expand All @@ -38,11 +39,13 @@ class LoginFragment : BaseFragment() {
.autoDisposable(scopeProvider)
.subscribe { mProgressBar.visibility = it }
mViewModel.username.toReactiveStream()
.distinctUntilChanged()
.observeOn(RxSchedulers.ui)
.filter { it != tvUsername.text.toString() }
.autoDisposable(scopeProvider)
.subscribe { tvUsername.setText(it, TextView.BufferType.EDITABLE) }
mViewModel.password.toReactiveStream()
.distinctUntilChanged()
.observeOn(RxSchedulers.ui)
.filter { it != tvPassword.text.toString() }
.autoDisposable(scopeProvider)
.subscribe { tvPassword.setText(it, TextView.BufferType.EDITABLE) }

Expand All @@ -53,7 +56,7 @@ class LoginFragment : BaseFragment() {

mBtnSignIn.clicksThrottleFirst()
.autoDisposable(scopeProvider)
.subscribe { mViewModel.login() }
.subscribe { mViewModel.login(tvUsername.text.toString(), tvPassword.text.toString()) }

tvUsername.textChanges()
.autoDisposable(scopeProvider)
Expand Down
38 changes: 18 additions & 20 deletions app/src/main/java/com/qingmei2/sample/ui/login/LoginRepository.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.qingmei2.sample.ui.login

import arrow.core.Either
import arrow.core.Tuple2
import com.qingmei2.rhine.base.repository.BaseRepositoryBoth
import com.qingmei2.rhine.base.repository.ILocalDataSource
import com.qingmei2.rhine.base.repository.IRemoteDataSource
Expand All @@ -15,7 +14,6 @@ import com.qingmei2.sample.manager.UserManager
import com.qingmei2.sample.repository.UserInfoRepository
import io.reactivex.Completable
import io.reactivex.Flowable
import io.reactivex.Single

class LoginRepository(
remoteDataSource: LoginRemoteDataSource,
Expand All @@ -39,12 +37,8 @@ class LoginRepository(
.doOnError { localDataSource.clearPrefsUser() }
}

fun prefsUser(): Flowable<Either<Errors, Tuple2<String, String>>> {
return localDataSource.fetchPrefsUser()
}

fun prefsAutoLogin(): Single<Boolean> {
return localDataSource.isAutoLogin()
fun fetchAutoLogin(): Flowable<AutoLoginEvent> {
return localDataSource.fetchAutoLogin()
}
}

Expand Down Expand Up @@ -73,10 +67,6 @@ class LoginLocalDataSource(
private val userRepository: UserInfoRepository
) : ILocalDataSource {

fun isAutoLogin(): Single<Boolean> {
return Single.just(userRepository.isAutoLogin)
}

fun savePrefsUser(username: String, password: String): Completable {
return Completable.fromAction {
userRepository.username = username
Expand All @@ -91,11 +81,19 @@ class LoginLocalDataSource(
}
}

fun fetchPrefsUser(): Flowable<Either<Errors, Tuple2<String, String>>> =
Flowable.just(userRepository).map {
when (it.username.isNotEmpty() && it.password.isNotEmpty()) {
true -> Either.right(Tuple2(it.username, it.password))
false -> Either.left(Errors.EmptyResultsError)
}
}
}
fun fetchAutoLogin(): Flowable<AutoLoginEvent> {
val username = userRepository.username
val password = userRepository.password
val isAutoLogin = userRepository.isAutoLogin
return Flowable.just(when (username.isNotEmpty() && password.isNotEmpty() && isAutoLogin) {
true -> AutoLoginEvent(true, username, password)
false -> AutoLoginEvent(false, "", "")
})
}
}

data class AutoLoginEvent(
val autoLogin: Boolean,
val username: String,
val password: String
)
58 changes: 24 additions & 34 deletions app/src/main/java/com/qingmei2/sample/ui/login/LoginViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ package com.qingmei2.sample.ui.login
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import arrow.core.*
import arrow.core.Option
import arrow.core.none
import arrow.core.some
import com.qingmei2.rhine.base.viewmodel.BaseViewModel
import com.qingmei2.rhine.ext.arrow.whenNotNull
import com.qingmei2.rhine.ext.livedata.toReactiveStream
import com.qingmei2.rhine.util.SingletonHolderSingleArg
import com.qingmei2.sample.base.Result
import com.qingmei2.sample.http.Errors
import com.qingmei2.sample.entity.UserInfo
import com.qingmei2.sample.http.Errors
import com.qingmei2.sample.http.globalHandleError
import com.qingmei2.sample.utils.toast
import com.uber.autodispose.autoDisposable
import io.reactivex.Single
import io.reactivex.functions.BiFunction
import retrofit2.HttpException

@SuppressWarnings("checkResult")
Expand All @@ -32,12 +33,12 @@ class LoginViewModel(

val userInfo: MutableLiveData<UserInfo> = MutableLiveData()

private val autoLogin: MutableLiveData<Boolean> = MutableLiveData()
private val autoLogin: MutableLiveData<AutoLoginEvent> = MutableLiveData()

init {
autoLogin.toReactiveStream()
.filter { it }
.doOnNext { login() }
.filter { it.autoLogin }
.doOnNext { login(it.username, it.password) }
.autoDisposable(this)
.subscribe()

Expand Down Expand Up @@ -67,29 +68,20 @@ class LoginViewModel(
.subscribe()
}

private fun initAutoLogin() =
Single.zip(repo.prefsUser().firstOrError(), repo.prefsAutoLogin(),
BiFunction { either: Either<Errors, Tuple2<String, String>>, autoLogin: Boolean ->
autoLogin to either
})
.doOnSuccess { pair ->
pair.second.fold({ error ->
applyState(error = error.some())
}, { tuple2 ->
applyState(
username = tuple2.a.some(),
password = tuple2.b.some(),
autoLogin = pair.first
)
})
}

private fun initAutoLogin(): Single<AutoLoginEvent> {
return repo.fetchAutoLogin()
.singleOrError()
.onErrorReturn { AutoLoginEvent(false, "", "") }
.doOnSuccess { event ->
applyState(autoLogin = event, loginIndicator = false)
}
}

fun login() {
when (username.value.isNullOrEmpty() || password.value.isNullOrEmpty()) {
fun login(username: String?, password: String?) {
when (username.isNullOrEmpty() || password.isNullOrEmpty()) {
true -> applyState(error = Errors.EmptyInputError.some())
false -> repo
.login(username.value!!, password.value!!)
.login(username, password)
.compose(globalHandleError())
.map { either ->
either.fold({
Expand All @@ -115,20 +107,18 @@ class LoginViewModel(

private fun applyState(user: Option<UserInfo> = none(),
error: Option<Throwable> = none(),
username: Option<String> = none(),
password: Option<String> = none(),
loginIndicator: Boolean? = null,
autoLogin: Boolean = false) {
autoLogin: AutoLoginEvent? = null) {
this.error.postValue(error)

this.userInfo.postValue(user.orNull())

username.whenNotNull { this.username.value = it }
password.whenNotNull { this.password.value = it }

loginIndicator?.apply(loginIndicatorVisible::postValue)

this.autoLogin.postValue(autoLogin)
autoLogin?.let {
this.username.postValue(it.username)
this.password.postValue(it.password)
this.autoLogin.postValue(autoLogin)
}
}
}

Expand Down
45 changes: 17 additions & 28 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,31 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">

<data>
<fragment
android:id="@+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/navigation_main" />

<variable
name="activity"
type="com.qingmei2.sample.ui.MainActivity" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment
android:id="@+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/navigation_main" />

</androidx.constraintlayout.widget.ConstraintLayout>

</layout>
</androidx.constraintlayout.widget.ConstraintLayout>

0 comments on commit a0f4bb9

Please sign in to comment.