Browse Source

Merge pull request #647 from gre/pixelpushgre

Pixelpushgrekhalil
master
Meriadec Pillet 7 years ago
committed by GitHub
parent
commit
2918e05df3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      package.json
  2. 14
      src/components/GradientBox.js
  3. 4
      src/components/base/Ellipsis.js
  4. 5
      src/components/base/GrowScroll/index.js
  5. 19
      src/components/base/Modal/index.js
  6. 240
      src/components/modals/OperationDetails.js
  7. 14
      src/components/modals/ReleaseNotes.js
  8. 1
      src/config/constants.js
  9. 8
      src/index.ejs
  10. 3
      static/i18n/en/app.yml
  11. 4
      yarn.lock

1
package.json

@ -65,6 +65,7 @@
"invariant": "^2.2.4", "invariant": "^2.2.4",
"lodash": "^4.17.5", "lodash": "^4.17.5",
"lru-cache": "^4.1.3", "lru-cache": "^4.1.3",
"measure-scrollbar": "^1.1.0",
"moment": "^2.22.2", "moment": "^2.22.2",
"qrcode": "^1.2.0", "qrcode": "^1.2.0",
"qrcode-reader": "^1.0.4", "qrcode-reader": "^1.0.4",

14
src/components/GradientBox.js

@ -0,0 +1,14 @@
// @flow
import styled from 'styled-components'
export default styled.div`
width: 100%;
height: 60px;
position: absolute;
bottom: 68px;
left: 0;
right: 0;
background: linear-gradient(rgba(255, 255, 255, 0), #ffffff 70%);
z-index: 2;
pointer-events: none;
`

4
src/components/base/Ellipsis.js

@ -7,10 +7,10 @@ import Text from 'components/base/Text'
const outerStyle = { width: 0 } const outerStyle = { width: 0 }
const innerStyle = { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } const innerStyle = { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }
export default ({ children, ...p }: { children: any }) => ( export default ({ children, canSelect, ...p }: { children: any, canSelect?: boolean }) => (
<Box grow horizontal> <Box grow horizontal>
<Box grow {...p} style={outerStyle}> <Box grow {...p} style={outerStyle}>
<Text style={innerStyle}>{children}</Text> <Text style={{ ...innerStyle, userSelect: canSelect ? 'text' : 'none' }}>{children}</Text>
</Box> </Box>
</Box> </Box>
) )

5
src/components/base/GrowScroll/index.js

