Untitled

 avatar
unknown
plain_text
a year ago
5.4 kB
7
Indexable

    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