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/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
}
}
}
diff --git a/src/components/Web3Donation/Alerts.jsx b/src/components/Web3Donation/Alerts.jsx
new file mode 100644
index 00000000..84ffd6f6
--- /dev/null
+++ b/src/components/Web3Donation/Alerts.jsx
@@ -0,0 +1,62 @@
+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 = ({
+ hasCorrectNetwork,
+ hasAccount,
+ networkName,
+ error,
+ transactionHash,
+ web3Connected
+}) => {
+ return !web3Connected ? (
+
+ ) : (
+
+
+ {!hasAccount &&
{alertMessages().noaccount}
}
+ {!hasCorrectNetwork && (
+
+ )}
+ {error &&
{error.message}
}
+
+
+ {transactionHash && (
+
+ )}
+
+ )
+}
+
+Alerts.propTypes = {
+ hasCorrectNetwork: PropTypes.bool,
+ hasAccount: PropTypes.bool,
+ networkName: PropTypes.string,
+ error: PropTypes.object,
+ transactionHash: PropTypes.string,
+ web3Connected: PropTypes.bool
+}
+
+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..397cba0c
--- /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 = {
+ hasCorrectNetwork: PropTypes.bool,
+ hasAccount: PropTypes.bool,
+ amount: PropTypes.number,
+ onAmountChange: PropTypes.func,
+ handleButton: PropTypes.func
+ }
+
+ render() {
+ const {
+ hasCorrectNetwork,
+ hasAccount,
+ amount,
+ onAmountChange,
+ handleButton
+ } = this.props
+
+ return (
+
+ )
+ }
+}
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 53%
rename from src/components/atoms/Web3Donation.jsx
rename to src/components/Web3Donation/index.jsx
index c81283af..347d7bc4 100644
--- a/src/components/atoms/Web3Donation.jsx
+++ b/src/components/Web3Donation/index.jsx
@@ -1,94 +1,22 @@
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'
+import { getNetworkName } from './utils'
const ONE_SECOND = 1000
const ONE_MINUTE = ONE_SECOND * 60
-const InputGroup = ({
- networkId,
- selectedAccount,
- amount,
- onAmountChange,
- handleWeb3Button
-}) => (
-
-)
-
-InputGroup.propTypes = {
- networkId: PropTypes.string,
- selectedAccount: PropTypes.string,
- amount: PropTypes.number,
- onAmountChange: PropTypes.func,
- 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}
-
- )
- }
-
- if (transactionHash) {
- return (
-
- )
- }
-
- return null
-}
-
-Alerts.propTypes = {
- accounts: PropTypes.array,
- networkId: PropTypes.string,
- error: PropTypes.object,
- transactionHash: PropTypes.string
-}
-
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
@@ -103,28 +31,55 @@ 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 })
}
- initPoll() {
+ initAccountsPoll() {
if (!this.interval) {
this.interval = setInterval(this.fetchAccounts, ONE_SECOND)
}
@@ -143,15 +98,17 @@ 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) {
this.setState({
- networkError: null,
+ error: null,
networkId: netId
})
+
+ getNetworkName(netId).then(networkName => {
+ this.setState({ networkName: networkName })
+ })
}
})
}
@@ -162,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 })
@@ -210,6 +166,9 @@ export default class Web3Donation extends PureComponent {
}
render() {
+ const hasCorrectNetwork = this.state.networkId === '1'
+ const hasAccount = this.state.accounts.length !== 0
+
return (
- {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/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/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
+}
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/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'