diff --git a/README.md b/README.md index 88b68622..749b88b0 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ - [🎉 Features](#-features) - [🎆 EXIF extraction](#-exif-extraction) - - [💰 Cryptocurrency donation via Web3/MetaMask](#-cryptocurrency-donation-via-web3-metamask) + - [💰 Cryptocurrency donation via Web3/MetaMask](#-cryptocurrency-donation-via-web3metamask) - [🕸 Related Posts](#-related-posts) - [🐝 Coinhive](#-coinhive) - [🏆 SEO component](#-seo-component) @@ -55,11 +55,11 @@ If you want to know how this works, have a look at the respective component unde ### 💰 Cryptocurrency donation via Web3/MetaMask -Lets visitors say thanks with Bitcoin or Ether. Includes full Web3 client for sending Ether via MetaMask or Mist. +Lets visitors say thanks with Bitcoin or Ether. Uses [web3.js](https://github.com/ethereum/web3.js) for sending Ether transactions via MetaMask, Brave or Mist. Component listens to account & network changes and adapts accordingly. As a fallback, QR codes are generated with [react-qr-svg](https://github.com/no23reason/react-qr-svg) from the addresses defined in [`config.js`](config.js). -screen shot 2018-10-11 at 21 01 37 +screen shot 2018-10-13 at 18 40 56 If you want to know how this works, have a look at the respective components under @@ -70,7 +70,7 @@ If you want to know how this works, have a look at the respective components und Under each post a list of related posts is displayed which are based on the tags of the currently viewed post. Also allows loading more related posts in place. -screen shot 2018-10-11 at 21 03 03 +screen shot 2018-10-11 at 21 03 03 If you want to know how this works, have a look at the respective component under @@ -80,7 +80,7 @@ If you want to know how this works, have a look at the respective component unde Includes a component for mining Monero with JavaScript via [Coinhive](https://coinhive.com). -screen shot 2018-10-11 at 21 09 49 +screen shot 2018-10-11 at 21 09 49 Functionality is opt-in on a post basis. Simply add this to any post's frontmatter to activate it for this post: diff --git a/package.json b/package.json index c8ab57f6..3dd366d1 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,8 @@ "dms2dec": "^1.1.0", "fast-exif": "^1.0.1", "fraction.js": "^4.0.9", - "gatsby": "^2.0.21", - "gatsby-image": "^2.0.13", + "gatsby": "^2.0.22", + "gatsby-image": "^2.0.14", "gatsby-plugin-catch-links": "^2.0.4", "gatsby-plugin-favicon": "^3.1.4", "gatsby-plugin-feed": "^2.0.8", @@ -78,7 +78,7 @@ "@babel/node": "^7.0.0", "@babel/preset-env": "^7.1.0", "babel-eslint": "^10.0.1", - "eslint": "^5.6.1", + "eslint": "^5.7.0", "eslint-config-prettier": "^3.1.0", "eslint-loader": "^2.1.1", "eslint-plugin-graphql": "^2.1.1", diff --git a/src/components/atoms/Modal.module.scss b/src/components/atoms/Modal.module.scss index d00c65b4..cfade373 100644 --- a/src/components/atoms/Modal.module.scss +++ b/src/components/atoms/Modal.module.scss @@ -10,14 +10,15 @@ bottom: 0; z-index: 10; background: rgba($body-background-color, .9); - backdrop-filter: blur(5px); + // backdrop-filter: blur(5px); animation: fadein .3s; - padding: $spacer / 2; + padding: $spacer; @media (min-width: $screen-sm) { display: flex; - align-items: center; + align-items: flex-start; justify-content: center; + padding-top: 6vh; } } @@ -42,20 +43,31 @@ cursor: pointer; background: transparent; border: 0; - -webkit-appearance: none; + appearance: none; line-height: 1; - font-size: $font-size-large; - padding: 3px; + font-size: $font-size-h2; + padding: 4px; position: absolute; top: 0; right: ($spacer/4); - color: $brand-grey; + color: $brand-grey-light; font-weight: 500; + + &:hover, + &:focus { + color: $brand-grey; + } } -// Prevent background scrolling when modal is open .isModalOpen { + // Prevent background scrolling when modal is open overflow: hidden; + + // more cross-browser backdrop-filter + body > div:first-child { + transition: filter .85s ease-out; + filter: blur(5px); + } } .modal__title { diff --git a/src/components/atoms/Web3Donation.jsx b/src/components/atoms/Web3Donation.jsx index 68c26e05..c81283af 100644 --- a/src/components/atoms/Web3Donation.jsx +++ b/src/components/atoms/Web3Donation.jsx @@ -1,11 +1,85 @@ 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' 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, 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 ( +
+ You are awesome, thanks! +
+ + See your transaction on etherscan.io. + +
+ ) + } + + 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, @@ -13,6 +87,7 @@ export default class Web3Donation extends PureComponent { networkId: null, accounts: [], selectedAccount: null, + amount: 0.01, receipt: null, transactionHash: null, loading: false, @@ -120,7 +195,7 @@ export default class Web3Donation extends PureComponent { { from: this.state.selectedAccount, to: this.props.address, - value: '10000000000000000' + value: this.state.amount * 1e18 // ETH -> Wei }, (error, transactionHash) => { if (error) this.setState({ error, loading: false }) @@ -130,57 +205,45 @@ export default class Web3Donation extends PureComponent { ) } + onAmountChange = ({ target }) => { + this.setState({ amount: target.value }) + } + render() { return (
-

web3

-

Send a donation with MetaMask or Mist.

+
+

web3

+

Send Ether with MetaMask, Brave, or Mist.

+
{this.state.web3Connected ? ( -
+
{this.state.loading ? ( 'Hang on...' ) : ( - + )} - {this.state.accounts.length === 0 && ( -
- Web3 detected, but no account. Are you logged into your MetaMask - account? -
- )} - - {this.state.networkId !== '1' && ( -
Please connect to Main network
- )} - - {this.state.error && ( -
{this.state.error.message}
- )} - - {this.state.transactionHash && ( -
- You are awesome, thanks! -
- - See your transaction on etherscan.io. - -
- )} +
) : ( -
No Web3 capable browser detected.
+ + No Web3 detected. Install MetaMask + , Brave, or{' '} + Mist. + )}
) diff --git a/src/components/atoms/Web3Donation.module.scss b/src/components/atoms/Web3Donation.module.scss index 9905ad60..dcf801d6 100644 --- a/src/components/atoms/Web3Donation.module.scss +++ b/src/components/atoms/Web3Donation.module.scss @@ -10,23 +10,89 @@ 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; + position: relative; + + @media (min-width: $screen-sm) { + display: flex; + max-width: 18rem; + } + button { - margin: auto; + width: 100%; + border-top-left-radius: 0; + border-top-right-radius: 0; + border-color: lighten($brand-grey-light, 10%); + + @media (min-width: $screen-sm) { + width: 50%; + border-top-right-radius: $border-radius; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-left: 0; + } + } +} + +.input { + position: relative; + + @media (min-width: $screen-sm) { + width: 50%; } - h4 { - font-size: $font-size-large; - margin-top: 0; - margin-bottom: $spacer / 4; - color: $brand-grey; + input { text-align: center; - } + border: 1px solid lighten($brand-grey-light, 20%); + font-size: $font-size-large; + padding: $spacer / 3 $spacer / 3 $spacer / 3 $spacer * 1.7; + border-bottom: 0; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; - p { - color: $brand-grey-light; + @media (min-width: $screen-sm) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: $border-radius; + border-bottom: 1px solid lighten($brand-grey-light, 20%); + border-right: 0; + } + + &::-webkit-inner-spin-button { + margin-left: -($spacer / 2); + } } } +.currency { + position: absolute; + top: 1px; + bottom: 1px; + left: 1px; + font-size: $font-size-small; + padding: $spacer / 3; + color: $brand-grey-light; + background: $brand-light; + border-right: 1px solid rgba($brand-grey-light, .4); + border-top-left-radius: $border-radius; + border-bottom-left-radius: $border-radius; + display: flex; + align-items: center; +} + .alert { margin-top: $spacer / 2; font-size: $font-size-small; diff --git a/src/components/molecules/ModalThanks.jsx b/src/components/molecules/ModalThanks.jsx index 0e86656e..d035be71 100644 --- a/src/components/molecules/ModalThanks.jsx +++ b/src/components/molecules/ModalThanks.jsx @@ -36,6 +36,11 @@ class ModalThanks extends PureComponent {
+
+

Other wallets

+

Send Bitcoin or Ether from any wallet.

+
+ {Object.keys(author).map((address, i) => (
diff --git a/src/components/molecules/ModalThanks.module.scss b/src/components/molecules/ModalThanks.module.scss index 0f499ab2..0c10f1e1 100644 --- a/src/components/molecules/ModalThanks.module.scss +++ b/src/components/molecules/ModalThanks.module.scss @@ -6,6 +6,30 @@ justify-content: space-between; flex-wrap: wrap; } + + h4 { + text-align: center; + margin: 0; + margin-bottom: $spacer / 2; + color: $brand-grey; + text-transform: capitalize; + } + + header { + width: 100%; + text-align: center; + margin-bottom: $spacer; + + h4 { + font-size: $font-size-large; + margin-top: 0; + margin-bottom: $spacer / 6; + } + + p { + color: $brand-grey-light; + } + } } .coin { @@ -16,14 +40,6 @@ margin-top: 0; } - h4 { - font-size: $font-size-large; - margin-top: 0; - margin-bottom: $spacer / 2; - color: $brand-grey; - text-align: center; - } - > svg { margin-bottom: $spacer / 2; } diff --git a/src/components/molecules/RelatedPosts.jsx b/src/components/molecules/RelatedPosts.jsx index da6b9ef0..76e8c534 100644 --- a/src/components/molecules/RelatedPosts.jsx +++ b/src/components/molecules/RelatedPosts.jsx @@ -103,7 +103,7 @@ class RelatedPosts extends PureComponent { className={`${styles.button} btn`} onClick={this.shufflePosts} > - More Related Posts + Refresh Related Posts ) diff --git a/src/styles/_code.scss b/src/styles/_code.scss index 6db3a6e7..4979db36 100644 --- a/src/styles/_code.scss +++ b/src/styles/_code.scss @@ -43,7 +43,7 @@ pre { border-radius: $border-radius; // make 'em scrollable - overflow: scroll; + overflow: auto; -webkit-overflow-scrolling: touch; max-height: 300px;