mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 17:33:23 +01:00
Send Token screen partial UI
This commit is contained in:
parent
983fa2a117
commit
8b919758e5
@ -95,6 +95,8 @@ var actions = {
|
||||
// account detail screen
|
||||
SHOW_SEND_PAGE: 'SHOW_SEND_PAGE',
|
||||
showSendPage: showSendPage,
|
||||
SHOW_SEND_TOKEN_PAGE: 'SHOW_SEND_TOKEN_PAGE',
|
||||
showSendTokenPage,
|
||||
ADD_TO_ADDRESS_BOOK: 'ADD_TO_ADDRESS_BOOK',
|
||||
addToAddressBook: addToAddressBook,
|
||||
REQUEST_ACCOUNT_EXPORT: 'REQUEST_ACCOUNT_EXPORT',
|
||||
@ -928,6 +930,12 @@ function showSendPage () {
|
||||
}
|
||||
}
|
||||
|
||||
function showSendTokenPage () {
|
||||
return {
|
||||
type: actions.SHOW_SEND_TOKEN_PAGE,
|
||||
}
|
||||
}
|
||||
|
||||
function buyEth (opts) {
|
||||
return (dispatch) => {
|
||||
const url = getBuyEthUrl(opts)
|
||||
|
@ -9,6 +9,7 @@ const NewKeyChainScreen = require('./new-keychain')
|
||||
// accounts
|
||||
const MainContainer = require('./main-container')
|
||||
const SendTransactionScreen = require('./send')
|
||||
const SendTokenScreen = require('./components/send-token')
|
||||
const ConfirmTxScreen = require('./conf-tx')
|
||||
// notice
|
||||
const NoticeScreen = require('./components/notice')
|
||||
@ -327,6 +328,10 @@ App.prototype.renderPrimary = function () {
|
||||
log.debug('rendering send tx screen')
|
||||
return h(SendTransactionScreen, {key: 'send-transaction'})
|
||||
|
||||
case 'sendToken':
|
||||
log.debug('rendering send token screen')
|
||||
return h(SendTokenScreen, {key: 'sendToken'})
|
||||
|
||||
case 'newKeychain':
|
||||
log.debug('rendering new keychain screen')
|
||||
return h(NewKeyChainScreen, {key: 'new-keychain'})
|
||||
|
213
ui/app/components/send-token/index.js
Normal file
213
ui/app/components/send-token/index.js
Normal file
@ -0,0 +1,213 @@
|
||||
const Component = require('react').Component
|
||||
const connect = require('react-redux').connect
|
||||
const h = require('react-hyperscript')
|
||||
const ethUtil = require('ethereumjs-util')
|
||||
const inherits = require('util').inherits
|
||||
const actions = require('../../actions')
|
||||
const selectors = require('../../selectors')
|
||||
|
||||
// const BalanceComponent = require('./balance-component')
|
||||
const Identicon = require('../identicon')
|
||||
const TokenBalance = require('../token-balance')
|
||||
const CurrencyToggle = require('../send/currency-toggle')
|
||||
const GasTooltip = require('../send/gas-tooltip')
|
||||
const GasFeeDisplay = require('../send/gas-fee-display')
|
||||
|
||||
|
||||
module.exports = connect(mapStateToProps, mapDispatchToProps)(SendTokenScreen)
|
||||
|
||||
function mapStateToProps (state) {
|
||||
// const sidebarOpen = state.appState.sidebarOpen
|
||||
|
||||
const identities = state.metamask.identities
|
||||
const addressBook = state.metamask.addressBook
|
||||
const conversionRate = state.metamask.conversionRate
|
||||
const currentBlockGasLimit = state.metamask.currentBlockGasLimit
|
||||
// const accounts = state.metamask.accounts
|
||||
// const network = state.metamask.network
|
||||
const selectedTokenAddress = state.metamask.selectedTokenAddress
|
||||
// const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
|
||||
// const checksumAddress = selectedAddress && ethUtil.toChecksumAddress(selectedAddress)
|
||||
// const identity = identities[selectedAddress]
|
||||
|
||||
return {
|
||||
// sidebarOpen,
|
||||
// selectedAddress,
|
||||
// checksumAddress,
|
||||
selectedTokenAddress,
|
||||
identities,
|
||||
addressBook,
|
||||
conversionRate,
|
||||
currentBlockGasLimit,
|
||||
selectedToken: selectors.getSelectedToken(state),
|
||||
// selectedToken: selectors.getSelectedToken(state),
|
||||
// identity,
|
||||
// network,
|
||||
}
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return {
|
||||
// showSidebar: () => { dispatch(actions.showSidebar()) },
|
||||
// hideSidebar: () => { dispatch(actions.hideSidebar()) },
|
||||
// showModal: (payload) => { dispatch(actions.showModal(payload)) },
|
||||
// showSendPage: () => { dispatch(actions.showSendPage()) },
|
||||
// showSendTokenPage: () => { dispatch(actions.showSendTokenPage()) },
|
||||
}
|
||||
}
|
||||
|
||||
inherits(SendTokenScreen, Component)
|
||||
function SendTokenScreen () {
|
||||
Component.call(this)
|
||||
this.state = {
|
||||
to: '',
|
||||
selectedCurrency: 'USD',
|
||||
isGasTooltipOpen: false,
|
||||
gasPrice: '0x5d21dba00',
|
||||
gasLimit: '0x7b0d',
|
||||
}
|
||||
}
|
||||
|
||||
SendTokenScreen.prototype.renderToAddressInput = function () {
|
||||
const {
|
||||
identities,
|
||||
addressBook,
|
||||
} = this.props
|
||||
|
||||
const {
|
||||
to,
|
||||
} = this.state
|
||||
|
||||
return h('div.send-screen-input-wrapper', {}, [
|
||||
h('div', ['To:']),
|
||||
h('input.large-input.send-screen-input', {
|
||||
name: 'address',
|
||||
list: 'addresses',
|
||||
placeholder: 'Address',
|
||||
value: to,
|
||||
onChange: e => this.setState({ to: e.target.value }),
|
||||
}),
|
||||
h('datalist#addresses', [
|
||||
// Corresponds to the addresses owned.
|
||||
Object.entries(identities).map(([key, { address, name }]) => {
|
||||
return h('option', {
|
||||
value: address,
|
||||
label: name,
|
||||
key: address,
|
||||
})
|
||||
}),
|
||||
addressBook.map(({ address, name }) => {
|
||||
return h('option', {
|
||||
value: address,
|
||||
label: name,
|
||||
key: address,
|
||||
})
|
||||
}),
|
||||
]),
|
||||
])
|
||||
}
|
||||
|
||||
SendTokenScreen.prototype.renderAmountInput = function () {
|
||||
const {
|
||||
selectedCurrency,
|
||||
} = this.state
|
||||
|
||||
const {
|
||||
selectedToken: {symbol},
|
||||
} = this.props
|
||||
|
||||
return h('div.send-screen-input-wrapper', {}, [
|
||||
h('div.send-screen-amount-labels', [
|
||||
h('span', ['Amount']),
|
||||
h(CurrencyToggle, {
|
||||
selectedCurrency,
|
||||
onClick: currency => this.setState({ selectedCurrency: currency }),
|
||||
}),
|
||||
]),
|
||||
h('input.large-input.send-screen-input', {
|
||||
placeholder: `0 ${symbol}`,
|
||||
type: 'number',
|
||||
onChange: e => this.setState({ amount: e.target.value }),
|
||||
}),
|
||||
])
|
||||
}
|
||||
|
||||
SendTokenScreen.prototype.renderGasInput = function () {
|
||||
const {
|
||||
isGasTooltipOpen,
|
||||
gasPrice,
|
||||
gasLimit,
|
||||
selectedCurrency,
|
||||
} = this.state
|
||||
|
||||
const {
|
||||
conversionRate,
|
||||
currentBlockGasLimit,
|
||||
} = this.props
|
||||
|
||||
return h('div.send-screen-input-wrapper', [
|
||||
isGasTooltipOpen && h(GasTooltip, {
|
||||
className: 'send-tooltip',
|
||||
gasPrice,
|
||||
gasLimit,
|
||||
onClose: () => this.setState({ isGasTooltipOpen: false }),
|
||||
onFeeChange: ({ gasLimit, gasPrice }) => {
|
||||
this.setState({ gasLimit, gasPrice })
|
||||
},
|
||||
}),
|
||||
|
||||
h('div.send-screen-gas-labels', {}, [
|
||||
h('span', [ h('i.fa.fa-bolt'), 'Gas fee:']),
|
||||
h('span', ['What\'s this?']),
|
||||
]),
|
||||
h('div.large-input.send-screen-gas-input', [
|
||||
h(GasFeeDisplay, {
|
||||
conversionRate,
|
||||
gasPrice,
|
||||
currentCurrency: selectedCurrency,
|
||||
gas: gasLimit,
|
||||
blockGasLimit: currentBlockGasLimit,
|
||||
}),
|
||||
h(
|
||||
'div.send-screen-gas-input-customize',
|
||||
{ onClick: () => this.setState({ isGasTooltipOpen: !isGasTooltipOpen }) },
|
||||
['Customize']
|
||||
),
|
||||
]),
|
||||
])
|
||||
}
|
||||
|
||||
SendTokenScreen.prototype.renderMemoInput = function () {
|
||||
return h('div.send-screen-input-wrapper', {}, [
|
||||
h('div', {}, ['Transaction memo (optional)']),
|
||||
h(
|
||||
'input.large-input.send-screen-input',
|
||||
{ onChange: e => this.setState({ memo: e.target.value }) }
|
||||
),
|
||||
])
|
||||
}
|
||||
|
||||
SendTokenScreen.prototype.render = function () {
|
||||
const {
|
||||
selectedTokenAddress,
|
||||
selectedToken,
|
||||
} = this.props
|
||||
|
||||
return h('div.send-token', [
|
||||
h(Identicon, {
|
||||
diameter: 75,
|
||||
address: selectedTokenAddress,
|
||||
}),
|
||||
h('div.send-token__title', ['Send Tokens']),
|
||||
h('div.send-token__description', ['Send Tokens to anyone with an Ethereum account']),
|
||||
h('div.send-token__balance-text', ['Your Token Balance is:']),
|
||||
h('div.send-token__token-balance', [
|
||||
h(TokenBalance, { token: selectedToken, balanceOnly: true }),
|
||||
]),
|
||||
h('div.send-token__token-symbol', [selectedToken.symbol]),
|
||||
this.renderToAddressInput(),
|
||||
this.renderAmountInput(),
|
||||
this.renderGasInput(),
|
||||
this.renderMemoInput(),
|
||||
])
|
||||
}
|
@ -93,8 +93,10 @@ TokenBalance.prototype.componentDidUpdate = function (nextProps) {
|
||||
|
||||
TokenBalance.prototype.updateBalance = function (tokens = []) {
|
||||
const [{ string, symbol }] = tokens
|
||||
const { balanceOnly } = this.props
|
||||
|
||||
this.setState({
|
||||
balance: `${string} ${symbol}`,
|
||||
balance: balanceOnly ? string : `${string} ${symbol}`,
|
||||
isLoading: false,
|
||||
})
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ function mapDispatchToProps (dispatch) {
|
||||
hideSidebar: () => { dispatch(actions.hideSidebar()) },
|
||||
showModal: (payload) => { dispatch(actions.showModal(payload)) },
|
||||
showSendPage: () => { dispatch(actions.showSendPage()) },
|
||||
showSendTokenPage: () => { dispatch(actions.showSendTokenPage()) },
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +61,7 @@ TxView.prototype.renderHeroBalance = function () {
|
||||
}
|
||||
|
||||
TxView.prototype.renderButtons = function () {
|
||||
const {selectedToken, showModal, showSendPage } = this.props
|
||||
const {selectedToken, showModal, showSendPage, showSendTokenPage } = this.props
|
||||
|
||||
return !selectedToken
|
||||
? (
|
||||
@ -90,7 +91,7 @@ TxView.prototype.renderButtons = function () {
|
||||
textAlign: 'center',
|
||||
marginLeft: '0.8em',
|
||||
},
|
||||
onClick: showSendPage,
|
||||
onClick: showSendTokenPage,
|
||||
}, 'SEND'),
|
||||
])
|
||||
)
|
||||
|
@ -203,3 +203,44 @@
|
||||
font-size: .8em;
|
||||
padding: 1px 4px;
|
||||
}
|
||||
|
||||
.send-token {
|
||||
width: 498px;
|
||||
height: 605px;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .08);
|
||||
padding: 46px 40.5px 26px;
|
||||
position: relative;
|
||||
top: -26px;
|
||||
z-index: 25;
|
||||
align-items: center;
|
||||
font-family: "Montserrat Light";
|
||||
|
||||
.identicon {
|
||||
position: absolute;
|
||||
top: -35px;
|
||||
z-index: 25;
|
||||
}
|
||||
|
||||
&__title {
|
||||
color: $scorpion;
|
||||
font-size: 20px;
|
||||
line-height: 29px;
|
||||
}
|
||||
|
||||
&__description,
|
||||
&__balance-text,
|
||||
&__token-symbol {
|
||||
margin-top: 10px;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
&__token-balance {
|
||||
font-size: 43px;
|
||||
line-height: 40px;
|
||||
margin-top: 13px;
|
||||
}
|
||||
}
|
||||
|
@ -219,6 +219,16 @@ function reduceApp (state, action) {
|
||||
warning: null,
|
||||
})
|
||||
|
||||
case actions.SHOW_SEND_TOKEN_PAGE:
|
||||
return extend(appState, {
|
||||
currentView: {
|
||||
name: 'sendToken',
|
||||
context: appState.currentView.context,
|
||||
},
|
||||
transForward: true,
|
||||
warning: null,
|
||||
})
|
||||
|
||||
case actions.SHOW_NEW_KEYCHAIN:
|
||||
return extend(appState, {
|
||||
currentView: {
|
||||
|
Loading…
Reference in New Issue
Block a user