Align list displays with SectionList (UI consistency) (#4621)

* Render Dapps via SectionList

* Initial rendering of accounts via SectionList

* Width vars

* Allow classNames in certifications & tags

* Overlay of info on hover

* Adjust hover balances

* Large owner icons (align with vaults)

* Consistent block mined at message

* Attach ParityBackground to html

* Adjust page padding to align

* Lint fixes

* Link to different types of addresses

* Make content parts clickable only (a within a)

* Force Chrome hardware acceleration

* Trust the vendors... don't go crazy with transform :)

* Use faster & default transitions

* Remove extra container (double scrolling)

* Remove unused container style

* Make dapp iframe background white

* Stop event propgation on tag click
This commit is contained in:
Jaco Greeff 2017-02-24 15:21:36 +01:00 committed by GitHub
parent afecf5b148
commit f670b180d7
24 changed files with 372 additions and 235 deletions

View File

@ -6,12 +6,15 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<title><%= htmlWebpackPlugin.options.title %></title> <title><%= htmlWebpackPlugin.options.title %></title>
<style> <style>
html {
background: white;
}
html, body, #container { html, body, #container {
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0; margin: 0;
padding: 0; padding: 0;
background: white;
font-family: 'Roboto', sans-serif; font-family: 'Roboto', sans-serif;
font-size: 16px; font-size: 16px;
font-weight: 300; font-weight: 300;

View File

@ -14,6 +14,7 @@
/* You should have received a copy of the GNU General Public License /* You should have received a copy of the GNU General Public License
/* along with Parity. If not, see <http://www.gnu.org/licenses/>. /* along with Parity. If not, see <http://www.gnu.org/licenses/>.
*/ */
.balances { .balances {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
@ -21,16 +22,22 @@
vertical-align: top; vertical-align: top;
} }
.balance,
.empty {
margin: 0.75em 0.5em 0 0;
}
.empty { .empty {
line-height: 24px; line-height: 24px;
margin: 0 0.5em 0 0;
opacity: 0.25; opacity: 0.25;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.balance { .balance {
background: rgba(255, 255, 255, 0.07); background: rgba(255, 255, 255, 0.07);
border-radius: 16px; border-radius: 16px;
margin: 0.75em 0.5em 0 0;
max-height: 24px; max-height: 24px;
max-width: 100%; max-width: 100%;
display: flex; display: flex;

View File

@ -27,18 +27,19 @@ class Certifications extends Component {
static propTypes = { static propTypes = {
address: PropTypes.string.isRequired, address: PropTypes.string.isRequired,
certifications: PropTypes.array.isRequired, certifications: PropTypes.array.isRequired,
className: PropTypes.string,
dappsUrl: PropTypes.string.isRequired dappsUrl: PropTypes.string.isRequired
} }
render () { render () {
const { certifications } = this.props; const { certifications, className } = this.props;
if (certifications.length === 0) { if (certifications.length === 0) {
return null; return null;
} }
return ( return (
<div className={ styles.certifications }> <div className={ [styles.certifications, className].join(' ') }>
{ certifications.map(this.renderCertification) } { certifications.map(this.renderCertification) }
</div> </div>
); );

View File

@ -25,21 +25,24 @@ $transitionAll: all 0.75s cubic-bezier(0.23, 1, 0.32, 1);
height: 100%; height: 100%;
padding: 0em; padding: 0em;
position: relative; position: relative;
transition: $transitionAll; /*transform: translateZ(0);
transition: $transitionAll;*/
width: 100%; width: 100%;
.hoverOverlay { .hoverOverlay {
background: $background; background: $background;
left: 0; left: 0;
margin-top: -1.5em; margin-top: -1.5em;
margin-bottom: 3em;
opacity: inherit; opacity: inherit;
padding: 0 1.5em 1.5em 1.5em; padding: 0 1.5em 1.5em 1.5em;
position: absolute; position: absolute;
right: 0; right: 0;
top: 100%; top: 100%;
transition: $transitionAll; /*transition: $transitionAll;*/
transform: scale(0.5, 0); opacity: 0;
transform-origin: top center; /*transform: scale(0.5, 0);
transform-origin: top center;*/
z-index: 100; z-index: 100;
} }
@ -48,7 +51,8 @@ $transitionAll: all 0.75s cubic-bezier(0.23, 1, 0.32, 1);
.hoverOverlay { .hoverOverlay {
background: $backgroundHover; background: $backgroundHover;
transform: scale(1, 1); /*transform: scale(1, 1);*/
opacity: 1;
} }
} }
} }
@ -74,3 +78,8 @@ $transitionAll: all 0.75s cubic-bezier(0.23, 1, 0.32, 1);
.light .padded { .light .padded {
background: rgba(0, 0, 0, 0.5) !important; background: rgba(0, 0, 0, 0.5) !important;
} }
.link {
width: 100%;
height: 100%;
}

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';
import { Card } from 'material-ui/Card'; import { Card } from 'material-ui/Card';
import { nodeOrStringProptype } from '~/util/proptypes'; import { nodeOrStringProptype } from '~/util/proptypes';
@ -30,6 +31,7 @@ export default class Container extends Component {
compact: PropTypes.bool, compact: PropTypes.bool,
hover: PropTypes.node, hover: PropTypes.node,
light: PropTypes.bool, light: PropTypes.bool,
link: PropTypes.string,
onClick: PropTypes.func, onClick: PropTypes.func,
style: PropTypes.object, style: PropTypes.object,
tabIndex: PropTypes.number, tabIndex: PropTypes.number,
@ -37,13 +39,27 @@ export default class Container extends Component {
} }
render () { render () {
const { children, className, compact, light, onClick, style, tabIndex } = this.props; const { children, className, compact, light, link, onClick, style, tabIndex } = this.props;
const props = {}; const props = {};
if (Number.isInteger(tabIndex)) { if (Number.isInteger(tabIndex)) {
props.tabIndex = tabIndex; props.tabIndex = tabIndex;
} }
const card = (
<Card
className={
compact
? styles.compact
: styles.padded
}
onClick={ onClick }
>
{ this.renderTitle() }
{ children }
</Card>
);
return ( return (
<div <div
className={ className={
@ -58,17 +74,18 @@ export default class Container extends Component {
style={ style } style={ style }
{ ...props } { ...props }
> >
<Card {
className={ link
compact ? (
? styles.compact <Link
: styles.padded className={ styles.link }
} to={ link }
onClick={ onClick } >
> { card }
{ this.renderTitle() } </Link>
{ children } )
</Card> : card
}
{ this.renderHover() } { this.renderHover() }
</div> </div>
); );

View File

@ -18,6 +18,12 @@
.container { .container {
height: 100%; height: 100%;
position: relative; position: relative;
&:not(:hover) {
.tags {
display: none;
}
}
} }
.image { .image {
@ -26,16 +32,20 @@
top: 1.5em; top: 1.5em;
} }
.author,
.description { .description {
margin-left: 72px; margin-left: 72px;
} }
.title { .title {
mragin-bottom: 0.5em;
} }
.author, .version { .titleLink {
color: rgb(0, 151, 167);
}
.author {
font-size: 0.75em; font-size: 0.75em;
opacity: 0.5; opacity: 0.5;
margin-top: 0.5em; margin-top: 1em;
} }

View File

@ -15,7 +15,6 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';
import Container, { Title as ContainerTitle } from '~/ui/Container'; import Container, { Title as ContainerTitle } from '~/ui/Container';
import DappIcon from '~/ui/DappIcon'; import DappIcon from '~/ui/DappIcon';
@ -50,6 +49,12 @@ export default class DappCard extends Component {
className={ className={
[styles.container, className].join(' ') [styles.container, className].join(' ')
} }
hover={
<div className={ styles.author }>
{ app.author }, v{ app.version }
</div>
}
link={ this.getLink(app) }
onClick={ onClick } onClick={ onClick }
> >
<DappIcon <DappIcon
@ -57,6 +62,7 @@ export default class DappCard extends Component {
className={ styles.image } className={ styles.image }
/> />
<Tags <Tags
className={ styles.tags }
tags={ tags={
showTags showTags
? [app.type] ? [app.type]
@ -65,34 +71,29 @@ export default class DappCard extends Component {
/> />
<div className={ styles.description }> <div className={ styles.description }>
<ContainerTitle <ContainerTitle
className={ styles.title } className={
title={
showLink showLink
? this.renderLink(app) ? styles.titleLink
: app.name : styles.title
} }
title={ app.name }
byline={ app.description } byline={ app.description }
/> />
<div className={ styles.author }>
{ app.author }, v{ app.version }
</div>
{ children } { children }
</div> </div>
</Container> </Container>
); );
} }
renderLink (app) { getLink (app) {
return ( const { showLink } = this.props;
<Link
to={ if (!showLink) {
app.url === 'web' return null;
? '/web' }
: `/app/${app.id}`
} return app.url === 'web'
> ? '/web'
{ app.name } : `/app/${app.id}`;
</Link>
);
} }
} }

View File

@ -15,10 +15,17 @@
/* along with Parity. If not, see <http://www.gnu.org/licenses/>. /* along with Parity. If not, see <http://www.gnu.org/licenses/>.
*/ */
.layout { .layout,
padding: 0.25em; .layoutPadded {
&>div { &>div {
margin-bottom: 0.75em; margin-bottom: 0.5em;
} }
} }
.layout {
padding: 0.25em 0.25em 3em 0.25em;
}
.layoutPadded {
padding: 0.5em 0.5em 3em 0.5em;
}

View File

@ -26,11 +26,12 @@ export default class Page extends Component {
buttons: PropTypes.array, buttons: PropTypes.array,
className: PropTypes.string, className: PropTypes.string,
children: PropTypes.node, children: PropTypes.node,
padded: PropTypes.bool,
title: nodeOrStringProptype() title: nodeOrStringProptype()
}; };
render () { render () {
const { buttons, className, children, title } = this.props; const { buttons, className, children, padded, title } = this.props;
return ( return (
<div> <div>
@ -44,7 +45,16 @@ export default class Page extends Component {
) )
: null : null
} }
<div className={ [styles.layout, className].join(' ') }> <div
className={
[
padded
? styles.layoutPadded
: styles.layout,
className
].join(' ')
}
>
{ children } { children }
</div> </div>
</div> </div>

View File

@ -23,6 +23,7 @@ class ParityBackground extends Component {
}; };
static propTypes = { static propTypes = {
attachDocument: PropTypes.bool,
backgroundSeed: PropTypes.string, backgroundSeed: PropTypes.string,
children: PropTypes.node, children: PropTypes.node,
className: PropTypes.string, className: PropTypes.string,
@ -70,17 +71,25 @@ class ParityBackground extends Component {
} }
render () { render () {
const { children, className, onClick } = this.props; const { attachDocument, children, className, onClick } = this.props;
const style = { const style = {
...this.state.style, ...this.state.style,
...this.props.style ...this.props.style
}; };
if (attachDocument) {
document.documentElement.style.background = style.background;
}
return ( return (
<div <div
className={ className } className={ className }
style={ style } style={
attachDocument
? {}
: style
}
onTouchTap={ onClick } onTouchTap={ onClick }
> >
{ children } { children }

View File

@ -15,6 +15,11 @@
/* along with Parity. If not, see <http://www.gnu.org/licenses/>. /* along with Parity. If not, see <http://www.gnu.org/licenses/>.
*/ */
$transition: all 0.25s;
$widthNormal: 33.33%;
$widthShrunk: 29%;
$widthExpanded: 42%;
.section { .section {
position: relative; position: relative;
width: 100%; width: 100%;
@ -38,13 +43,14 @@
/* case where <> 3 columns are required should the need arrise from a UI pov. */ /* case where <> 3 columns are required should the need arrise from a UI pov. */
.item { .item {
box-sizing: border-box; box-sizing: border-box;
cursor: pointer;
display: flex; display: flex;
flex: 0 1 33.33%; flex: 0 1 $widthNormal;
max-width: 33.33%; max-width: $widthNormal;
opacity: 0.85; opacity: 0.85;
padding: 0.25em; padding: 0.25em;
transition: all 0.75s cubic-bezier(0.23, 1, 0.32, 1); /* https://www.binarymoon.co.uk/2014/02/fixing-css-transitions-in-google-chrome/ */
transform: translateZ(0);
transition: $transition;
&:hover { &:hover {
opacity: 1; opacity: 1;
@ -55,12 +61,12 @@
&:hover { &:hover {
.item { .item {
&.stretchOn { &.stretchOn {
flex: 0 1 29%; flex: 0 1 $widthShrunk;
max-width: 29%; max-width: $widthShrunk;
&:hover { &:hover {
flex: 0 0 42%; flex: 0 0 $widthExpanded;
max-width: 42%; max-width: $widthExpanded;
} }
} }
} }

View File

@ -22,6 +22,7 @@ import styles from './tags.css';
export default class Tags extends Component { export default class Tags extends Component {
static propTypes = { static propTypes = {
className: PropTypes.string,
floating: PropTypes.bool, floating: PropTypes.bool,
horizontal: PropTypes.bool, horizontal: PropTypes.bool,
handleAddSearchToken: PropTypes.func, handleAddSearchToken: PropTypes.func,
@ -35,7 +36,7 @@ export default class Tags extends Component {
}; };
render () { render () {
const { floating, horizontal, tags } = this.props; const { className, floating, horizontal, tags } = this.props;
if (!tags || tags.length === 0) { if (!tags || tags.length === 0) {
return null; return null;
@ -51,6 +52,8 @@ export default class Tags extends Component {
classes.push(styles.horizontal); classes.push(styles.horizontal);
} }
classes.push(className);
return ( return (
<div className={ classes.join(' ') }> <div className={ classes.join(' ') }>
{ this.renderTags() } { this.renderTags() }
@ -73,7 +76,12 @@ export default class Tags extends Component {
.sort() .sort()
.map((tag, index) => { .map((tag, index) => {
const onClick = handleAddSearchToken const onClick = handleAddSearchToken
? () => handleAddSearchToken(tag) ? (event) => {
event.stopPropagation();
event.preventDefault();
handleAddSearchToken(tag);
}
: null; : null;
return ( return (

View File

@ -92,7 +92,7 @@ class Account extends Component {
{ this.renderTransferDialog(account, balance) } { this.renderTransferDialog(account, balance) }
{ this.renderVerificationDialog() } { this.renderVerificationDialog() }
{ this.renderActionbar(balance) } { this.renderActionbar(balance) }
<Page> <Page padded>
<Header <Header
account={ account } account={ account }
balance={ balance } balance={ balance }

View File

@ -18,7 +18,7 @@ import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { Container } from '~/ui'; import { Container, SectionList } from '~/ui';
import { fetchCertifiers, fetchCertifications } from '~/redux/providers/certifications/actions'; import { fetchCertifiers, fetchCertifications } from '~/redux/providers/certifications/actions';
import Summary from '../Summary'; import Summary from '../Summary';
@ -40,14 +40,6 @@ class List extends Component {
handleAddSearchToken: PropTypes.func handleAddSearchToken: PropTypes.func
}; };
render () {
return (
<div className={ styles.list }>
{ this.renderAccounts() }
</div>
);
}
componentWillMount () { componentWillMount () {
const { accounts, fetchCertifiers, fetchCertifications } = this.props; const { accounts, fetchCertifiers, fetchCertifications } = this.props;
@ -57,7 +49,7 @@ class List extends Component {
} }
} }
renderAccounts () { render () {
const { accounts, balances, empty } = this.props; const { accounts, balances, empty } = this.props;
if (empty) { if (empty) {
@ -70,26 +62,30 @@ class List extends Component {
); );
} }
const addresses = this.getAddresses(); const addresses = this
.getAddresses()
.map((address, idx) => {
const account = accounts[address] || {};
const balance = balances[address] || {};
const owners = account.owners || null;
return addresses.map((address, idx) => { return {
const account = accounts[address] || {}; account,
const balance = balances[address] || {}; balance,
owners
};
});
const owners = account.owners || null; return (
<SectionList
return ( items={ addresses }
<div renderItem={ this.renderSummary }
className={ styles.item } />
key={ address } );
>
{ this.renderSummary(account, balance, owners) }
</div>
);
});
} }
renderSummary (account, balance, owners) { renderSummary = (item) => {
const { account, balance, owners } = item;
const { handleAddSearchToken, link } = this.props; const { handleAddSearchToken, link } = this.props;
return ( return (

View File

@ -16,6 +16,7 @@
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router'; import { Link } from 'react-router';
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import ReactTooltip from 'react-tooltip'; import ReactTooltip from 'react-tooltip';
@ -27,13 +28,14 @@ import { arrayOrObjectProptype, nullableProptype } from '~/util/proptypes';
import styles from '../accounts.css'; import styles from '../accounts.css';
export default class Summary extends Component { class Summary extends Component {
static contextTypes = { static contextTypes = {
api: React.PropTypes.object api: React.PropTypes.object
}; };
static propTypes = { static propTypes = {
account: PropTypes.object.isRequired, account: PropTypes.object.isRequired,
accountsInfo: PropTypes.object.isRequired,
balance: PropTypes.object, balance: PropTypes.object,
link: PropTypes.string, link: PropTypes.string,
name: PropTypes.string, name: PropTypes.string,
@ -90,7 +92,7 @@ export default class Summary extends Component {
} }
render () { render () {
const { account, handleAddSearchToken } = this.props; const { account, handleAddSearchToken, noLink } = this.props;
const { tags } = account.meta; const { tags } = account.meta;
if (!account) { if (!account) {
@ -108,52 +110,71 @@ export default class Summary extends Component {
/> />
); );
const description = this.getDescription(account.meta);
return ( return (
<Container> <Container
<Tags tags={ tags } handleAddSearchToken={ handleAddSearchToken } /> className={ styles.account }
hover={
<div className={ styles.overlay }>
{ this.renderBalance(false) }
{ this.renderDescription(account.meta) }
{ this.renderOwners() }
{ this.renderCertifications() }
</div>
}
link={ this.getLink() }
>
<Tags
className={ styles.tags }
tags={ tags }
handleAddSearchToken={ handleAddSearchToken }
/>
<div className={ styles.heading }> <div className={ styles.heading }>
<IdentityIcon <IdentityIcon
address={ address } address={ address }
/> />
<ContainerTitle <ContainerTitle
byline={ addressComponent } byline={ addressComponent }
className={ styles.main } className={
description={ description } noLink
title={ this.renderLink() } ? styles.main
: styles.mainLink
}
title={
<IdentityName
address={ address }
name={ name }
unknown
/>
}
/> />
</div> </div>
{ this.renderBalance(true) }
{ this.renderOwners() }
{ this.renderBalance() }
{ this.renderCertifications() }
</Container> </Container>
); );
} }
getDescription (meta = {}) { renderDescription (meta = {}) {
const { blockNumber } = meta; const { blockNumber } = meta;
if (!blockNumber) { if (!blockNumber) {
return null; return null;
} }
const formattedBlockNumber = (new BigNumber(blockNumber)).toFormat();
return ( return (
<FormattedMessage <div className={ styles.blockDescription }>
id='accounts.summary.minedBlock' <FormattedMessage
defaultMessage='Mined at block #{blockNumber}' id='accounts.summary.minedBlock'
values={ { defaultMessage='Mined at block #{blockNumber}'
blockNumber: formattedBlockNumber values={ {
} } blockNumber: (new BigNumber(blockNumber)).toFormat()
/> } }
/>
</div>
); );
} }
renderOwners () { renderOwners () {
const { owners } = this.props; const { accountsInfo, owners } = this.props;
const ownersValid = (owners || []).filter((owner) => owner.address && new BigNumber(owner.address).gt(0)); const ownersValid = (owners || []).filter((owner) => owner.address && new BigNumber(owner.address).gt(0));
if (!ownersValid || ownersValid.length === 0) { if (!ownersValid || ownersValid.length === 0) {
@ -163,55 +184,58 @@ export default class Summary extends Component {
return ( return (
<div className={ styles.owners }> <div className={ styles.owners }>
{ {
ownersValid.map((owner, index) => ( ownersValid.map((owner, index) => {
<div key={ `${index}_${owner.address}` }> const account = accountsInfo[owner.address];
<div let ownerLinkType = 'addresses';
data-tip
data-for={ `owner_${owner.address}` } if (account) {
data-effect='solid' if (account.uuid || account.hardware) {
ownerLinkType = 'accounts';
} else if (account.wallet) {
ownerLinkType = 'wallet';
} else if (account.meta.contract) {
ownerLinkType = 'contract';
}
}
return (
<Link
className={ styles.owner }
key={ `${index}_${owner.address}` }
to={ `/${ownerLinkType}/${owner.address}` }
> >
<IdentityIcon address={ owner.address } button /> <div
</div> data-tip
<ReactTooltip id={ `owner_${owner.address}` }> data-for={ `owner_${owner.address}` }
<strong>{ owner.name } </strong><small> (owner)</small> data-effect='solid'
</ReactTooltip> >
</div> <IdentityIcon
)) address={ owner.address }
center
/>
</div>
<ReactTooltip id={ `owner_${owner.address}` }>
<strong>{ owner.name } </strong><small> (owner)</small>
</ReactTooltip>
</Link>
);
})
} }
</div> </div>
); );
} }
renderLink () { getLink () {
const { link, noLink, account, name } = this.props; const { link, account } = this.props;
const { address } = account; const { address } = account;
const baseLink = account.wallet const baseLink = account.wallet
? 'wallet' ? 'wallet'
: link || 'accounts'; : link || 'accounts';
const viewLink = `/${baseLink}/${address}`; return `/${baseLink}/${address}`;
const content = (
<IdentityName
address={ address }
name={ name }
unknown
/>
);
if (noLink) {
return content;
}
return (
<Link to={ viewLink }>
{ content }
</Link>
);
} }
renderBalance () { renderBalance (onlyEth) {
const { balance } = this.props; const { balance } = this.props;
if (!balance) { if (!balance) {
@ -219,7 +243,15 @@ export default class Summary extends Component {
} }
return ( return (
<Balance balance={ balance } /> <Balance
balance={ balance }
className={
onlyEth
? styles.ethBalances
: styles.allBalances
}
showOnlyEth={ onlyEth }
/>
); );
} }
@ -231,7 +263,23 @@ export default class Summary extends Component {
} }
return ( return (
<Certifications address={ account.address } /> <Certifications
address={ account.address }
className={ styles.Certifications }
/>
); );
} }
} }
function mapStateToProps (state) {
const { accountsInfo } = state.personal;
return {
accountsInfo
};
}
export default connect(
mapStateToProps,
null
)(Summary);

View File

@ -20,10 +20,45 @@
left: 7em; left: 7em;
} }
.owners { .account {
margin-top: 1em; position: relative;
display: flex;
margin-bottom: -0.5em; .blockDescription {
color: rgba(255, 255, 255, 0.25);
margin-top: 1.5em;
}
.ethBalances {
opacity: 1;
}
.owners {
display: flex;
justify-content: center;
flex-wrap: wrap;
margin-bottom: -0.5em;
margin-top: 1em;
.owner {
margin: 0.5em;
}
}
.overlay {
margin-top: -3.25em;
}
&:not(:hover) {
.tags {
display: none;
}
}
&:hover {
.ethBalances {
opacity: 0;
}
}
} }
.toolbar { .toolbar {
@ -61,7 +96,12 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
.main { .main,
.mainLink {
flex: 1; flex: 1;
} }
.mainLink h3 {
color: rgb(0, 151, 167);
}
} }

View File

@ -90,7 +90,7 @@ class Address extends Component {
{ this.renderEditDialog(contact) } { this.renderEditDialog(contact) }
{ this.renderActionbar(contact) } { this.renderActionbar(contact) }
{ this.renderDelete(contact) } { this.renderDelete(contact) }
<Page> <Page padded>
<Header <Header
account={ contact || { address, meta: {} } } account={ contact || { address, meta: {} } }
balance={ balance } balance={ balance }

View File

@ -33,7 +33,10 @@ export default class Container extends Component {
const { children, onCloseFirstRun, showFirstRun, upgradeStore } = this.props; const { children, onCloseFirstRun, showFirstRun, upgradeStore } = this.props;
return ( return (
<ParityBackground className={ styles.container }> <ParityBackground
attachDocument
className={ styles.container }
>
<FirstRun <FirstRun
onClose={ onCloseFirstRun } onClose={ onCloseFirstRun }
visible={ showFirstRun } visible={ showFirstRun }

View File

@ -136,7 +136,7 @@ class Contract extends Component {
{ this.renderDeleteDialog(account) } { this.renderDeleteDialog(account) }
{ this.renderEditDialog(account) } { this.renderEditDialog(account) }
{ this.renderExecuteDialog() } { this.renderExecuteDialog() }
<Page> <Page padded>
<Header <Header
account={ account } account={ account }
balance={ balance } balance={ balance }

View File

@ -82,7 +82,6 @@ class Contracts extends Component {
<div> <div>
{ this.renderActionbar() } { this.renderActionbar() }
{ this.renderAddContract() } { this.renderAddContract() }
{ this.renderAddContract() }
{ this.renderDeployContract() } { this.renderDeployContract() }
<Page> <Page>
<List <List

View File

@ -15,6 +15,7 @@
/* along with Parity. If not, see <http://www.gnu.org/licenses/>. /* along with Parity. If not, see <http://www.gnu.org/licenses/>.
*/ */
.frame { .frame {
background: white;
border: 0; border: 0;
position: absolute; position: absolute;
height: 100%; height: 100%;

View File

@ -14,43 +14,14 @@
/* You should have received a copy of the GNU General Public License /* You should have received a copy of the GNU General Public License
/* along with Parity. If not, see <http://www.gnu.org/licenses/>. /* along with Parity. If not, see <http://www.gnu.org/licenses/>.
*/ */
.list {
display: flex;
flex-wrap: wrap;
margin: -0.125em;
position: relative;
.item {
box-sizing: border-box;
flex: 0 1 50%;
opacity: 0.85;
padding: 0.125em;
}
}
.list+.list {
margin-top: -0.25em;
}
.overlay { .overlay {
background: rgba(0, 0, 0, 0.85); line-height: 1.5em;
bottom: 0.5em; margin: 0 auto;
left: -0.125em; text-align: left;
position: absolute; max-width: 980px;
right: -0.125em;
top: -0.25em;
z-index: 100;
padding: 1em;
.body { &>div:first-child {
line-height: 1.5em; padding-bottom: 1em;
margin: 0 auto;
text-align: left;
max-width: 980px;
&>div:first-child {
padding-bottom: 1em;
}
} }
} }

View File

@ -23,7 +23,7 @@ import { connect } from 'react-redux';
import { DappPermissions, DappsVisible } from '~/modals'; import { DappPermissions, DappsVisible } from '~/modals';
import PermissionStore from '~/modals/DappPermissions/store'; import PermissionStore from '~/modals/DappPermissions/store';
import { Actionbar, Button, DappCard, Page } from '~/ui'; import { Actionbar, Button, DappCard, Page, SectionList } from '~/ui';
import { LockedIcon, VisibleIcon } from '~/ui/Icons'; import { LockedIcon, VisibleIcon } from '~/ui/Icons';
import DappsStore from './dappsStore'; import DappsStore from './dappsStore';
@ -53,26 +53,24 @@ class Dapps extends Component {
if (this.store.externalOverlayVisible) { if (this.store.externalOverlayVisible) {
externalOverlay = ( externalOverlay = (
<div className={ styles.overlay }> <div className={ styles.overlay }>
<div className={ styles.body }> <div>
<div> <FormattedMessage
<FormattedMessage id='dapps.external.warning'
id='dapps.external.warning' defaultMessage='Applications made available on the network by 3rd-party authors are not affiliated with Parity nor are they published by Parity. Each remain under the control of their respective authors. Please ensure that you understand the goals for each before interacting.'
defaultMessage='Applications made available on the network by 3rd-party authors are not affiliated with Parity nor are they published by Parity. Each remain under the control of their respective authors. Please ensure that you understand the goals for each before interacting.' />
/> </div>
</div> <div>
<div> <Checkbox
<Checkbox className={ styles.accept }
className={ styles.accept } label={
label={ <FormattedMessage
<FormattedMessage id='dapps.external.accept'
id='dapps.external.accept' defaultMessage='I understand that these applications are not affiliated with Parity'
defaultMessage='I understand that these applications are not affiliated with Parity' />
/> }
} checked={ false }
checked={ false } onCheck={ this.onClickAcceptExternal }
onCheck={ this.onClickAcceptExternal } />
/>
</div>
</div> </div>
</div> </div>
); );
@ -125,30 +123,23 @@ class Dapps extends Component {
} }
renderList (items, overlay) { renderList (items, overlay) {
if (!items || !items.length) {
return null;
}
return ( return (
<div className={ styles.list }> <SectionList
{ overlay } items={ items }
{ items.map(this.renderApp) } overlay={ overlay }
</div> renderItem={ this.renderApp }
/>
); );
} }
renderApp = (app) => { renderApp = (app) => {
return ( return (
<div <DappCard
className={ styles.item } app={ app }
key={ app.id } key={ app.id }
> showLink
<DappCard showTags
app={ app } />
showLink
showTags
/>
</div>
); );
} }

View File

@ -120,7 +120,7 @@ class Wallet extends Component {
{ this.renderTransferDialog() } { this.renderTransferDialog() }
{ this.renderDeleteDialog(walletAccount) } { this.renderDeleteDialog(walletAccount) }
{ this.renderActionbar() } { this.renderActionbar() }
<Page> <Page padded>
<div className={ styles.info }> <div className={ styles.info }>
<Header <Header
className={ styles.header } className={ styles.header }