mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-10-22 19:26:13 +02:00
e6c4d63ccd
Calls to `eth.sign` are now transiently persisted in memory, and displayed in a chronological stack with pending transactions (which are still persisted to disk). This allows the user a method to sign/cancel transactions even if they miss the Chrome notification. Improved a lot of the view routing, to avoid cases where routes would show an empty account view, or transition to the accounts list when it shouldn't. Broke the transaction approval view into a couple components so messages and transactions could have their own templates.
243 lines
6.3 KiB
JavaScript
243 lines
6.3 KiB
JavaScript
const inherits = require('util').inherits
|
|
const React = require('react')
|
|
const Component = require('react').Component
|
|
const PropTypes = require('react').PropTypes
|
|
const connect = require('react-redux').connect
|
|
const h = require('react-hyperscript')
|
|
const extend = require('xtend')
|
|
const actions = require('./actions')
|
|
const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
|
|
// init
|
|
const InitializeMenuScreen = require('./first-time/init-menu')
|
|
const CreateVaultScreen = require('./first-time/create-vault')
|
|
const CreateVaultCompleteScreen = require('./first-time/create-vault-complete')
|
|
const RestoreVaultScreen = require('./first-time/restore-vault')
|
|
// unlock
|
|
const UnlockScreen = require('./unlock')
|
|
// accounts
|
|
const AccountsScreen = require('./accounts')
|
|
const AccountDetailScreen = require('./account-detail')
|
|
const SendTransactionScreen = require('./send')
|
|
const ConfirmTxScreen = require('./conf-tx')
|
|
// other views
|
|
const ConfigScreen = require('./config')
|
|
const InfoScreen = require('./info')
|
|
const LoadingIndicator = require('./loading')
|
|
|
|
module.exports = connect(mapStateToProps)(App)
|
|
|
|
|
|
inherits(App, Component)
|
|
function App() { Component.call(this) }
|
|
|
|
function mapStateToProps(state) {
|
|
return {
|
|
// state from plugin
|
|
isInitialized: state.metamask.isInitialized,
|
|
isUnlocked: state.metamask.isUnlocked,
|
|
currentView: state.appState.currentView,
|
|
activeAddress: state.appState.activeAddress,
|
|
transForward: state.appState.transForward,
|
|
seedWords: state.metamask.seedWords,
|
|
}
|
|
}
|
|
|
|
App.prototype.render = function() {
|
|
// const { selectedReddit, posts, isFetching, lastUpdated } = this.props
|
|
var state = this.props
|
|
var view = state.currentView.name
|
|
var transForward = state.transForward
|
|
var shouldHaveFooter = true
|
|
switch (view) {
|
|
case 'restoreVault':
|
|
shouldHaveFooter = false;
|
|
case 'createVault':
|
|
shouldHaveFooter = false;
|
|
case 'createVaultComplete':
|
|
shouldHaveFooter = false;
|
|
}
|
|
|
|
return (
|
|
|
|
h('.flex-column.flex-grow.full-height', {
|
|
style: {
|
|
// Windows was showing a vertical scroll bar:
|
|
overflowY: 'hidden',
|
|
}
|
|
},
|
|
[
|
|
|
|
h(LoadingIndicator),
|
|
|
|
// top row
|
|
h('.app-header.flex-column.flex-center', {
|
|
}, [
|
|
h('h1', 'MetaMask'),
|
|
]),
|
|
|
|
// panel content
|
|
h('.app-primary.flex-grow' + (transForward ? '.from-right' : '.from-left'), {
|
|
style: {
|
|
height: '380px',
|
|
}
|
|
}, [
|
|
h(ReactCSSTransitionGroup, {
|
|
transitionName: "main",
|
|
transitionEnterTimeout: 300,
|
|
transitionLeaveTimeout: 300,
|
|
}, [
|
|
this.renderPrimary(),
|
|
]),
|
|
]),
|
|
|
|
// footer
|
|
h('.app-footer.flex-row.flex-space-around', {
|
|
style: {
|
|
display: shouldHaveFooter ? 'flex' : 'none',
|
|
alignItems: 'center',
|
|
height: '56px',
|
|
}
|
|
}, [
|
|
|
|
// settings icon
|
|
h('i.fa.fa-cog.fa-lg' + (view === 'config' ? '.active' : '.cursor-pointer'), {
|
|
style: {
|
|
opacity: state.isUnlocked ? '1.0' : '0.0',
|
|
transition: 'opacity 200ms ease-in',
|
|
//transform: `translateX(${state.isUnlocked ? '0px' : '-100px'})`,
|
|
},
|
|
onClick: function(ev) {
|
|
state.dispatch(actions.showConfigPage())
|
|
},
|
|
}),
|
|
|
|
// toggle
|
|
onOffToggle({
|
|
toggleMetamaskActive: this.toggleMetamaskActive.bind(this),
|
|
isUnlocked: state.isUnlocked,
|
|
}),
|
|
|
|
// help
|
|
h('i.fa.fa-question.fa-lg.cursor-pointer', {
|
|
style: {
|
|
opacity: state.isUnlocked ? '1.0' : '0.0',
|
|
},
|
|
onClick() { state.dispatch(actions.showInfoPage()) }
|
|
}),
|
|
]),
|
|
])
|
|
)
|
|
}
|
|
|
|
App.prototype.toggleMetamaskActive = function(){
|
|
if (!this.props.isUnlocked) {
|
|
// currently inactive: redirect to password box
|
|
var passwordBox = document.querySelector('input[type=password]')
|
|
if (!passwordBox) return
|
|
passwordBox.focus()
|
|
} else {
|
|
// currently active: deactivate
|
|
this.props.dispatch(actions.lockMetamask(false))
|
|
}
|
|
}
|
|
|
|
App.prototype.renderPrimary = function(state){
|
|
var state = this.props
|
|
|
|
// If seed words haven't been dismissed yet, show them still.
|
|
/*
|
|
if (state.seedWords) {
|
|
return h(CreateVaultCompleteScreen, {key: 'createVaultComplete'})
|
|
}
|
|
*/
|
|
|
|
// show initialize screen
|
|
if (!state.isInitialized) {
|
|
|
|
// show current view
|
|
switch (state.currentView.name) {
|
|
|
|
case 'createVault':
|
|
return h(CreateVaultScreen, {key: 'createVault'})
|
|
|
|
case 'restoreVault':
|
|
return h(RestoreVaultScreen, {key: 'restoreVault'})
|
|
|
|
default:
|
|
return h(InitializeMenuScreen, {key: 'menuScreenInit'})
|
|
|
|
}
|
|
}
|
|
|
|
// show unlock screen
|
|
if (!state.isUnlocked) {
|
|
return h(UnlockScreen, {key: 'locked'})
|
|
}
|
|
|
|
// show current view
|
|
switch (state.currentView.name) {
|
|
|
|
case 'createVaultComplete':
|
|
return h(CreateVaultCompleteScreen, {key: 'created-vault'})
|
|
|
|
case 'accounts':
|
|
return h(AccountsScreen, {key: 'accounts'})
|
|
|
|
case 'accountDetail':
|
|
return h(AccountDetailScreen, {key: 'account-detail'})
|
|
|
|
case 'sendTransaction':
|
|
return h(SendTransactionScreen, {key: 'send-transaction'})
|
|
|
|
case 'confTx':
|
|
return h(ConfirmTxScreen, {key: 'confirm-tx'})
|
|
|
|
case 'config':
|
|
return h(ConfigScreen, {key: 'config'})
|
|
|
|
case 'info':
|
|
return h(InfoScreen, {key: 'info'})
|
|
|
|
case 'createVault':
|
|
return h(CreateVaultScreen, {key: 'createVault'})
|
|
|
|
default:
|
|
return h(AccountDetailScreen, {key: 'account-detail'})
|
|
}
|
|
}
|
|
|
|
function onOffToggle(state){
|
|
var buttonSize = '50px';
|
|
var lockWidth = '20px';
|
|
return (
|
|
h('.app-toggle.flex-row.flex-center.lock' + (state.isUnlocked ? '.unlocked' : '.locked'), {
|
|
width: buttonSize,
|
|
height: buttonSize,
|
|
}, [
|
|
h('div', {
|
|
onClick: state.toggleMetamaskActive,
|
|
style: {
|
|
width: lockWidth,
|
|
height: '' + parseInt(lockWidth) * 1.5 + 'px',
|
|
position: 'relative',
|
|
}
|
|
}, [
|
|
h('img.lock-top', {
|
|
src: 'images/lock-top.png',
|
|
style: {
|
|
width: lockWidth,
|
|
position: 'absolute',
|
|
}
|
|
}),
|
|
h('img', {
|
|
src: 'images/lock-base.png',
|
|
style: {
|
|
width: lockWidth,
|
|
position: 'absolute',
|
|
}
|
|
}),
|
|
])
|
|
])
|
|
)
|
|
}
|