aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChi Kei Chan <chikeichan@gmail.com>2017-09-07 19:24:03 +0800
committerChi Kei Chan <chikeichan@gmail.com>2017-09-07 19:24:03 +0800
commit8b919758e51e16536b6edaf33d4978d551363249 (patch)
treea1861401480401d94cc908cf2bc5eeabca0d67e6
parent983fa2a11721aa7d1307ef76d516e25a50d0eedf (diff)
downloadtangerine-wallet-browser-8b919758e51e16536b6edaf33d4978d551363249.tar
tangerine-wallet-browser-8b919758e51e16536b6edaf33d4978d551363249.tar.gz
tangerine-wallet-browser-8b919758e51e16536b6edaf33d4978d551363249.tar.bz2
tangerine-wallet-browser-8b919758e51e16536b6edaf33d4978d551363249.tar.lz
tangerine-wallet-browser-8b919758e51e16536b6edaf33d4978d551363249.tar.xz
tangerine-wallet-browser-8b919758e51e16536b6edaf33d4978d551363249.tar.zst
tangerine-wallet-browser-8b919758e51e16536b6edaf33d4978d551363249.zip
Send Token screen partial UI
-rw-r--r--ui/app/actions.js8
-rw-r--r--ui/app/app.js5
-rw-r--r--ui/app/components/send-token/index.js213
-rw-r--r--ui/app/components/token-balance.js4
-rw-r--r--ui/app/components/tx-view.js5
-rw-r--r--ui/app/css/itcss/components/send.scss41
-rw-r--r--ui/app/reducers/app.js10
7 files changed, 283 insertions, 3 deletions
diff --git a/ui/app/actions.js b/ui/app/actions.js
index fe6048aa2..3a65155a6 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -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)
diff --git a/ui/app/app.js b/ui/app/app.js
index 9ad85d85d..1ca59e406 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -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'})
diff --git a/ui/app/components/send-token/index.js b/ui/app/components/send-token/index.js
new file mode 100644
index 000000000..a49e559dc
--- /dev/null
+++ b/ui/app/components/send-token/index.js
@@ -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(),
+ ])
+}
diff --git a/ui/app/components/token-balance.js b/ui/app/components/token-balance.js
index b4a249300..3a923eb9d 100644
--- a/ui/app/components/token-balance.js
+++ b/ui/app/components/token-balance.js
@@ -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,
})
}
diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js
index c9be0d67d..f5ac6e2dc 100644
--- a/ui/app/components/tx-view.js
+++ b/ui/app/components/tx-view.js
@@ -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'),
])
)
diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss
index 016833db9..87c4c0a1b 100644
--- a/ui/app/css/itcss/components/send.scss
+++ b/ui/app/css/itcss/components/send.scss
@@ -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;
+ }
+}
diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js
index ea7145f22..f444aaf38 100644
--- a/ui/app/reducers/app.js
+++ b/ui/app/reducers/app.js
@@ -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: {