From 47788ff79bcb118a56f80216c49fbc6d68fc4954 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sat, 13 Oct 2018 20:13:50 +0200 Subject: [PATCH 1/4] web3 fixes --- src/components/atoms/Input.module.scss | 4 + src/components/atoms/Web3Donation.jsx | 143 +++++++++++++++++++------ 2 files changed, 113 insertions(+), 34 deletions(-) diff --git a/src/components/atoms/Input.module.scss b/src/components/atoms/Input.module.scss index 1550d2c6..43bb6708 100644 --- a/src/components/atoms/Input.module.scss +++ b/src/components/atoms/Input.module.scss @@ -25,4 +25,8 @@ border-color: $input-border-focus; outline: 0; } + + &[disabled] { + color: $brand-grey-dimmed; + } } diff --git a/src/components/atoms/Web3Donation.jsx b/src/components/atoms/Web3Donation.jsx index c81283af..f20e6d88 100644 --- a/src/components/atoms/Web3Donation.jsx +++ b/src/components/atoms/Web3Donation.jsx @@ -46,29 +46,41 @@ InputGroup.propTypes = { handleWeb3Button: PropTypes.func } -const Alerts = ({ accounts, networkId, error, transactionHash }) => { - if (error || accounts.length === 0) { - return ( -
- {accounts.length === 0 && - 'Web3 detected, but no account. Are you logged into your MetaMask account?'} - {networkId !== '1' && 'Please connect to Main network'} - {error && error.message} -
- ) - } +const Alerts = ({ + accounts, + networkId, + networkName, + error, + transactionHash +}) => { + const isCorrectNetwork = networkId === '1' + const hasAccount = accounts.length !== 0 - if (transactionHash) { - return ( -
- You are awesome, thanks! -
- - See your transaction on etherscan.io. - -
- ) - } + if (error || hasAccount || isCorrectNetwork) +
+ {!hasAccount && ( +
+ Web3 detected, but no account. Are you logged into your MetaMask + account? +
+ )} + {!isCorrectNetwork && ( +
+ Please connect to Main network. You are on{' '} + {networkName} right now. +
+ )} + {error &&
{error.message}
} +
+ + if (transactionHash) +
+ You are awesome, thanks! +
+ + See your transaction on etherscan.io. + +
return null } @@ -76,6 +88,7 @@ const Alerts = ({ accounts, networkId, error, transactionHash }) => { Alerts.propTypes = { accounts: PropTypes.array, networkId: PropTypes.string, + networkName: PropTypes.string, error: PropTypes.object, transactionHash: PropTypes.string } @@ -85,6 +98,7 @@ export default class Web3Donation extends PureComponent { web3Connected: false, networkError: null, networkId: null, + networkName: null, accounts: [], selectedAccount: null, amount: 0.01, @@ -103,28 +117,67 @@ export default class Web3Donation extends PureComponent { networkInterval = null componentDidMount() { - if (typeof window.web3 === 'undefined') { - // no web3 - this.setState({ web3Connected: false }) - } else { + this.initAllTheTings() + } + + componentWillUnmount() { + this.resetAllTheThings() + } + + // getPermissions = async ethereum => { + // try { + // // Request account access if needed + // await ethereum.enable() + // } catch (error) { + // // User denied account access... + // console.log(error) + // } + // } + + initAllTheTings() { + // Modern dapp browsers... + // if (window.ethereum) { + // this.web3 = new Web3(window.ethereum) + // this.setState({ web3Connected: true }) + // this.getPermissions(this.web3.eth) + // } + + // Legacy dapp browsers... + if (window.web3) { // this.web3 = new Web3(Web3.givenProvider || 'ws://localhost:8546') this.web3 = new Web3(window.web3.currentProvider) this.setState({ web3Connected: true }) this.fetchAccounts() this.fetchNetwork() - this.initPoll() + this.initAccountsPoll() this.initNetworkPoll() } + // Non-dapp browsers... + else { + this.setState({ web3Connected: false }) + } } - componentWillUnmount() { + resetAllTheThings() { clearInterval(this.interval) clearInterval(this.networkInterval) - this.setState({ web3Connected: false }) + this.setState({ + web3Connected: false, + networkError: null, + networkId: null, + networkName: null, + accounts: [], + selectedAccount: null, + amount: 0.01, + receipt: null, + transactionHash: null, + loading: false, + error: null + }) } - initPoll() { + initAccountsPoll() { if (!this.interval) { this.interval = setInterval(this.fetchAccounts, ONE_SECOND) } @@ -143,14 +196,35 @@ export default class Web3Donation extends PureComponent { web3.eth && //web3.eth.net.getId((err, netId) => { web3.version.getNetwork((err, netId) => { - if (err) { - this.setState({ networkError: err }) - } + if (err) this.setState({ networkError: err }) if (netId != this.state.networkId) { + let networkName + + switch (netId) { + case '1': + networkName = 'Main' + break + case '2': + networkName = 'Morden' + break + case '3': + networkName = 'Ropsten' + break + case '4': + networkName = 'Rinkeby' + break + case '42': + networkName = 'Kovan' + break + default: + networkName = 'Private' + } + this.setState({ networkError: null, - networkId: netId + networkId: netId, + networkName: networkName }) } }) @@ -234,6 +308,7 @@ export default class Web3Donation extends PureComponent { From 0039f6b6e724ffd76d058fa66553c7decdd0a821 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sat, 13 Oct 2018 20:37:13 +0200 Subject: [PATCH 2/4] component splitup --- README.md | 2 +- src/components/Web3Donation/Alerts.jsx | 52 +++++++++++ .../Web3Donation/Alerts.module.scss | 13 +++ src/components/Web3Donation/InputGroup.jsx | 49 ++++++++++ .../InputGroup.module.scss} | 31 ------- .../index.jsx} | 91 +------------------ src/components/Web3Donation/index.module.scss | 22 +++++ src/components/atoms/Modal.module.scss | 1 + src/components/molecules/ModalThanks.jsx | 2 +- 9 files changed, 142 insertions(+), 121 deletions(-) create mode 100644 src/components/Web3Donation/Alerts.jsx create mode 100644 src/components/Web3Donation/Alerts.module.scss create mode 100644 src/components/Web3Donation/InputGroup.jsx rename src/components/{atoms/Web3Donation.module.scss => Web3Donation/InputGroup.module.scss} (77%) rename src/components/{atoms/Web3Donation.jsx => Web3Donation/index.jsx} (73%) create mode 100644 src/components/Web3Donation/index.module.scss diff --git a/README.md b/README.md index 749b88b0..e3b8dd4c 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ As a fallback, QR codes are generated with [react-qr-svg](https://github.com/no2 If you want to know how this works, have a look at the respective components under -- [`src/components/atoms/Web3Donation.jsx`](src/components/atoms/Web3Donation.jsx) +- [`src/components/Web3Donation/index.jsx`](src/components/Web3Donation/index.jsx) - [`src/components/atoms/Qr.jsx`](src/components/atoms/Qr.jsx) ### 🕸 Related Posts diff --git a/src/components/Web3Donation/Alerts.jsx b/src/components/Web3Donation/Alerts.jsx new file mode 100644 index 00000000..70212f4a --- /dev/null +++ b/src/components/Web3Donation/Alerts.jsx @@ -0,0 +1,52 @@ +import React from 'react' +import PropTypes from 'prop-types' +import styles from './Alerts.module.scss' + +const Alerts = ({ + accounts, + networkId, + networkName, + error, + transactionHash +}) => { + const isCorrectNetwork = networkId === '1' + const hasAccount = accounts.length !== 0 + + if (error || hasAccount || isCorrectNetwork) +
+ {!hasAccount && ( +
+ Web3 detected, but no account. Are you logged into your MetaMask + account? +
+ )} + {!isCorrectNetwork && ( +
+ Please connect to Main network. You are on{' '} + {networkName} right now. +
+ )} + {error &&
{error.message}
} +
+ + if (transactionHash) +
+ You are awesome, thanks! +
+ + See your transaction on etherscan.io. + +
+ + return null +} + +Alerts.propTypes = { + accounts: PropTypes.array, + networkId: PropTypes.string, + networkName: PropTypes.string, + error: PropTypes.object, + transactionHash: PropTypes.string +} + +export default Alerts diff --git a/src/components/Web3Donation/Alerts.module.scss b/src/components/Web3Donation/Alerts.module.scss new file mode 100644 index 00000000..f5b301e9 --- /dev/null +++ b/src/components/Web3Donation/Alerts.module.scss @@ -0,0 +1,13 @@ +@import 'variables'; +@import 'mixins'; + +.alert { + margin-top: $spacer / 2; + font-size: $font-size-small; + color: darken($alert-error, 60%); +} + +.success { + composes: alert; + color: darken($alert-success, 60%); +} diff --git a/src/components/Web3Donation/InputGroup.jsx b/src/components/Web3Donation/InputGroup.jsx new file mode 100644 index 00000000..92db2eb4 --- /dev/null +++ b/src/components/Web3Donation/InputGroup.jsx @@ -0,0 +1,49 @@ +import React, { PureComponent } from 'react' +import PropTypes from 'prop-types' +import Input from '../atoms/Input' +import styles from './InputGroup.module.scss' + +export default class InputGroup extends PureComponent { + static propTypes = { + networkId: PropTypes.string, + selectedAccount: PropTypes.string, + amount: PropTypes.number, + onAmountChange: PropTypes.func, + handleWeb3Button: PropTypes.func + } + + render() { + const { + networkId, + selectedAccount, + amount, + onAmountChange, + handleWeb3Button + } = this.props + + return ( +
+
+ +
+ ETH +
+
+ +
+ ) + } +} diff --git a/src/components/atoms/Web3Donation.module.scss b/src/components/Web3Donation/InputGroup.module.scss similarity index 77% rename from src/components/atoms/Web3Donation.module.scss rename to src/components/Web3Donation/InputGroup.module.scss index dcf801d6..e273de90 100644 --- a/src/components/atoms/Web3Donation.module.scss +++ b/src/components/Web3Donation/InputGroup.module.scss @@ -1,26 +1,6 @@ @import 'variables'; @import 'mixins'; -.web3 { - @include divider; - - width: 100%; - text-align: center; - margin-top: $spacer / 2; - margin-bottom: $spacer; - padding-bottom: $spacer * 1.5; - - small { - color: darken($alert-info, 60%); - margin-top: -($spacer / 2); - display: block; - } -} - -.web3Row { - min-height: 58px; -} - .inputGroup { max-width: 17rem; margin: auto; @@ -92,14 +72,3 @@ display: flex; align-items: center; } - -.alert { - margin-top: $spacer / 2; - font-size: $font-size-small; - color: darken($alert-error, 60%); -} - -.success { - composes: alert; - color: darken($alert-success, 60%); -} diff --git a/src/components/atoms/Web3Donation.jsx b/src/components/Web3Donation/index.jsx similarity index 73% rename from src/components/atoms/Web3Donation.jsx rename to src/components/Web3Donation/index.jsx index f20e6d88..4d5cb130 100644 --- a/src/components/atoms/Web3Donation.jsx +++ b/src/components/Web3Donation/index.jsx @@ -1,98 +1,13 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import Web3 from 'web3' -import Input from '../atoms/Input' -import styles from './Web3Donation.module.scss' +import InputGroup from './InputGroup' +import Alerts from './Alerts' +import styles from './index.module.scss' const ONE_SECOND = 1000 const ONE_MINUTE = ONE_SECOND * 60 -const InputGroup = ({ - networkId, - selectedAccount, - amount, - onAmountChange, - handleWeb3Button -}) => ( -
-
- -
- ETH -
-
- -
-) - -InputGroup.propTypes = { - networkId: PropTypes.string, - selectedAccount: PropTypes.string, - amount: PropTypes.number, - onAmountChange: PropTypes.func, - handleWeb3Button: PropTypes.func -} - -const Alerts = ({ - accounts, - networkId, - networkName, - error, - transactionHash -}) => { - const isCorrectNetwork = networkId === '1' - const hasAccount = accounts.length !== 0 - - if (error || hasAccount || isCorrectNetwork) -
- {!hasAccount && ( -
- Web3 detected, but no account. Are you logged into your MetaMask - account? -
- )} - {!isCorrectNetwork && ( -
- Please connect to Main network. You are on{' '} - {networkName} right now. -
- )} - {error &&
{error.message}
} -
- - if (transactionHash) -
- You are awesome, thanks! -
- - See your transaction on etherscan.io. - -
- - return null -} - -Alerts.propTypes = { - accounts: PropTypes.array, - networkId: PropTypes.string, - networkName: PropTypes.string, - error: PropTypes.object, - transactionHash: PropTypes.string -} - export default class Web3Donation extends PureComponent { state = { web3Connected: false, diff --git a/src/components/Web3Donation/index.module.scss b/src/components/Web3Donation/index.module.scss new file mode 100644 index 00000000..5796a2e1 --- /dev/null +++ b/src/components/Web3Donation/index.module.scss @@ -0,0 +1,22 @@ +@import 'variables'; +@import 'mixins'; + +.web3 { + @include divider; + + width: 100%; + text-align: center; + margin-top: $spacer / 2; + margin-bottom: $spacer; + padding-bottom: $spacer * 1.5; + + small { + color: darken($alert-info, 60%); + margin-top: -($spacer / 2); + display: block; + } +} + +.web3Row { + min-height: 58px; +} diff --git a/src/components/atoms/Modal.module.scss b/src/components/atoms/Modal.module.scss index cfade373..28ae690b 100644 --- a/src/components/atoms/Modal.module.scss +++ b/src/components/atoms/Modal.module.scss @@ -52,6 +52,7 @@ right: ($spacer/4); color: $brand-grey-light; font-weight: 500; + outline: 0; &:hover, &:focus { diff --git a/src/components/molecules/ModalThanks.jsx b/src/components/molecules/ModalThanks.jsx index d035be71..118156be 100644 --- a/src/components/molecules/ModalThanks.jsx +++ b/src/components/molecules/ModalThanks.jsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react' import { StaticQuery, graphql } from 'gatsby' -import Web3Donation from '../atoms/Web3Donation' +import Web3Donation from '../Web3Donation' import Qr from '../atoms/Qr' import Modal from '../atoms/Modal' import styles from './ModalThanks.module.scss' From fc38c6b889e271f3483fcb67162e213215d5a885 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sat, 13 Oct 2018 23:35:21 +0200 Subject: [PATCH 3/4] Alerts refactor --- src/components/Web3Donation/Alerts.jsx | 80 ++++++++++--------- src/components/Web3Donation/InputGroup.jsx | 18 ++--- src/components/Web3Donation/index.jsx | 91 +++++++--------------- src/components/Web3Donation/utils.js | 25 ++++++ 4 files changed, 107 insertions(+), 107 deletions(-) create mode 100644 src/components/Web3Donation/utils.js diff --git a/src/components/Web3Donation/Alerts.jsx b/src/components/Web3Donation/Alerts.jsx index 70212f4a..84ffd6f6 100644 --- a/src/components/Web3Donation/Alerts.jsx +++ b/src/components/Web3Donation/Alerts.jsx @@ -1,52 +1,62 @@ -import React from 'react' +import React, { Fragment } from 'react' import PropTypes from 'prop-types' import styles from './Alerts.module.scss' +const alertMessages = (networkName, transactionHash) => ({ + noAccount: + 'Web3 detected, but no account. Are you logged into your MetaMask account?', + noCorrectNetwork: `Please connect to Main network. You are on ${networkName} right now.`, + noWeb3: + 'No Web3 detected. Install MetaMask, Brave, or Mist.', + success: `You are awesome, thanks!
+ + See your transaction on etherscan.io. + ` +}) + const Alerts = ({ - accounts, - networkId, + hasCorrectNetwork, + hasAccount, networkName, error, - transactionHash + transactionHash, + web3Connected }) => { - const isCorrectNetwork = networkId === '1' - const hasAccount = accounts.length !== 0 + return !web3Connected ? ( + + ) : ( + +
+ {!hasAccount &&
{alertMessages().noaccount}
} + {!hasCorrectNetwork && ( +
+ )} + {error &&
{error.message}
} +
- if (error || hasAccount || isCorrectNetwork) -
- {!hasAccount && ( -
- Web3 detected, but no account. Are you logged into your MetaMask - account? -
+ {transactionHash && ( +
)} - {!isCorrectNetwork && ( -
- Please connect to Main network. You are on{' '} - {networkName} right now. -
- )} - {error &&
{error.message}
} -
- - if (transactionHash) -
- You are awesome, thanks! -
- - See your transaction on etherscan.io. - -
- - return null + + ) } Alerts.propTypes = { - accounts: PropTypes.array, - networkId: PropTypes.string, + hasCorrectNetwork: PropTypes.bool, + hasAccount: PropTypes.bool, networkName: PropTypes.string, error: PropTypes.object, - transactionHash: PropTypes.string + transactionHash: PropTypes.string, + web3Connected: PropTypes.bool } export default Alerts diff --git a/src/components/Web3Donation/InputGroup.jsx b/src/components/Web3Donation/InputGroup.jsx index 92db2eb4..397cba0c 100644 --- a/src/components/Web3Donation/InputGroup.jsx +++ b/src/components/Web3Donation/InputGroup.jsx @@ -5,20 +5,20 @@ import styles from './InputGroup.module.scss' export default class InputGroup extends PureComponent { static propTypes = { - networkId: PropTypes.string, - selectedAccount: PropTypes.string, + hasCorrectNetwork: PropTypes.bool, + hasAccount: PropTypes.bool, amount: PropTypes.number, onAmountChange: PropTypes.func, - handleWeb3Button: PropTypes.func + handleButton: PropTypes.func } render() { const { - networkId, - selectedAccount, + hasCorrectNetwork, + hasAccount, amount, onAmountChange, - handleWeb3Button + handleButton } = this.props return ( @@ -26,7 +26,7 @@ export default class InputGroup extends PureComponent {
diff --git a/src/components/Web3Donation/index.jsx b/src/components/Web3Donation/index.jsx index 4d5cb130..347d7bc4 100644 --- a/src/components/Web3Donation/index.jsx +++ b/src/components/Web3Donation/index.jsx @@ -4,6 +4,7 @@ import Web3 from 'web3' import InputGroup from './InputGroup' import Alerts from './Alerts' import styles from './index.module.scss' +import { getNetworkName } from './utils' const ONE_SECOND = 1000 const ONE_MINUTE = ONE_SECOND * 60 @@ -11,13 +12,11 @@ const ONE_MINUTE = ONE_SECOND * 60 export default class Web3Donation extends PureComponent { state = { web3Connected: false, - networkError: null, networkId: null, networkName: null, accounts: [], selectedAccount: null, amount: 0.01, - receipt: null, transactionHash: null, loading: false, error: null @@ -77,19 +76,7 @@ export default class Web3Donation extends PureComponent { resetAllTheThings() { clearInterval(this.interval) clearInterval(this.networkInterval) - this.setState({ - web3Connected: false, - networkError: null, - networkId: null, - networkName: null, - accounts: [], - selectedAccount: null, - amount: 0.01, - receipt: null, - transactionHash: null, - loading: false, - error: null - }) + this.setState({ web3Connected: false }) } initAccountsPoll() { @@ -111,35 +98,16 @@ export default class Web3Donation extends PureComponent { web3.eth && //web3.eth.net.getId((err, netId) => { web3.version.getNetwork((err, netId) => { - if (err) this.setState({ networkError: err }) + if (err) this.setState({ error: err }) if (netId != this.state.networkId) { - let networkName - - switch (netId) { - case '1': - networkName = 'Main' - break - case '2': - networkName = 'Morden' - break - case '3': - networkName = 'Ropsten' - break - case '4': - networkName = 'Rinkeby' - break - case '42': - networkName = 'Kovan' - break - default: - networkName = 'Private' - } - this.setState({ - networkError: null, - networkId: netId, - networkName: networkName + error: null, + networkId: netId + }) + + getNetworkName(netId).then(networkName => { + this.setState({ networkName: networkName }) }) } }) @@ -151,18 +119,17 @@ export default class Web3Donation extends PureComponent { web3 && web3.eth && web3.eth.getAccounts((err, accounts) => { - if (err) { - this.setState({ accountsError: err }) - } + if (err) this.setState({ error: err }) this.setState({ + error: null, accounts, selectedAccount: accounts[0] }) }) } - handleWeb3Button = () => { + handleButton = () => { const { web3 } = this this.setState({ loading: true }) @@ -199,6 +166,9 @@ export default class Web3Donation extends PureComponent { } render() { + const hasCorrectNetwork = this.state.networkId === '1' + const hasAccount = this.state.accounts.length !== 0 + return (
@@ -206,35 +176,30 @@ export default class Web3Donation extends PureComponent {

Send Ether with MetaMask, Brave, or Mist.

- {this.state.web3Connected ? ( + {this.state.web3Connected && (
{this.state.loading ? ( 'Hang on...' ) : ( )} - -
- ) : ( - - No Web3 detected. Install MetaMask - , Brave, or{' '} - Mist. - )} + +
) } diff --git a/src/components/Web3Donation/utils.js b/src/components/Web3Donation/utils.js new file mode 100644 index 00000000..92ccdd51 --- /dev/null +++ b/src/components/Web3Donation/utils.js @@ -0,0 +1,25 @@ +export const getNetworkName = async netId => { + let networkName + + switch (netId) { + case '1': + networkName = 'Main' + break + case '2': + networkName = 'Morden' + break + case '3': + networkName = 'Ropsten' + break + case '4': + networkName = 'Rinkeby' + break + case '42': + networkName = 'Kovan' + break + default: + networkName = 'Private' + } + + return networkName +} From af60744e9ea8d1910ee6111afa78ab021c529a24 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sun, 14 Oct 2018 00:16:15 +0200 Subject: [PATCH 4/4] search fix --- gatsby-config.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/gatsby-config.js b/gatsby-config.js index e178bf05..a7807d10 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -91,22 +91,18 @@ module.exports = { // Attributes for custom indexing logic. See https://lunrjs.com/docs/lunr.Builder.html for details fields: [ { name: 'title', store: true, attributes: { boost: 20 } }, - { name: 'content' }, { name: 'excerpt', attributes: { boost: 10 } }, - { name: 'category', store: true, attributes: { boost: 5 } }, - { name: 'tags', store: true }, - { name: 'url', store: true } + { name: 'tags', store: true, attributes: { boost: 5 } }, + { name: 'content' } ], // How to resolve each field's value for a supported node type resolvers: { // For any node of type MarkdownRemark, list how to resolve the fields' values MarkdownRemark: { title: node => node.frontmatter.title, - content: node => node.rawMarkdownBody, - excerpt: node => node.frontmatter.excerpt, - category: node => node.frontmatter.category, + excerpt: node => node.excerpt, tags: node => node.frontmatter.tags, - url: node => node.fields.slug + content: node => node.rawMarkdownBody } } }