diff options
Diffstat (limited to 'ui/app/components/identicon')
-rw-r--r-- | ui/app/components/identicon/identicon.component.js | 99 | ||||
-rw-r--r-- | ui/app/components/identicon/identicon.container.js | 12 | ||||
-rw-r--r-- | ui/app/components/identicon/index.js | 1 | ||||
-rw-r--r-- | ui/app/components/identicon/index.scss | 7 | ||||
-rw-r--r-- | ui/app/components/identicon/tests/identicon.component.test.js | 51 |
5 files changed, 170 insertions, 0 deletions
diff --git a/ui/app/components/identicon/identicon.component.js b/ui/app/components/identicon/identicon.component.js new file mode 100644 index 000000000..b892e5ae5 --- /dev/null +++ b/ui/app/components/identicon/identicon.component.js @@ -0,0 +1,99 @@ +import React, { PureComponent } from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' +import { toDataUrl } from '../../../lib/blockies' +import contractMap from 'eth-contract-metadata' +import { checksumAddress } from '../../../app/util' +import Jazzicon from '../jazzicon' + +const getStyles = diameter => ( + { + height: diameter, + width: diameter, + borderRadius: diameter / 2, + } +) + +export default class Identicon extends PureComponent { + static propTypes = { + address: PropTypes.string, + className: PropTypes.string, + diameter: PropTypes.number, + image: PropTypes.string, + useBlockie: PropTypes.bool, + } + + static defaultProps = { + diameter: 46, + } + + renderImage () { + const { className, diameter, image } = this.props + + return ( + <img + className={classnames('identicon', className)} + src={image} + style={getStyles(diameter)} + /> + ) + } + + renderJazzicon () { + const { address, className, diameter } = this.props + + return ( + <Jazzicon + address={address} + diameter={diameter} + className={classnames('identicon', className)} + style={getStyles(diameter)} + /> + ) + } + + renderBlockie () { + const { address, className, diameter } = this.props + + return ( + <div + className={classnames('identicon', className)} + style={getStyles(diameter)} + > + <img + src={toDataUrl(address)} + height={diameter} + width={diameter} + /> + </div> + ) + } + + render () { + const { className, address, image, diameter, useBlockie } = this.props + + if (image) { + return this.renderImage() + } + + if (address) { + const checksummedAddress = checksumAddress(address) + + if (contractMap[checksummedAddress] && contractMap[checksummedAddress].logo) { + return this.renderJazzicon() + } + + return useBlockie + ? this.renderBlockie() + : this.renderJazzicon() + } + + return ( + <img + className={classnames('balance-icon', className)} + src="./images/eth_logo.svg" + style={getStyles(diameter)} + /> + ) + } +} diff --git a/ui/app/components/identicon/identicon.container.js b/ui/app/components/identicon/identicon.container.js new file mode 100644 index 000000000..bc49bc18e --- /dev/null +++ b/ui/app/components/identicon/identicon.container.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux' +import Identicon from './identicon.component' + +const mapStateToProps = state => { + const { metamask: { useBlockie } } = state + + return { + useBlockie, + } +} + +export default connect(mapStateToProps)(Identicon) diff --git a/ui/app/components/identicon/index.js b/ui/app/components/identicon/index.js new file mode 100644 index 000000000..799c886f2 --- /dev/null +++ b/ui/app/components/identicon/index.js @@ -0,0 +1 @@ +export { default } from './identicon.container' diff --git a/ui/app/components/identicon/index.scss b/ui/app/components/identicon/index.scss new file mode 100644 index 000000000..657afc48f --- /dev/null +++ b/ui/app/components/identicon/index.scss @@ -0,0 +1,7 @@ +.identicon { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + overflow: hidden; +} diff --git a/ui/app/components/identicon/tests/identicon.component.test.js b/ui/app/components/identicon/tests/identicon.component.test.js new file mode 100644 index 000000000..2944818f5 --- /dev/null +++ b/ui/app/components/identicon/tests/identicon.component.test.js @@ -0,0 +1,51 @@ +import React from 'react' +import assert from 'assert' +import thunk from 'redux-thunk' +import configureMockStore from 'redux-mock-store' +import { mount } from 'enzyme' +import Identicon from '../identicon.component' + +describe('Identicon', () => { + const state = { + metamask: { + useBlockie: false, + }, + } + + const middlewares = [thunk] + const mockStore = configureMockStore(middlewares) + const store = mockStore(state) + + it('renders default eth_logo identicon with no props', () => { + const wrapper = mount( + <Identicon store={store}/> + ) + + assert.equal(wrapper.find('img.balance-icon').prop('src'), './images/eth_logo.svg') + }) + + it('renders custom image and add className props', () => { + const wrapper = mount( + <Identicon + store={store} + className="test-image" + image="test-image" + /> + ) + + assert.equal(wrapper.find('img.test-image').prop('className'), 'identicon test-image') + assert.equal(wrapper.find('img.test-image').prop('src'), 'test-image') + }) + + it('renders div with address prop', () => { + const wrapper = mount( + <Identicon + store={store} + className="test-address" + address="0xTest" + /> + ) + + assert.equal(wrapper.find('div.test-address').prop('className'), 'identicon test-address') + }) +}) |