Untitled
private val binding by viewBinding(FragmentAuthForgotPasswordBinding::bind) @SuppressLint("ShowToast") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) configureInsets(binding.root) navController.addOnDestinationChangedListener { _, _, _ -> snackbar?.let { it.dismiss() snackbar = null } } binding.authForgotPasswordEmailInputEdittext.setOnFocusChangeListener { _, hasFocus -> if (!hasFocus) { viewModel.setForgotPasswordState(viewModel.forgotPasswordFlow.value.copy(shouldShowEmailErrors = true)) } } binding.authForgotPasswordEmailInputEdittext.onTextChanged { viewModel.setForgotPasswordState(viewModel.forgotPasswordFlow.value.copy(email = it)) } binding.authForgotPasswordButtonReset.setOnClickListener { // Tapping submit enables all errors viewModel.setForgotPasswordState( viewModel.forgotPasswordFlow.value.copy( shouldShowEmailErrors = true, ) ) val error = viewModel.forgotPasswordFlow.value.error when (error) { is ViewModelError.InputError -> { val inputError = error.failedInput as ViewModelError.Input.ForgotPassword if (inputError.emailError?.isNotEmpty() == true) { binding.authForgotPasswordEmailInput.error = inputError.emailError binding.authForgotPasswordEmailInputEdittext.requestFocus() showSoftKeyboard(InputMethodManager.SHOW_IMPLICIT) } } else -> { } } if (error !is ViewModelError.InputError) { // We only block submissions for known input errors. Other types of errors are not validated locally. viewModel.doPasswordReset() } } binding.authForgotPasswordButtonCancel.setOnClickListener { navController.safeNavigate(R.id.action_navigate_to_login) // Clear showing error states in case the user navigates back. viewModel.setForgotPasswordState(viewModel.forgotPasswordFlow.value.copy(shouldShowEmailErrors = false)) } viewModel.loginStateFlow.invokeOnMain(viewLifecycleOwner.lifecycleScope) { loginState -> // If login email input was filled out already use that here. binding.authForgotPasswordEmailInputEdittext.setText(loginState.userIdentifier) } viewModel.forgotPasswordFlow.invokeOnMain(viewLifecycleOwner.lifecycleScope) { forgotState -> if (forgotState.processingComplete) { binding.authForgotPasswordProgress.visibility = View.INVISIBLE binding.authForgotPasswordButtonReset.visibility = View.INVISIBLE navController.safeNavigate(R.id.action_navigate_to_forgot_password_confirmation) Handler(Looper.getMainLooper()).postDelayed({ // reset state in case forgot password is used again. // post delayed because otherwise the view renders the button back while the view is animating away and looks bad. viewModel.setForgotPasswordState( viewModel.forgotPasswordFlow.value.copy( isProcessing = false, processingComplete = false, error = ViewModelError.None ) ) }, 1000) return@invokeOnMain } var errorMessage = "" var retryAction: (() -> Unit)? = null var showSnackbar = false when (forgotState.error) { is ViewModelError.GenericError -> { errorMessage = forgotState.error.message retryAction = forgotState.error.retryAction showSnackbar = true } is ViewModelError.InputError -> { val inputError = forgotState.error.failedInput as ViewModelError.Input.ForgotPassword if (forgotState.shouldShowEmailErrors) { binding.authForgotPasswordEmailInput.error = inputError.emailError } } is ViewModelError.None -> { if (forgotState.shouldShowEmailErrors) { binding.authForgotPasswordEmailInput.error = null } } } if (showSnackbar) { snackbar = GGSnackbar.showStandardWarn(view, errorMessage, retryAction) // Clear error state so it doesn't keep appearing. viewModel.setForgotPasswordState(forgotState.copy(error = ViewModelError.None)) } progressVisible(forgotState.isProcessing) } } override fun progressVisible(progressVisible: Boolean) { binding.authForgotPasswordProgress.visibility = if (progressVisible) View.VISIBLE else View.INVISIBLE binding.authForgotPasswordButtonReset.visibility = if (progressVisible) View.INVISIBLE else View.VISIBLE }
Leave a Comment