diff --git a/src/components/base/CopyWithFeedback.js b/src/components/base/CopyWithFeedback.js new file mode 100644 index 00000000..3ced0e88 --- /dev/null +++ b/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 { + 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 ( + + + {isCopied ? t('app:common.copied') : t('app:common.copy')} + + ) + } +} + +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) diff --git a/src/components/modals/OperationDetails.js b/src/components/modals/OperationDetails.js index 8110b92f..721acd26 100644 --- a/src/components/modals/OperationDetails.js +++ b/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) => { {t('app:operationDetails.identifier')} {hash} - - ( - - - {t('app:common.copy')} - - )} - /> + + + @@ -300,11 +284,14 @@ export class Recipients extends Component<{ recipients: Array<*>, t: T }, *> { const shouldShowMore = recipients.length > 3 return ( - - {(shouldShowMore ? recipients.slice(0, numToShow) : recipients).map(recipient => ( - {recipient} - ))} - + {(shouldShowMore ? recipients.slice(0, numToShow) : recipients).map(recipient => ( + + {recipient} + + + + + ))} {shouldShowMore && !showMore && ( @@ -314,13 +301,10 @@ export class Recipients extends Component<{ recipients: Array<*>, t: T }, *> { )} - {showMore && ( - - {recipients - .slice(numToShow) - .map(recipient => {recipient})} - - )} + {showMore && + recipients + .slice(numToShow) + .map(recipient => {recipient})} {shouldShowMore && showMore && ( diff --git a/static/i18n/en/app.yml b/static/i18n/en/app.yml index fa5c2385..a9514d11 100644 --- a/static/i18n/en/app.yml +++ b/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 diff --git a/static/i18n/fr/app.yml b/static/i18n/fr/app.yml index 68304948..1f6f945c 100644 --- a/static/i18n/fr/app.yml +++ b/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