diff --git a/package.json b/package.json index 5a7f9d60..60f9013d 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "prettier": "^1.14.3", "prettier-eslint-cli": "^4.7.1", "prettier-stylelint": "^0.4.2", - "stylelint": "^9.6.0", + "stylelint": "^9.7.0", "stylelint-config-css-modules": "^1.3.0", "stylelint-config-standard": "^18.2.0", "stylelint-scss": "^3.3.2" diff --git a/src/components/Web3Donation/Alerts.jsx b/src/components/Web3Donation/Alerts.jsx index 3151150a..3ff8b278 100644 --- a/src/components/Web3Donation/Alerts.jsx +++ b/src/components/Web3Donation/Alerts.jsx @@ -2,65 +2,58 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import styles from './Alerts.module.scss' -const Message = ({ message, ...props }) => ( -
-) +export 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.', + transaction: `See your transaction on etherscan.io.`, + waitingForUser: 'Waiting for your confirmation', + waitingConfirmation: 'Waiting for network confirmation, hang on', + success: 'Confirmed. You are awesome, thanks!' +}) export default class Alerts extends PureComponent { static propTypes = { - hasCorrectNetwork: PropTypes.bool.isRequired, - hasAccount: PropTypes.bool.isRequired, - networkName: PropTypes.string, - error: PropTypes.object, - transactionHash: PropTypes.string, - confirmationNumber: PropTypes.number, - receipt: PropTypes.object, - web3Connected: PropTypes.bool.isRequired + message: PropTypes.object, + transactionHash: PropTypes.string } - 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.', - transaction: `See your transaction on etherscan.io.` - }) + constructMessage = () => { + const { transactionHash, message } = this.props + + let messageOutput + + if (transactionHash) { + messageOutput = + message.text + + '
' + + alertMessages(null, transactionHash).transaction + } else { + messageOutput = message.text + } + + return messageOutput + } + + classes() { + const { status } = this.props.message + + if (status === 'success') { + return styles.success + } else if (status === 'error') { + return styles.error + } + return styles.alert + } render() { - const { - hasCorrectNetwork, - hasAccount, - networkName, - error, - transactionHash, - web3Connected - } = this.props - return ( -
- {!web3Connected ? ( - - ) : ( - <> - {!hasAccount && ( - - )} - {!hasCorrectNetwork && ( - - )} - {error && } - - {transactionHash && ( - - )} - - )} -
+
) } } diff --git a/src/components/Web3Donation/Alerts.module.scss b/src/components/Web3Donation/Alerts.module.scss index 857df040..1b3aa060 100644 --- a/src/components/Web3Donation/Alerts.module.scss +++ b/src/components/Web3Donation/Alerts.module.scss @@ -2,16 +2,44 @@ @import 'mixins'; .alert { - margin-top: $spacer / 2; font-size: $font-size-small; - color: darken($alert-error, 60%); + display: inline-block; &:empty { display: none; } + + &::after { + overflow: hidden; + display: inline-block; + vertical-align: bottom; + animation: ellipsis steps(4, end) 1s infinite; + content: '\2026'; // ascii code for the ellipsis character + width: 0; + position: absolute; + } +} + +.error { + composes: alert; + color: darken($alert-error, 60%); + + &::after { + display: none; + } } .success { composes: alert; color: darken($alert-success, 60%); + + &::after { + display: none; + } +} + +@keyframes ellipsis { + to { + width: .75rem; + } } diff --git a/src/components/Web3Donation/InputGroup.jsx b/src/components/Web3Donation/InputGroup.jsx index f5476a0a..1bc3ea20 100644 --- a/src/components/Web3Donation/InputGroup.jsx +++ b/src/components/Web3Donation/InputGroup.jsx @@ -7,21 +7,17 @@ import styles from './InputGroup.module.scss' export default class InputGroup extends PureComponent { static propTypes = { - isCorrectNetwork: PropTypes.bool.isRequired, - hasAccount: PropTypes.bool.isRequired, amount: PropTypes.string.isRequired, onAmountChange: PropTypes.func.isRequired, - handleButton: PropTypes.func.isRequired, + sendTransaction: PropTypes.func.isRequired, selectedAccount: PropTypes.string } render() { const { - isCorrectNetwork, - hasAccount, amount, onAmountChange, - handleButton, + sendTransaction, selectedAccount } = this.props @@ -30,7 +26,6 @@ export default class InputGroup extends PureComponent {
ETH
- - {isCorrectNetwork && - hasAccount && ( -
- - {selectedAccount && } -
- )} +
+ + {selectedAccount && } +
) } diff --git a/src/components/Web3Donation/index.jsx b/src/components/Web3Donation/index.jsx index 96c4057f..0b56c962 100644 --- a/src/components/Web3Donation/index.jsx +++ b/src/components/Web3Donation/index.jsx @@ -1,29 +1,25 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import InputGroup from './InputGroup' -import Alerts from './Alerts' +import Alerts, { alertMessages } from './Alerts' import styles from './index.module.scss' import { getWeb3, getAccounts, getNetwork } from './utils' const ONE_SECOND = 1000 const ONE_MINUTE = ONE_SECOND * 60 +const correctNetwork = 1 export default class Web3Donation extends PureComponent { state = { - web3Connected: false, netId: null, networkName: null, - isCorrectNetwork: false, - loading: true, accounts: [], selectedAccount: null, amount: '0.01', transactionHash: null, receipt: null, - inTransaction: false, - error: null, - message: 'Hang on', - success: false + message: null, + inTransaction: false } static propTypes = { @@ -43,22 +39,24 @@ export default class Web3Donation extends PureComponent { } initWeb3 = async () => { + this.setState({ message: { text: 'Checking' } }) + try { this.web3 = await getWeb3() - this.setState({ web3Connected: this.web3 ? true : false }) - this.web3 ? this.initAllTheTings() : this.setState({ loading: false }) + this.web3 + ? this.initAllTheTings() + : this.setState({ + message: { status: 'error', text: alertMessages().noWeb3 } + }) } catch (error) { - this.setState({ error }) - this.setState({ web3Connected: false }) + this.setState({ message: { status: 'error', text: error } }) } } async initAllTheTings() { - await this.fetchAccounts() - await this.fetchNetwork() - - this.setState({ loading: false }) + this.fetchAccounts() + this.fetchNetwork() this.initAccountsPoll() this.initNetworkPoll() @@ -67,7 +65,6 @@ export default class Web3Donation extends PureComponent { resetAllTheThings() { clearInterval(this.interval) clearInterval(this.networkInterval) - this.setState({ web3Connected: false }) } initAccountsPoll() { @@ -84,40 +81,44 @@ export default class Web3Donation extends PureComponent { fetchNetwork = async () => { const { web3 } = this + const { netId, networkName } = await getNetwork(web3) - try { - const { netId, networkName } = await getNetwork(web3) - + if (netId === correctNetwork) { + this.setState({ netId, networkName }) + } else { this.setState({ - error: null, - netId, - networkName, - isCorrectNetwork: netId === 1 + message: { + status: 'error', + text: alertMessages(networkName).noCorrectNetwork + } }) - } catch (error) { - this.setState({ error }) } } fetchAccounts = async () => { const { web3 } = this + const accounts = await getAccounts(web3) - try { - const accounts = await getAccounts(web3) - + if (accounts[0]) { this.setState({ - error: null, accounts, - selectedAccount: accounts[0] ? accounts[0].toLowerCase() : null + selectedAccount: accounts[0].toLowerCase() + }) + } else { + this.setState({ + message: { status: 'error', text: alertMessages().noAccount } }) - } catch (error) { - this.setState({ error }) } } - sendTransaction() { + sendTransaction = () => { const { web3 } = this + this.setState({ + inTransaction: true, + message: { text: alertMessages().waitingForUser } + }) + web3.eth .sendTransaction({ from: this.state.selectedAccount, @@ -127,50 +128,32 @@ export default class Web3Donation extends PureComponent { .once('transactionHash', transactionHash => { this.setState({ transactionHash, - message: 'Waiting for network confirmation, hang on' + message: { text: alertMessages().waitingConfirmation } }) }) - .on('error', error => this.setState({ error, inTransaction: false })) + .on('error', error => + this.setState({ message: { status: 'error', text: error } }) + ) .then(() => { this.setState({ - message: 'Confirmed. You are awesome, thanks!', - success: true + message: { status: 'success', text: alertMessages().success } }) }) } - handleButton = () => { - this.setState({ - inTransaction: true, - message: 'Waiting for your confirmation' - }) - - this.sendTransaction() - } - onAmountChange = ({ target }) => { this.setState({ amount: target.value }) } render() { const { - isCorrectNetwork, - accounts, selectedAccount, - web3Connected, - inTransaction, - loading, amount, - networkName, - error, transactionHash, - confirmationNumber, message, - success + inTransaction } = this.state - const hasAccount = accounts.length !== 0 - return (
@@ -179,38 +162,21 @@ export default class Web3Donation extends PureComponent {
- {loading ? ( -
Checking
- ) : inTransaction ? ( -
- {message} -
+ {selectedAccount && + this.state.netId === correctNetwork && + !inTransaction ? ( + ) : ( - web3Connected && ( - + message && ( + ) )}
- - {!loading && ( - - )}
) } diff --git a/src/components/molecules/ModalThanks.jsx b/src/components/molecules/ModalThanks.jsx index 118156be..de16af84 100644 --- a/src/components/molecules/ModalThanks.jsx +++ b/src/components/molecules/ModalThanks.jsx @@ -37,7 +37,7 @@ class ModalThanks extends PureComponent {
-

Other wallets

+

Any other wallets

Send Bitcoin or Ether from any wallet.