Skip to content
This repository was archived by the owner on Feb 5, 2025. It is now read-only.

Conversation

@shiki
Copy link
Contributor

@shiki shiki commented Jun 3, 2021

Part of fixing woocommerce/woocommerce-ios#4034.

There is a linked WP PR for this: wordpress-mobile/WordPress-iOS#16655.

Originally intended to fix just WooCommerce but apparently, WP has the same issue. So this fixes both apps. 🤸

Findings

Both apps have this problem when logging in with a site address. This is for WordPress specifically:

  1. Log in with a valid self-hosted site address domain. Don't include the scheme. Add a typo.
  2. After the error is displayed, fix the typo. Still exclude the scheme.
  3. Continue logging in, providing the valid credentials. The app will fail to log the user in. The WordPressOrgXMLRPCValidator.guessXMLRPCURLForSite fails because we did not provide the scheme.

This problem only surfaces when the user made a mistake on the first try. Which is quite likely. It also happens if there was previously an XML-RPC error. Or any other error that is displayed below the site address text field.

Here is a video showing this bug:

wp-before.mov

If there was no error on the first try, the app is able to log the user in because we automatically fix the siteAddress.

You'll also notice in the video that the text disappears when the error is displayed. And the Continue button also does not show the activity indicator anymore if the user tries a second time. It looks like the app is doing nothing.

Solution

Logging In

For some reason, if the error is displayed at some point, the loginFields.siteAddress gets reset because this callback gets called:

cell.onChangeSelectionHandler = { [weak self] textfield in
self?.loginFields.siteAddress = textfield.nonNilTrimmedText()
self?.configureSubmitButton()
}

I still have no idea why that text field change callback is called. But I fixed it by resetting loginFields.siteAddress before any view controller is displayed. See here for the fix. Let me know if there's a better way for this.

Disappearing Text

I fixed the disappearing text by resetting the value when the cell is recreated in configureTextField:

Activity Indicator

The reason the activity indicator on the button does not show up when the user retries because this block gets called right after the activity indicator is shown:

So the activity indicator gets dismissed immediately.

I fixed this by keeping the “view is loading” state in a variable:

/// A state variable that is `true` if network calls are currently happening and so the
/// view should be showing a loading indicator.
///
/// This should only be modified within `configureViewLoading(_ loading:)`.
///
/// This state is mainly used in `configureSubmitButton()` to determine whether the button
/// should show an activity indicator.
private var viewIsLoading: Bool = false

And making sure that the configureSubmitButton uses that state so the activity indicator is not unintentionally dismissed:

/// Configures the appearance and state of the submit button.
///
/// Use this instead of the overridden `configureSubmitButton(animating:)` since this uses the
/// _current_ `viewIsLoading` state.
private func configureSubmitButton() {

Let me know if there's a better way to do this. I wasn't quite sure how to properly handle this. I wanted to use a didSet handler but it looks like configureViewLoading is an override from the parent class. So I couldn't just remove it.

Here is the final result:

wp-after.mov

Testing

  1. You can use the branch in Fix Site Address UI Bugs When Displaying In-Page Errors WordPress-iOS#16655.
  2. Log in with a valid self-hosted site address domain. Don't include the scheme. Add a typo.
  3. After the error is displayed, fix the typo. Still exclude the scheme.
  4. Press Continue.
  5. Confirm that the activity indicator is visible and the text field is disabled.
  6. Provide the credentials.
  7. Confirm that you were able to log in.

shiki added 5 commits June 8, 2021 10:53
This is causing an issue where when there's an XML-RPC error displayed, the text
field will no longer be disabled when the user tries to submit another site URL.

This was first created in cf6b66f. As far as I can understand, there doesn't
seem to be a critical need to keep this. The reference will still be pointed to
the _current text field_ if the cell is recreated.
When an XML-RPC error is displayed, the URL that the user entered gets cleared.
This retains the text to match with our other error handling UIs like the fancy dialog
which does not clear the text field.
This function should be used instead of the one with the `animating: loading`
argument to avoid incorrectly disabling the loading state of the button.
@shiki shiki force-pushed the issue/wc-4034-fix-login-ui branch from 6f2f13d to 52dfad9 Compare June 8, 2021 16:53
shiki added 3 commits June 8, 2021 10:59
This fixes this bug:

1. Log in with a site address that has a blocked XML-RPC. For example, https://do.wpmt.co/ddos.
2. After the error is displayed, log in with a valid self-hosted site address.
3. Continue entering the credentials to log in.
4. You will not be able to.

This also does not work with WooCommerce. The WC app will spit out a "...is
connected to a different account" error.
@shiki shiki changed the title Fix Site Address UI Bugs When Displaying XML-RPC Errors Fix Site Address UI Bugs When Displaying In-Page Errors Jun 8, 2021
}

if row == .siteAddress {
siteURLField = nil
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this because this was preventing the text field from being disabled when the user tapped Continue for the second time. There are no implications in removing this, right? 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There doesn't appear to be a side effect. It looks like this was there to clean up setting the siteURLField as first responder, but your change seems to have made no difference. Sooooo 👍 .

@ScoutHarris
Copy link
Contributor

I still have no idea why that text field change callback is called

The idea is to enable/disable the Continue button on the fly as the user enters the URL. What's supposed to happen is Continue is disabled until something resembling a URL is entered. But that's not happening. It's enabled as soon as the first character is entered. It looks like the validateSiteForSignin method isn't doing what we're expecting it to do, specifically the call to idnEncodedURL.

    func validateSiteForSignin() -> Bool {
        guard let url = URL(string: NSURL.idnEncodedURL(siteAddress)) else {
            return false
        }

        return !url.absoluteString.isEmpty
    }

I checked internal, and it's doing the same thing, so this definitely pre-dates your PR. But that's why that callback is there.

@ScoutHarris
Copy link
Contributor

I know this isn't your doing (it appears to be mine 🤦 ), but there is a print("🔴 SAVC > fetchSiteInfo") in SiteAddressViewController here. Would you be a dear and remove it please?

Copy link
Contributor

@ScoutHarris ScoutHarris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

:shipit:

@shiki
Copy link
Contributor Author

shiki commented Jun 10, 2021

It looks like the validateSiteForSignin method isn't doing what we're expecting it to do, specifically the call to idnEncodedURL.

Ah, thanks for the explanation!

Would you be a dear and remove it please?

Since you asked nicely... removed in d6447e7. 🤣


Thank you very much for the review, @ScoutHarris!

@shiki shiki merged commit 40549a6 into develop Jun 10, 2021
@shiki shiki deleted the issue/wc-4034-fix-login-ui branch June 10, 2021 01:41
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants