Merge branch 'development' of github.com:gnosis/safe-react into 80-send-funds

This commit is contained in:
mmv 2019-04-29 12:58:28 +04:00
commit d8b5ab4e42
12 changed files with 165 additions and 54 deletions

View File

@ -77,6 +77,7 @@
"immutable": "^4.0.0-rc.9",
"material-ui-search-bar": "^1.0.0-beta.13",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"qrcode.react": "^0.9.3",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-final-form": "^4.1.0",

View File

@ -4,6 +4,7 @@ import classNames from 'classnames'
import OpenInNew from '@material-ui/icons/OpenInNew'
import { withStyles } from '@material-ui/core/styles'
import Paragraph from '~/components/layout/Paragraph'
import Link from '~/components/layout/Link'
import Button from '~/components/layout/Button'
import Identicon from '~/components/Identicon'
import Dot from '@material-ui/icons/FiberManualRecord'
@ -17,7 +18,7 @@ import {
} from '~/theme/variables'
import { upperFirst } from '~/utils/css'
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
import { openAddressInEtherScan } from '~/logic/wallets/getWeb3'
import { getEtherScanLink } from '~/logic/wallets/getWeb3'
import CircleDot from '~/components/Header/component/CircleDot'
const metamask = require('../../assets/metamask.svg')
@ -121,11 +122,9 @@ const UserDetails = ({
{address}
</Paragraph>
{userAddress && (
<OpenInNew
className={classes.open}
style={openIconStyle}
onClick={openAddressInEtherScan(userAddress, network)}
/>
<Link className={classes.open} to={getEtherScanLink(userAddress, network)} target="_blank">
<OpenInNew style={openIconStyle} />
</Link>
)}
</Block>
</Block>

View File

@ -31,10 +31,26 @@ type Props = {
}
const Col = ({
children, margin, layout = 'inherit', overflow,
xs, sm, md, lg,
start, center, end, top, middle, bottom, around, between,
xsOffset, smOffset, mdOffset, lgOffset,
children,
margin,
layout = 'inherit',
overflow,
xs,
sm,
md,
lg,
start,
center,
end,
top,
middle,
bottom,
around,
between,
xsOffset,
smOffset,
mdOffset,
lgOffset,
className,
...props
}: Props) => {
@ -64,7 +80,7 @@ const Col = ({
return (
<div className={colClassNames} {...props}>
{ children }
{children}
</div>
)
}

View File

@ -18,17 +18,14 @@ type Props = {
const GnosisLink = ({
to, children, color, className, padding, ...props
}: Props) => {
const classes = cx(
styles.link,
color || 'regular',
padding ? capitalize(padding, 'padding') : undefined,
className,
)
const internal = /^\/(?!\/)/.test(to)
const classes = cx(styles.link, color || 'regular', padding ? capitalize(padding, 'padding') : undefined, className)
const LinkElement = internal ? Link : 'a'
return (
<Link className={classes} to={to} {...props}>
{ children }
</Link>
<LinkElement className={classes} href={internal ? null : to} to={internal ? to : null} {...props}>
{children}
</LinkElement>
)
}

View File

@ -33,9 +33,7 @@ export const ETHEREUM_NETWORK_IDS = {
export const openTxInEtherScan = (tx: string, network: string) => `https://${network}.etherscan.io/tx/${tx}`
export const openAddressInEtherScan = (address: string, network: string) => () => {
window.open(`https://${network}.etherscan.io/address/${address}`)
}
export const getEtherScanLink = (address: string, network: string) => `https://${network}.etherscan.io/address/${address}`
let web3
export const getWeb3 = () => web3 || new Web3(window.web3.currentProvider)

View File

@ -6,11 +6,12 @@ import OpenInNew from '@material-ui/icons/OpenInNew'
import Identicon from '~/components/Identicon'
import OpenPaper from '~/components/Stepper/OpenPaper'
import Row from '~/components/layout/Row'
import Link from '~/components/layout/Link'
import Paragraph from '~/components/layout/Paragraph'
import {
xs, sm, lg, border, secondary,
} from '~/theme/variables'
import { openAddressInEtherScan, getWeb3 } from '~/logic/wallets/getWeb3'
import { getEtherScanLink, getWeb3 } from '~/logic/wallets/getWeb3'
import { FIELD_LOAD_NAME, FIELD_LOAD_ADDRESS } from '~/routes/load/components/fields'
import { sameAddress } from '~/logic/wallets/ethAddresses'
import { getGnosisSafeContract } from '~/logic/contracts/safeContracts'
@ -113,12 +114,12 @@ class ReviewComponent extends React.PureComponent<Props, State> {
</Paragraph>
<Row className={classes.container}>
<Identicon address={safeAddress} diameter={32} />
<Paragraph size="md" color="disabled" noMargin className={classes.address}>{safeAddress}</Paragraph>
<OpenInNew
className={classes.open}
style={openIconStyle}
onClick={openAddressInEtherScan(safeAddress, network)}
/>
<Paragraph size="md" color="disabled" noMargin className={classes.address}>
{safeAddress}
</Paragraph>
<Link className={classes.open} to={getEtherScanLink(safeAddress, network)} target="_blank">
<OpenInNew style={openIconStyle} />
</Link>
</Row>
</Block>
<Block margin="lg">
@ -126,7 +127,7 @@ class ReviewComponent extends React.PureComponent<Props, State> {
Connected wallet client is owner?
</Paragraph>
<Paragraph size="lg" color="primary" noMargin weight="bolder" className={classes.name}>
{ isOwner ? 'Yes' : 'No (read-only)' }
{isOwner ? 'Yes' : 'No (read-only)'}
</Paragraph>
</Block>
</Block>
@ -145,5 +146,4 @@ const Review = ({ network, userAddress }: LayoutProps) => (controls: React$Node,
</React.Fragment>
)
export default Review

View File

@ -9,12 +9,13 @@ import Identicon from '~/components/Identicon'
import OpenPaper from '~/components/Stepper/OpenPaper'
import Col from '~/components/layout/Col'
import Row from '~/components/layout/Row'
import Link from '~/components/layout/Link'
import Paragraph from '~/components/layout/Paragraph'
import {
sm, md, lg, border, secondary, background,
} from '~/theme/variables'
import Hairline from '~/components/layout/Hairline'
import { openAddressInEtherScan } from '~/logic/wallets/getWeb3'
import { getEtherScanLink } from '~/logic/wallets/getWeb3'
import { FIELD_NAME, FIELD_CONFIRMATIONS, getNumOwnersFrom } from '../fields'
const openIconStyle = {
@ -128,11 +129,9 @@ const ReviewComponent = ({ values, classes, network }: Props) => {
<Paragraph size="md" color="disabled" noMargin>
{addresses[index]}
</Paragraph>
<OpenInNew
className={classes.open}
style={openIconStyle}
onClick={openAddressInEtherScan(addresses[index], network)}
/>
<Link className={classes.open} to={getEtherScanLink(addresses[index], network)} target="_blank">
<OpenInNew style={openIconStyle} />
</Link>
</Block>
</Block>
</Col>

View File

@ -3,14 +3,26 @@ import * as React from 'react'
import { withStyles } from '@material-ui/core/styles'
import Close from '@material-ui/icons/Close'
import IconButton from '@material-ui/core/IconButton'
import OpenInNew from '@material-ui/icons/OpenInNew'
import Link from '~/components/layout/Link'
import QRCode from 'qrcode.react'
import Paragraph from '~/components/layout/Paragraph'
import Identicon from '~/components/Identicon'
import Button from '~/components/layout/Button'
import Block from '~/components/layout/Block'
import Row from '~/components/layout/Row'
import { lg, md } from '~/theme/variables'
import Hairline from '~/components/layout/Hairline'
import Col from '~/components/layout/Col'
import {
xxl, lg, sm, md, background, secondary,
} from '~/theme/variables'
import { copyToClipboard } from '~/utils/clipboard'
const styles = () => ({
heading: {
padding: `${md} ${lg}`,
padding: `${sm} ${lg}`,
justifyContent: 'space-between',
maxHeight: '75px',
},
manage: {
fontSize: '24px',
@ -19,22 +31,81 @@ const styles = () => ({
height: '35px',
width: '35px',
},
detailsContainer: {
backgroundColor: background,
},
qrContainer: {
backgroundColor: '#fff',
padding: md,
borderRadius: '3px',
boxShadow: '0 0 5px 0 rgba(74, 85, 121, 0.5)',
},
safeName: {
margin: `${xxl} 0 20px`,
},
buttonRow: {
height: '84px',
justifyContent: 'center',
},
button: {
height: '42px',
},
addressContainer: {
marginTop: '28px',
},
address: {
marginLeft: '6px',
},
})
const openIconStyle = {
height: '16px',
color: secondary,
}
type Props = {
onClose: () => void,
classes: Object,
safeName: string,
safeAddress: string,
etherScanLink: string,
}
const Send = ({ classes, onClose }: Props) => (
const Receive = ({
classes, onClose, safeAddress, safeName, etherScanLink,
}: Props) => (
<React.Fragment>
<Row align="center" grow className={classes.heading}>
<Paragraph className={classes.manage} noMargin>Receive Funds</Paragraph>
<Paragraph className={classes.manage} weight="bolder" noMargin>
Receive funds
</Paragraph>
<IconButton onClick={onClose} disableRipple>
<Close className={classes.close} />
</IconButton>
</Row>
<Col layout="column" middle="xs" className={classes.detailsContainer}>
<Hairline />
<Paragraph className={classes.safeName} weight="bolder" size="xl" noMargin>
{safeName}
</Paragraph>
<Block className={classes.qrContainer}>
<QRCode value={safeAddress} size={135} />
</Block>
<Block align="center" className={classes.addressContainer}>
<Identicon address={safeAddress} diameter={32} />
<Paragraph onClick={copyToClipboard} className={classes.address}>{safeAddress}</Paragraph>
<Link className={classes.open} to={etherScanLink} target="_blank">
<OpenInNew style={openIconStyle} />
</Link>
</Block>
</Col>
<Hairline />
<Row align="center" className={classes.buttonRow}>
<Button color="primary" className={classes.button} minWidth={140} onClick={onClose} variant="contained">
Done
</Button>
</Row>
</React.Fragment>
)
export default withStyles(styles)(Send)
export default withStyles(styles)(Receive)

View File

@ -44,7 +44,15 @@ const INITIAL_FORM_STATE = {
const AddCustomToken = (props: Props) => {
const {
classes, setActiveScreen, onClose, addToken, updateActiveTokens, safeAddress, activeTokens, tokens, activateTokenForAllSafes,
classes,
setActiveScreen,
onClose,
addToken,
updateActiveTokens,
safeAddress,
activeTokens,
tokens,
activateTokenForAllSafes,
} = props
const [formValues, setFormValues] = useState(INITIAL_FORM_STATE)

View File

@ -38,6 +38,8 @@ type Props = {
tokens: List<Token>,
activeTokens: List<Token>,
safeAddress: string,
safeName: string,
etherScanLink: string,
}
type Action = 'Token' | 'Send' | 'Receive'
@ -69,7 +71,7 @@ class Balances extends React.Component<Props, State> {
hideZero, showToken, showReceive, showSend,
} = this.state
const {
classes, granted, tokens, safeAddress, activeTokens,
classes, granted, tokens, safeAddress, activeTokens, safeName, etherScanLink,
} = this.props
const columns = generateColumns()
@ -166,7 +168,12 @@ class Balances extends React.Component<Props, State> {
handleClose={this.onHide('Receive')}
open={showReceive}
>
<Receive onClose={this.onHide('Receive')} />
<Receive
safeName={safeName}
safeAddress={safeAddress}
etherScanLink={etherScanLink}
onClose={this.onHide('Receive')}
/>
</Modal>
</React.Fragment>
)

View File

@ -9,10 +9,11 @@ import Identicon from '~/components/Identicon'
import { withStyles } from '@material-ui/core/styles'
import Heading from '~/components/layout/Heading'
import Row from '~/components/layout/Row'
import Link from '~/components/layout/Link'
import Paragraph from '~/components/layout/Paragraph'
import NoSafe from '~/components/NoSafe'
import { type SelectorProps } from '~/routes/safe/container/selector'
import { openAddressInEtherScan } from '~/logic/wallets/getWeb3'
import { getEtherScanLink } from '~/logic/wallets/getWeb3'
import {
sm, xs, secondary, smallFontSize,
} from '~/theme/variables'
@ -95,7 +96,8 @@ class Layout extends React.Component<Props, State> {
return <NoSafe provider={provider} text="Safe not found" />
}
const { address, ethBalance } = safe
const { address, ethBalance, name } = safe
const etherScanLink = getEtherScanLink(address, network)
return (
<React.Fragment>
@ -104,7 +106,7 @@ class Layout extends React.Component<Props, State> {
<Block className={classes.name}>
<Row>
<Heading tag="h2" color="secondary">
{safe.get('name')}
{name}
</Heading>
{!granted && <Block className={classes.readonly}>Read Only</Block>}
</Row>
@ -112,11 +114,9 @@ class Layout extends React.Component<Props, State> {
<Paragraph size="md" color="disabled" onClick={this.copyAddress} title="Click to copy" noMargin>
{address}
</Paragraph>
<OpenInNew
className={classes.open}
style={openIconStyle}
onClick={openAddressInEtherScan(address, network)}
/>
<Link className={classes.open} to={etherScanLink} target="_blank">
<OpenInNew style={openIconStyle} />
</Link>
</Block>
</Block>
</Block>
@ -135,6 +135,8 @@ class Layout extends React.Component<Props, State> {
activeTokens={activeTokens}
granted={granted}
safeAddress={address}
safeName={name}
etherScanLink={etherScanLink}
/>
)}
</React.Fragment>

View File

@ -13251,6 +13251,19 @@ q@^1.1.2:
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
qr.js@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f"
integrity sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=
qrcode.react@^0.9.3:
version "0.9.3"
resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-0.9.3.tgz#91de1287912bdc5ccfb3b091737b828d6ced60c5"
integrity sha512-gGd30Ez7cmrKxyN2M3nueaNLk/f9J7NDRgaD5fVgxGpPLsYGWMn9UQ+XnDpv95cfszTQTdaf4QGLNMf3xU0hmw==
dependencies:
prop-types "^15.6.0"
qr.js "0.0.0"
qs@6.5.2, qs@~6.5.2:
version "6.5.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"