1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-24 19:10:22 +01:00
metamask-extension/app/scripts/lib/notifications.js

160 lines
4.8 KiB
JavaScript
Raw Normal View History

const createId = require('hat')
2016-06-25 02:22:27 +02:00
const extend = require('xtend')
const unmountComponentAtNode = require('react-dom').unmountComponentAtNode
const findDOMNode = require('react-dom').findDOMNode
const render = require('react-dom').render
const h = require('react-hyperscript')
2016-06-25 02:22:27 +02:00
const PendingTxDetails = require('../../../ui/app/components/pending-tx-details')
const PendingMsgDetails = require('../../../ui/app/components/pending-msg-details')
const MetaMaskUiCss = require('../../../ui/css')
const extension = require('./extension')
var notificationHandlers = {}
2016-07-12 05:53:26 +02:00
const notifications = {
createUnlockRequestNotification: createUnlockRequestNotification,
createTxNotification: createTxNotification,
createMsgNotification: createMsgNotification,
}
module.exports = notifications
window.METAMASK_NOTIFIER = notifications
2016-06-03 02:29:49 +02:00
setupListeners()
2016-06-21 22:18:32 +02:00
function setupListeners () {
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
if (!extension.notifications) return console.error('Chrome notifications API missing...')
2016-06-03 02:29:49 +02:00
// notification button press
extension.notifications.onButtonClicked.addListener(function (notificationId, buttonIndex) {
2016-06-03 02:29:49 +02:00
var handlers = notificationHandlers[notificationId]
if (buttonIndex === 0) {
handlers.confirm()
} else {
handlers.cancel()
}
extension.notifications.clear(notificationId)
2016-06-03 02:29:49 +02:00
})
// notification teardown
extension.notifications.onClosed.addListener(function (notificationId) {
2016-06-03 02:29:49 +02:00
delete notificationHandlers[notificationId]
})
}
// creation helper
2016-06-21 22:18:32 +02:00
function createUnlockRequestNotification (opts) {
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
if (!extension.notifications) return console.error('Chrome notifications API missing...')
var message = 'An Ethereum app has requested a signature. Please unlock your account.'
var id = createId()
extension.notifications.create(id, {
type: 'basic',
iconUrl: '/images/icon-128.png',
title: opts.title,
message: message,
})
}
function createTxNotification (state) {
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
if (!extension.notifications) return console.error('Chrome notifications API missing...')
2016-07-12 05:53:26 +02:00
renderTxNotificationSVG(state, function (err, notificationSvgSource) {
2016-06-24 01:53:45 +02:00
if (err) throw err
2016-06-25 02:22:27 +02:00
showNotification(extend(state, {
title: 'New Unsigned Transaction',
2016-06-25 02:22:27 +02:00
imageUrl: toSvgUri(notificationSvgSource),
}))
})
}
function createMsgNotification (state) {
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
if (!extension.notifications) return console.error('Chrome notifications API missing...')
2016-06-25 02:22:27 +02:00
2016-07-12 05:53:26 +02:00
renderMsgNotificationSVG(state, function (err, notificationSvgSource) {
2016-06-25 02:22:27 +02:00
if (err) throw err
showNotification(extend(state, {
title: 'New Unsigned Message',
2016-06-25 02:22:27 +02:00
imageUrl: toSvgUri(notificationSvgSource),
}))
})
}
function showNotification (state) {
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
if (!extension.notifications) return console.error('Chrome notifications API missing...')
var id = createId()
extension.notifications.create(id, {
2016-06-25 02:22:27 +02:00
type: 'image',
requireInteraction: true,
iconUrl: '/images/icon-128.png',
2016-06-25 02:22:27 +02:00
imageUrl: state.imageUrl,
title: state.title,
message: '',
buttons: [{
title: 'Approve',
2016-06-21 22:18:32 +02:00
}, {
title: 'Reject',
2016-06-21 22:18:32 +02:00
}],
})
notificationHandlers[id] = {
2016-06-25 02:22:27 +02:00
confirm: state.onConfirm,
cancel: state.onCancel,
}
2016-06-25 02:22:27 +02:00
}
2016-06-23 04:28:11 +02:00
2016-07-12 05:53:26 +02:00
function renderTxNotificationSVG (state, cb) {
2016-06-25 02:22:27 +02:00
var content = h(PendingTxDetails, state)
renderNotificationSVG(content, cb)
}
2016-06-23 04:28:11 +02:00
2016-07-12 05:53:26 +02:00
function renderMsgNotificationSVG (state, cb) {
2016-06-25 02:22:27 +02:00
var content = h(PendingMsgDetails, state)
renderNotificationSVG(content, cb)
}
2016-06-23 04:28:11 +02:00
2016-07-12 05:53:26 +02:00
function renderNotificationSVG (content, cb) {
2016-06-23 04:28:11 +02:00
var container = document.createElement('div')
var confirmView = h('div.app-primary', {
style: {
width: '360px',
height: '240px',
padding: '16px',
// background: '#F7F7F7',
background: 'white',
},
}, [
h('style', MetaMaskUiCss()),
2016-06-25 02:22:27 +02:00
content,
2016-06-23 04:28:11 +02:00
])
2016-07-12 05:53:26 +02:00
render(confirmView, container, function ready() {
2016-06-23 04:28:11 +02:00
var rootElement = findDOMNode(this)
var viewSource = rootElement.outerHTML
2016-06-23 04:28:11 +02:00
unmountComponentAtNode(container)
var svgSource = svgWrapper(viewSource)
2016-06-23 04:28:11 +02:00
// insert content into svg wrapper
cb(null, svgSource)
2016-06-23 04:28:11 +02:00
})
}
2016-07-12 05:53:26 +02:00
function svgWrapper (content) {
var wrapperSource = `
2016-06-28 22:21:25 +02:00
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="240">
<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)
2016-06-25 02:22:27 +02:00
}
2016-07-12 05:53:26 +02:00
function toSvgUri (content) {
2016-06-25 02:22:27 +02:00
return 'data:image/svg+xml;utf8,' + encodeURIComponent(content)
}