From 9abf6e37d1d15d90bf543efe0905808b4a2ae96f Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 6 Jun 2022 15:33:00 +0100 Subject: [PATCH] adding updated forgot password email input and breaker screens --- .../features/onboarding/OnboardingAction.kt | 2 +- .../onboarding/OnboardingViewEvents.kt | 2 +- .../onboarding/OnboardingViewModel.kt | 2 +- .../ftueauth/FtueAuthCombinedLoginFragment.kt | 1 + .../FtueAuthResetPasswordBreakerFragment.kt | 74 ++++++++++ ...FtueAuthResetPasswordEmailEntryFragment.kt | 73 ++++++++++ .../onboarding/ftueauth/FtueAuthVariant.kt | 35 +++-- .../fragment_ftue_reset_password_breaker.xml | 130 +++++++++++++++++ ...agment_ftue_reset_password_email_input.xml | 131 ++++++++++++++++++ vector/src/main/res/values/donottranslate.xml | 2 + .../onboarding/OnboardingViewModelTest.kt | 2 +- 11 files changed, 440 insertions(+), 14 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordBreakerFragment.kt create mode 100644 vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordEmailEntryFragment.kt create mode 100644 vector/src/main/res/layout/fragment_ftue_reset_password_breaker.xml create mode 100644 vector/src/main/res/layout/fragment_ftue_reset_password_email_input.xml diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt index b6a7550a58..dc8f260c13 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt @@ -47,7 +47,7 @@ sealed interface OnboardingAction : VectorViewModelAction { data class LoginWithToken(val loginToken: String) : OnboardingAction data class WebLoginSuccess(val credentials: Credentials) : OnboardingAction data class InitWith(val loginConfig: LoginConfig?) : OnboardingAction - data class ResetPassword(val email: String, val newPassword: String) : OnboardingAction + data class ResetPassword(val email: String, val newPassword: String?) : OnboardingAction object ResetPasswordMailConfirmed : OnboardingAction data class MaybeUpdateHomeserverFromMatrixId(val userId: String) : OnboardingAction diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt index bf53a72cc3..ffd65b1287 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt @@ -47,7 +47,7 @@ sealed class OnboardingViewEvents : VectorViewEvents { object OnHomeserverEdited : OnboardingViewEvents() data class OnSignModeSelected(val signMode: SignMode) : OnboardingViewEvents() object OnForgetPasswordClicked : OnboardingViewEvents() - object OnResetPasswordSendThreePidDone : OnboardingViewEvents() + data class OnResetPasswordSendThreePidDone(val email: String) : OnboardingViewEvents() object OnResetPasswordMailConfirmationSuccess : OnboardingViewEvents() object OnResetPasswordMailConfirmationSuccessDone : OnboardingViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 38a72441e0..5bac6ec0bc 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -451,7 +451,7 @@ class OnboardingViewModel @AssistedInject constructor( resetState = createResetState(action, state.selectedHomeserver) ) } - _viewEvents.post(OnboardingViewEvents.OnResetPasswordSendThreePidDone) + _viewEvents.post(OnboardingViewEvents.OnResetPasswordSendThreePidDone(action.email)) }, onFailure = { setState { copy(isLoading = false) } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt index 205a604aab..d9086952da 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt @@ -61,6 +61,7 @@ class FtueAuthCombinedLoginFragment @Inject constructor( views.editServerButton.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.EditServerSelection)) } views.loginPasswordInput.setOnImeDoneListener { submit() } views.loginInput.setOnFocusLostListener { viewModel.handle(OnboardingAction.MaybeUpdateHomeserverFromMatrixId(views.loginInput.content())) } + views.loginForgotPassword.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnForgetPasswordClicked)) } } private fun setupSubmitButton() { diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordBreakerFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordBreakerFragment.kt new file mode 100644 index 0000000000..07e628d9fb --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordBreakerFragment.kt @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.onboarding.ftueauth + +import android.os.Bundle +import android.os.Parcelable +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.airbnb.mvrx.args +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.R +import im.vector.app.core.utils.colorTerminatingFullStop +import im.vector.app.databinding.FragmentFtueResetPasswordBreakerBinding +import im.vector.app.features.onboarding.OnboardingAction +import im.vector.app.features.onboarding.RegisterAction +import im.vector.app.features.themes.ThemeProvider +import im.vector.app.features.themes.ThemeUtils +import kotlinx.parcelize.Parcelize +import javax.inject.Inject + +@Parcelize +data class FtueAuthResetPasswordBreakerArgument( + val email: String +) : Parcelable + +@AndroidEntryPoint +class FtueAuthResetPasswordBreakerFragment : AbstractFtueAuthFragment() { + + @Inject lateinit var themeProvider: ThemeProvider + private val params: FtueAuthResetPasswordBreakerArgument by args() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueResetPasswordBreakerBinding { + return FragmentFtueResetPasswordBreakerBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupUi() + } + + private fun setupUi() { + views.emailVerificationGradientContainer.setBackgroundResource( + when (themeProvider.isLightTheme()) { + true -> R.drawable.bg_waiting_for_email_verification + false -> R.drawable.bg_color_background + } + ) + views.emailVerificationTitle.text = getString(R.string.ftue_auth_reset_password_breaker_title) + .colorTerminatingFullStop(ThemeUtils.getColor(requireContext(), R.attr.colorSecondary)) + views.emailVerificationSubtitle.text = getString(R.string.ftue_auth_email_verification_subtitle, params.email) + views.emailVerificationResendEmail.debouncedClicks { + viewModel.handle(OnboardingAction.PostRegisterAction(RegisterAction.SendAgainThreePid)) + } + } + + override fun resetViewModel() { + viewModel.handle(OnboardingAction.ResetResetPassword) + } +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordEmailEntryFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordEmailEntryFragment.kt new file mode 100644 index 0000000000..9770d4c262 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordEmailEntryFragment.kt @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.onboarding.ftueauth + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.lifecycle.lifecycleScope +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.extensions.associateContentStateWith +import im.vector.app.core.extensions.content +import im.vector.app.core.extensions.editText +import im.vector.app.core.extensions.isEmail +import im.vector.app.core.extensions.setOnImeDoneListener +import im.vector.app.databinding.FragmentFtueResetPasswordEmailInputBinding +import im.vector.app.features.onboarding.OnboardingAction +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import reactivecircus.flowbinding.android.widget.textChanges + +@AndroidEntryPoint +class FtueAuthResetPasswordEmailEntryFragment : AbstractFtueAuthFragment() { + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueResetPasswordEmailInputBinding { + return FragmentFtueResetPasswordEmailInputBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupViews() + } + + private fun setupViews() { + views.emailEntryInput.associateContentStateWith(button = views.emailEntrySubmit) + views.emailEntryInput.setOnImeDoneListener { startPasswordReset() } + views.emailEntrySubmit.debouncedClicks { startPasswordReset() } + + views.emailEntryInput.editText().textChanges() + .onEach { + views.emailEntryInput.error = null + views.emailEntrySubmit.isEnabled = it.isEmail() + } + .launchIn(viewLifecycleOwner.lifecycleScope) + } + + private fun startPasswordReset() { + val email = views.emailEntryInput.content() + viewModel.handle(OnboardingAction.ResetPassword(email = email, newPassword = null)) + } + + override fun onError(throwable: Throwable) { + views.emailEntryInput.error = errorFormatter.toHumanReadable(throwable) + } + + override fun resetViewModel() { + viewModel.handle(OnboardingAction.ResetResetPassword) + } +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt index fa37e2edce..49c937827e 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt @@ -162,18 +162,33 @@ class FtueAuthVariant( ) is OnboardingViewEvents.OnWebLoginError -> onWebLoginError(viewEvents) is OnboardingViewEvents.OnForgetPasswordClicked -> - activity.addFragmentToBackstack( - views.loginFragmentContainer, - FtueAuthResetPasswordFragment::class.java, - option = commonOption - ) + when { + vectorFeatures.isOnboardingCombinedLoginEnabled() -> activity.addFragmentToBackstack( + views.loginFragmentContainer, + FtueAuthResetPasswordEmailEntryFragment::class.java, + option = commonOption + ) + else -> activity.addFragmentToBackstack( + views.loginFragmentContainer, + FtueAuthResetPasswordFragment::class.java, + option = commonOption + ) + } is OnboardingViewEvents.OnResetPasswordSendThreePidDone -> { supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE) - activity.addFragmentToBackstack( - views.loginFragmentContainer, - FtueAuthResetPasswordMailConfirmationFragment::class.java, - option = commonOption - ) + when { + vectorFeatures.isOnboardingCombinedLoginEnabled() -> activity.addFragmentToBackstack( + views.loginFragmentContainer, + FtueAuthResetPasswordBreakerFragment::class.java, + FtueAuthResetPasswordBreakerArgument(viewEvents.email), + option = commonOption + ) + else -> activity.addFragmentToBackstack( + views.loginFragmentContainer, + FtueAuthResetPasswordMailConfirmationFragment::class.java, + option = commonOption + ) + } } is OnboardingViewEvents.OnResetPasswordMailConfirmationSuccess -> { supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE) diff --git a/vector/src/main/res/layout/fragment_ftue_reset_password_breaker.xml b/vector/src/main/res/layout/fragment_ftue_reset_password_breaker.xml new file mode 100644 index 0000000000..96b276c5ce --- /dev/null +++ b/vector/src/main/res/layout/fragment_ftue_reset_password_breaker.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + +