mirror of
https://github.com/element-hq/element-android
synced 2024-10-26 20:57:20 +03:00
SoftLogout: Inherit from Login stuff to get free forgot password functionality
This commit is contained in:
parent
17bcd680b0
commit
14562f7285
6 changed files with 47 additions and 39 deletions
|
@ -20,6 +20,7 @@ import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.annotation.CallSuper
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
|
@ -49,13 +50,14 @@ import javax.inject.Inject
|
||||||
/**
|
/**
|
||||||
* The LoginActivity manages the fragment navigation and also display the loading View
|
* The LoginActivity manages the fragment navigation and also display the loading View
|
||||||
*/
|
*/
|
||||||
class LoginActivity : VectorBaseActivity(), ToolbarConfigurable {
|
open class LoginActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||||
|
|
||||||
private val loginViewModel: LoginViewModel by viewModel()
|
private val loginViewModel: LoginViewModel by viewModel()
|
||||||
private lateinit var loginSharedActionViewModel: LoginSharedActionViewModel
|
private lateinit var loginSharedActionViewModel: LoginSharedActionViewModel
|
||||||
|
|
||||||
@Inject lateinit var loginViewModelFactory: LoginViewModel.Factory
|
@Inject lateinit var loginViewModelFactory: LoginViewModel.Factory
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
override fun injectWith(injector: ScreenComponent) {
|
override fun injectWith(injector: ScreenComponent) {
|
||||||
injector.inject(this)
|
injector.inject(this)
|
||||||
}
|
}
|
||||||
|
@ -75,17 +77,17 @@ class LoginActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||||
// Find findViewById does not work, I do not know why
|
// Find findViewById does not work, I do not know why
|
||||||
// findViewById<View?>(R.id.loginLogo)
|
// findViewById<View?>(R.id.loginLogo)
|
||||||
?.children
|
?.children
|
||||||
?.first { it.id == R.id.loginLogo }
|
?.firstOrNull { it.id == R.id.loginLogo }
|
||||||
?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") }
|
?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") }
|
||||||
// TODO
|
// TODO
|
||||||
ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim)
|
ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getLayoutRes() = R.layout.activity_login
|
final override fun getLayoutRes() = R.layout.activity_login
|
||||||
|
|
||||||
override fun initUiAndData() {
|
override fun initUiAndData() {
|
||||||
if (isFirstCreation()) {
|
if (isFirstCreation()) {
|
||||||
addFragment(R.id.loginFragmentContainer, LoginSplashFragment::class.java)
|
addFirstFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get config extra
|
// Get config extra
|
||||||
|
@ -116,6 +118,10 @@ class LoginActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||||
.disposeOnDestroy()
|
.disposeOnDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun addFirstFragment() {
|
||||||
|
addFragment(R.id.loginFragmentContainer, LoginSplashFragment::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleLoginNavigation(loginNavigation: LoginNavigation) {
|
private fun handleLoginNavigation(loginNavigation: LoginNavigation) {
|
||||||
// Assigning to dummy make sure we do not forget a case
|
// Assigning to dummy make sure we do not forget a case
|
||||||
@Suppress("UNUSED_VARIABLE")
|
@Suppress("UNUSED_VARIABLE")
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package im.vector.riotx.features.login
|
package im.vector.riotx.features.login
|
||||||
|
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
import com.airbnb.mvrx.*
|
import com.airbnb.mvrx.*
|
||||||
import com.squareup.inject.assisted.Assisted
|
import com.squareup.inject.assisted.Assisted
|
||||||
import com.squareup.inject.assisted.AssistedInject
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
|
@ -37,6 +38,7 @@ import im.vector.riotx.core.utils.DataSource
|
||||||
import im.vector.riotx.core.utils.PublishDataSource
|
import im.vector.riotx.core.utils.PublishDataSource
|
||||||
import im.vector.riotx.features.notifications.PushRuleTriggerListener
|
import im.vector.riotx.features.notifications.PushRuleTriggerListener
|
||||||
import im.vector.riotx.features.session.SessionListener
|
import im.vector.riotx.features.session.SessionListener
|
||||||
|
import im.vector.riotx.features.signout.soft.SoftLogoutActivity
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.concurrent.CancellationException
|
import java.util.concurrent.CancellationException
|
||||||
|
|
||||||
|
@ -60,8 +62,11 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
override fun create(viewModelContext: ViewModelContext, state: LoginViewState): LoginViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: LoginViewState): LoginViewModel? {
|
||||||
val activity: LoginActivity = (viewModelContext as ActivityViewModelContext).activity()
|
return when (val activity: FragmentActivity = (viewModelContext as ActivityViewModelContext).activity()) {
|
||||||
return activity.loginViewModelFactory.create(state)
|
is LoginActivity -> activity.loginViewModelFactory.create(state)
|
||||||
|
is SoftLogoutActivity -> activity.loginViewModelFactory.create(state)
|
||||||
|
else -> error("Invalid Activity")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +457,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startAuthenticationFlow() {
|
private fun startAuthenticationFlow() {
|
||||||
// No op
|
// Ensure Wizard is ready
|
||||||
loginWizard
|
loginWizard
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,17 +26,18 @@ import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.di.ScreenComponent
|
import im.vector.riotx.core.di.ScreenComponent
|
||||||
import im.vector.riotx.core.extensions.replaceFragment
|
import im.vector.riotx.core.extensions.replaceFragment
|
||||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
|
||||||
import im.vector.riotx.features.MainActivity
|
import im.vector.riotx.features.MainActivity
|
||||||
import im.vector.riotx.features.MainActivityArgs
|
import im.vector.riotx.features.MainActivityArgs
|
||||||
|
import im.vector.riotx.features.login.LoginActivity
|
||||||
import kotlinx.android.synthetic.main.activity_login.*
|
import kotlinx.android.synthetic.main.activity_login.*
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In this screen, the user is viewing a message informing that he has been logged out
|
* In this screen, the user is viewing a message informing that he has been logged out
|
||||||
|
* Extends LoginActivity to get the login with SSO and forget password functionality for free
|
||||||
*/
|
*/
|
||||||
class SoftLogoutActivity : VectorBaseActivity() {
|
class SoftLogoutActivity : LoginActivity() {
|
||||||
|
|
||||||
private val softLogoutViewModel: SoftLogoutViewModel by viewModel()
|
private val softLogoutViewModel: SoftLogoutViewModel by viewModel()
|
||||||
// TODO For forgotten pwd
|
// TODO For forgotten pwd
|
||||||
|
@ -46,24 +47,23 @@ class SoftLogoutActivity : VectorBaseActivity() {
|
||||||
@Inject lateinit var session: Session
|
@Inject lateinit var session: Session
|
||||||
|
|
||||||
override fun injectWith(injector: ScreenComponent) {
|
override fun injectWith(injector: ScreenComponent) {
|
||||||
|
super.injectWith(injector)
|
||||||
injector.inject(this)
|
injector.inject(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getLayoutRes() = R.layout.activity_login
|
|
||||||
|
|
||||||
override fun initUiAndData() {
|
override fun initUiAndData() {
|
||||||
super.initUiAndData()
|
super.initUiAndData()
|
||||||
|
|
||||||
if (isFirstCreation()) {
|
|
||||||
replaceFragment(R.id.loginFragmentContainer, SoftLogoutFragment::class.java)
|
|
||||||
}
|
|
||||||
|
|
||||||
softLogoutViewModel
|
softLogoutViewModel
|
||||||
.subscribe(this) {
|
.subscribe(this) {
|
||||||
updateWithState(it)
|
updateWithState(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun addFirstFragment() {
|
||||||
|
replaceFragment(R.id.loginFragmentContainer, SoftLogoutFragment::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateWithState(softLogoutViewState: SoftLogoutViewState) {
|
private fun updateWithState(softLogoutViewState: SoftLogoutViewState) {
|
||||||
if (softLogoutViewState.asyncLoginAction is Success) {
|
if (softLogoutViewState.asyncLoginAction is Success) {
|
||||||
MainActivity.restartApp(this, MainActivityArgs())
|
MainActivity.restartApp(this, MainActivityArgs())
|
||||||
|
|
|
@ -24,13 +24,14 @@ import com.airbnb.mvrx.activityViewModel
|
||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.dialogs.withColoredButton
|
import im.vector.riotx.core.dialogs.withColoredButton
|
||||||
import im.vector.riotx.core.error.ErrorFormatter
|
|
||||||
import im.vector.riotx.core.extensions.cleanup
|
import im.vector.riotx.core.extensions.cleanup
|
||||||
import im.vector.riotx.core.extensions.configureWith
|
import im.vector.riotx.core.extensions.configureWith
|
||||||
import im.vector.riotx.core.extensions.hideKeyboard
|
import im.vector.riotx.core.extensions.hideKeyboard
|
||||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
|
||||||
import im.vector.riotx.features.MainActivity
|
import im.vector.riotx.features.MainActivity
|
||||||
import im.vector.riotx.features.MainActivityArgs
|
import im.vector.riotx.features.MainActivityArgs
|
||||||
|
import im.vector.riotx.features.login.AbstractLoginFragment
|
||||||
|
import im.vector.riotx.features.login.LoginNavigation
|
||||||
|
import im.vector.riotx.features.login.LoginViewState
|
||||||
import kotlinx.android.synthetic.main.fragment_generic_recycler.*
|
import kotlinx.android.synthetic.main.fragment_generic_recycler.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -40,9 +41,8 @@ import javax.inject.Inject
|
||||||
* - or to cleanup all the data
|
* - or to cleanup all the data
|
||||||
*/
|
*/
|
||||||
class SoftLogoutFragment @Inject constructor(
|
class SoftLogoutFragment @Inject constructor(
|
||||||
private val errorFormatter: ErrorFormatter,
|
|
||||||
private val softLogoutController: SoftLogoutController
|
private val softLogoutController: SoftLogoutController
|
||||||
) : VectorBaseFragment(), SoftLogoutController.Listener {
|
) : AbstractLoginFragment(), SoftLogoutController.Listener {
|
||||||
|
|
||||||
private val softLogoutViewModel: SoftLogoutViewModel by activityViewModel()
|
private val softLogoutViewModel: SoftLogoutViewModel by activityViewModel()
|
||||||
|
|
||||||
|
@ -52,9 +52,6 @@ class SoftLogoutFragment @Inject constructor(
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
|
|
||||||
// TODO setupSubmitButton()
|
|
||||||
// TODO setupPasswordReveal()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
|
@ -82,7 +79,7 @@ class SoftLogoutFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun ssoSubmit() {
|
override fun ssoSubmit() {
|
||||||
// TODO
|
// TODO loginSharedActionViewModel.post(LoginNavigation.Sso)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clearData() {
|
override fun clearData() {
|
||||||
|
@ -113,29 +110,28 @@ class SoftLogoutFragment @Inject constructor(
|
||||||
|
|
||||||
private fun cleanupUi() {
|
private fun cleanupUi() {
|
||||||
recyclerView.hideKeyboard()
|
recyclerView.hideKeyboard()
|
||||||
// TODO softLogoutPasswordFieldTil.error = null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupSubmitButton() {
|
|
||||||
// softLogoutPasswordField.textChanges()
|
|
||||||
// .map { it.trim().isNotEmpty() }
|
|
||||||
// .subscribeBy {
|
|
||||||
// softLogoutPasswordFieldTil.error = null
|
|
||||||
// softLogoutSubmit.isEnabled = it
|
|
||||||
// }
|
|
||||||
// .disposeOnDestroyView()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun forgetPasswordClicked() {
|
override fun forgetPasswordClicked() {
|
||||||
// TODO
|
loginSharedActionViewModel.post(LoginNavigation.OnForgetPasswordClicked)
|
||||||
// loginSharedActionViewModel.post(LoginNavigation.OnForgetPasswordClicked)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun revealPasswordClicked() {
|
override fun revealPasswordClicked() {
|
||||||
softLogoutViewModel.handle(SoftLogoutAction.TogglePassword)
|
softLogoutViewModel.handle(SoftLogoutAction.TogglePassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invalidate() = withState(softLogoutViewModel) { state ->
|
override fun updateWithState(state: LoginViewState) {
|
||||||
softLogoutController.update(state)
|
super.updateWithState(state)
|
||||||
|
|
||||||
|
withState(softLogoutViewModel) { state2 ->
|
||||||
|
softLogoutController.update(state2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(throwable: Throwable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resetViewModel() {
|
||||||
|
// No op
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ import im.vector.riotx.core.platform.VectorViewModel
|
||||||
import im.vector.riotx.features.login.LoginMode
|
import im.vector.riotx.features.login.LoginMode
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO Get login flow to tell if it's SSO or Password, or store this info during sigin?
|
* TODO SSO
|
||||||
* TODO Reset password
|
* TODO Reset password
|
||||||
* TODO Test push: disable the pushers?
|
* TODO Test push: disable the pushers?
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
|
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@id/loginLogo"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="60dp"
|
android:layout_height="60dp"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
|
|
Loading…
Reference in a new issue