Fix blockies icons overriding contract map icons. Refactor Identicon component (#5599)
parent
315028ec53
commit
554f79c0e2
@ -1,124 +0,0 @@ |
|||||||
const Component = require('react').Component |
|
||||||
const h = require('react-hyperscript') |
|
||||||
const inherits = require('util').inherits |
|
||||||
const connect = require('react-redux').connect |
|
||||||
const isNode = require('detect-node') |
|
||||||
const findDOMNode = require('react-dom').findDOMNode |
|
||||||
const jazzicon = require('jazzicon') |
|
||||||
const iconFactoryGen = require('../../lib/icon-factory') |
|
||||||
const iconFactory = iconFactoryGen(jazzicon) |
|
||||||
const { toDataUrl } = require('../../lib/blockies') |
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(IdenticonComponent) |
|
||||||
|
|
||||||
inherits(IdenticonComponent, Component) |
|
||||||
function IdenticonComponent () { |
|
||||||
Component.call(this) |
|
||||||
|
|
||||||
this.defaultDiameter = 46 |
|
||||||
} |
|
||||||
|
|
||||||
function mapStateToProps (state) { |
|
||||||
return { |
|
||||||
useBlockie: state.metamask.useBlockie, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IdenticonComponent.prototype.render = function () { |
|
||||||
var props = this.props |
|
||||||
const { className = '', address, image } = props |
|
||||||
var diameter = props.diameter || this.defaultDiameter |
|
||||||
const style = { |
|
||||||
height: diameter, |
|
||||||
width: diameter, |
|
||||||
borderRadius: diameter / 2, |
|
||||||
} |
|
||||||
if (image) { |
|
||||||
return h('img', { |
|
||||||
className: `${className} identicon`, |
|
||||||
src: image, |
|
||||||
style: { |
|
||||||
...style, |
|
||||||
}, |
|
||||||
}) |
|
||||||
} else if (address) { |
|
||||||
return h('div', { |
|
||||||
className: `${className} identicon`, |
|
||||||
key: 'identicon-' + address, |
|
||||||
style: { |
|
||||||
display: 'flex', |
|
||||||
flexShrink: 0, |
|
||||||
alignItems: 'center', |
|
||||||
justifyContent: 'center', |
|
||||||
...style, |
|
||||||
overflow: 'hidden', |
|
||||||
}, |
|
||||||
}) |
|
||||||
} else { |
|
||||||
return h('img.balance-icon', { |
|
||||||
className, |
|
||||||
src: './images/eth_logo.svg', |
|
||||||
style: { |
|
||||||
...style, |
|
||||||
}, |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IdenticonComponent.prototype.componentDidMount = function () { |
|
||||||
var props = this.props |
|
||||||
const { address, useBlockie } = props |
|
||||||
|
|
||||||
if (!address) return |
|
||||||
|
|
||||||
if (!isNode) { |
|
||||||
// eslint-disable-next-line react/no-find-dom-node
|
|
||||||
var container = findDOMNode(this) |
|
||||||
|
|
||||||
const diameter = props.diameter || this.defaultDiameter |
|
||||||
|
|
||||||
if (useBlockie) { |
|
||||||
_generateBlockie(container, address, diameter) |
|
||||||
} else { |
|
||||||
_generateJazzicon(container, address, diameter) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IdenticonComponent.prototype.componentDidUpdate = function () { |
|
||||||
var props = this.props |
|
||||||
const { address, useBlockie } = props |
|
||||||
|
|
||||||
if (!address) return |
|
||||||
|
|
||||||
if (!isNode) { |
|
||||||
// eslint-disable-next-line react/no-find-dom-node
|
|
||||||
var container = findDOMNode(this) |
|
||||||
|
|
||||||
var children = container.children |
|
||||||
for (var i = 0; i < children.length; i++) { |
|
||||||
container.removeChild(children[i]) |
|
||||||
} |
|
||||||
|
|
||||||
const diameter = props.diameter || this.defaultDiameter |
|
||||||
|
|
||||||
if (useBlockie) { |
|
||||||
_generateBlockie(container, address, diameter) |
|
||||||
} else { |
|
||||||
_generateJazzicon(container, address, diameter) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function _generateBlockie (container, address, diameter) { |
|
||||||
const img = new Image() |
|
||||||
img.src = toDataUrl(address) |
|
||||||
img.height = diameter |
|
||||||
img.width = diameter |
|
||||||
container.appendChild(img) |
|
||||||
} |
|
||||||
|
|
||||||
function _generateJazzicon (container, address, diameter) { |
|
||||||
const img = iconFactory.iconForAddress(address, diameter) |
|
||||||
container.appendChild(img) |
|
||||||
} |
|
@ -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)} |
||||||
|
/> |
||||||
|
) |
||||||
|
} |
||||||
|
} |
@ -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) |
@ -0,0 +1 @@ |
|||||||
|
export { default } from './identicon.container' |
@ -0,0 +1,7 @@ |
|||||||
|
.identicon { |
||||||
|
display: flex; |
||||||
|
flex-shrink: 0; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
overflow: hidden; |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
export { default } from './jazzicon.component' |
@ -0,0 +1,69 @@ |
|||||||
|
import React, { PureComponent } from 'react' |
||||||
|
import PropTypes from 'prop-types' |
||||||
|
import isNode from 'detect-node' |
||||||
|
import { findDOMNode } from 'react-dom' |
||||||
|
import jazzicon from 'jazzicon' |
||||||
|
import iconFactoryGenerator from '../../../lib/icon-factory' |
||||||
|
const iconFactory = iconFactoryGenerator(jazzicon) |
||||||
|
|
||||||
|
/** |
||||||
|
* Wrapper around the jazzicon library to return a React component, as the library returns an |
||||||
|
* HTMLDivElement which needs to be appended. |
||||||
|
*/ |
||||||
|
export default class Jazzicon extends PureComponent { |
||||||
|
static propTypes = { |
||||||
|
address: PropTypes.string.isRequired, |
||||||
|
className: PropTypes.string, |
||||||
|
diameter: PropTypes.number, |
||||||
|
style: PropTypes.object, |
||||||
|
} |
||||||
|
|
||||||
|
static defaultProps = { |
||||||
|
diameter: 46, |
||||||
|
} |
||||||
|
|
||||||
|
componentDidMount () { |
||||||
|
if (!isNode) { |
||||||
|
this.appendJazzicon() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
componentDidUpdate (prevProps) { |
||||||
|
const { address: prevAddress } = prevProps |
||||||
|
const { address } = this.props |
||||||
|
|
||||||
|
if (!isNode && address !== prevAddress) { |
||||||
|
this.removeExistingChildren() |
||||||
|
this.appendJazzicon() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
removeExistingChildren () { |
||||||
|
// eslint-disable-next-line react/no-find-dom-node
|
||||||
|
const container = findDOMNode(this) |
||||||
|
const { children } = container |
||||||
|
|
||||||
|
for (let i = 0; i < children.length; i++) { |
||||||
|
container.removeChild(children[i]) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
appendJazzicon () { |
||||||
|
// eslint-disable-next-line react/no-find-dom-node
|
||||||
|
const container = findDOMNode(this) |
||||||
|
const { address, diameter } = this.props |
||||||
|
const image = iconFactory.iconForAddress(address, diameter) |
||||||
|
container.appendChild(image) |
||||||
|
} |
||||||
|
|
||||||
|
render () { |
||||||
|
const { className, style } = this.props |
||||||
|
|
||||||
|
return ( |
||||||
|
<div |
||||||
|
className={className} |
||||||
|
style={style} |
||||||
|
/> |
||||||
|
) |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue