mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Merge pull request #312 from MetaMask/svg-notif
initial svg notifications
This commit is contained in:
commit
ac2269b16e
@ -42,7 +42,7 @@
|
|||||||
"constructor-super": 2,
|
"constructor-super": 2,
|
||||||
"curly": [2, "multi-line"],
|
"curly": [2, "multi-line"],
|
||||||
"dot-location": [2, "property"],
|
"dot-location": [2, "property"],
|
||||||
"eol-last": 2,
|
"eol-last": 1,
|
||||||
"eqeqeq": [2, "allow-null"],
|
"eqeqeq": [2, "allow-null"],
|
||||||
"generator-star-spacing": [2, { "before": true, "after": true }],
|
"generator-star-spacing": [2, { "before": true, "after": true }],
|
||||||
"handle-callback-err": [2, "^(err|error)$" ],
|
"handle-callback-err": [2, "^(err|error)$" ],
|
||||||
@ -87,7 +87,7 @@
|
|||||||
"no-mixed-spaces-and-tabs": 2,
|
"no-mixed-spaces-and-tabs": 2,
|
||||||
"no-multi-spaces": 2,
|
"no-multi-spaces": 2,
|
||||||
"no-multi-str": 2,
|
"no-multi-str": 2,
|
||||||
"no-multiple-empty-lines": [2, { "max": 1 }],
|
"no-multiple-empty-lines": [1, { "max": 2 }],
|
||||||
"no-native-reassign": 2,
|
"no-native-reassign": 2,
|
||||||
"no-negated-in-lhs": 2,
|
"no-negated-in-lhs": 2,
|
||||||
"no-new": 2,
|
"no-new": 2,
|
||||||
@ -112,7 +112,7 @@
|
|||||||
"no-sparse-arrays": 2,
|
"no-sparse-arrays": 2,
|
||||||
"no-this-before-super": 2,
|
"no-this-before-super": 2,
|
||||||
"no-throw-literal": 2,
|
"no-throw-literal": 2,
|
||||||
"no-trailing-spaces": 2,
|
"no-trailing-spaces": 1,
|
||||||
"no-undef": 2,
|
"no-undef": 2,
|
||||||
"no-undef-init": 2,
|
"no-undef-init": 2,
|
||||||
"no-unexpected-multiline": 2,
|
"no-unexpected-multiline": 2,
|
||||||
@ -129,7 +129,7 @@
|
|||||||
"no-with": 2,
|
"no-with": 2,
|
||||||
"one-var": [2, { "initialized": "never" }],
|
"one-var": [2, { "initialized": "never" }],
|
||||||
"operator-linebreak": [2, "after", { "overrides": { "?": "before", ":": "before" } }],
|
"operator-linebreak": [2, "after", { "overrides": { "?": "before", ":": "before" } }],
|
||||||
"padded-blocks": [2, "never"],
|
"padded-blocks": [1, "never"],
|
||||||
"quotes": [2, "single", "avoid-escape"],
|
"quotes": [2, "single", "avoid-escape"],
|
||||||
"semi": [2, "never"],
|
"semi": [2, "never"],
|
||||||
"semi-spacing": [2, { "before": false, "after": true }],
|
"semi-spacing": [2, { "before": false, "after": true }],
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
const createId = require('hat')
|
const createId = require('hat')
|
||||||
|
const unmountComponentAtNode = require('react-dom').unmountComponentAtNode
|
||||||
|
const findDOMNode = require('react-dom').findDOMNode
|
||||||
|
const render = require('react-dom').render
|
||||||
|
const h = require('react-hyperscript')
|
||||||
const uiUtils = require('../../../ui/app/util')
|
const uiUtils = require('../../../ui/app/util')
|
||||||
|
const renderPendingTx = require('../../../ui/app/components/pending-tx').prototype.renderGeneric
|
||||||
|
const MetaMaskUiCss = require('../../../ui/css')
|
||||||
var notificationHandlers = {}
|
var notificationHandlers = {}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@ -49,31 +55,32 @@ function createUnlockRequestNotification (opts) {
|
|||||||
function createTxNotification (opts) {
|
function createTxNotification (opts) {
|
||||||
// guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
|
// guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
|
||||||
if (!chrome.notifications) return console.error('Chrome notifications API missing...')
|
if (!chrome.notifications) return console.error('Chrome notifications API missing...')
|
||||||
var message = [
|
|
||||||
'Submitted by ' + opts.txParams.origin,
|
|
||||||
'to: ' + uiUtils.addressSummary(opts.txParams.to),
|
|
||||||
'from: ' + uiUtils.addressSummary(opts.txParams.from),
|
|
||||||
'value: ' + uiUtils.formatBalance(opts.txParams.value),
|
|
||||||
'data: ' + uiUtils.dataSize(opts.txParams.data),
|
|
||||||
].join('\n')
|
|
||||||
|
|
||||||
var id = createId()
|
renderTransactionNotificationSVG(opts, function(err, source){
|
||||||
chrome.notifications.create(id, {
|
if (err) throw err
|
||||||
type: 'basic',
|
|
||||||
requireInteraction: true,
|
var imageUrl = 'data:image/svg+xml;utf8,' + encodeURIComponent(source)
|
||||||
iconUrl: '/images/icon-128.png',
|
|
||||||
title: opts.title,
|
var id = createId()
|
||||||
message: message,
|
chrome.notifications.create(id, {
|
||||||
buttons: [{
|
type: 'image',
|
||||||
title: 'confirm',
|
// requireInteraction: true,
|
||||||
}, {
|
iconUrl: '/images/icon-128.png',
|
||||||
title: 'cancel',
|
imageUrl: imageUrl,
|
||||||
}],
|
title: opts.title,
|
||||||
|
message: '',
|
||||||
|
buttons: [{
|
||||||
|
title: 'confirm',
|
||||||
|
}, {
|
||||||
|
title: 'cancel',
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
notificationHandlers[id] = {
|
||||||
|
confirm: opts.confirm,
|
||||||
|
cancel: opts.cancel,
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
notificationHandlers[id] = {
|
|
||||||
confirm: opts.confirm,
|
|
||||||
cancel: opts.cancel,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createMsgNotification (opts) {
|
function createMsgNotification (opts) {
|
||||||
@ -103,3 +110,54 @@ function createMsgNotification (opts) {
|
|||||||
cancel: opts.cancel,
|
cancel: opts.cancel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderTransactionNotificationSVG(opts, cb){
|
||||||
|
var state = {
|
||||||
|
nonInteractive: true,
|
||||||
|
inlineIdenticons: true,
|
||||||
|
txData: {
|
||||||
|
txParams: opts.txParams,
|
||||||
|
time: (new Date()).getTime(),
|
||||||
|
},
|
||||||
|
identities: {
|
||||||
|
|
||||||
|
},
|
||||||
|
accounts: {
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var container = document.createElement('div')
|
||||||
|
var confirmView = h('div.app-primary', {
|
||||||
|
style: {
|
||||||
|
width: '450px',
|
||||||
|
height: '300px',
|
||||||
|
padding: '16px',
|
||||||
|
// background: '#F7F7F7',
|
||||||
|
background: 'white',
|
||||||
|
},
|
||||||
|
}, [
|
||||||
|
h('style', MetaMaskUiCss()),
|
||||||
|
renderPendingTx(h, state),
|
||||||
|
])
|
||||||
|
|
||||||
|
render(confirmView, container, function ready(){
|
||||||
|
var rootElement = findDOMNode(this)
|
||||||
|
var viewSource = rootElement.outerHTML
|
||||||
|
unmountComponentAtNode(container)
|
||||||
|
var svgSource = svgWrapper(viewSource)
|
||||||
|
// insert content into svg wrapper
|
||||||
|
cb(null, svgSource)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function svgWrapper(content){
|
||||||
|
var wrapperSource = `
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="450" height="300">
|
||||||
|
<foreignObject x="0" y="0" width="100%" height="100%">
|
||||||
|
<body xmlns="http://www.w3.org/1999/xhtml" height="100%">{{content}}</body>
|
||||||
|
</foreignObject>
|
||||||
|
</svg>
|
||||||
|
`
|
||||||
|
return wrapperSource.split('{{content}}').join(content)
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
const assert = require('assert')
|
|
||||||
const sinon = require('sinon')
|
|
||||||
|
|
||||||
const path = require('path')
|
|
||||||
const IconFactoryGen = require(path.join(__dirname, '..', '..', '..', 'ui', 'lib', 'icon-factory.js'))
|
|
||||||
|
|
||||||
describe('icon-factory', function() {
|
|
||||||
let iconFactory, address, diameter
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
iconFactory = IconFactoryGen((d,n) => 'stubicon')
|
|
||||||
address = '0x012345671234567890'
|
|
||||||
diameter = 50
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should return a data-uri string for any address and diameter', function() {
|
|
||||||
const output = iconFactory.iconForAddress(address, diameter)
|
|
||||||
assert.ok(output.indexOf('data:image/svg') === 0)
|
|
||||||
assert.equal(output, iconFactory.cache[address][diameter])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should default to cache first', function() {
|
|
||||||
const testOutput = 'foo'
|
|
||||||
const mockSizeCache = {}
|
|
||||||
mockSizeCache[diameter] = testOutput
|
|
||||||
iconFactory.cache[address] = mockSizeCache
|
|
||||||
|
|
||||||
const output = iconFactory.iconForAddress(address, diameter)
|
|
||||||
assert.equal(output, testOutput)
|
|
||||||
})
|
|
||||||
})
|
|
@ -3,7 +3,7 @@ const lint = require('mocha-eslint');
|
|||||||
const lintPaths = ['app/**/*.js', 'ui/**/*.js', '!node_modules/**', '!dist/**', '!docs/**', '!app/scripts/chromereload.js']
|
const lintPaths = ['app/**/*.js', 'ui/**/*.js', '!node_modules/**', '!dist/**', '!docs/**', '!app/scripts/chromereload.js']
|
||||||
|
|
||||||
const lintOptions = {
|
const lintOptions = {
|
||||||
strict: true,
|
strict: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
lint(lintPaths, lintOptions)
|
lint(lintPaths, lintOptions)
|
@ -33,6 +33,7 @@ NewComponent.prototype.render = function () {
|
|||||||
this.pendingOrNot(),
|
this.pendingOrNot(),
|
||||||
h(Identicon, {
|
h(Identicon, {
|
||||||
address: identity.address,
|
address: identity.address,
|
||||||
|
imageify: true,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
|
|
@ -5,7 +5,7 @@ const connect = require('react-redux').connect
|
|||||||
const actions = require('../actions')
|
const actions = require('../actions')
|
||||||
const valuesFor = require('../util').valuesFor
|
const valuesFor = require('../util').valuesFor
|
||||||
const findDOMNode = require('react-dom').findDOMNode
|
const findDOMNode = require('react-dom').findDOMNode
|
||||||
const AccountPanel = require('./account-panel')
|
const AccountListItem = require('./account-list-item')
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(AccountsScreen)
|
module.exports = connect(mapStateToProps)(AccountsScreen)
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ AccountsScreen.prototype.render = function () {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return h(AccountPanel, {
|
return h(AccountListItem, {
|
||||||
key: `acct-panel-${identity.address}`,
|
key: `acct-panel-${identity.address}`,
|
||||||
identity,
|
identity,
|
||||||
selectedAddress: this.props.selectedAddress,
|
selectedAddress: this.props.selectedAddress,
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
const inherits = require('util').inherits
|
const inherits = require('util').inherits
|
||||||
const Component = require('react').Component
|
const Component = require('react').Component
|
||||||
const h = require('react-hyperscript')
|
const h = require('react-hyperscript')
|
||||||
|
const Identicon = require('./identicon')
|
||||||
const formatBalance = require('../util').formatBalance
|
const formatBalance = require('../util').formatBalance
|
||||||
const addressSummary = require('../util').addressSummary
|
const addressSummary = require('../util').addressSummary
|
||||||
|
|
||||||
const Panel = require('./panel')
|
|
||||||
|
|
||||||
module.exports = AccountPanel
|
module.exports = AccountPanel
|
||||||
|
|
||||||
|
|
||||||
inherits(AccountPanel, Component)
|
inherits(AccountPanel, Component)
|
||||||
function AccountPanel () {
|
function AccountPanel () {
|
||||||
Component.call(this)
|
Component.call(this)
|
||||||
@ -19,13 +19,8 @@ AccountPanel.prototype.render = function () {
|
|||||||
var account = state.account || {}
|
var account = state.account || {}
|
||||||
var isFauceting = state.isFauceting
|
var isFauceting = state.isFauceting
|
||||||
|
|
||||||
var panelOpts = {
|
var panelState = {
|
||||||
key: `accountPanel${identity.address}`,
|
key: `accountPanel${identity.address}`,
|
||||||
onClick: (event) => {
|
|
||||||
if (state.onShowDetail) {
|
|
||||||
state.onShowDetail(identity.address, event)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
identiconKey: identity.address,
|
identiconKey: identity.address,
|
||||||
identiconLabel: identity.name,
|
identiconLabel: identity.name,
|
||||||
attributes: [
|
attributes: [
|
||||||
@ -37,10 +32,41 @@ AccountPanel.prototype.render = function () {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
return h(Panel, panelOpts,
|
return (
|
||||||
!state.onShowDetail ? null : h('.arrow-right.cursor-pointer', [
|
|
||||||
h('i.fa.fa-chevron-right.fa-lg'),
|
h('.identity-panel.flex-row.flex-space-between', {
|
||||||
]))
|
style: {
|
||||||
|
flex: '1 0 auto',
|
||||||
|
cursor: panelState.onClick ? 'pointer' : undefined,
|
||||||
|
},
|
||||||
|
onClick: panelState.onClick,
|
||||||
|
}, [
|
||||||
|
|
||||||
|
// account identicon
|
||||||
|
h('.identicon-wrapper.flex-column.select-none', [
|
||||||
|
h(Identicon, {
|
||||||
|
address: panelState.identiconKey,
|
||||||
|
imageify: !state.inlineIdenticons,
|
||||||
|
}),
|
||||||
|
h('span.font-small', panelState.identiconLabel),
|
||||||
|
]),
|
||||||
|
|
||||||
|
// account address, balance
|
||||||
|
h('.identity-data.flex-column.flex-justify-center.flex-grow.select-none', [
|
||||||
|
|
||||||
|
panelState.attributes.map((attr) => {
|
||||||
|
return h('.flex-row.flex-space-between', {
|
||||||
|
key: '' + Math.round(Math.random() * 1000000),
|
||||||
|
}, [
|
||||||
|
h('label.font-small.no-select', attr.key),
|
||||||
|
h('span.font-small', attr.value),
|
||||||
|
])
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function balanceOrFaucetingIndication (account, isFauceting) {
|
function balanceOrFaucetingIndication (account, isFauceting) {
|
||||||
|
@ -39,12 +39,9 @@ IdenticonComponent.prototype.componentDidMount = function () {
|
|||||||
if (!address) return
|
if (!address) return
|
||||||
|
|
||||||
var container = findDOMNode(this)
|
var container = findDOMNode(this)
|
||||||
|
|
||||||
var diameter = state.diameter || this.defaultDiameter
|
var diameter = state.diameter || this.defaultDiameter
|
||||||
var dataUri = iconFactory.iconForAddress(address, diameter)
|
var imageify = state.imageify
|
||||||
|
var img = iconFactory.iconForAddress(address, diameter, imageify)
|
||||||
var img = document.createElement('img')
|
|
||||||
img.src = dataUri
|
|
||||||
container.appendChild(img)
|
container.appendChild(img)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
const inherits = require('util').inherits
|
|
||||||
const Component = require('react').Component
|
|
||||||
const h = require('react-hyperscript')
|
|
||||||
const Identicon = require('./identicon')
|
|
||||||
|
|
||||||
module.exports = Panel
|
|
||||||
|
|
||||||
inherits(Panel, Component)
|
|
||||||
function Panel () {
|
|
||||||
Component.call(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
Panel.prototype.render = function () {
|
|
||||||
var state = this.props
|
|
||||||
|
|
||||||
var style = {
|
|
||||||
flex: '1 0 auto',
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.onClick) style.cursor = 'pointer'
|
|
||||||
|
|
||||||
return (
|
|
||||||
h('.identity-panel.flex-row.flex-space-between', {
|
|
||||||
style,
|
|
||||||
onClick: state.onClick,
|
|
||||||
}, [
|
|
||||||
|
|
||||||
// account identicon
|
|
||||||
h('.identicon-wrapper.flex-column.select-none', [
|
|
||||||
h(Identicon, {
|
|
||||||
address: state.identiconKey,
|
|
||||||
}),
|
|
||||||
h('span.font-small', state.identiconLabel),
|
|
||||||
]),
|
|
||||||
|
|
||||||
// account address, balance
|
|
||||||
h('.identity-data.flex-column.flex-justify-center.flex-grow.select-none', [
|
|
||||||
|
|
||||||
state.attributes.map((attr) => {
|
|
||||||
return h('.flex-row.flex-space-between', {
|
|
||||||
key: '' + Math.round(Math.random() * 1000000),
|
|
||||||
}, [
|
|
||||||
h('label.font-small.no-select', attr.key),
|
|
||||||
h('span.font-small', attr.value),
|
|
||||||
])
|
|
||||||
}),
|
|
||||||
]),
|
|
||||||
|
|
||||||
// outlet for inserting additional stuff
|
|
||||||
state.children,
|
|
||||||
])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -16,6 +16,10 @@ function PendingTx () {
|
|||||||
|
|
||||||
PendingTx.prototype.render = function () {
|
PendingTx.prototype.render = function () {
|
||||||
var state = this.props
|
var state = this.props
|
||||||
|
return this.renderGeneric(h, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
PendingTx.prototype.renderGeneric = function (h, state) {
|
||||||
var txData = state.txData
|
var txData = state.txData
|
||||||
|
|
||||||
var txParams = txData.txParams || {}
|
var txParams = txData.txParams || {}
|
||||||
@ -24,6 +28,7 @@ PendingTx.prototype.render = function () {
|
|||||||
var account = state.accounts[address] || { address: address }
|
var account = state.accounts[address] || { address: address }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
h('.transaction', {
|
h('.transaction', {
|
||||||
key: txData.id,
|
key: txData.id,
|
||||||
}, [
|
}, [
|
||||||
@ -40,6 +45,7 @@ PendingTx.prototype.render = function () {
|
|||||||
showFullAddress: true,
|
showFullAddress: true,
|
||||||
identity: identity,
|
identity: identity,
|
||||||
account: account,
|
account: account,
|
||||||
|
inlineIdenticons: state.inlineIdenticons,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// tx data
|
// tx data
|
||||||
@ -62,15 +68,25 @@ PendingTx.prototype.render = function () {
|
|||||||
]),
|
]),
|
||||||
|
|
||||||
// send + cancel
|
// send + cancel
|
||||||
h('.flex-row.flex-space-around', [
|
state.nonInteractive ? null : actionButtons(state),
|
||||||
h('button', {
|
|
||||||
onClick: state.cancelTransaction,
|
|
||||||
}, 'Cancel'),
|
|
||||||
h('button', {
|
|
||||||
onClick: state.sendTransaction,
|
|
||||||
}, 'Send'),
|
|
||||||
]),
|
|
||||||
])
|
])
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function actionButtons(state){
|
||||||
|
return (
|
||||||
|
|
||||||
|
h('.flex-row.flex-space-around', [
|
||||||
|
h('button', {
|
||||||
|
onClick: state.cancelTransaction,
|
||||||
|
}, 'Cancel'),
|
||||||
|
h('button', {
|
||||||
|
onClick: state.sendTransaction,
|
||||||
|
}, 'Send'),
|
||||||
|
])
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
@ -12,42 +12,49 @@ function IconFactory (jazzicon) {
|
|||||||
this.cache = {}
|
this.cache = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
IconFactory.prototype.iconForAddress = function (address, diameter) {
|
IconFactory.prototype.iconForAddress = function (address, diameter, imageify) {
|
||||||
if (this.isCached(address, diameter)) {
|
if (imageify) {
|
||||||
return this.cache[address][diameter]
|
return this.generateIdenticonImg(address, diameter)
|
||||||
|
} else {
|
||||||
|
return this.generateIdenticonSvg(address, diameter)
|
||||||
}
|
}
|
||||||
|
|
||||||
const dataUri = this.generateNewUri(address, diameter)
|
|
||||||
this.cacheIcon(address, diameter, dataUri)
|
|
||||||
return dataUri
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IconFactory.prototype.generateNewUri = function (address, diameter) {
|
// returns img dom element
|
||||||
|
IconFactory.prototype.generateIdenticonImg = function (address, diameter) {
|
||||||
|
var identicon = this.generateIdenticonSvg(address, diameter)
|
||||||
|
var identiconSrc = identicon.innerHTML
|
||||||
|
var dataUri = toDataUri(identiconSrc)
|
||||||
|
var img = document.createElement('img')
|
||||||
|
img.src = dataUri
|
||||||
|
return img
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns svg dom element
|
||||||
|
IconFactory.prototype.generateIdenticonSvg = function (address, diameter) {
|
||||||
|
var cacheId = `${address}:${diameter}`
|
||||||
|
// check cache, lazily generate and populate cache
|
||||||
|
var identicon = this.cache[cacheId] || (this.cache[cacheId] = this.generateNewIdenticon(address, diameter))
|
||||||
|
// create a clean copy so you can modify it
|
||||||
|
var cleanCopy = identicon.cloneNode(true)
|
||||||
|
return cleanCopy
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates a new identicon
|
||||||
|
IconFactory.prototype.generateNewIdenticon = function (address, diameter) {
|
||||||
var numericRepresentation = jsNumberForAddress(address)
|
var numericRepresentation = jsNumberForAddress(address)
|
||||||
var identicon = this.jazzicon(diameter, numericRepresentation)
|
var identicon = this.jazzicon(diameter, numericRepresentation)
|
||||||
var identiconSrc = identicon.innerHTML
|
return identicon
|
||||||
var dataUri = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(identiconSrc)
|
|
||||||
return dataUri
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IconFactory.prototype.cacheIcon = function (address, diameter, icon) {
|
// util
|
||||||
if (!(address in this.cache)) {
|
|
||||||
var sizeCache = {}
|
|
||||||
sizeCache[diameter] = icon
|
|
||||||
this.cache[address] = sizeCache
|
|
||||||
return sizeCache
|
|
||||||
} else {
|
|
||||||
this.cache[address][diameter] = icon
|
|
||||||
return icon
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IconFactory.prototype.isCached = function (address, diameter) {
|
|
||||||
return address in this.cache && diameter in this.cache[address]
|
|
||||||
}
|
|
||||||
|
|
||||||
function jsNumberForAddress (address) {
|
function jsNumberForAddress (address) {
|
||||||
var addr = address.slice(2, 10)
|
var addr = address.slice(2, 10)
|
||||||
var seed = parseInt(addr, 16)
|
var seed = parseInt(addr, 16)
|
||||||
return seed
|
return seed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toDataUri(identiconSrc){
|
||||||
|
return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(identiconSrc)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user