Browse Source

Add CopyWithFeedback component. Use it in OperationDetails modal.

master
meriadec 7 years ago
parent
commit
8ce841cfdb
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 79
      src/components/base/CopyWithFeedback.js
  2. 48
      src/components/modals/OperationDetails.js
  3. 1
      static/i18n/en/app.yml
  4. 1
      static/i18n/fr/app.yml

79
src/components/base/CopyWithFeedback.js

@ -0,0 +1,79 @@
// @flow
import React, { PureComponent } from 'react'
import styled from 'styled-components'
import { translate } from 'react-i18next'
import type { T } from 'types/common'
import { darken, lighten } from 'styles/helpers'
import IconCopy from 'icons/Copy'
import Box from 'components/base/Box'
let clipboard = null
if (!process.env.STORYBOOK_ENV) {
const electron = require('electron')
clipboard = electron.clipboard // eslint-disable-line
}
type Props = {
t: T,
text: string,
}
type State = {
isCopied: boolean,
}
class CopyWithFeedback extends PureComponent<Props, State> {
state = {
isCopied: false,
}
componentWillUnmount() {
this._isUnmounted = true
}
_isUnmounted = false
handleCopy = () => {
const { text } = this.props
clipboard && clipboard.writeText(text)
this.setState({ isCopied: true })
setTimeout(() => {
this.setState({ isCopied: false })
}, 1e3)
}
render() {
const { t } = this.props
const { isCopied } = this.state
return (
<ClickableWrapper onClick={this.handleCopy}>
<IconCopy size={16} />
<span>{isCopied ? t('app:common.copied') : t('app:common.copy')}</span>
</ClickableWrapper>
)
}
}
const ClickableWrapper = styled(Box).attrs({
horizontal: true,
align: 'center',
flow: 1,
color: 'wallet',
fontSize: 4,
ff: 'Open Sans|SemiBold',
cursor: 'pointer',
})`
&:hover {
color: ${p => lighten(p.theme.colors.wallet, 0.05)};
}
&:active {
color: ${p => darken(p.theme.colors.wallet, 0.1)};
}
`
export default translate()(CopyWithFeedback)

48
src/components/modals/OperationDetails.js

@ -16,7 +16,6 @@ import { MODAL_OPERATION_DETAILS } from 'config/constants'
import { getMarketColor } from 'styles/helpers'
import Box from 'components/base/Box'
import CopyToClipboard from 'components/base/CopyToClipboard'
import GradientBox from 'components/GradientBox'
import GrowScroll from 'components/base/GrowScroll'
import Button from 'components/base/Button'
@ -24,12 +23,12 @@ import Bar from 'components/base/Bar'
import FormattedVal from 'components/base/FormattedVal'
import Modal, { ModalBody, ModalTitle, ModalFooter, ModalContent } from 'components/base/Modal'
import Text from 'components/base/Text'
import CopyWithFeedback from 'components/base/CopyWithFeedback'
import { createStructuredSelector, createSelector } from 'reselect'
import { accountSelector } from 'reducers/accounts'
import { currencySettingsForAccountSelector, marketIndicatorSelector } from 'reducers/settings'
import IconCopy from 'icons/Copy'
import IconChevronRight from 'icons/ChevronRight'
import CounterValue from 'components/CounterValue'
import ConfirmationCheck from 'components/OperationsList/ConfirmationCheck'
@ -45,13 +44,9 @@ const OpDetailsTitle = styled(Box).attrs({
letter-spacing: 2px;
`
const CopyBtn = styled(Box).attrs({
horizontal: true,
flow: 1,
const GradientHover = styled(Box).attrs({
align: 'center',
color: 'wallet',
cursor: 'pointer',
ff: 'Open Sans|SemiBold',
})`
background: white;
position: absolute;
@ -68,19 +63,15 @@ const OpDetailsData = styled(Box).attrs({
fontSize: 4,
relative: true,
})`
${CopyBtn} {
${GradientHover} {
display: none;
}
&:hover ${CopyBtn} {
&:hover ${GradientHover} {
display: flex;
}
`
const CanSelect = styled.div`
user-select: text;
`
const B = styled(Bar).attrs({
color: 'lightGrey',
size: 1,
@ -216,16 +207,9 @@ const OperationDetails = connect(mapStateToProps)((props: Props) => {
<OpDetailsTitle>{t('app:operationDetails.identifier')}</OpDetailsTitle>
<OpDetailsData>
<Ellipsis canSelect>{hash}</Ellipsis>
<CopyToClipboard
data={hash}
render={copy => (
<CopyBtn onClick={copy}>
<IconCopy size={16} />
<span>{t('app:common.copy')}</span>
</CopyBtn>
)}
/>
<GradientHover>
<CopyWithFeedback text={hash} />
</GradientHover>
</OpDetailsData>
</Box>
<B />
@ -300,11 +284,14 @@ export class Recipients extends Component<{ recipients: Array<*>, t: T }, *> {
const shouldShowMore = recipients.length > 3
return (
<Box>
<OpDetailsData>
{(shouldShowMore ? recipients.slice(0, numToShow) : recipients).map(recipient => (
<CanSelect key={recipient}>{recipient}</CanSelect>
))}
<OpDetailsData key={recipient}>
{recipient}
<GradientHover>
<CopyWithFeedback text={recipient} />
</GradientHover>
</OpDetailsData>
))}
{shouldShowMore &&
!showMore && (
<Box onClick={this.onClick} py={1}>
@ -314,13 +301,10 @@ export class Recipients extends Component<{ recipients: Array<*>, t: T }, *> {
</More>
</Box>
)}
{showMore && (
<OpDetailsData>
{recipients
{showMore &&
recipients
.slice(numToShow)
.map(recipient => <CanSelect key={recipient}>{recipient}</CanSelect>)}
</OpDetailsData>
)}
.map(recipient => <OpDetailsData key={recipient}>{recipient}</OpDetailsData>)}
{shouldShowMore &&
showMore && (
<Box onClick={this.onClick} py={1}>

1
static/i18n/en/app.yml

@ -35,6 +35,7 @@ common:
reverify: Re-verify
verify: Verify
copy: Copy
copied: Copied!
addressCopied: Address copied!
lockScreen:
title: Welcome back

1
static/i18n/fr/app.yml

@ -35,6 +35,7 @@ common:
reverify: Re-verify
verify: Verify
copy: Copy
copied: Copied!
addressCopied: Address copied!
lockScreen:
title: Welcome back

Loading…
Cancel
Save