Skip to content
This repository has been archived by the owner on Mar 11, 2024. It is now read-only.

Network-aware LoadingContainer #9

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

SeanJCasey
Copy link
Contributor

Uses the networkMismatch flag to allow handling of network-related halting of loading drizzle.

Updates the redux LoadingContainer and adds a new Context API-friendly Loading Container

@cds-amal
Copy link
Member

@SeanJCasey, when you have time, please update the README and the test-apps to reflect/document this feature. I am excited to try this out! Thanks!

@SeanJCasey SeanJCasey force-pushed the feature/network-aware-loading-container branch from 32eeeef to 31fe5d9 Compare August 24, 2019 23:35
@SeanJCasey SeanJCasey marked this pull request as ready for review August 24, 2019 23:36
@SeanJCasey
Copy link
Contributor Author

Update the test app for the react context api with a LoadingContainer. We can add the overrides for this component at a later time. The README reflects the new props for this component.

@cds-amal cds-amal self-requested a review August 25, 2019 00:07
@SeanJCasey SeanJCasey force-pushed the feature/network-aware-loading-container branch from 31fe5d9 to d23391a Compare August 29, 2019 13:21
@adrianmcli
Copy link
Contributor

@SeanJCasey I'm having trouble running this on the test-UI apps. I have:

  1. Pulled the branch,
  2. Ran lerna bootstrap,
  3. And put the app on a network where the contracts are not deployed.

I'm getting the following error on both React apps (legacy context AND new context) instead of the nice warning message:

Screen Shot 2019-09-15 at 2 39 25 AM

@SeanJCasey
Copy link
Contributor Author

@adrianmcli Did you set networkWhitelist in drizzleOptions? If the option is absent, it will default to [], which means all networks are approved.

@adrianmcli
Copy link
Contributor

@SeanJCasey Can you add that to the test-UI app then?

@SeanJCasey
Copy link
Contributor Author

@adrianmcli Sure, I can add a networkWhitelist config option with values if that's what you mean. So long as you're sure it won't trip people up to have particular networks blocked. What networks do you want to be enabled?

@adrianmcli
Copy link
Contributor

@SeanJCasey I think the goal is to make sure that the repo's test apps are actually able to test the features in our packages. Do you have any thoughts on what the defaults should be?

@SeanJCasey
Copy link
Contributor Author

@adrianmcli How about [1, 4] (Mainnet, Rinkeby) for the allowed networks? Then Ropsten etc will catch the network mismatch. Ganache is allowed by default, regardless of the values in the array.

@adrianmcli
Copy link
Contributor

@adrianmcli Did you set networkWhitelist in drizzleOptions? If the option is absent, it will default to [], which means all networks are approved.

Actually I'm confused. Why is a network whitelist needed? I thought the purpose of this PR is to make it such that the dapp will try to detect the contract on the current network, and if it isn't there then it'll show a friendly message in the UI.

@SeanJCasey
Copy link
Contributor Author

The purpose of this PR is to allow the LoadingContainer to work with the networkWhitelist option that was merged previously. This blog post details and has links to both that PR and this one: http://seanjcasey.com/blog/drizzle-network-whitelist

Good question re: explicitly defining a networkWhitelist rather than reading from contracts or catching an error. @cds-amal and I discussed this and decided on the current option so that devs can be explicit about which networks they do or don't want their dApps accessed on and which are expected to work.

@adrianmcli
Copy link
Contributor

Right, but if it doesn't support it, it should display a message instead of throwing an error in the console right?

@SeanJCasey
Copy link
Contributor Author

Yes, but the idea was to separate out functionality and UI/UX. Rather than assuming UI/UX, we just provide a developer with the networkMismatch flag that is produced when the provider is connected to a network that is not in the networkWhitelist. LoadingContainer then serves as a sample UI implementation.

@adrianmcli
Copy link
Contributor

@SeanJCasey Ok sounds good. So let's just put in the [1, 4] and let's see where we go.

@SeanJCasey SeanJCasey force-pushed the feature/network-aware-loading-container branch from d23391a to b80d82b Compare September 20, 2019 22:15
@SeanJCasey SeanJCasey force-pushed the feature/network-aware-loading-container branch from b80d82b to eb260a8 Compare September 20, 2019 22:23
@SeanJCasey
Copy link
Contributor Author

@adrianmcli I added the networkWhitelist to react redux and context test uis and squashed into the feat commit. Tested those two flows. We should be good to go!

@adrianmcli
Copy link
Contributor

Thanks @SeanJCasey, I'm on vacation until Tuesday unfortunately but let's get this merged asap.

@cds-amal
Copy link
Member

Just adding a note that this resolves #23

@adrianmcli
Copy link
Contributor

Seems to work as expected! Thanks @SeanJCasey

Copy link
Contributor

@adrianmcli adrianmcli left a comment

Choose a reason for hiding this comment

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

I have some questions regarding the code and refactor requests.

