Merge branch 'development' of github.com:gnosis/safe-react into 80-send-funds
This commit is contained in:
commit
d8b5ab4e42
|
@ -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",
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
|
|
@ -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>
|
||||
|
|
13
yarn.lock
13
yarn.lock
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue