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 }
> >
{ this.renderTitle() } { card }
{ children } </Link>
</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;
}
return app.url === 'web'
? '/web' ? '/web'
: `/app/${app.id}` : `/app/${app.id}`;
}
>
{ app.name }
</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()
return addresses.map((address, idx) => { .map((address, idx) => {
const account = accounts[address] || {}; const account = accounts[address] || {};
const balance = balances[address] || {}; const balance = balances[address] || {};
const owners = account.owners || null; const owners = account.owners || null;
return ( return {
<div account,
className={ styles.item } balance,
key={ address } owners
> };
{ this.renderSummary(account, balance, owners) }
</div>
);
}); });
return (
<SectionList
items={ addresses }
renderItem={ this.renderSummary }
/>
);
} }
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 (
<div className={ styles.blockDescription }>
<FormattedMessage <FormattedMessage
id='accounts.summary.minedBlock' id='accounts.summary.minedBlock'
defaultMessage='Mined at block #{blockNumber}' defaultMessage='Mined at block #{blockNumber}'
values={ { values={ {
blockNumber: formattedBlockNumber 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];
let ownerLinkType = 'addresses';
if (account) {
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}` }
>
<div <div
data-tip data-tip
data-for={ `owner_${owner.address}` } data-for={ `owner_${owner.address}` }
data-effect='solid' data-effect='solid'
> >
<IdentityIcon address={ owner.address } button /> <IdentityIcon
address={ owner.address }
center
/>
</div> </div>
<ReactTooltip id={ `owner_${owner.address}` }> <ReactTooltip id={ `owner_${owner.address}` }>
<strong>{ owner.name } </strong><small> (owner)</small> <strong>{ owner.name } </strong><small> (owner)</small>
</ReactTooltip> </ReactTooltip>
</div> </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 ( renderBalance (onlyEth) {
<Link to={ viewLink }>
{ content }
</Link>
);
}
renderBalance () {
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;
} }
.account {
position: relative;
.blockDescription {
color: rgba(255, 255, 255, 0.25);
margin-top: 1.5em;
}
.ethBalances {
opacity: 1;
}
.owners { .owners {
margin-top: 1em;
display: flex; display: flex;
justify-content: center;
flex-wrap: wrap;
margin-bottom: -0.5em; 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,36 +14,8 @@
/* 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);
bottom: 0.5em;
left: -0.125em;
position: absolute;
right: -0.125em;
top: -0.25em;
z-index: 100;
padding: 1em;
.body {
line-height: 1.5em; line-height: 1.5em;
margin: 0 auto; margin: 0 auto;
text-align: left; text-align: left;
@ -53,4 +25,3 @@
padding-bottom: 1em; 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,7 +53,6 @@ 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'
@ -74,7 +73,6 @@ class Dapps extends Component {
/> />
</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
className={ styles.item }
key={ app.id }
>
<DappCard <DappCard
app={ app } app={ app }
key={ app.id }
showLink showLink
showTags 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 }