return this.props.networkMismatchComp;
}

return (
Copy link
Contributor

Choose a reason for hiding this comment

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

This section can be re-written as:

return this.props.networkMismatchComp || <main>...</main>

This allows us to avoid the nested if statement and also makes it clear that this.props.networkMismatchComp is a component.

import React, { Children, Component } from "react";
import PropTypes from "prop-types";

/*
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the purpose of this comment block?

* Create component.
*/

class LoadingContainer extends Component {
Copy link
Contributor

Choose a reason for hiding this comment

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

This component has a ton of if-statements, consider refactoring.

render() {
if (this.props.drizzleState) {
if (this.props.drizzleState.web3.status === "failed") {
if (this.props.errorComp) {
Copy link
Contributor

Choose a reason for hiding this comment

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

As above, this can be written as:

return this.props.errorComp || <main>...</main>

In order to avoid another if-statement.


if (this.props.drizzleState.web3.networkMismatch) {
if (this.props.networkMismatchComp) {
return this.props.networkMismatchComp;
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above.


if (
this.props.drizzleState.web3.status === "initialized" &&
Object.keys(this.props.drizzleState.accounts).length === 0
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider de-structuring and using intermediate variables.

@adrianmcli
Copy link
Contributor

@SeanJCasey I've went ahead and refactored LoadingContainer.js:

import React, { Children, Component } from "react";
import PropTypes from "prop-types";

class LoadingContainer extends Component {
  renderFailed() {
    return (
      this.props.errorComp || (
        <main className="container loading-screen">
          <div className="pure-g">
            <div className="pure-u-1-1">
              <h1>⚠️</h1>
              <p>
                This browser has no connection to the Ethereum network. Please
                use the Chrome/FireFox extension MetaMask, or dedicated Ethereum
                browsers Mist or Parity.
              </p>
            </div>
          </div>
        </main>
      )
    );
  }

  renderNetworkMismatch() {
    return (
      this.props.networkMismatchComp || (
        <main className="container network-warning">
          <div className="pure-g">
            <div className="pure-u-1-1">
              <h1>⚠️</h1>
              <p>This dapp does not support this network.</p>
            </div>
          </div>
        </main>
      )
    );
  }

  renderNoAccounts() {
    return (
      <main className="container loading-screen">
        <div className="pure-g">
          <div className="pure-u-1-1">
            <h1>🦊</h1>
            <p>
              <strong>{"We can't find any Ethereum accounts!"}</strong> Please
              check and make sure Metamask or your browser are pointed at the
              correct network and your account is unlocked.
            </p>
          </div>
        </div>
      </main>
    );
  }
  render() {
    const { drizzleState, children, loadingComp } = this.props;
    if (drizzleState) {
      if (drizzleState.web3.status === "failed") {
        this.renderFailed();
      }

      if (drizzleState.web3.networkMismatch) {
        this.renderNetworkMismatch();
      }

      const noAccounts = Object.keys(drizzleState.accounts).length === 0;
      if (drizzleState.web3.status === "initialized" && noAccounts) {
        this.renderNoAccounts();
      }

      if (drizzleState.drizzleStatus.initialized) {
        return Children.only(children);
      }
    }

    return (
      loadingComp || (
        <main className="container loading-screen">
          <div className="pure-g">
            <div className="pure-u-1-1">
              <h1>⚙️</h1>
              <p>Loading dapp...</p>
            </div>
          </div>
        </main>
      )
    );
  }
}

LoadingContainer.propTypes = {
  drizzleState: PropTypes.object,
  children: PropTypes.node,
  loadingComp: PropTypes.node,
  errorComp: PropTypes.node,
  networkMismatchComp: PropTypes.node,
};

export default LoadingContainer;

@SeanJCasey
Copy link
Contributor Author

Hey @adrianmcli , cool please do refactor as you see fit. I just copy/pasted/edited from the redux LoadingContainer for stylistic congruence (i.e., I implemented the networkMismatchComp the same way that the loadingComp and errorComp were already implemented), so if you refactor the new-context-api component, you might want to do so for the redux version as well.

@adrianmcli
Copy link
Contributor

adrianmcli commented Oct 1, 2019

@SeanJCasey On second glance, it appears my testing of the UIs failed. It doesn't recognize and allow Ganache because Ganache doesn't have a stable network ID of 5557 as this line assumes.

Context:

@adrianmcli How about [1, 4] (Mainnet, Rinkeby) for the allowed networks? Then Ropsten etc will catch the network mismatch. Ganache is allowed by default, regardless of the values in the array.

@SeanJCasey
Copy link
Contributor Author

@adrianmcli Hmm, interesting. I'll need to summon and defer to @cds-amal . We came to the conclusion that allowing port 5777 should (almost?) always be sufficient. Even if it isn't, we just need to make an addition to the readme that port 5777 is always allowed, but any custom ports need to be added (which might be obvious anyways if the user defines the networkMismatch config var).

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.

None yet

3 participants