mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-16 20:10:04 +03:00
Login screens: reset state when navigating back
This commit is contained in:
parent
6525314af8
commit
7f1f98c2e5
14 changed files with 141 additions and 16 deletions
|
@ -36,6 +36,7 @@ import im.vector.riotx.features.home.group.GroupListFragment
|
|||
import im.vector.riotx.features.home.room.detail.RoomDetailFragment
|
||||
import im.vector.riotx.features.home.room.list.RoomListFragment
|
||||
import im.vector.riotx.features.login.LoginFragment
|
||||
import im.vector.riotx.features.login.LoginServerUrlFormFragment
|
||||
import im.vector.riotx.features.login.LoginSsoFallbackFragment
|
||||
import im.vector.riotx.features.reactions.EmojiSearchResultFragment
|
||||
import im.vector.riotx.features.roomdirectory.PublicRoomsFragment
|
||||
|
@ -194,4 +195,10 @@ interface FragmentModule {
|
|||
@IntoMap
|
||||
@FragmentKey(PublicRoomsFragment::class)
|
||||
fun bindPublicRoomsFragment(fragment: PublicRoomsFragment): Fragment
|
||||
|
||||
// TODO Add all other LoginFragment
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(LoginServerUrlFormFragment::class)
|
||||
fun bindLoginServerUrlFormFragment(fragment: LoginServerUrlFormFragment): Fragment
|
||||
}
|
||||
|
|
|
@ -20,12 +20,13 @@ import android.os.Bundle
|
|||
import android.view.View
|
||||
import androidx.annotation.CallSuper
|
||||
import com.airbnb.mvrx.activityViewModel
|
||||
import im.vector.riotx.core.platform.OnBackPressed
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
|
||||
/**
|
||||
* Parent Fragment for all the login/registration screens
|
||||
*/
|
||||
abstract class AbstractLoginFragment() : VectorBaseFragment() {
|
||||
abstract class AbstractLoginFragment : VectorBaseFragment(), OnBackPressed {
|
||||
|
||||
protected val viewModel: LoginViewModel by activityViewModel()
|
||||
protected lateinit var loginSharedActionViewModel: LoginSharedActionViewModel
|
||||
|
@ -37,4 +38,12 @@ abstract class AbstractLoginFragment() : VectorBaseFragment() {
|
|||
loginSharedActionViewModel = activityViewModelProvider.get(LoginSharedActionViewModel::class.java)
|
||||
}
|
||||
|
||||
override fun onBackPressed(): Boolean {
|
||||
resetViewModel()
|
||||
// Do not consume the Back event
|
||||
return false
|
||||
}
|
||||
|
||||
// Reset any modification of the viewModel by the current fragment
|
||||
abstract fun resetViewModel()
|
||||
}
|
||||
|
|
|
@ -20,10 +20,18 @@ import im.vector.matrix.android.api.auth.data.Credentials
|
|||
import im.vector.riotx.core.platform.VectorViewModelAction
|
||||
|
||||
sealed class LoginAction : VectorViewModelAction {
|
||||
data class UpdateServerType(val serverType: ServerType) : LoginAction()
|
||||
data class UpdateHomeServer(val homeServerUrl: String) : LoginAction()
|
||||
data class UpdateSignMode(val signMode: SignMode) : LoginAction()
|
||||
data class Login(val login: String, val password: String) : LoginAction()
|
||||
data class SsoLoginSuccess(val credentials: Credentials) : LoginAction()
|
||||
data class InitWith(val loginConfig: LoginConfig) : LoginAction()
|
||||
data class UpdateServerType(val serverType: ServerType) : LoginAction()
|
||||
data class UpdateSignMode(val signMode: SignMode) : LoginAction()
|
||||
|
||||
// Reset actions
|
||||
open class ResetAction : LoginAction()
|
||||
|
||||
object ResetHomeServerType : ResetAction()
|
||||
object ResetHomeServerUrl : ResetAction()
|
||||
object ResetSignMode : ResetAction()
|
||||
object ResetLogin : ResetAction()
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ class LoginActivity : VectorBaseActivity() {
|
|||
when (it) {
|
||||
is LoginNavigation.OpenServerSelection -> addFragmentToBackstack(R.id.simpleFragmentContainer, LoginServerSelectionFragment::class.java)
|
||||
is LoginNavigation.OnServerSelectionDone -> onServerSelectionDone()
|
||||
is LoginNavigation.OnSignModeSelected -> onSignModeSelected()
|
||||
is LoginNavigation.OnSignModeSelected -> onSignModeSelected(it)
|
||||
is LoginNavigation.OpenSsoLoginFallback -> addFragmentToBackstack(R.id.simpleFragmentContainer, LoginSsoFallbackFragment::class.java)
|
||||
is LoginNavigation.GoBack -> supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||
}
|
||||
|
@ -85,10 +85,12 @@ class LoginActivity : VectorBaseActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun onSignModeSelected() = withState(loginViewModel) {
|
||||
when (it.signMode) {
|
||||
SignMode.SignUp -> Unit // TODO addFragmentToBackstack(R.id.simpleFragmentContainer, SignUpFragment::class.java)
|
||||
SignMode.SignIn -> addFragmentToBackstack(R.id.simpleFragmentContainer, LoginFragment::class.java)
|
||||
private fun onSignModeSelected(mode: LoginNavigation.OnSignModeSelected) {
|
||||
// We cannot use the state, it is not ready...
|
||||
when (mode.signMode) {
|
||||
SignMode.Unknown -> error("Sign mode has to be set before calling this method")
|
||||
SignMode.SignUp -> Unit // TODO addFragmentToBackstack(R.id.simpleFragmentContainer, SignUpFragment::class.java)
|
||||
SignMode.SignIn -> addFragmentToBackstack(R.id.simpleFragmentContainer, LoginFragment::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,10 @@ class LoginFragment @Inject constructor() : AbstractLoginFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun resetViewModel() {
|
||||
viewModel.handle(LoginAction.ResetLogin)
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) { state ->
|
||||
TransitionManager.beginDelayedTransition(login_fragment)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import im.vector.riotx.core.platform.VectorSharedAction
|
|||
sealed class LoginNavigation : VectorSharedAction {
|
||||
object OpenServerSelection : LoginNavigation()
|
||||
object OnServerSelectionDone : LoginNavigation()
|
||||
object OnSignModeSelected : LoginNavigation()
|
||||
data class OnSignModeSelected(val signMode: SignMode) : LoginNavigation()
|
||||
object OpenSsoLoginFallback : LoginNavigation()
|
||||
object GoBack : LoginNavigation()
|
||||
}
|
||||
|
|
|
@ -77,6 +77,10 @@ class LoginServerSelectionFragment @Inject constructor() : AbstractLoginFragment
|
|||
loginSharedActionViewModel.post(LoginNavigation.OnServerSelectionDone)
|
||||
}
|
||||
|
||||
override fun resetViewModel() {
|
||||
viewModel.handle(LoginAction.ResetHomeServerType)
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) {
|
||||
updateSelectedChoice(it.serverType)
|
||||
}
|
||||
|
|
|
@ -16,14 +16,16 @@
|
|||
|
||||
package im.vector.riotx.features.login
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.core.view.isVisible
|
||||
import butterknife.OnClick
|
||||
import com.airbnb.mvrx.withState
|
||||
import com.airbnb.mvrx.*
|
||||
import com.jakewharton.rxbinding3.widget.textChanges
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.error.ErrorFormatter
|
||||
import im.vector.riotx.core.utils.openUrlInExternalBrowser
|
||||
import kotlinx.android.synthetic.main.fragment_login_server_url_form.*
|
||||
import javax.inject.Inject
|
||||
|
@ -31,7 +33,9 @@ import javax.inject.Inject
|
|||
/**
|
||||
*
|
||||
*/
|
||||
class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment() {
|
||||
class LoginServerUrlFormFragment @Inject constructor(
|
||||
private val errorFormatter: ErrorFormatter
|
||||
) : AbstractLoginFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_login_server_url_form
|
||||
|
||||
|
@ -64,10 +68,29 @@ class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment()
|
|||
openUrlInExternalBrowser(requireActivity(), "https://example.org")
|
||||
}
|
||||
|
||||
override fun resetViewModel() {
|
||||
viewModel.handle(LoginAction.ResetHomeServerUrl)
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@OnClick(R.id.loginServerUrlFormSubmit)
|
||||
fun submit() {
|
||||
// TODO Static check of homeserver url, empty, malformed, etc.
|
||||
viewModel.handle(LoginAction.InitWith(LoginConfig(loginServerUrlFormHomeServerUrl.text.toString(), null)))
|
||||
// Static check of homeserver url, empty, malformed, etc.
|
||||
var serverUrl = loginServerUrlFormHomeServerUrl.text.toString()
|
||||
|
||||
when {
|
||||
serverUrl.isBlank() -> {
|
||||
loginServerUrlFormHomeServerUrlTil.error = getString(R.string.login_error_invalid_home_server)
|
||||
}
|
||||
else -> {
|
||||
if (serverUrl.startsWith("http").not()) {
|
||||
serverUrl = "https://$serverUrl"
|
||||
loginServerUrlFormHomeServerUrl.setText(serverUrl)
|
||||
|
||||
}
|
||||
viewModel.handle(LoginAction.UpdateHomeServer(serverUrl))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) { state ->
|
||||
|
@ -90,5 +113,25 @@ class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment()
|
|||
}
|
||||
else -> error("This fragment should not be display in matrix.org mode")
|
||||
}
|
||||
|
||||
when (state.asyncHomeServerLoginFlowRequest) {
|
||||
is Uninitialized -> {
|
||||
progressBar.isVisible = false
|
||||
touchArea.isVisible = false
|
||||
}
|
||||
is Loading -> {
|
||||
progressBar.isVisible = true
|
||||
touchArea.isVisible = true
|
||||
}
|
||||
is Fail -> {
|
||||
progressBar.isVisible = false
|
||||
touchArea.isVisible = false
|
||||
// TODO Error text is not correct
|
||||
loginServerUrlFormHomeServerUrlTil.error = errorFormatter.toHumanReadable(state.asyncHomeServerLoginFlowRequest.error)
|
||||
}
|
||||
is Success -> {
|
||||
// The home server is valid, the next screen will be opened by the Activity
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,10 @@ class LoginSignUpSignInSelectionFragment @Inject constructor() : AbstractLoginFr
|
|||
loginSharedActionViewModel.post(LoginNavigation.OnSignModeSelected)
|
||||
}
|
||||
|
||||
override fun resetViewModel() {
|
||||
viewModel.handle(LoginAction.ResetSignMode)
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) {
|
||||
updateViews(it.serverType)
|
||||
}
|
||||
|
|
|
@ -31,4 +31,8 @@ class LoginSplashFragment @Inject constructor() : AbstractLoginFragment() {
|
|||
fun getStarted() {
|
||||
loginSharedActionViewModel.post(LoginNavigation.OpenServerSelection)
|
||||
}
|
||||
|
||||
override fun resetViewModel() {
|
||||
// Nothing to do
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ import javax.inject.Inject
|
|||
|
||||
/**
|
||||
* Only login is supported for the moment
|
||||
* TODO Migrate to new flow
|
||||
*/
|
||||
class LoginSsoFallbackFragment @Inject constructor() : VectorBaseFragment(), OnBackPressed {
|
||||
|
||||
|
|
|
@ -68,6 +68,44 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
|||
is LoginAction.UpdateHomeServer -> handleUpdateHomeserver(action)
|
||||
is LoginAction.Login -> handleLogin(action)
|
||||
is LoginAction.SsoLoginSuccess -> handleSsoLoginSuccess(action)
|
||||
is LoginAction.ResetAction -> handleResetAction(action)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleResetAction(action: LoginAction.ResetAction) {
|
||||
// Cancel any request
|
||||
currentTask?.cancel()
|
||||
currentTask = null
|
||||
|
||||
when (action) {
|
||||
LoginAction.ResetLogin -> {
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Uninitialized
|
||||
)
|
||||
}
|
||||
}
|
||||
LoginAction.ResetHomeServerUrl -> {
|
||||
setState {
|
||||
copy(
|
||||
asyncHomeServerLoginFlowRequest = Uninitialized
|
||||
)
|
||||
}
|
||||
}
|
||||
LoginAction.ResetHomeServerType -> {
|
||||
setState {
|
||||
copy(
|
||||
serverType = ServerType.MatrixOrg
|
||||
)
|
||||
}
|
||||
}
|
||||
LoginAction.ResetSignMode -> {
|
||||
setState {
|
||||
copy(
|
||||
signMode = SignMode.Unknown
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +145,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
|||
)
|
||||
}
|
||||
|
||||
authenticator.authenticate(homeServerConnectionConfigFinal, action.login, action.password, object : MatrixCallback<Session> {
|
||||
currentTask = authenticator.authenticate(homeServerConnectionConfigFinal, action.login, action.password, object : MatrixCallback<Session> {
|
||||
override fun onSuccess(data: Session) {
|
||||
onSessionCreated(data)
|
||||
}
|
||||
|
@ -153,7 +191,6 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
|||
}
|
||||
|
||||
private fun handleUpdateHomeserver(action: LoginAction.UpdateHomeServer) = withState { state ->
|
||||
|
||||
var newConfig: HomeServerConnectionConfig? = null
|
||||
Try {
|
||||
val homeServerUri = action.homeServerUrl
|
||||
|
@ -167,6 +204,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
|||
&& state.asyncHomeServerLoginFlowRequest is Success) return@withState
|
||||
|
||||
currentTask?.cancel()
|
||||
currentTask = null
|
||||
homeServerConnectionConfig = newConfig
|
||||
|
||||
val homeServerConnectionConfigFinal = homeServerConnectionConfig
|
||||
|
|
|
@ -22,7 +22,7 @@ import com.airbnb.mvrx.Uninitialized
|
|||
|
||||
data class LoginViewState(
|
||||
val serverType: ServerType = ServerType.MatrixOrg,
|
||||
val signMode: SignMode = SignMode.SignUp,
|
||||
val signMode: SignMode = SignMode.Unknown,
|
||||
val asyncLoginAction: Async<Unit> = Uninitialized,
|
||||
val asyncHomeServerLoginFlowRequest: Async<LoginMode> = Uninitialized
|
||||
) : MvRxState
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package im.vector.riotx.features.login
|
||||
|
||||
enum class SignMode {
|
||||
Unknown,
|
||||
// Account creation
|
||||
SignUp,
|
||||
// Login
|
||||
|
|
Loading…
Add table
Reference in a new issue