diff options
Diffstat (limited to 'ui')
38 files changed, 1973 insertions, 900 deletions
diff --git a/ui/app/account-and-transaction-details.js b/ui/app/account-and-transaction-details.js new file mode 100644 index 000000000..03f2d9db5 --- /dev/null +++ b/ui/app/account-and-transaction-details.js @@ -0,0 +1,38 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits +// Main Views +const TxView = require('./components/tx-view') +const WalletView = require('./components/wallet-view') + +module.exports = AccountAndTransactionDetails + +inherits(AccountAndTransactionDetails, Component) +function AccountAndTransactionDetails () { + Component.call(this) +} + +AccountAndTransactionDetails.prototype.render = function () { + return h('div', { + style: { + display: 'flex', + flex: '1 0 auto', + }, + }, [ + // wallet + h(WalletView, { + style: { + }, + responsiveDisplayClassname: '.lap-visible', + }, [ + ]), + + // transaction + h(TxView, { + style: { + } + }, [ + ]), + ]) +} + diff --git a/ui/app/actions.js b/ui/app/actions.js index eafd04b4c..13a767343 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -5,6 +5,11 @@ var actions = { GO_HOME: 'GO_HOME', goHome: goHome, + // sidebar state + SIDEBAR_OPEN: 'UI_SIDEBAR_OPEN', + SIDEBAR_CLOSE: 'UI_SIDEBAR_CLOSE', + showSidebar: showSidebar, + hideSidebar: hideSidebar, // menu state getNetworkStatus: 'getNetworkStatus', // transition state @@ -763,6 +768,19 @@ function useEtherscanProvider () { } } +function showSidebar () { + return { + type: actions.SIDEBAR_OPEN, + } +} + +function hideSidebar () { + return { + type: actions.SIDEBAR_CLOSE, + } +} + + function showLoadingIndication (message) { return { type: actions.SHOW_LOADING, diff --git a/ui/app/add-token.js b/ui/app/add-token.js index 15ef7a852..5c6dea4a0 100644 --- a/ui/app/add-token.js +++ b/ui/app/add-token.js @@ -212,7 +212,6 @@ AddTokenScreen.prototype.attemptToAutoFillTokenParams = async function (address) const [ symbol, decimals ] = results if (symbol && decimals) { - console.log('SETTING SYMBOL AND DECIMALS', { symbol, decimals }) this.setState({ symbol: symbol[0], decimals: decimals[0].toString() }) } } diff --git a/ui/app/app.js b/ui/app/app.js index 4565bdd37..660a68230 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -9,12 +9,16 @@ const NewKeyChainScreen = require('./new-keychain') // unlock const UnlockScreen = require('./unlock') // accounts -const AccountDetailScreen = require('./account-detail') +const MainContainer = require('./main-container') const SendTransactionScreen = require('./send') const ConfirmTxScreen = require('./conf-tx') // notice const NoticeScreen = require('./components/notice') const generateLostAccountsNotice = require('../lib/lost-accounts-notice') + +// slideout menu +const WalletView = require('./components/wallet-view') + // other views const ConfigScreen = require('./config') const AddTokenScreen = require('./add-token') @@ -30,9 +34,10 @@ const QrView = require('./components/qr-code') const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete') const HDRestoreVaultScreen = require('./keychains/hd/restore-vault') const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation') +const ReactCSSTransitionGroup = require('react-addons-css-transition-group') const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns -module.exports = connect(mapStateToProps)(App) +module.exports = connect(mapStateToProps, mapDispatchToProps)(App) inherits(App, Component) function App () { Component.call(this) } @@ -47,6 +52,7 @@ function mapStateToProps (state) { return { // state from plugin + sidebarOpen: state.appState.sidebarOpen, isLoading: state.appState.isLoading, loadingMessage: state.appState.loadingMessage, noActiveNotices: state.metamask.noActiveNotices, @@ -72,9 +78,15 @@ function mapStateToProps (state) { } } +function mapDispatchToProps (dispatch) { + return { + hideSidebar: () => {dispatch(actions.hideSidebar())}, + } +} + App.prototype.render = function () { var props = this.props - const { isLoading, loadingMessage, transForward, network } = props + const { isLoading, loadingMessage, transForward, network, sidebarOpen } = props const isLoadingNetwork = network === 'loading' && props.currentView.name !== 'config' const loadMessage = loadingMessage || isLoadingNetwork ? `Connecting to ${this.getNetworkName()}` : null @@ -85,7 +97,9 @@ App.prototype.render = function () { h('.flex-column.full-height', { style: { // Windows was showing a vertical scroll bar: - overflow: 'hidden', + overflowX: 'hidden', + // TODO: check with dev who committed L75, see if this still happens, and whether auto is enough + // overflowY: 'auto', position: 'relative', alignItems: 'center', }, @@ -93,26 +107,75 @@ App.prototype.render = function () { // app bar this.renderAppBar(), + + // sidebar + this.renderSidebar(), + + // network dropdown this.renderNetworkDropdown(), - this.renderDropdown(), + // this.renderDropdown(), h(Loading, { isLoading: isLoading || isLoadingNetwork, loadingMessage: loadMessage, }), - // panel content - h('.app-primary' + (transForward ? '.from-right' : '.from-left'), { - style: { - width: '100%', - }, - }, [ - this.renderPrimary(), - ]), + // content + this.renderPrimary(), ]) ) } +App.prototype.renderSidebar = function() { + // if (!this.props.sidebarOpen) { + // return null; + // } + + return h('div', { + }, [ + h('style', ` + .sidebar-enter { + transition: transform 300ms ease-in-out; + transform: translateX(-100%); + } + .sidebar-enter.sidebar-enter-active { + transition: transform 300ms ease-in-out; + transform: translateX(0%); + } + .sidebar-leave { + transition: transform 200ms ease-out; + transform: translateX(0%); + } + .sidebar-leave.sidebar-leave-active { + transition: transform 200ms ease-out; + transform: translateX(-100%); + } + `), + + h(ReactCSSTransitionGroup, { + transitionName: 'sidebar', + transitionEnterTimeout: 300, + transitionLeaveTimeout: 200, + }, [ + // content + this.props.sidebarOpen ? h(WalletView, { + responsiveDisplayClassname: '.sidebar', + style: {}, + }) : undefined, + + ]), + + // overlay + // TODO: add onClick for overlay to close sidebar + this.props.sidebarOpen ? h('div.sidebar-overlay', { + style: {}, + onClick: () => { + this.props.hideSidebar() + }, + }, []) : undefined, + ]) +} + App.prototype.renderAppBar = function () { if (window.METAMASK_UI_TYPE === 'notification') { return null @@ -125,28 +188,16 @@ App.prototype.renderAppBar = function () { return ( h('.full-width', { - height: '38px', + style: {} }, [ h('.app-header.flex-row.flex-space-between', { - style: { - alignItems: 'center', - visibility: props.isUnlocked ? 'visible' : 'none', - background: props.isUnlocked ? 'white' : 'none', - height: '38px', - position: 'relative', - zIndex: 12, - }, + style: {}, }, [ - h('div.left-menu-section', { - style: { - display: 'flex', - flexDirection: 'row', - alignItems: 'center', - }, + h('div.left-menu-wrapper', { + style: {}, }, [ - // mini logo h('img', { height: 24, @@ -154,6 +205,20 @@ App.prototype.renderAppBar = function () { src: '/images/icon-128.png', }), + // metamask name + h('h1', { + style: { + position: 'relative', + left: '9px', + }, + }, 'MetaMask'), + + ]), + + h('div.network-component-wrapper', { + style: {}, + }, [ + // Network Indicator h(NetworkIndicator, { network: this.props.network, provider: this.props.provider, @@ -163,48 +228,10 @@ App.prototype.renderAppBar = function () { this.setState({ isNetworkMenuOpen: !isNetworkMenuOpen }) }, }), - ]), - - // metamask name - props.isUnlocked && h('h1', { - style: { - position: 'relative', - left: '9px', - }, - }, 'MetaMask'), - props.isUnlocked && h('div', { - style: { - display: 'flex', - flexDirection: 'row', - alignItems: 'center', - }, - }, [ - - props.isUnlocked && h(AccountDropdowns, { - style: {}, - enableAccountsSelector: true, - identities: this.props.identities, - selected: this.props.selected, - network: this.props.network, - }, []), - - // hamburger - props.isUnlocked && h(SandwichExpando, { - className: 'sandwich-expando', - width: 16, - barHeight: 2, - padding: 0, - isOpen: state.isMainMenuOpen, - color: 'rgb(247,146,30)', - onClick: () => { - this.setState({ - isMainMenuOpen: !state.isMainMenuOpen, - }) - }, - }), ]), ]), + ]) ) } @@ -235,8 +262,8 @@ App.prototype.renderNetworkDropdown = function () { zIndex: 11, style: { position: 'absolute', - left: '2px', - top: '36px', + right: '2px', + top: '38px', }, innerStyle: { padding: '2px 16px 2px 0px', @@ -456,28 +483,22 @@ App.prototype.renderPrimary = function () { // show unlock screen if (!props.isUnlocked) { - switch (props.currentView.name) { - - case 'restoreVault': - log.debug('rendering restore vault screen') - return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'}) - - case 'config': - log.debug('rendering config screen from unlock screen.') - return h(ConfigScreen, {key: 'config'}) - - default: - log.debug('rendering locked screen') - return h(UnlockScreen, {key: 'locked'}) - } + return h(MainContainer, { + currentViewName: props.currentView.name, + isUnlocked: props.isUnlocked, + }) } + // Note for @Zanibar - isUnlocked stays true. + // console.log("props.isUnlocked", props.isUnlocked) + // console.log("props.isUnlocked", props.currentView.name) + // show current view switch (props.currentView.name) { case 'accountDetail': - log.debug('rendering account detail screen') - return h(AccountDetailScreen, {key: 'account-detail'}) + log.debug('rendering main container') + return h(MainContainer, {key: 'account-detail'}) case 'sendTransaction': log.debug('rendering send tx screen') @@ -545,7 +566,7 @@ App.prototype.renderPrimary = function () { default: log.debug('rendering default, account detail screen') - return h(AccountDetailScreen, {key: 'account-detail'}) + return h(MainContainer, {key: 'account-detail'}) } } diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js index 3a33ebf74..93c07599d 100644 --- a/ui/app/components/ens-input.js +++ b/ui/app/components/ens-input.js @@ -44,6 +44,13 @@ EnsInput.prototype.render = function () { return h('div', { style: { width: '100%' }, }, [ + h('span', { + style: { + textAlign: 'left', + } + }, [ + 'To:' + ]), h('input.large-input', opts), // The address book functionality. h('datalist#addresses', diff --git a/ui/app/components/network.js b/ui/app/components/network.js index 698a0bbb9..ba1d0ea11 100644 --- a/ui/app/components/network.js +++ b/ui/app/components/network.js @@ -60,7 +60,7 @@ Network.prototype.render = function () { } return ( - h('#network_component.pointer', { + h('.network-component.pointer', { title: hoverText, onClick: (event) => this.props.onClick(event), }, [ diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index 5324ccd64..1c47440f2 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -20,6 +20,34 @@ const GWEI_FACTOR = new BN(1e9) const MIN_GAS_PRICE_BN = MIN_GAS_PRICE_GWEI_BN.mul(GWEI_FACTOR) const MIN_GAS_LIMIT_BN = new BN(21000) + +// Faked, for Icon +const Identicon = require('./identicon') +const ARAGON = '960b236A07cf122663c4303350609A66A7B288C0' + +// Next: create separate react components +// roughly 5 components: +// heroIcon +// numericDisplay (contains symbol + currency) +// divider +// contentBox +// actionButtons +const sectionDivider = h('div', { + style: { + height:'1px', + background:'#E7E7E7', + }, +}) + +const contentDivider = h('div', { + style: { + marginLeft: '16px', + marginRight: '16px', + height:'1px', + background:'#E7E7E7', + }, +}) + module.exports = PendingTx inherits(PendingTx, Component) function PendingTx () { @@ -70,344 +98,342 @@ PendingTx.prototype.render = function () { this.inputs = [] return ( - - h('div', { - key: txMeta.id, + h('div.flex-column.flex-grow', { + style: { + // overflow: 'scroll', + minWidth: '355px', // TODO: maxWidth TBD, use home.html + }, }, [ - h('form#pending-tx-form', { - onSubmit: this.onSubmit.bind(this), - + // Main Send token Card + h('div.send-screen.flex-column.flex-grow', { + style: { + marginLeft: '3.5%', + marginRight: '3.5%', + background: '#FFFFFF', // $background-white + boxShadow: '0 2px 4px 0 rgba(0,0,0,0.08)', + } }, [ + h('section.flex-center.flex-row', { + style: { + zIndex: 15, // $token-icon-z-index + marginTop: '-35px', + } + }, [ + h(Identicon, { + address: ARAGON, + diameter: 76, + }), + ]), - // tx info - h('div', [ + // + // Required Fields + // - h('.flex-row.flex-center', { - style: { - maxWidth: '100%', - }, - }, [ + h('h3.flex-center', { + style: { + marginTop: '-18px', + fontSize: '16px', + }, + }, [ + 'Confirm Transaction', + ]), - h(MiniAccountPanel, { - imageSeed: address, - picOrder: 'right', - }, [ - h('span.font-small', { - style: { - fontFamily: 'Montserrat Bold, Montserrat, sans-serif', - }, - }, identity.name), - - h(Copyable, { - value: ethUtil.toChecksumAddress(address), - }, [ - h('span.font-small', { - style: { - fontFamily: 'Montserrat Light, Montserrat, sans-serif', - }, - }, addressSummary(address, 6, 4, false)), - ]), - - h('span.font-small', { - style: { - fontFamily: 'Montserrat Light, Montserrat, sans-serif', - }, - }, [ - h(EthBalance, { - value: balance, - conversionRate, - currentCurrency, - inline: true, - labelColor: '#F7861C', - }), - ]), - ]), + h('h3.flex-center', { + style: { + textAlign: 'center', + fontSize: '12px', + }, + }, [ + 'You\'re sending to Recipient ...5924', + ]), - forwardCarrat(), + h('h3.flex-center', { + style: { + textAlign: 'center', + fontSize: '36px', + marginTop: '8px', + }, + }, [ + '0.24', + ]), - this.miniAccountPanelForRecipient(), - ]), + h('h3.flex-center', { + style: { + textAlign: 'center', + fontSize: '12px', + marginTop: '4px', + }, + }, [ + 'ANT', + ]), - h('style', ` - .table-box { - margin: 7px 0px 0px 0px; - width: 100%; - } - .table-box .row { - margin: 0px; - background: rgb(236,236,236); - display: flex; - justify-content: space-between; - font-family: Montserrat Light, sans-serif; - font-size: 13px; - padding: 5px 25px; - } - .table-box .row .value { - font-family: Montserrat Regular; - } - `), + // error message + props.error && h('span.error.flex-center', props.error), - h('.table-box', [ + sectionDivider, - // Ether Value - // Currently not customizable, but easily modified - // in the way that gas and gasLimit currently are. - h('.row', [ - h('.cell.label', 'Amount'), - h(EthBalance, { value: txParams.value, currentCurrency, conversionRate }), - ]), + h('section.flex-row.flex-center', { + }, [ + h('div', { + style: { + width: '50%', + } + }, [ + h('span', { + style: { + textAlign: 'left', + fontSize: '12px', + } + }, [ + 'From' + ]) + ]), - // Gas Limit (customizable) - h('.cell.row', [ - h('.cell.label', 'Gas Limit'), - h('.cell.value', { - }, [ - h(BNInput, { - name: 'Gas Limit', - value: gasBn, - precision: 0, - scale: 0, - // The hard lower limit for gas. - min: MIN_GAS_LIMIT_BN.toString(10), - max: safeGasLimit, - suffix: 'UNITS', - style: { - position: 'relative', - top: '5px', - }, - onChange: this.gasLimitChanged.bind(this), - - ref: (hexInput) => { this.inputs.push(hexInput) }, - }), - ]), - ]), + h('div', { + style: { + width: '50%', + } + },[ + h('div', { + style: { + textAlign: 'left', + fontSize: '10px', + marginBottom: '-10px', + }, + }, 'Aragon Token'), - // Gas Price (customizable) - h('.cell.row', [ - h('.cell.label', 'Gas Price'), - h('.cell.value', { - }, [ - h(BNInput, { - name: 'Gas Price', - value: gasPriceBn, - precision: 9, - scale: 9, - suffix: 'GWEI', - min: MIN_GAS_PRICE_GWEI_BN.toString(10), - style: { - position: 'relative', - top: '5px', - }, - onChange: this.gasPriceChanged.bind(this), - ref: (hexInput) => { this.inputs.push(hexInput) }, - }), - ]), - ]), + h('div', { + style: { + textAlign: 'left', + fontSize: '8px', + }, + }, 'Your Balance 2.34 ANT') + ]) + ]), - // Max Transaction Fee (calculated) - h('.cell.row', [ - h('.cell.label', 'Max Transaction Fee'), - h(EthBalance, { value: txFeeBn.toString(16), currentCurrency, conversionRate }), - ]), + contentDivider, - h('.cell.row', { + h('section.flex-row.flex-center', { + }, [ + h('div', { + style: { + width: '50%', + } + }, [ + h('span', { style: { - fontFamily: 'Montserrat Regular', - background: 'white', - padding: '10px 25px', - }, + textAlign: 'left', + fontSize: '12px', + } }, [ - h('.cell.label', 'Max Total'), - h('.cell.value', { - style: { - display: 'flex', - alignItems: 'center', - }, - }, [ - h(EthBalance, { - value: maxCost.toString(16), - currentCurrency, - conversionRate, - inline: true, - labelColor: 'black', - fontSize: '16px', - }), - ]), - ]), + 'To' + ]) + ]), - // Data size row: - h('.cell.row', { + h('div', { + style: { + width: '50%', + } + },[ + h('div', { style: { - background: '#f7f7f7', - paddingBottom: '0px', + textAlign: 'left', + fontSize: '10px', + marginBottom: '-10px', }, - }, [ - h('.cell.label'), - h('.cell.value', { - style: { - fontFamily: 'Montserrat Light', - fontSize: '11px', - }, - }, `Data included: ${dataLength} bytes`), - ]), - ]), // End of Table + }, 'Ethereum Address'), + h('div', { + style: { + textAlign: 'left', + fontSize: '8px', + }, + }, '...5924') + ]) ]), - h('style', ` - .conf-buttons button { - margin-left: 10px; - text-transform: uppercase; - } - `), + contentDivider, - txMeta.simulationFails ? - h('.error', { - style: { - marginLeft: 50, - fontSize: '0.9em', - }, - }, 'Transaction Error. Exception thrown in contract code.') - : null, - - !isValidAddress ? - h('.error', { + h('section.flex-row.flex-center', { + }, [ + h('div', { style: { - marginLeft: 50, - fontSize: '0.9em', - }, - }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH.') - : null, - - insufficientBalance ? - h('span.error', { + width: '50%', + } + }, [ + h('span', { + style: { + textAlign: 'left', + fontSize: '12px', + } + }, [ + 'Gas Fee' + ]) + ]), + + h('div', { style: { - marginLeft: 50, - fontSize: '0.9em', - }, - }, 'Insufficient balance for transaction') - : null, - - // send + cancel - h('.flex-row.flex-space-around.conf-buttons', { + width: '50%', + } + },[ + h('div', { + style: { + textAlign: 'left', + fontSize: '10px', + marginBottom: '-10px', + }, + }, '$0.04 USD'), + + h('div', { + style: { + textAlign: 'left', + fontSize: '8px', + }, + }, '0.001575 ETH') + ]) + ]), + + contentDivider, + + h('section.flex-row.flex-center', { style: { - display: 'flex', - justifyContent: 'flex-end', - margin: '14px 25px', - }, + backgroundColor: '#F6F6F6', // $wild-sand + borderRadius: '8px', + marginLeft: '10px', + marginRight: '10px', + paddingLeft: '6px', + paddingRight: '6px', + marginBottom: '10px', + } }, [ + h('div', { + style: { + width: '50%', + } + }, [ + h('div', { + style: { + textAlign: 'left', + fontSize: '12px', + marginBottom: '-10px', + } + }, [ + 'Total Tokens' + ]), + h('div', { + style: { + textAlign: 'left', + fontSize: '8px', + } + }, [ + 'Total Gas' + ]) - insufficientBalance ? - h('button.btn-green', { - onClick: props.buyEth, - }, 'Buy Ether') - : null, - - h('button', { - onClick: (event) => { - this.resetGasFields() - event.preventDefault() - }, - }, 'Reset'), - - // Accept Button - h('input.confirm.btn-green', { - type: 'submit', - value: 'SUBMIT', - style: { marginLeft: '10px' }, - disabled: insufficientBalance || !this.state.valid || !isValidAddress || this.state.submitting, - }), + ]), - h('button.cancel.btn-red', { - onClick: props.cancelTransaction, - }, 'Reject'), - ]), - ]), - ]) - ) -} + h('div', { + style: { + width: '50%', + } + },[ + h('div', { + style: { + textAlign: 'left', + fontSize: '10px', + marginBottom: '-10px', + }, + }, '0.24 ANT (127.00 USD)'), -PendingTx.prototype.miniAccountPanelForRecipient = function () { - const props = this.props - const txData = props.txData - const txParams = txData.txParams || {} - const isContractDeploy = !('to' in txParams) - - // If it's not a contract deploy, send to the account - if (!isContractDeploy) { - return h(MiniAccountPanel, { - imageSeed: txParams.to, - picOrder: 'left', - }, [ + h('div', { + style: { + textAlign: 'left', + fontSize: '8px', + }, + }, '0.249 ETH') + ]) + ]), - h('span.font-small', { - style: { - fontFamily: 'Montserrat Bold, Montserrat, sans-serif', - }, - }, nameForAddress(txParams.to, props.identities)), + ]), // end of container - h(Copyable, { - value: ethUtil.toChecksumAddress(txParams.to), + h('form#pending-tx-form.flex-column.flex-center', { + onSubmit: this.onSubmit.bind(this), }, [ - h('span.font-small', { + // Reset Button + // h('button', { + // onClick: (event) => { + // this.resetGasFields() + // event.preventDefault() + // }, + // }, 'Reset'), + + // Accept Button + h('input.confirm.btn-green', { + type: 'submit', + value: 'CONFIRM', style: { - fontFamily: 'Montserrat Light, Montserrat, sans-serif', + marginTop: '8px', + width: '8em', + color: '#FFFFFF', + borderRadius: '2px', + fontSize: '12px', + lineHeight: '20px', + textAlign: 'center', + borderStyle: 'none', }, - }, addressSummary(txParams.to, 6, 4, false)), - ]), - - ]) - } else { - return h(MiniAccountPanel, { - picOrder: 'left', - }, [ + disabled: insufficientBalance || !this.state.valid || !isValidAddress || this.state.submitting, + }), - h('span.font-small', { - style: { - fontFamily: 'Montserrat Bold, Montserrat, sans-serif', - }, - }, 'New Contract'), - - ]) - } -} - -PendingTx.prototype.gasPriceChanged = function (newBN, valid) { - log.info(`Gas price changed to: ${newBN.toString(10)}`) - const txMeta = this.gatherTxMeta() - txMeta.txParams.gasPrice = '0x' + newBN.toString('hex') - this.setState({ - txData: clone(txMeta), - valid, - }) -} - -PendingTx.prototype.gasLimitChanged = function (newBN, valid) { - log.info(`Gas limit changed to ${newBN.toString(10)}`) - const txMeta = this.gatherTxMeta() - txMeta.txParams.gas = '0x' + newBN.toString('hex') - this.setState({ - txData: clone(txMeta), - valid, - }) + // Cancel Button + h('button.cancel.btn-light', { + style: { + background: '#F7F7F7', // $alabaster + border: 'none', + opacity: 1, + width: '8em', + }, + onClick: props.cancelTransaction, + }, 'CANCEL'), + ]), + ]) // end of minwidth wrapper + ) } -PendingTx.prototype.resetGasFields = function () { - log.debug(`pending-tx resetGasFields`) - - this.inputs.forEach((hexInput) => { - if (hexInput) { - hexInput.setValid() - } - }) - - this.setState({ - txData: null, - valid: true, - }) -} +// PendingTx.prototype.gasPriceChanged = function (newBN, valid) { +// log.info(`Gas price changed to: ${newBN.toString(10)}`) +// const txMeta = this.gatherTxMeta() +// txMeta.txParams.gasPrice = '0x' + newBN.toString('hex') +// this.setState({ +// txData: clone(txMeta), +// valid, +// }) +// } + +// PendingTx.prototype.gasLimitChanged = function (newBN, valid) { +// log.info(`Gas limit changed to ${newBN.toString(10)}`) +// const txMeta = this.gatherTxMeta() +// txMeta.txParams.gas = '0x' + newBN.toString('hex') +// this.setState({ +// txData: clone(txMeta), +// valid, +// }) +// } + +// PendingTx.prototype.resetGasFields = function () { +// log.debug(`pending-tx resetGasFields`) + +// this.inputs.forEach((hexInput) => { +// if (hexInput) { +// hexInput.setValid() +// } +// }) + +// this.setState({ +// txData: null, +// valid: true, +// }) +// } PendingTx.prototype.onSubmit = function (event) { event.preventDefault() @@ -466,15 +492,3 @@ PendingTx.prototype.bnMultiplyByFraction = function (targetBN, numerator, denomi const denomBN = new BN(denominator) return targetBN.mul(numBN).div(denomBN) } - -function forwardCarrat () { - return ( - h('img', { - src: 'images/forward-carrat.svg', - style: { - padding: '5px 6px 0px 10px', - height: '37px', - }, - }) - ) -} diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js new file mode 100644 index 000000000..6b8e9e4dd --- /dev/null +++ b/ui/app/components/tx-view.js @@ -0,0 +1,227 @@ +const Component = require('react').Component +const connect = require('react-redux').connect +const h = require('react-hyperscript') +const inherits = require('util').inherits +const actions = require('../actions') +// slideout menu +const WalletView = require('./wallet-view') + +const Identicon = require('./identicon') +// const AccountDropdowns = require('./account-dropdowns').AccountDropdowns +// const Content = require('./wallet-content-display') + +module.exports = connect(mapStateToProps, mapDispatchToProps)(TxView) + +function mapStateToProps (state) { + return { + sidebarOpen: state.appState.sidebarOpen, + } +} + +function mapDispatchToProps (dispatch) { + return { + showSidebar: () => {dispatch(actions.showSidebar())}, + hideSidebar: () => {dispatch(actions.hideSidebar())}, + } +} + +const contentDivider = h('div', { + style: { + marginLeft: '1.3em', + marginRight: '1.3em', + height:'1px', + background:'#E7E7E7', // TODO: make custom color + }, +}) + +inherits(TxView, Component) +function TxView () { + Component.call(this) +} + +TxView.prototype.render = function () { + const selected = '0x82df11beb942BEeeD58d466fCb0F0791365C7684' // TODO: remove fake address + + return h('div.tx-view.flex-column', { + style: { + flex: '62 0 62%', + background: '#FFFFFF', + } + }, [ + + h('div.flex-row.phone-visible', { + style: { + margin: '1em 0.9em', + alignItems: 'center' + }, + onClick: () => { + this.props.sidebarOpen ? this.props.hideSidebar() : this.props.showSidebar() + }, + }, [ + // burger + h('div.fa.fa-bars', { + style: { + fontSize: '1.3em', + }, + }, []), + + //account display + h('.identicon-wrapper.select-none', { + style: { + marginLeft: '0.9em', + }, + }, [ + h(Identicon, { + diameter: 24, + address: selected, + }), + ]), + + h('span.account-name', { + style: {} + }, [ + 'Account 1' + ]), + + ]), + + // laptop: flex-row, flex-center + // mobile: flex-column + h('div.hero-balance', { + style: {}, + }, [ + + // laptop: 50px 50px + // mobile: 100px 100px + h('img.hero-balance-icon', { + src: '../images/eth_logo.svg', + style: {} + }), + + // laptop: 5vw? + // phone: 50vw? + h('div.flex-column.hero-balance-display', {}, [ + h('div.token-amount', { + style: {} + }, '1001.124 ETH'), + + h('div.fiat-amount', { + style: {} + }, '$300,000 USD'), + ]), + + // laptop: 10vw? + // phone: 75vw? + h('div.flex-row.flex-center.hero-balance-buttons', { + style: {} + }, [ + h('button.btn-clear', { + style: { + textAlign: 'center', + }, + }, 'BUY'), + + h('button.btn-clear', { + style: { + textAlign: 'center', + marginLeft: '1.4em', + }, + }, 'SEND'), + + ]), + ]), + + h('div.flex-row', { + style: { + margin: '1.8em 0.9em 0.8em 0.9em', + } + }, [ + + // tx-view-tab.js + h('div.flex-row', { + }, [ + + h('div', { + style: { + borderBottom: '0.07em solid black', + paddingBottom: '0.015em', + } + }, 'TRANSACTIONS'), + + h('div', { + style: { + marginLeft: '1.25em', + } + }, 'TOKENS'), + + ]), + ]), + + contentDivider, + + this.renderTransactionListItem(), + + contentDivider, + + this.renderTransactionListItem(), + + contentDivider, + + ]) + // column + // tab row + // divider + // item +} + +TxView.prototype.renderTransactionListItem = function () { + return h('div.flex-column', { + style: { + alignItems: 'stretch', + margin: '0.6em 1.3em 0.6em 1.3em', + } + }, [ + + h('div', { + style: { + flexGrow: 1, + marginTop: '0.3em', + } + }, 'Jul 01, 2017'), + + h('div.flex-row', { + style: { + alignItems: 'stretch', + } + }, [ + + h('div', { + style: { + flexGrow: 1, + } + }, 'icon'), + + h('div', { + style: { + flexGrow: 3, + } + }, 'Hash'), + + h('div', { + style: { + flexGrow: 5, + } + }, 'Status'), + + h('div', { + style: { + flexGrow: 2, + } + }, 'Details'), + + ]) + + ]) +} + + diff --git a/ui/app/components/wallet-content-display.js b/ui/app/components/wallet-content-display.js new file mode 100644 index 000000000..3baffad69 --- /dev/null +++ b/ui/app/components/wallet-content-display.js @@ -0,0 +1,56 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits + +module.exports = WalletContentDisplay + +inherits(WalletContentDisplay, Component) +function WalletContentDisplay () { + Component.call(this) +} + +WalletContentDisplay.prototype.render = function () { + const { title, amount, fiatValue, active, style } = this.props + + // TODO: Separate component: wallet-content-account + return h('div.flex-column', { + style: { + marginLeft: '1.3em', + alignItems: 'flex-start', + ...style, + } + }, [ + + h('span', { + style: { + fontSize: '1.1em', + }, + }, title), + + h('span', { + style: { + fontSize: '1.8em', + margin: '0.4em 0em', + }, + }, amount), + + h('span', { + style: { + fontSize: '1.3em', + }, + }, fiatValue), + + active && h('div', { + style: { + position: 'absolute', + marginLeft: '-1.3em', + height: '6em', + width: '0.3em', + background: '#D8D8D8', // TODO: add to resuable colors + } + }, [ + ]) + ]) + +} + diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js new file mode 100644 index 000000000..cb1448598 --- /dev/null +++ b/ui/app/components/wallet-view.js @@ -0,0 +1,97 @@ +const Component = require('react').Component +const connect = require('react-redux').connect +const h = require('react-hyperscript') +const inherits = require('util').inherits +const Identicon = require('./identicon') +const AccountDropdowns = require('./account-dropdowns').AccountDropdowns +const Content = require('./wallet-content-display') +const actions = require('../actions') + +module.exports = connect(mapStateToProps, mapDispatchToProps)(WalletView) + +function mapStateToProps (state) { + return { + network: state.metamask.network, + sidebarOpen: state.appState.sidebarOpen, + } +} + +function mapDispatchToProps (dispatch) { + return { + showSendPage: () => {dispatch(actions.showSendPage())}, + hideSidebar: () => {dispatch(actions.hideSidebar())}, + } +} + +inherits(WalletView, Component) +function WalletView () { + Component.call(this) +} + +const noop = () => {} + +WalletView.prototype.render = function () { + const selected = '0x82df11beb942BEeeD58d466fCb0F0791365C7684' // TODO: remove fake address + const { network, responsiveDisplayClassname, style } = this.props + + return h('div.wallet-view.flex-column' + (responsiveDisplayClassname || ''), { + style: { + flex: '28 0 28%', + background: '#FAFAFA', // TODO: add to reusable colors + ...style, + } + }, [ + + // TODO: Separate component: wallet account details + h('div.flex-column', { + style: {} + }, [ + + h('.identicon-wrapper.select-none', [ + h(Identicon, { + diameter: 24, + address: selected, + }), + ]), + + h('span.account-name', { + style: {} + }, [ + 'Account 1' + ]), + + h( + AccountDropdowns, + { + style: { + marginLeft: 'auto', + cursor: 'pointer', + }, + selected, + network, // TODO: this prop could be in the account dropdown container + identities: {}, + }, + ), + + ]), + + h(Content, { + title: 'Wallet', + amount: '1001.124 ETH', + fiatValue: '$300,000.00 USD', + active: true, + }), + + // Wallet contents + h(Content, { + title: "Total Token Balance", + amount: "45.439 ETH", + fiatValue: "$13,000.00 USD", + active: false, + style: { + marginTop: '1.3em', + } + }) + + ]) +} diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js index 34727ff78..4a8c616e2 100644 --- a/ui/app/conf-tx.js +++ b/ui/app/conf-tx.js @@ -52,66 +52,25 @@ ConfirmTxScreen.prototype.render = function () { log.info(`rendering a combined ${unconfTxList.length} unconf msg & txs`) if (unconfTxList.length === 0) return h(Loading, { isLoading: true }) - return ( - - h('.flex-column.flex-grow', [ - - // subtitle and nav - h('.section-title.flex-row.flex-center', [ - !isNotification ? h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { - onClick: this.goHome.bind(this), - }) : null, - h('h2.page-subtitle', 'Confirm Transaction'), - isNotification ? h(NetworkIndicator, { - network: network, - provider: provider, - }) : null, - ]), - - h('h3', { - style: { - alignSelf: 'center', - display: unconfTxList.length > 1 ? 'block' : 'none', - }, - }, [ - h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { - style: { - display: props.index === 0 ? 'none' : 'inline-block', - }, - onClick: () => props.dispatch(actions.previousTx()), - }), - ` ${props.index + 1} of ${unconfTxList.length} `, - h('i.fa.fa-arrow-right.fa-lg.cursor-pointer', { - style: { - display: props.index + 1 === unconfTxList.length ? 'none' : 'inline-block', - }, - onClick: () => props.dispatch(actions.nextTx()), - }), - ]), - - warningIfExists(props.warning), - - currentTxView({ - // Properties - txData: txData, - key: txData.id, - selectedAddress: props.selectedAddress, - accounts: props.accounts, - identities: props.identities, - conversionRate, - currentCurrency, - blockGasLimit, - // Actions - buyEth: this.buyEth.bind(this, txParams.from || props.selectedAddress), - sendTransaction: this.sendTransaction.bind(this), - cancelTransaction: this.cancelTransaction.bind(this, txData), - signMessage: this.signMessage.bind(this, txData), - signPersonalMessage: this.signPersonalMessage.bind(this, txData), - cancelMessage: this.cancelMessage.bind(this, txData), - cancelPersonalMessage: this.cancelPersonalMessage.bind(this, txData), - }), - ]) - ) + return currentTxView({ + // Properties + txData: txData, + key: txData.id, + selectedAddress: props.selectedAddress, + accounts: props.accounts, + identities: props.identities, + conversionRate, + currentCurrency, + blockGasLimit, + // Actions + buyEth: this.buyEth.bind(this, txParams.from || props.selectedAddress), + sendTransaction: this.sendTransaction.bind(this), + cancelTransaction: this.cancelTransaction.bind(this, txData), + signMessage: this.signMessage.bind(this, txData), + signPersonalMessage: this.signPersonalMessage.bind(this, txData), + cancelMessage: this.cancelMessage.bind(this, txData), + cancelPersonalMessage: this.cancelPersonalMessage.bind(this, txData), + }) } function currentTxView (opts) { diff --git a/ui/app/css/debug.css b/ui/app/css/debug.css deleted file mode 100644 index 3e125bcd4..000000000 --- a/ui/app/css/debug.css +++ /dev/null @@ -1,21 +0,0 @@ -/* -debug / dev -*/ - -#app-content { - border: 2px solid green; -} - -#design-container { - position: absolute; - left: 360px; - top: -42px; - width: calc(100vw - 360px); - height: 100vh; - overflow: scroll; -} - -#design-container img { - width: 2000px; - margin-right: 600px; -}
\ No newline at end of file diff --git a/ui/app/css/index.scss b/ui/app/css/index.scss new file mode 100644 index 000000000..01899ccad --- /dev/null +++ b/ui/app/css/index.scss @@ -0,0 +1,13 @@ +/* + ITCSS + + http://www.creativebloq.com/web-design/manage-large-css-projects-itcss-101517528 + https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/ + */ +@import './itcss/settings/index.scss'; +@import './itcss/tools/index.scss'; +@import './itcss/generic/index.scss'; +@import './itcss/base/index.scss'; +@import './itcss/objects/index.scss'; +@import './itcss/components/index.scss'; +@import './itcss/trumps/index.scss'; diff --git a/ui/app/css/itcss/base/index.scss b/ui/app/css/itcss/base/index.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/css/itcss/base/index.scss diff --git a/ui/app/css/itcss/components/buttons.scss b/ui/app/css/itcss/components/buttons.scss new file mode 100644 index 000000000..114a2f892 --- /dev/null +++ b/ui/app/css/itcss/components/buttons.scss @@ -0,0 +1,83 @@ +/* + Buttons + */ + +.btn-green { + background-color: #02C9B1; // TODO: reusable color in colors.css +} + +button.btn-clear { + background: white; + border: 1px solid; +} + +// No longer used in flat design, remove when modal buttons done +// div.wallet-btn { +// border: 1px solid rgb(91, 93, 103); +// border-radius: 2px; +// height: 30px; +// width: 75px; +// font-size: 0.8em; +// text-align: center; +// line-height: 25px; +// } + +// .btn-red { +// background: rgba(254, 35, 17, 1); +// box-shadow: 0px 3px 6px rgba(254, 35, 17, 0.36); +// } + +// button[disabled], input[type="submit"][disabled] { +// cursor: not-allowed; +// background: rgba(197, 197, 197, 1); +// box-shadow: 0px 3px 6px rgba(197, 197, 197, 0.36); +// } + +// button.spaced { +// margin: 2px; +// } + +// button:not([disabled]):hover, input[type="submit"]:not([disabled]):hover { +// transform: scale(1.1); +// } +// button:not([disabled]):active, input[type="submit"]:not([disabled]):active { +// transform: scale(0.95); +// } + +button.primary { + padding: 8px 12px; + background: #F7861C; + box-shadow: 0px 3px 6px rgba(247, 134, 28, 0.36); + color: white; + font-size: 1.1em; + font-family: 'Montserrat Regular'; + text-transform: uppercase; +} + +.btn-light { + padding: 8px 12px; + // background: #FFFFFF; // $bg-white + box-shadow: 0px 3px 6px rgba(247, 134, 28, 0.36); + color: #585D67; // TODO: make reusable light button color + font-size: 1.1em; + font-family: 'Montserrat Regular'; + text-transform: uppercase; + text-align: center; + line-height: 20px; + border-radius: 2px; + border: 1px solid #979797; // #TODO: make reusable light border color + opacity: 0.5; +} + +// TODO: cleanup: not used anywhere +button.btn-thin { + border: 1px solid; + border-color: #4D4D4D; + color: #4D4D4D; + background: rgb(255, 174, 41); + border-radius: 4px; + min-width: 200px; + margin: 12px 0; + padding: 6px; + font-size: 13px; +} diff --git a/ui/app/css/itcss/components/footer.scss b/ui/app/css/itcss/components/footer.scss new file mode 100644 index 000000000..000a53eed --- /dev/null +++ b/ui/app/css/itcss/components/footer.scss @@ -0,0 +1,4 @@ +.app-footer { + padding-bottom: 10px; + align-items: center; +} diff --git a/ui/app/css/itcss/components/header.scss b/ui/app/css/itcss/components/header.scss new file mode 100644 index 000000000..405c45f7f --- /dev/null +++ b/ui/app/css/itcss/components/header.scss @@ -0,0 +1,54 @@ +.app-header { + align-items: center; + visibility: visible; + background: rgb(239, 239, 239); + padding-top: 1.5vh; + height: 12vh; + max-height: 60px; + position: relative; + z-index: 12; + padding: 6px 8px; + // background: #EFEFEF; // $gallery + + @media screen and (max-width: 575px) { + position: fixed; + height: 34px; + width: 100%; + box-shadow: 0px 2px 2px 1px rgba(0, 0, 0, 0.08); + z-index: 30; + } +} + +.app-header h1 { + font-family: 'Montserrat Regular'; + text-transform: uppercase; + color: #22232C; // $shark +} + +h2.page-subtitle { + font-family: 'Montserrat Regular'; + text-transform: uppercase; + color: #AEAEAE; + font-size: 1em; + margin: 12px; +} + +.network-component-wrapper { + display: flex; + flex-direction: row; + align-items: center; + + @media screen and (min-width: 576px) { + margin-bottom: 1.8em; + } +} + +.left-menu-wrapper { + display: flex; + flex-direction: row; + align-items: center; + + @media screen and (min-width: 576px) { + margin-bottom: 1.8em; + } +}
\ No newline at end of file diff --git a/ui/app/css/itcss/components/hero-balance.scss b/ui/app/css/itcss/components/hero-balance.scss new file mode 100644 index 000000000..fabba9ed8 --- /dev/null +++ b/ui/app/css/itcss/components/hero-balance.scss @@ -0,0 +1,96 @@ +$break-small: 575px; +$break-medium: 780px; +$break-large: 576px; + +.hero-balance { + @media screen and (max-width: $break-small) { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + margin: 0.3em 0.9em 0.8em 0.9em; + } + + @media screen and (min-width: $break-large) { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + margin: 2.8em 0.9em 0.8em 0.9em; + } + + .hero-balance-display { + + @media screen and (max-width: $break-small) { + text-align: center; + + .token-amount { + font-size: 175%; + margin-top: 12.5%; + } + + .fiat-amount { + font-size: 115%; + margin-top: 8.5%; + color: #A0A0A0; + } + } + + @media screen and (min-width: $break-large) { + flex-grow: 3; + margin-left: 3%; + justify-content: flex-start; + align-items: flex-start; + + .token-amount { + font-size: 135%; + } + + .fiat-amount { + margin-top: 0.25%; + font-size: 105%; + } + + } + + } + + .hero-balance-icon { + border-radius: 25px; + width: 45px; + height: 45px; + // TODO: colors + border: 1px solid #DEDEDE; + } + + .hero-balance-buttons { + @media screen and (max-width: $break-small) { + width: 100%; + height: 100px; // needed a round number to set the heights of the buttons inside + } + + @media screen and (min-width: $break-large) { + flex-grow: 2; + } + + button.btn-clear { + font-size: 75%; + background: white; + border: 1px solid; + + @media screen and (max-width: $break-small) { + width: 28%; + height: 55%; + } + + @media screen and (min-width: $break-large) { + width: 5%; + flex-grow: 2; + height: 4.2vh; + min-height: 28px; + font-size: .7em; + } + } + + } +}
\ No newline at end of file diff --git a/ui/app/css/itcss/components/identicon.scss b/ui/app/css/itcss/components/identicon.scss new file mode 100644 index 000000000..2f2de6ed8 --- /dev/null +++ b/ui/app/css/itcss/components/identicon.scss @@ -0,0 +1,7 @@ +.identicon { + height: 46px; + width: 46px; + background-size: cover; + border-radius: 100%; + border: 3px solid gray; +} diff --git a/ui/app/css/itcss/components/index.scss b/ui/app/css/itcss/components/index.scss new file mode 100644 index 000000000..8b6698eed --- /dev/null +++ b/ui/app/css/itcss/components/index.scss @@ -0,0 +1,8 @@ +@import './buttons.scss'; +@import './header.scss'; +@import './footer.scss'; +@import './identicon.scss'; +@import './network.scss'; +@import './newui-sections.scss'; +@import './hero-balance.scss'; +@import './sections.scss'; diff --git a/ui/app/css/itcss/components/network.scss b/ui/app/css/itcss/components/network.scss new file mode 100644 index 000000000..75c3a68d8 --- /dev/null +++ b/ui/app/css/itcss/components/network.scss @@ -0,0 +1,11 @@ +.network-indicator { + display: flex; + align-items: center; + font-size: 0.6em; +} + +.network-name { + width: 5.2em; + line-height: 9px; + text-rendering: geometricPrecision; +} diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss new file mode 100644 index 000000000..761e74561 --- /dev/null +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -0,0 +1,109 @@ +/* + NewUI Container Elements + */ + +// Main container +.main-container { + position: absolute; + z-index: 18; + font-family: DIN OT; + display: flex; + flex-wrap: wrap; + align-items: stretch; + overflow-y: scroll; +} + +.sidebar { + flex: 1 0 230px; + background: rgb(250, 250, 250); + z-index: 26; + position: fixed; + top: 35px; + left: 0px; + right: 0px; + bottom: 0px; + opacity: 1; + visibility: visible; + will-change: transform; + overflow-y: auto; + box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 4px; + width: 85%; + height: 100%; +} + +.sidebar-overlay { + z-index: 25; + position: fixed; + top: 35px; + left: 0px; + right: 0px; + bottom: 0px; + opacity: 1; + visibility: visible; + background-color: rgba(0, 0, 0, 0.3); +} + +@media screen and (min-width: 576px) { + .lap-visible { + display: flex; + } + + .phone-visible { + display: none; + } + + .main-container { + margin-top: 35px; + width: 85%; + height: 90vh; + box-shadow: 0 0 7px 0 rgba(0,0,0,0.08); + } +} + +@media screen and (min-width: 769px) { + .main-container { + margin-top: 35px; + width: 80%; + height: 82vh; + box-shadow: 0 0 7px 0 rgba(0,0,0,0.08); + } +} + +@media screen and (min-width: 1281px) { + .main-container { + margin-top: 35px; + width: 65%; + height: 82vh; + box-shadow: 0 0 7px 0 rgba(0,0,0,0.08); + } +} + +@media screen and (max-width: 575px) { + .lap-visible { + display: none; + } + + .phone-visible { + display: flex; + } + + .main-container { + margin-top: 35px; + width: 100%; + height: 100%; + } + + button.btn-clear { + width: 93px; + height: 50px; + font-size: .7em; + background: white; + border: 1px solid; + } +} + +// wallet view +.account-name { + font-size: 102%; + margin-left: 3%; +} diff --git a/ui/app/css/index.css b/ui/app/css/itcss/components/sections.scss index 49b432a1f..965abbe28 100644 --- a/ui/app/css/index.css +++ b/ui/app/css/itcss/components/sections.scss @@ -1,182 +1,13 @@ /* -faint orange (textfield shades) #FAF6F0 -light orange (button shades): #F5C26D -dark orange (text): #F5A623 -borders/font/any gray: #4A4A4A +App Sections + TODO: Move into separate files. */ /* -application specific styles +debug / dev */ -* { - box-sizing: border-box; -} - -html, body { - font-family: 'Montserrat Regular', Arial; - color: #4D4D4D; - font-weight: 300; - line-height: 1.4em; - background: #F7F7F7; - margin: 0; - padding: 0; -} - -html { - min-height: 500px; -} - -.app-root { - overflow: hidden; - position: relative -} - -.app-primary { - display: flex; -} - -input:focus, textarea:focus { - outline: none; -} - -.full-size { - height: 100%; - width: 100%; -} - -.full-width { - width: 100%; -} - -.full-height { - height: 100%; -} - -.full-flex-height { - display: flex; - flex: 1 1 auto; - flex-direction: column; -} - -#app-content { - overflow-x: hidden; - min-width: 357px; - height: 100%; - display: flex; - flex-direction: column; -} - -button, input[type="submit"] { - font-family: 'Montserrat Bold'; - outline: none; - cursor: pointer; - padding: 8px 12px; - border: none; - color: white; - transform-origin: center center; - transition: transform 50ms ease-in; - /* default orange */ - background: rgba(247, 134, 28, 1); - box-shadow: 0px 3px 6px rgba(247, 134, 28, 0.36); -} - -.btn-green, input[type="submit"].btn-green { - background: rgba(106, 195, 96, 1); - box-shadow: 0px 3px 6px rgba(106, 195, 96, 0.36); -} - -.btn-red { - background: rgba(254, 35, 17, 1); - box-shadow: 0px 3px 6px rgba(254, 35, 17, 0.36); -} - -button[disabled], input[type="submit"][disabled] { - cursor: not-allowed; - background: rgba(197, 197, 197, 1); - box-shadow: 0px 3px 6px rgba(197, 197, 197, 0.36); -} - -button.spaced { - margin: 2px; -} - -button:not([disabled]):hover, input[type="submit"]:not([disabled]):hover { - transform: scale(1.1); -} -button:not([disabled]):active, input[type="submit"]:not([disabled]):active { - transform: scale(0.95); -} - -a { - text-decoration: none; - color: inherit; -} - -a:hover{ - color: #df6b0e; -} - -/* -app -*/ - -.active { - color: #909090; -} - -button.primary { - padding: 8px 12px; - background: #F7861C; - box-shadow: 0px 3px 6px rgba(247, 134, 28, 0.36); - color: white; - font-size: 1.1em; - font-family: 'Montserrat Regular'; - text-transform: uppercase; -} - -button.btn-thin { - border: 1px solid; - border-color: #4D4D4D; - color: #4D4D4D; - background: rgb(255, 174, 41); - border-radius: 4px; - min-width: 200px; - margin: 12px 0; - padding: 6px; - font-size: 13px; -} - -.app-header { - padding: 6px 8px; -} - -.app-header h1 { - font-family: 'Montserrat Regular'; - text-transform: uppercase; - color: #AEAEAE; -} - -h2.page-subtitle { - font-family: 'Montserrat Regular'; - text-transform: uppercase; - color: #AEAEAE; - font-size: 1em; - margin: 12px; -} - -.app-footer { - padding-bottom: 10px; - align-items: center; -} - -.identicon { - height: 46px; - width: 46px; - background-size: cover; - border-radius: 100%; - border: 3px solid gray; -} +/* initialize */ textarea.twelve-word-phrase { padding: 12px; @@ -187,32 +18,6 @@ textarea.twelve-word-phrase { resize: none; } -.network-indicator { - display: flex; - align-items: center; - font-size: 0.6em; - -} - -.network-name { - width: 5.2em; - line-height: 9px; - text-rendering: geometricPrecision; -} - -.check { - margin-left: 12px; - color: #F7861C; - flex: 1 0 auto; - display: flex; - justify-content: flex-end; -} -/* -app sections -*/ - -/* initialize */ - .initialize-screen hr { width: 60px; margin: 12px; @@ -290,9 +95,6 @@ app sections .unlock-screen input[type=password] { width: 260px; - /*height: 36px; - margin-bottom: 24px; - padding: 8px;*/ } .sizing-input{ @@ -324,20 +126,6 @@ app sections font-size: 1.2em; } -input.large-input, textarea.large-input { - /*margin-bottom: 24px;*/ - padding: 8px; -} - -input.large-input { - height: 36px; -} - -.letter-spacey { - letter-spacing: 0.1em; -} - - /* accounts */ @@ -460,6 +248,7 @@ input.large-input { height: 100%; visibility: hidden; } + .editing-label { display: flex; justify-content: flex-start; @@ -469,6 +258,7 @@ input.large-input { text-rendering: geometricPrecision; color: #F7861C; } + .name-label:hover .edit-text { visibility: visible; } @@ -486,12 +276,8 @@ input.large-input { /* Send Screen */ -.send-screen { - -} - .send-screen section { - margin: 8px 16px; + margin: 4px 16px; } .send-screen input { @@ -702,5 +488,5 @@ div.message-container > div:first-child { } .pop-hover:hover { - transform: scale(1.1); + transform: scale(1.1); } diff --git a/ui/app/css/itcss/generic/index.scss b/ui/app/css/itcss/generic/index.scss new file mode 100644 index 000000000..a0ce312cc --- /dev/null +++ b/ui/app/css/itcss/generic/index.scss @@ -0,0 +1,64 @@ +/* + Generic + */ + +@import './reset.scss'; + +* { + box-sizing: border-box; +} + +html, body { + font-family: 'Montserrat Regular', Arial; + color: #4D4D4D; + font-weight: 300; + line-height: 1.4em; + background: #F7F7F7; + width: 100%; + height: 100%; + margin: 0; + padding: 0; +} + +html { + min-height: 500px; +} + +.app-root { + overflow: hidden; + position: relative +} + +.app-primary { + display: flex; +} + +input:focus, textarea:focus { + outline: none; +} + +#app-content { + overflow-x: hidden; + min-width: 357px; + height: 100%; + display: flex; + flex-direction: column; +} + +a { + text-decoration: none; + color: inherit; +} + +a:hover{ + color: #df6b0e; +} + +input.large-input, textarea.large-input { + /*margin-bottom: 24px;*/ + padding: 8px; +} + +input.large-input { + height: 36px; +} diff --git a/ui/app/css/reset.css b/ui/app/css/itcss/generic/reset.scss index 9ce89e8bc..fef74825d 100644 --- a/ui/app/css/reset.css +++ b/ui/app/css/itcss/generic/reset.scss @@ -45,4 +45,8 @@ q:before, q:after { table { border-collapse: collapse; border-spacing: 0; -}
\ No newline at end of file +} + +button { + border-style: none; +} diff --git a/ui/app/css/itcss/objects/index.scss b/ui/app/css/itcss/objects/index.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/css/itcss/objects/index.scss diff --git a/ui/app/css/itcss/settings/index.scss b/ui/app/css/itcss/settings/index.scss new file mode 100644 index 000000000..446546d0c --- /dev/null +++ b/ui/app/css/itcss/settings/index.scss @@ -0,0 +1,2 @@ +@import './variables.scss'; +@import './typography.scss'; diff --git a/ui/app/css/fonts.css b/ui/app/css/itcss/settings/typography.scss index 3b9f581b9..2afaa26e1 100644 --- a/ui/app/css/fonts.css +++ b/ui/app/css/itcss/settings/typography.scss @@ -8,7 +8,6 @@ font-weight: normal; font-style: normal; font-size: 'small'; - } @font-face { @@ -23,14 +22,21 @@ font-family: 'Montserrat Light'; src: url('/fonts/Montserrat/Montserrat-Light.woff') format('woff'); src: url('/fonts/Montserrat/Montserrat-Light.ttf') format('truetype'); - font-weight: normal; - font-style: normal; + font-weight: normal; + font-style: normal; } @font-face { font-family: 'Montserrat UltraLight'; src: url('/fonts/Montserrat/Montserrat-UltraLight.woff') format('woff'); src: url('/fonts/Montserrat/Montserrat-UltraLight.ttf') format('truetype'); - font-weight: normal; - font-style: normal; + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: 'DIN OT'; + src: url('/fonts/DIN_OT/DINOT-2.otf') format('opentype'); + font-weight: normal; + font-style: normal; } diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss new file mode 100644 index 000000000..6d105f2e3 --- /dev/null +++ b/ui/app/css/itcss/settings/variables.scss @@ -0,0 +1,13 @@ +/* + Variables + */ + +// Colors +$white-linen: #FAF6F0; // formerly 'faint orange (textfield shades)' +$rajah: #F5C26D; // formerly 'light orange (button shades)' +$buttercup: #F5A623; // formerly 'dark orange (text)' +$tundora: #4A4A4A; // formerly 'borders/font/any gray' +$gallery: #EFEFEF; +$alabaster: #F7F7F7; +$shark: #22232C; +$wild-sand: #F6F6F6;
\ No newline at end of file diff --git a/ui/app/css/itcss/tools/index.scss b/ui/app/css/itcss/tools/index.scss new file mode 100644 index 000000000..3634c839b --- /dev/null +++ b/ui/app/css/itcss/tools/index.scss @@ -0,0 +1,2 @@ +@import './utilities.scss'; + diff --git a/ui/app/css/lib.css b/ui/app/css/itcss/tools/utilities.scss index 81647d1c1..2b7ffcb04 100644 --- a/ui/app/css/lib.css +++ b/ui/app/css/itcss/tools/utilities.scss @@ -1,15 +1,38 @@ +/* + Utility Classes + */ + /* color */ .color-orange { - color: #F7861C; + color: #F7861C; // TODO: move to settings/variables } .color-forest { - color: #0A5448; + color: #0A5448; // TODO: move to settings/variables } /* lib */ +.full-size { + height: 100%; + width: 100%; +} + +.full-width { + width: 100%; +} + +.full-height { + height: 100%; +} + +.full-flex-height { + display: flex; + flex: 1 1 auto; + flex-direction: column; +} + .full-width { width: 100%; } @@ -243,10 +266,6 @@ hr.horizontal-line { margin: 13px; } -i.fa.fa-question-circle.fa-lg.menu-icon { - font-size: 18px; -} - .ether-icon { background: rgb(0, 163, 68); border-radius: 20px; @@ -277,29 +296,22 @@ i.fa.fa-question-circle.fa-lg.menu-icon { } /* - Hacky breakpoint fix for account + tab sections - Resolves issue from @frankiebee in - https://github.com/MetaMask/metamask-extension/pull/1835 - Please remove this when integrating new designs + Misc */ -@media screen and (min-width: 575px) and (max-width: 800px) { - .account-data-subsection { - flex: 0 0 auto !important; // reset flex - margin-left: 10px !important; // create additional horizontal space - margin-right: 10px !important; - width: 40%; - } - - .tabSection { - flex: 0 0 auto !important; - margin-left: 10px !important; - margin-right: 10px !important; - min-width: 285px; - width: 49%; - } - - .name-label { - width: 80%; - } +// Move into component-level contextual 'active' state later +.letter-spacey { + letter-spacing: 0.1em; +} + +.active { + color: #909090; } + +.check { + margin-left: 7px; + color: #F7861C; + flex: 1 0 auto; + display: flex; + justify-content: flex-end; +}
\ No newline at end of file diff --git a/ui/app/css/itcss/trumps/index.scss b/ui/app/css/itcss/trumps/index.scss new file mode 100644 index 000000000..a6a6e4335 --- /dev/null +++ b/ui/app/css/itcss/trumps/index.scss @@ -0,0 +1,88 @@ +/* + Trumps + */ + + +// Transitions + +/* universal */ +.app-primary .main-enter { + position: absolute; + width: 100%; +} + +/* center position */ +.app-primary.from-right .main-enter-active, +.app-primary.from-left .main-enter-active { + overflow-x: hidden; + transform: translateX(0px); + transition: transform 300ms ease-in; +} + +/* exited positions */ +.app-primary.from-left .main-leave-active { + transform: translateX(360px); + transition: transform 300ms ease-in; +} +.app-primary.from-right .main-leave-active { + transform: translateX(-360px); + transition: transform 300ms ease-in; +} + +.sidebar.from-left { + transform: translateX(-320px); + transition: transform 300ms ease-in; +} + +/* loader transitions */ +.loader-enter, .loader-leave-active { + opacity: 0.0; + transition: opacity 150 ease-in; +} +.loader-enter-active, .loader-leave { + opacity: 1.0; + transition: opacity 150 ease-in; +} + +/* entering positions */ +.app-primary.from-right .main-enter:not(.main-enter-active) { + transform: translateX(360px); +} +.app-primary.from-left .main-enter:not(.main-enter-active) { + transform: translateX(-360px); +} + +i.fa.fa-question-circle.fa-lg.menu-icon { + font-size: 18px; +} + +/* + Hacky breakpoint fix for account + tab sections + Resolves issue from @frankiebee in + https://github.com/MetaMask/metamask-extension/pull/1835 + Please remove this when integrating new designs + */ + +// This is commented out, because it's not needed in NewUI. +// We will have a new css architecture w/ different breakpoints. + +// @media screen and (min-width: 575px) and (max-width: 800px) { +// .account-data-subsection { +// flex: 0 0 auto !important; // reset flex +// margin-left: 10px !important; // create additional horizontal space +// margin-right: 10px !important; +// width: 40%; +// } + +// .tabSection { +// flex: 0 0 auto !important; +// margin-left: 10px !important; +// margin-right: 10px !important; +// min-width: 285px; +// width: 49%; +// } + +// .name-label { +// width: 80%; +// } +// } diff --git a/ui/app/css/transitions.css b/ui/app/css/transitions.css deleted file mode 100644 index 393a944f9..000000000 --- a/ui/app/css/transitions.css +++ /dev/null @@ -1,42 +0,0 @@ -/* universal */ -.app-primary .main-enter { - position: absolute; - width: 100%; -} - -/* center position */ -.app-primary.from-right .main-enter-active, -.app-primary.from-left .main-enter-active { - overflow-x: hidden; - transform: translateX(0px); - transition: transform 300ms ease-in; -} - -/* exited positions */ -.app-primary.from-left .main-leave-active { - transform: translateX(360px); - transition: transform 300ms ease-in; -} -.app-primary.from-right .main-leave-active { - transform: translateX(-360px); - transition: transform 300ms ease-in; -} - -/* loader transitions */ -.loader-enter, .loader-leave-active { - opacity: 0.0; - transition: opacity 150 ease-in; -} -.loader-enter-active, .loader-leave { - opacity: 1.0; - transition: opacity 150 ease-in; -} - -/* entering positions */ -.app-primary.from-right .main-enter:not(.main-enter-active) { - transform: translateX(360px); -} -.app-primary.from-left .main-enter:not(.main-enter-active) { - transform: translateX(-360px); -} - diff --git a/ui/app/main-container.js b/ui/app/main-container.js new file mode 100644 index 000000000..31583f3e5 --- /dev/null +++ b/ui/app/main-container.js @@ -0,0 +1,71 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits +const TxView = require('./components/tx-view') +const WalletView = require('./components/wallet-view') +const AccountAndTransactionDetails = require('./account-and-transaction-details') +const HDRestoreVaultScreen = require('./keychains/hd/restore-vault') +const ConfigScreen = require('./config') +const UnlockScreen = require('./unlock') + +module.exports = MainContainer + +inherits(MainContainer, Component) +function MainContainer () { + Component.call(this) +} + +MainContainer.prototype.render = function () { + // 3. summarize: + // switch statement goes inside MainContainer, + // or a method in renderPrimary + // - pass resulting h() to MainContainer + // - error checking in separate func + // - router in separate func + let contents = { + component: AccountAndTransactionDetails, + key: 'account-detail', + style: {}, + } + + if (this.props.isUnlocked === false) { + switch (this.props.currentViewName) { + case 'restoreVault': + log.debug('rendering restore vault screen') + contents = { + component: HDRestoreVaultScreen, + key: 'HDRestoreVaultScreen', + } + case 'config': + log.debug('rendering config screen from unlock screen.') + contents = { + component: ConfigScreen, + key: 'config', + } + default: + log.debug('rendering locked screen') + contents = { + component: UnlockScreen, + style: { + boxShadow: 'none', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + background: '#F7F7F7', + // must force 100%, because lock screen is full-width + width: '100%', + }, + key: 'locked', + } + } + } + + return h('div.main-container', { + style: contents.style, + }, [ + h(contents.component, { + key: contents.key, + }, []) + ]) +} + diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index 2fcc9bfe0..bf1de4577 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -36,6 +36,7 @@ function reduceApp (state, action) { var appState = extend({ shouldClose: false, menuOpen: false, + sidebarOpen: false, currentView: seedWords ? seedConfView : defaultView, accountDetail: { subview: 'transactions', @@ -46,6 +47,16 @@ function reduceApp (state, action) { }, state.appState) switch (action.type) { + // sidebar methods + case actions.SIDEBAR_OPEN: + return extend(appState, { + sidebarOpen: true, + }) + + case actions.SIDEBAR_CLOSE: + return extend(appState, { + sidebarOpen: false, + }) // transition methods diff --git a/ui/app/send.js b/ui/app/send.js index a21a219eb..ab527019f 100644 --- a/ui/app/send.js +++ b/ui/app/send.js @@ -11,6 +11,9 @@ const isHex = require('./util').isHex const EthBalance = require('./components/eth-balance') const EnsInput = require('./components/ens-input') const ethUtil = require('ethereumjs-util') + +const ARAGON = '960b236A07cf122663c4303350609A66A7B288C0' + module.exports = connect(mapStateToProps)(SendTransactionScreen) function mapStateToProps (state) { @@ -56,172 +59,425 @@ SendTransactionScreen.prototype.render = function () { return ( - h('.send-screen.flex-column.flex-grow', [ - - // - // Sender Profile - // + h('div.flex-column.flex-grow', { + style: { + minWidth: '355px', // TODO: maxWidth TBD, use home.html + }, + }, [ - h('.account-data-subsection.flex-row.flex-grow', { + // Main Send token Card + h('div.send-screen.flex-column.flex-grow', { style: { - margin: '0 20px', - }, + marginLeft: '3.5%', + marginRight: '3.5%', + background: '#FFFFFF', // $background-white + boxShadow: '0 2px 4px 0 rgba(0,0,0,0.08)', + } }, [ + h('section.flex-center.flex-row', { + style: { + zIndex: 15, // $token-icon-z-index + marginTop: '-35px', + } + }, [ + h(Identicon, { + address: ARAGON, + diameter: 76, + }), + ]), - // header - identicon + nav - h('.flex-row.flex-space-between', { + h('h3.flex-center', { style: { - marginTop: '15px', + marginTop: '-18px', + fontSize: '16px', }, }, [ - // back button - h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', { - onClick: this.back.bind(this), + 'Send Tokens', + ]), + + h('h3.flex-center', { + style: { + textAlign: 'center', + fontSize: '12px', + }, + }, [ + 'Send Tokens to anyone with an Ethereum account', + ]), + + h('h3.flex-center', { + style: { + textAlign: 'center', + marginTop: '2px', + fontSize: '12px', + }, + }, [ + 'Your Aragon Token Balance is:', + ]), + + h('h3.flex-center', { + style: { + textAlign: 'center', + fontSize: '36px', + marginTop: '8px', + }, + }, [ + '2.34', + ]), + + h('h3.flex-center', { + style: { + textAlign: 'center', + fontSize: '12px', + marginTop: '4px', + }, + }, [ + 'ANT', + ]), + + // error message + props.error && h('span.error.flex-center', props.error), + + // 'to' field + h('section.flex-row.flex-center', { + style: { + fontSize: '12px', + }, + }, [ + h(EnsInput, { + name: 'address', + placeholder: 'Recipient Address', + onChange: this.recipientDidChange.bind(this), + network, + identities, + addressBook, }), + ]), - // large identicon - h('.identicon-wrapper.flex-column.flex-center.select-none', [ - h(Identicon, { - diameter: 62, - address: address, - }), + // 'amount' and send button + h('section.flex-column.flex-center', [ + h('div.flex-row.flex-center', { + style: { + fontSize: '12px', + width: '100%', + justifyContent: 'space-between', + } + },[ + h('span', { style: {} }, ['Amount']), + h('span', { style: {} }, ['Token <> USD']), ]), - // invisible place holder - h('i.fa.fa-users.fa-lg.invisible', { + h('input.large-input', { + name: 'amount', + placeholder: '0', + type: 'number', style: { - marginTop: '28px', + marginRight: '6px', + fontSize: '12px', + }, + dataset: { + persistentFormId: 'tx-amount', }, }), ]), - // account label + h('section.flex-column.flex-center', [ + h('div.flex-row.flex-center', { + style: { + fontSize: '12px', + width: '100%', + justifyContent: 'space-between', + } + },[ + h('span', { style: {} }, ['Gas Fee:']), + h('span', { style: { fontSize: '8px' } }, ['What\'s this?']), + ]), + + h('input.large-input', { + name: 'Gas Fee', + placeholder: '0', + type: 'number', + style: { + fontSize: '12px', + marginRight: '6px', + }, + // dataset: { + // persistentFormId: 'tx-amount', + // }, + }), + + ]), - h('.flex-column', { + h('section.flex-column.flex-center', { style: { - marginTop: '10px', - alignItems: 'flex-start', + marginBottom: '10px', }, }, [ - h('h2.font-medium.color-forest.flex-center', { + h('div.flex-row.flex-center', { style: { - paddingTop: '8px', - marginBottom: '8px', - }, - }, identity && identity.name), + fontSize: '12px', + width: '100%', + justifyContent: 'flex-start', + } + },[ + h('span', { style: {} }, ['Transaction Memo (optional)']), + ]), - // address and getter actions - h('.flex-row.flex-center', { + h('input.large-input', { + name: 'memo', + placeholder: '', + type: 'string', style: { - marginBottom: '8px', + marginRight: '6px', }, - }, [ + }), + ]), + ]), - h('div', { - style: { - lineHeight: '16px', - }, - }, addressSummary(address)), + // Buttons underneath card + h('section.flex-column.flex-center', [ - ]), + h('button.btn-light', { + onClick: this.onSubmit.bind(this), + style: { + marginTop: '8px', + width: '8em', + background: '#FFFFFF' + }, + }, 'Next'), - // balance - h('.flex-row.flex-center', [ + h('button.btn-light', { + onClick: this.back.bind(this), + style: { + background: '#F7F7F7', // $alabaster + border: 'none', + opacity: 1, + width: '8em', + }, + }, 'Cancel'), + ]), + ]) - h(EthBalance, { - value: account && account.balance, - conversionRate, - currentCurrency, - }), + ) +} - ]), - ]), - ]), +// WIP - hyperscript for renderSendToken - hook up later +SendTransactionScreen.prototype.renderSendToken = function () { + this.persistentFormParentId = 'send-tx-form' + + const props = this.props + const { + address, + account, + identity, + network, + identities, + addressBook, + conversionRate, + currentCurrency, + } = props + + return ( - // - // Required Fields - // + h('div.flex-column.flex-grow', { + style: { + minWidth: '355px', // TODO: maxWidth TBD, use home.html + }, + }, [ - h('h3.flex-center.text-transform-uppercase', { + // Main Send token Card + h('div.send-screen.flex-column.flex-grow', { style: { - background: '#EBEBEB', - color: '#AEAEAE', - marginTop: '15px', - marginBottom: '16px', - }, + marginLeft: '3.5%', + marginRight: '3.5%', + background: '#FFFFFF', // $background-white + boxShadow: '0 2px 4px 0 rgba(0,0,0,0.08)', + } }, [ - 'Send Transaction', - ]), + h('section.flex-center.flex-row', { + style: { + zIndex: 15, // $token-icon-z-index + marginTop: '-35px', + } + }, [ + h(Identicon, { + address: ARAGON, + diameter: 76, + }), + ]), - // error message - props.error && h('span.error.flex-center', props.error), - - // 'to' field - h('section.flex-row.flex-center', [ - h(EnsInput, { - name: 'address', - placeholder: 'Recipient Address', - onChange: this.recipientDidChange.bind(this), - network, - identities, - addressBook, - }), - ]), + h('h3.flex-center', { + style: { + marginTop: '-18px', + fontSize: '16px', + }, + }, [ + 'Send Tokens', + ]), - // 'amount' and send button - h('section.flex-row.flex-center', [ + h('h3.flex-center', { + style: { + textAlign: 'center', + fontSize: '12px', + }, + }, [ + 'Send Tokens to anyone with an Ethereum account', + ]), - h('input.large-input', { - name: 'amount', - placeholder: 'Amount', - type: 'number', + h('h3.flex-center', { style: { - marginRight: '6px', + textAlign: 'center', + marginTop: '2px', + fontSize: '12px', }, - dataset: { - persistentFormId: 'tx-amount', + }, [ + 'Your Aragon Token Balance is:', + ]), + + h('h3.flex-center', { + style: { + textAlign: 'center', + fontSize: '36px', + marginTop: '8px', }, - }), + }, [ + '2.34', + ]), - h('button.primary', { - onClick: this.onSubmit.bind(this), + h('h3.flex-center', { style: { - textTransform: 'uppercase', + textAlign: 'center', + fontSize: '12px', + marginTop: '4px', }, - }, 'Next'), + }, [ + 'ANT', + ]), - ]), + // error message + props.error && h('span.error.flex-center', props.error), - // - // Optional Fields - // - h('h3.flex-center.text-transform-uppercase', { - style: { - background: '#EBEBEB', - color: '#AEAEAE', - marginTop: '16px', - marginBottom: '16px', - }, - }, [ - 'Transaction Data (optional)', + // 'to' field + h('section.flex-row.flex-center', { + style: { + fontSize: '12px', + }, + }, [ + h(EnsInput, { + name: 'address', + placeholder: 'Recipient Address', + onChange: this.recipientDidChange.bind(this), + network, + identities, + addressBook, + }), + ]), + + // 'amount' and send button + h('section.flex-column.flex-center', [ + h('div.flex-row.flex-center', { + style: { + fontSize: '12px', + width: '100%', + justifyContent: 'space-between', + } + },[ + h('span', { style: {} }, ['Amount']), + h('span', { style: {} }, ['Token <> USD']), + ]), + + h('input.large-input', { + name: 'amount', + placeholder: '0', + type: 'number', + style: { + marginRight: '6px', + fontSize: '12px', + }, + dataset: { + persistentFormId: 'tx-amount', + }, + }), + + ]), + + h('section.flex-column.flex-center', [ + h('div.flex-row.flex-center', { + style: { + fontSize: '12px', + width: '100%', + justifyContent: 'space-between', + } + },[ + h('span', { style: {} }, ['Gas Fee:']), + h('span', { style: { fontSize: '8px' } }, ['What\'s this?']), + ]), + + h('input.large-input', { + name: 'Gas Fee', + placeholder: '0', + type: 'number', + style: { + fontSize: '12px', + marginRight: '6px', + }, + // dataset: { + // persistentFormId: 'tx-amount', + // }, + }), + + ]), + + h('section.flex-column.flex-center', { + style: { + marginBottom: '10px', + }, + }, [ + h('div.flex-row.flex-center', { + style: { + fontSize: '12px', + width: '100%', + justifyContent: 'flex-start', + } + },[ + h('span', { style: {} }, ['Transaction Memo (optional)']), + ]), + + h('input.large-input', { + name: 'memo', + placeholder: '', + type: 'string', + style: { + marginRight: '6px', + }, + }), + ]), ]), - // 'data' field + // Buttons underneath card h('section.flex-column.flex-center', [ - h('input.large-input', { - name: 'txData', - placeholder: '0x01234', + + h('button.btn-light', { + onClick: this.onSubmit.bind(this), style: { - width: '100%', - resize: 'none', + marginTop: '8px', + width: '8em', + background: '#FFFFFF' }, - dataset: { - persistentFormId: 'tx-data', + }, 'Next'), + + h('button.btn-light', { + onClick: this.back.bind(this), + style: { + background: '#F7F7F7', // $alabaster + border: 'none', + opacity: 1, + width: '8em', }, - }), + }, 'Cancel'), ]), ]) + ) } @@ -248,7 +504,11 @@ SendTransactionScreen.prototype.onSubmit = function () { const nickname = state.nickname || ' ' const input = document.querySelector('input[name="amount"]').value const value = util.normalizeEthStringToWei(input) - const txData = document.querySelector('input[name="txData"]').value + // TODO: check with team on whether txData is removed completely. + const txData = false; + // Must replace with memo data. + // const txData = document.querySelector('input[name="txData"]').value + const balance = this.props.balance let message @@ -267,7 +527,7 @@ SendTransactionScreen.prototype.onSubmit = function () { return this.props.dispatch(actions.displayWarning(message)) } - if (!isHex(ethUtil.stripHexPrefix(txData)) && txData) { + if (txData && !isHex(ethUtil.stripHexPrefix(txData))) { message = 'Transaction data must be hex string.' return this.props.dispatch(actions.displayWarning(message)) } diff --git a/ui/app/unlock.js b/ui/app/unlock.js index 9bacd5124..1918e2e6a 100644 --- a/ui/app/unlock.js +++ b/ui/app/unlock.js @@ -50,7 +50,7 @@ UnlockScreen.prototype.render = function () { id: 'password-box', placeholder: 'enter password', style: { - + background: 'white', }, onKeyPress: this.onKeyPress.bind(this), onInput: this.inputChanged.bind(this), @@ -4,11 +4,7 @@ const path = require('path') module.exports = bundleCss var cssFiles = { - 'fonts.css': fs.readFileSync(path.join(__dirname, '/app/css/fonts.css'), 'utf8'), - 'reset.css': fs.readFileSync(path.join(__dirname, '/app/css/reset.css'), 'utf8'), - 'lib.css': fs.readFileSync(path.join(__dirname, '/app/css/lib.css'), 'utf8'), - 'index.css': fs.readFileSync(path.join(__dirname, '/app/css/index.css'), 'utf8'), - 'transitions.css': fs.readFileSync(path.join(__dirname, '/app/css/transitions.css'), 'utf8'), + 'index.css': fs.readFileSync(path.join(__dirname, '/app/css/output/index.css'), 'utf8'), 'react-tooltip-component.css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-tooltip-component', 'dist', 'react-tooltip-component.css'), 'utf8'), 'react-css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-select', 'dist', 'react-select.css'), 'utf8'), } |