@ -2,6 +2,7 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import Box from 'components/base/Box' import Box from 'components/base/Box'
import measureScrollbar from 'measure-scrollbar/commonjs'
type Props = { type Props = {
children: any, children: any,
@ -11,6 +12,8 @@ type Props = {
export const GrowScrollContext = React.createContext() export const GrowScrollContext = React.createContext()
const scrollbarWidth = measureScrollbar()
class GrowScroll extends PureComponent<Props> { class GrowScroll extends PureComponent<Props> {
static defaultProps = { static defaultProps = {
full: false, full: false,
@ -47,7 +50,7 @@ class GrowScroll extends PureComponent<Props> {
const scrollContainerStyles = { const scrollContainerStyles = {
overflowY: 'scroll', overflowY: 'scroll',
marginRight: `-80px`, marginRight: `-${80 + scrollbarWidth}px`,
paddingRight: `80px`, paddingRight: `80px`,
...(maxHeight ...(maxHeight
? { ? {

19
src/components/base/Modal/index.js

@ -10,6 +10,7 @@ import { connect } from 'react-redux'
import Mortal from 'react-mortal' import Mortal from 'react-mortal'
import styled from 'styled-components' import styled from 'styled-components'
import noop from 'lodash/noop' import noop from 'lodash/noop'
import { EXPERIMENTAL_CENTER_MODAL } from 'config/constants'
import { rgba } from 'styles/helpers' import { rgba } from 'styles/helpers'
import { radii } from 'styles/theme' import { radii } from 'styles/theme'
@ -133,6 +134,18 @@ function stopPropagation(e) {
e.stopPropagation() e.stopPropagation()
} }
const wrap = EXPERIMENTAL_CENTER_MODAL
? children => (
<Box alignItems="center" justifyContent="center" grow>
{children}
</Box>
)
: children => (
<GrowScroll alignItems="center" full pt={8}>
{children}
</GrowScroll>
)
export class Modal extends Component<Props> { export class Modal extends Component<Props> {
static defaultProps = { static defaultProps = {
isOpened: false, isOpened: false,
@ -198,7 +211,7 @@ export class Modal extends Component<Props> {
<Container isVisible={isVisible} onClick={preventBackdropClick ? undefined : onClose}> <Container isVisible={isVisible} onClick={preventBackdropClick ? undefined : onClose}>
<Backdrop op={m.opacity} /> <Backdrop op={m.opacity} />
<NonClickableHeadArea onClick={stopPropagation} /> <NonClickableHeadArea onClick={stopPropagation} />
<GrowScroll alignItems="center" full py={8}> {wrap(
<Wrapper <Wrapper
tabIndex={-1} tabIndex={-1}
op={m.opacity} op={m.opacity}
@ -208,8 +221,8 @@ export class Modal extends Component<Props> {
width={width} width={width}
> >
<Pure isAnimated={isAnimated} render={render} data={data} onClose={onClose} /> <Pure isAnimated={isAnimated} render={render} data={data} onClose={onClose} />
</Wrapper> </Wrapper>,
</GrowScroll> )}
</Container> </Container>
)} )}
</Mortal> </Mortal>

240
src/components/modals/OperationDetails.js

@ -1,7 +1,6 @@
// @flow // @flow
import React, { Fragment } from 'react' import React, { Fragment, Component } from 'react'
import uniq from 'lodash/uniq'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { shell } from 'electron' import { shell } from 'electron'
import { translate } from 'react-i18next' import { translate } from 'react-i18next'
@ -17,16 +16,19 @@ import { MODAL_OPERATION_DETAILS } from 'config/constants'
import { getMarketColor } from 'styles/helpers' import { getMarketColor } from 'styles/helpers'
import Box from 'components/base/Box' import Box from 'components/base/Box'
import Spoiler from 'components/base/Spoiler' import GradientBox from 'components/GradientBox'
import GrowScroll from 'components/base/GrowScroll'
import Button from 'components/base/Button' import Button from 'components/base/Button'
import Bar from 'components/base/Bar' import Bar from 'components/base/Bar'
import FormattedVal from 'components/base/FormattedVal' import FormattedVal from 'components/base/FormattedVal'
import Modal, { ModalBody, ModalTitle, ModalFooter, ModalContent } from 'components/base/Modal' import Modal, { ModalBody, ModalTitle, ModalFooter, ModalContent } from 'components/base/Modal'
import Text from 'components/base/Text'
import { createStructuredSelector, createSelector } from 'reselect' import { createStructuredSelector, createSelector } from 'reselect'
import { accountSelector } from 'reducers/accounts' import { accountSelector } from 'reducers/accounts'
import { currencySettingsForAccountSelector, marketIndicatorSelector } from 'reducers/settings' import { currencySettingsForAccountSelector, marketIndicatorSelector } from 'reducers/settings'
import IconChevronRight from 'icons/ChevronRight'
import CounterValue from 'components/CounterValue' import CounterValue from 'components/CounterValue'
import ConfirmationCheck from 'components/OperationsList/ConfirmationCheck' import ConfirmationCheck from 'components/OperationsList/ConfirmationCheck'
import Ellipsis from '../base/Ellipsis' import Ellipsis from '../base/Ellipsis'
@ -102,91 +104,93 @@ const OperationDetails = connect(mapStateToProps)((props: Props) => {
const isConfirmed = confirmations >= currencySettings.confirmationsNb const isConfirmed = confirmations >= currencySettings.confirmationsNb
const url = getAccountOperationExplorer(account, operation) const url = getAccountOperationExplorer(account, operation)
const uniqSenders = uniq(senders)
return ( return (
<ModalBody onClose={onClose}> <ModalBody onClose={onClose}>
<ModalTitle>{t('app:operationDetails.title')}</ModalTitle> <ModalTitle>{t('app:operationDetails.title')}</ModalTitle>
<ModalContent flow={3}> <ModalContent style={{ height: 500 }} mx={-5} pb={0}>
<Box alignItems="center" mt={1}> <GrowScroll px={5} pb={8}>
<ConfirmationCheck <Box flow={3}>
marketColor={marketColor} <Box alignItems="center" mt={1}>
isConfirmed={isConfirmed} <ConfirmationCheck
style={{ marketColor={marketColor}
transform: 'scale(1.5)', isConfirmed={isConfirmed}
}} style={{
t={t} transform: 'scale(1.5)',
type={type} }}
withTooltip={false} t={t}
/> type={type}
<Box my={4} alignItems="center"> withTooltip={false}
<Box>
<FormattedVal unit={unit} alwaysShowSign showCode val={amount} fontSize={6} />
</Box>
<Box mt={1}>
<CounterValue
color="grey"
fontSize={5}
date={date}
currency={currency}
value={amount}
/> />
<Box my={4} alignItems="center">
<Box>
<FormattedVal unit={unit} alwaysShowSign showCode val={amount} fontSize={7} />
</Box>
<Box mt={1}>
<CounterValue
color="grey"
fontSize={5}
date={date}
currency={currency}
value={amount}
/>
</Box>
</Box>
</Box> </Box>
</Box> <Box horizontal flow={2}>
</Box> <Box flex={1}>
<Box horizontal flow={2}> <OpDetailsTitle>{t('app:operationDetails.account')}</OpDetailsTitle>
<Box flex={1}> <OpDetailsData>{name}</OpDetailsData>
<OpDetailsTitle>{t('app:operationDetails.account')}</OpDetailsTitle> </Box>
<OpDetailsData>{name}</OpDetailsData> <Box flex={1}>
</Box> <OpDetailsTitle>{t('app:operationDetails.date')}</OpDetailsTitle>
<Box flex={1}> <OpDetailsData>{moment(date).format('LLL')}</OpDetailsData>
<OpDetailsTitle>{t('app:operationDetails.date')}</OpDetailsTitle> </Box>
<OpDetailsData>{moment(date).format('LLL')}</OpDetailsData> </Box>
</Box> <B />
</Box> <Box horizontal flow={2}>
<B /> <Box flex={1}>
<Box horizontal flow={2}> <OpDetailsTitle>{t('app:operationDetails.fees')}</OpDetailsTitle>
<Box flex={1}> {fee ? (
<OpDetailsTitle>{t('app:operationDetails.fees')}</OpDetailsTitle> <Fragment>
{fee ? ( <OpDetailsData>
<Fragment> <FormattedVal unit={unit} showCode val={fee} color="dark" />
<OpDetailsData> </OpDetailsData>
<FormattedVal unit={unit} showCode val={fee} color="dark" /> </Fragment>
) : null}
</Box>
<Box flex={1}>
<OpDetailsTitle>{t('app:operationDetails.status')}</OpDetailsTitle>
<OpDetailsData color={isConfirmed ? 'positiveGreen' : null} horizontal>
<Box>
{isConfirmed
? t('app:operationDetails.confirmed')
: t('app:operationDetails.notConfirmed')}
</Box>
<Box>{`(${confirmations})`}</Box>
</OpDetailsData> </OpDetailsData>
</Fragment>
) : null}
</Box>
<Box flex={1}>
<OpDetailsTitle>{t('app:operationDetails.status')}</OpDetailsTitle>
<OpDetailsData color={isConfirmed ? 'positiveGreen' : null} horizontal>
<Box>
{isConfirmed
? t('app:operationDetails.confirmed')
: t('app:operationDetails.notConfirmed')}
</Box> </Box>
<Box>{`(${confirmations})`}</Box> </Box>
</OpDetailsData> <B />
<Box>
<OpDetailsTitle>{t('app:operationDetails.identifier')}</OpDetailsTitle>
<OpDetailsData>
<Ellipsis canSelect>{hash}</Ellipsis>
</OpDetailsData>
</Box>
<B />
<Box>
<OpDetailsTitle>{t('app:operationDetails.from')}</OpDetailsTitle>
<Recipients recipients={senders} t={t} />
</Box>
<B />
<Box>
<OpDetailsTitle>{t('app:operationDetails.to')}</OpDetailsTitle>
<Recipients recipients={recipients} t={t} />
</Box>
</Box> </Box>
</Box> </GrowScroll>
<B /> <GradientBox />
<Box>
<OpDetailsTitle>{t('app:operationDetails.from')}</OpDetailsTitle>
<OpDetailsData>{uniqSenders.map(v => <CanSelect key={v}>{v}</CanSelect>)}</OpDetailsData>
</Box>
<B />
<Box>
<OpDetailsTitle>{t('app:operationDetails.to')}</OpDetailsTitle>
<RenderRecipients recipients={recipients} t={t} />
</Box>
<B />
<Box>
<OpDetailsTitle>{t('app:operationDetails.identifier')}</OpDetailsTitle>
<OpDetailsData>
<CanSelect>
<Ellipsis>{hash}</Ellipsis>
</CanSelect>
</OpDetailsData>
</Box>
</ModalContent> </ModalContent>
<ModalFooter horizontal justify="flex-end" flow={2}> <ModalFooter horizontal justify="flex-end" flow={2}>
@ -194,7 +198,7 @@ const OperationDetails = connect(mapStateToProps)((props: Props) => {
{t('app:common.cancel')} {t('app:common.cancel')}
</Button> </Button>
{url ? ( {url ? (
<Button ml="auto" primary padded onClick={() => shell.openExternal(url)}> <Button primary padded onClick={() => shell.openExternal(url)}>
{t('app:operationDetails.viewOperation')} {t('app:operationDetails.viewOperation')}
</Button> </Button>
) : null} ) : null}
@ -223,31 +227,63 @@ const OperationDetailsWrapper = ({ t }: { t: T }) => (
export default translate()(OperationDetailsWrapper) export default translate()(OperationDetailsWrapper)
export function RenderRecipients({ recipients, t }: { recipients: *, t: T }) { const More = styled(Text).attrs({
// Hardcoded for now ff: p => (p.ff ? p.ff : 'Museo Sans|Bold'),
const numToShow = 2 fontSize: p => (p.fontSize ? p.fontSize : 2),
return ( color: p => (p.color ? p.color : 'dark'),
<Box> tabIndex: 0,
<OpDetailsData> })`
{recipients text-transform: ${p => (!p.textTransform ? 'auto' : 'uppercase')};
.slice(0, numToShow) cursor: pointer;
.map(recipient => <CanSelect key={recipient}>{recipient}</CanSelect>)} outline: none;
</OpDetailsData> `
{recipients.length > numToShow && (
<Spoiler export class Recipients extends Component<{ recipients: Array<*>, t: T }, *> {
title={t('app:operationDetails.showMore', { recipients: recipients.length - numToShow })} state = {
color="wallet" showMore: false,
ff="Open Sans|SemiBold" }
fontSize={4} onClick = () => {
mt={1} this.setState(({ showMore }) => ({ showMore: !showMore }))
> }
render() {
const { recipients, t } = this.props
const { showMore } = this.state
// Hardcoded for now
const numToShow = 2
const shouldShowMore = recipients.length > 3
return (
<Box>
<OpDetailsData>
{(shouldShowMore ? recipients.slice(0, numToShow) : recipients).map(recipient => (
<CanSelect key={recipient}>{recipient}</CanSelect>
))}
</OpDetailsData>
{shouldShowMore &&
!showMore && (
<Box onClick={this.onClick} py={1}>
<More fontSize={4} color="wallet" ff="Open Sans|SemiBold" mt={1}>
<IconChevronRight size={12} style={{ marginRight: 5 }} />
{t('app:operationDetails.showMore', { recipients: recipients.length - numToShow })}
</More>
</Box>
)}
{showMore && (
<OpDetailsData> <OpDetailsData>
{recipients {recipients
.slice(numToShow) .slice(numToShow)
.map(recipient => <CanSelect key={recipient}>{recipient}</CanSelect>)} .map(recipient => <CanSelect key={recipient}>{recipient}</CanSelect>)}
</OpDetailsData> </OpDetailsData>
</Spoiler> )}
)} {shouldShowMore &&
</Box> showMore && (
) <Box onClick={this.onClick} py={1}>
<More fontSize={4} color="wallet" ff="Open Sans|SemiBold" mt={1}>
<IconChevronRight size={12} style={{ marginRight: 5 }} />
{t('app:operationDetails.showLess')}
</More>
</Box>
)}
</Box>
)
}
} }

14
src/components/modals/ReleaseNotes.js

@ -13,6 +13,7 @@ import Box from 'components/base/Box'
import GrowScroll from 'components/base/GrowScroll' import GrowScroll from 'components/base/GrowScroll'
import Text from 'components/base/Text' import Text from 'components/base/Text'
import Spinner from 'components/base/Spinner' import Spinner from 'components/base/Spinner'
import GradientBox from 'components/GradientBox'
import type { T } from 'types/common' import type { T } from 'types/common'
@ -218,7 +219,7 @@ class ReleaseNotes extends PureComponent<Props, State> {
return ( return (
<ModalBody onClose={onClose}> <ModalBody onClose={onClose}>
<ModalTitle>{t('app:releaseNotes.title')}</ModalTitle> <ModalTitle>{t('app:releaseNotes.title')}</ModalTitle>
<ModalContent style={{ height: 400 }} mx={-5} pb={0}> <ModalContent style={{ height: 500 }} mx={-5} pb={0}>
<GrowScroll px={5} pb={8}> <GrowScroll px={5} pb={8}>
{content} {content}
</GrowScroll> </GrowScroll>
@ -237,15 +238,4 @@ class ReleaseNotes extends PureComponent<Props, State> {
} }
} }
const GradientBox = styled.div`
width: 100%;
height: 60px;
position: absolute;
bottom: 68px;
left: 0;
right: 0;
background: linear-gradient(rgba(255, 255, 255, 0), #ffffff 70%);
z-index: 2;
`
export default translate()(ReleaseNotes) export default translate()(ReleaseNotes)

1
src/config/constants.js

@ -66,6 +66,7 @@ export const SKIP_ONBOARDING = boolFromEnv('SKIP_ONBOARDING')
export const SHOW_LEGACY_NEW_ACCOUNT = boolFromEnv('SHOW_LEGACY_NEW_ACCOUNT') export const SHOW_LEGACY_NEW_ACCOUNT = boolFromEnv('SHOW_LEGACY_NEW_ACCOUNT')
export const HIGHLIGHT_I18N = boolFromEnv('HIGHLIGHT_I18N') export const HIGHLIGHT_I18N = boolFromEnv('HIGHLIGHT_I18N')
export const DISABLE_ACTIVITY_INDICATORS = boolFromEnv('DISABLE_ACTIVITY_INDICATORS') export const DISABLE_ACTIVITY_INDICATORS = boolFromEnv('DISABLE_ACTIVITY_INDICATORS')
export const EXPERIMENTAL_CENTER_MODAL = boolFromEnv('EXPERIMENTAL_CENTER_MODAL')
// Other constants // Other constants

8
src/index.ejs

@ -40,16 +40,16 @@
transform: rotate(0deg); transform: rotate(0deg);
} }
20% { 20% {
transform: rotate(360deg); transform: rotate(-360deg);
} }
30% { 30% {
transform: rotate(360deg); transform: rotate(-360deg);
} }
50% { 50% {
transform: rotate(720deg); transform: rotate(-720deg);
} }
60% { 60% {
transform: rotate(720deg); transform: rotate(-720deg);
} }
100% { 100% {
transform: rotate(0deg); transform: rotate(0deg);

3
static/i18n/en/app.yml

@ -167,7 +167,8 @@ operationDetails:
to: To to: To
identifier: Hash identifier: Hash
viewOperation: View operation viewOperation: View operation
showMore: See {{recipients}} more showMore: Show {{recipients}} more
showLess: Show less
operationList: operationList:
noMoreOperations: No more operations noMoreOperations: No more operations
manager: manager:

4
yarn.lock

@ -9322,6 +9322,10 @@ meant@~1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.1.tgz#66044fea2f23230ec806fb515efea29c44d2115d" resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.1.tgz#66044fea2f23230ec806fb515efea29c44d2115d"
measure-scrollbar@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/measure-scrollbar/-/measure-scrollbar-1.1.0.tgz#986890d22866255ec5b212480f097c55a82d1231"
media-typer@0.3.0: media-typer@0.3.0:
version "0.3.0" version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"

Loading…
Cancel
Save