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",
"lodash": "^4.17.5",
"lru-cache": "^4.1.3",
"measure-scrollbar": "^1.1.0",
"moment": "^2.22.2",
"qrcode": "^1.2.0",
"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 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 {...p} style={outerStyle}>
<Text style={innerStyle}>{children}</Text>
<Text style={{ ...innerStyle, userSelect: canSelect ? 'text' : 'none' }}>{children}</Text>
</Box>
</Box>
)

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

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

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

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

240
src/components/modals/OperationDetails.js

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

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 HIGHLIGHT_I18N = boolFromEnv('HIGHLIGHT_I18N')
export const DISABLE_ACTIVITY_INDICATORS = boolFromEnv('DISABLE_ACTIVITY_INDICATORS')
export const EXPERIMENTAL_CENTER_MODAL = boolFromEnv('EXPERIMENTAL_CENTER_MODAL')
// Other constants

8
src/index.ejs

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

3
static/i18n/en/app.yml

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

4
yarn.lock

@ -9322,6 +9322,10 @@ meant@~1.0.1:
version "1.0.1"
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:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"

Loading…
Cancel
Save