More func. component conversions (#1650)

* More func. component conversions

* Linting updates
This commit is contained in:
Jaco Greeff 2019-09-24 11:42:55 +02:00 committed by GitHub
parent 6f8da05805
commit 09c45ea3c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 184 additions and 233 deletions

View File

@ -313,14 +313,16 @@ class VanityApp extends TxComponent<Props, State> {
}
}
export default translate(styled(VanityApp)`
.vanity--App-matches {
padding: 1em 0;
}
export default translate(
styled(VanityApp)`
.vanity--App-matches {
padding: 1em 0;
}
.vanity--App-stats {
padding: 1em 0 0 0;
opacity: 0.45;
text-align: center;
}
`);
.vanity--App-stats {
padding: 1em 0 0 0;
opacity: 0.45;
text-align: center;
}
`
);

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/camelcase */
// Copyright 2017-2019 @polkadot/app-123code authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
@ -6,147 +5,103 @@
import { Option } from '@polkadot/types';
import { BalanceOf, EthereumAddress } from '@polkadot/types/interfaces';
import { I18nProps } from '@polkadot/react-components/types';
import { ApiProps } from '@polkadot/react-api/types';
import React from 'react';
import React, { useContext, useEffect, useState } from 'react';
import styled from 'styled-components';
import { withApi, withMulti } from '@polkadot/react-api';
import { ApiContext } from '@polkadot/react-api';
import { Button, Card } from '@polkadot/react-components';
import { formatBalance } from '@polkadot/util';
import translate from './translate';
import { addrToChecksum } from './util';
const ClaimInner = styled.div`
font-size: 1.15rem;
display: flex;
flex-direction: column;
justify-content: center;
min-height: 12rem;
align-items: center;
margin: 0 1rem;
h3 {
font-family: monospace;
font-size: 1.5rem;
max-width: 100%;
margin: 0.5rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
h2 {
margin: 0.5rem 0 2rem
font-family: monospace;
font-size: 2.5rem;
font-weight: 200;
}
`;
interface Props extends ApiProps, I18nProps {
interface Props extends I18nProps {
button: React.ReactNode;
ethereumAddress: EthereumAddress | null;
}
interface State {
claim: BalanceOf | null;
ethereumAddress: EthereumAddress | null;
hasClaim: boolean;
isBusy: boolean;
function Claim ({ button, className, ethereumAddress, t }: Props): React.ReactElement<Props> | null {
const { api } = useContext(ApiContext);
const [claimValue, setClaimValue] = useState<BalanceOf | null>(null);
const [claimAddress, setClaimAddress] = useState<EthereumAddress | null>(null);
const [isBusy, setIsBusy] = useState(false);
const _fetchClaim = (address: EthereumAddress): void => {
setIsBusy(true);
api.query.claims
.claims<Option<BalanceOf>>(address)
.then((claim): void => {
setClaimValue(claim.unwrapOr(null));
setIsBusy(false);
})
.catch((): void => setIsBusy(false));
};
useEffect((): void => {
if (ethereumAddress !== claimAddress) {
setClaimAddress(ethereumAddress);
ethereumAddress && _fetchClaim(ethereumAddress);
}
}, [ethereumAddress]);
if (isBusy || !claimAddress) {
return null;
}
const hasClaim = claimValue && claimValue.gten(0);
return (
<Card
isError={!hasClaim}
isSuccess={!!hasClaim}
>
<div className={className}>
{t('Your Ethereum account')}
<h3>{addrToChecksum(claimAddress.toString())}</h3>
{hasClaim && claimValue
? (
<>
{t('has a valid claim for')}
<h2>{formatBalance(claimValue)}</h2>
<Button.Group>{button}</Button.Group>
</>
)
: (
<>
{t('does not appear to have a valid claim. Please double check that you have signed the transaction correctly on the correct ETH account.')}
</>
)}
</div>
</Card>
);
}
class Claim extends React.PureComponent<Props, State> {
public static getDerivedStateFromProps ({ ethereumAddress }: Props, state: State): Pick<State, never> {
if (ethereumAddress) {
return {
ethereumAddress,
hasClaim: state.claim && state.claim.gten(0)
};
export default translate(
styled(Claim)`
font-size: 1.15rem;
display: flex;
flex-direction: column;
justify-content: center;
min-height: 12rem;
align-items: center;
margin: 0 1rem;
h3 {
font-family: monospace;
font-size: 1.5rem;
max-width: 100%;
margin: 0.5rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
return {
hasClaim: false
};
}
public state: State = {
claim: null,
ethereumAddress: null,
hasClaim: false,
isBusy: false
}
public componentDidMount (): void {
this.fetchClaim();
}
public componentDidUpdate (_: Props, prevState: State): void {
const { ethereumAddress } = this.state;
if (ethereumAddress !== prevState.ethereumAddress) {
this.fetchClaim();
h2 {
margin: 0.5rem 0 2rem;
font-family: monospace;
font-size: 2.5rem;
font-weight: 200;
}
}
public render (): React.ReactNode {
const { button, t } = this.props;
const { claim, ethereumAddress, hasClaim, isBusy } = this.state;
if (isBusy || !ethereumAddress) {
return null;
}
return (
<Card
isError={!hasClaim || !claim}
isSuccess={hasClaim && !!claim}
>
<ClaimInner>
{t('Your Ethereum account')}
<h3>{addrToChecksum(ethereumAddress.toString())}</h3>
{hasClaim && !!claim
? (
<>
{t('has a valid claim for')}
<h2>{formatBalance(claim)}</h2>
<Button.Group>
{button}
</Button.Group>
</>
)
: (
<>
{t('does not appear to have a valid claim. Please double check that you have signed the transaction correctly on the correct ETH account.')}
</>
)}
</ClaimInner>
</Card>
);
}
private fetchClaim (): void {
const { api } = this.props;
const { ethereumAddress } = this.state;
if (!ethereumAddress) {
return;
}
this.setState({ isBusy: true }, (): void => {
api.query.claims
.claims<Option<BalanceOf>>(ethereumAddress.toHex())
.then((claim): void => {
this.setState({
claim: claim.unwrapOr(null),
isBusy: false
});
});
});
}
}
export default withMulti(
Claim,
translate,
withApi
`
);

View File

@ -34,7 +34,7 @@ interface Props extends AppProps, ApiProps, I18nProps, TxModalProps {}
interface State extends TxModalState {
didCopy: boolean;
ethereumAddress?: EthereumAddress | null;
ethereumAddress: EthereumAddress | null;
claim?: Balance | null;
signature?: EcdsaSignature | null;
step: Step;

View File

@ -157,7 +157,7 @@ class Developer extends React.PureComponent<Props, State> {
}
private saveDeveloper = (): void => {
const { t } = this.props;
const { onStatusChange, t } = this.props;
const { types } = this.state;
try {
@ -166,16 +166,18 @@ class Developer extends React.PureComponent<Props, State> {
store.set('types', types);
this.setState({ isTypesValid: true });
this.props.onStatusChange({
onStatusChange({
status: 'success',
action: t('Your custom types have been added')
});
} catch (e) {
console.error(e);
} catch (error) {
console.error(error);
this.setState({ isTypesValid: false });
this.props.onStatusChange({
onStatusChange({
status: 'error',
action: t(`Error saving your custom types. ${e}`)
action: t(`Error saving your custom types. ${error.message}`)
});
}
}

View File

@ -5,7 +5,7 @@
import { BareProps } from '../types';
import BN from 'bn.js';
import React from 'react';
import React, { useEffect, useState } from 'react';
import ChartJs from 'chart.js';
import { HorizontalBar } from 'react-chartjs-2';
import { bnToBn } from '@polkadot/util';
@ -24,7 +24,7 @@ interface Props extends BareProps {
interface State {
chartData?: ChartJs.ChartData;
chartOptions?: ChartJs.ChartOptions;
valuesStr?: string;
jsonValues?: string;
}
interface Config {
@ -39,74 +39,71 @@ interface Config {
const alphaColor = (hexColor: string): string =>
ChartJs.helpers.color(hexColor).alpha(0.65).rgbString();
export default class ChartHorizBar extends React.PureComponent<Props, State> {
public state: State = {};
function calculateOptions (aspectRatio: number, values: Value[], jsonValues: string): State {
const chartData = values.reduce((data, { colors: [normalColor = '#00f', hoverColor], label, value }): Config => {
const dataset = data.datasets[0];
public static getDerivedStateFromProps ({ aspectRatio = 4, values }: Props, prevState: State): State | null {
const valuesStr = JSON.stringify(values);
dataset.backgroundColor.push(alphaColor(normalColor));
dataset.hoverBackgroundColor.push(alphaColor(hoverColor || normalColor));
dataset.data.push(bnToBn(value).toNumber());
data.labels.push(label);
if (valuesStr === prevState.valuesStr) {
return null;
}
return data;
}, {
labels: [] as string[],
datasets: [{
data: [] as number[],
backgroundColor: [] as string[],
hoverBackgroundColor: [] as string[]
}]
});
const chartData = values.reduce((data, { colors: [normalColor = '#00f', hoverColor], label, value }): Config => {
const dataset = data.datasets[0];
dataset.backgroundColor.push(alphaColor(normalColor));
dataset.hoverBackgroundColor.push(alphaColor(hoverColor || normalColor));
dataset.data.push(bnToBn(value).toNumber());
data.labels.push(label);
return data;
}, {
labels: [] as string[],
datasets: [{
data: [] as number[],
backgroundColor: [] as string[],
hoverBackgroundColor: [] as string[]
}]
});
return {
chartData,
chartOptions: {
// width/height by default this is "1", i.e. a square box
aspectRatio,
// no need for the legend, expect the labels contain everything
legend: {
display: false
},
scales: {
xAxes: [{
ticks: {
beginAtZero: true,
max: 100
}
}]
}
return {
chartData,
chartOptions: {
// width/height by default this is "1", i.e. a square box
aspectRatio,
// no need for the legend, expect the labels contain everything
legend: {
display: false
},
valuesStr
};
}
public render (): React.ReactNode {
const { className, style } = this.props;
const { chartData, chartOptions } = this.state;
if (!chartData) {
return null;
}
return (
<div
className={className}
style={style}
>
<HorizontalBar
data={chartData}
options={chartOptions}
/>
</div>
);
}
scales: {
xAxes: [{
ticks: {
beginAtZero: true,
max: 100
}
}]
}
},
jsonValues
};
}
export default function ChartHorizBar ({ aspectRatio = 4, className, style, values }: Props): React.ReactElement<Props> | null {
const [{ chartData, chartOptions, jsonValues }, setState] = useState<State>({});
useEffect((): void => {
const newJsonValues = JSON.stringify(values);
if (newJsonValues !== jsonValues) {
setState(calculateOptions(aspectRatio, values, newJsonValues));
}
}, [values]);
if (!chartData) {
return null;
}
return (
<div
className={className}
style={style}
>
<HorizontalBar
data={chartData}
options={chartOptions}
/>
</div>
);
}

View File

@ -14,23 +14,18 @@ interface Props extends BareProps {
[index: string]: any;
}
export default class Modal extends React.PureComponent<Props> {
public static Actions = SUIModal.Actions;
public static Content = SUIModal.Content;
public static Header = SUIModal.Header;
public static Description = SUIModal.Description;
public render (): React.ReactNode {
const { className } = this.props;
return (
<SUIModal
{...this.props}
className={classes('theme--default', 'ui--Modal', className)}
/>
);
}
function Modal (props: Props): React.ReactElement<Props> {
return (
<SUIModal
{...props}
className={classes('theme--default', 'ui--Modal', props.className)}
/>
);
}
Modal.Actions = SUIModal.Actions;
Modal.Content = SUIModal.Content;
Modal.Header = SUIModal.Header;
Modal.Description = SUIModal.Description;
export default Modal;

View File

@ -112,7 +112,7 @@ export function FeeDisplay ({ accountId, balances_all = ZERO_BALANCE, balances_f
const allWarn = extraWarn;
const overLimit = txLength.gten(MAX_SIZE_BYTES);
(hasAvailable !== state.hasAvailable) && onChange && onChange(hasAvailable);
onChange && onChange(hasAvailable);
setExtra({
extraAmount,
@ -149,7 +149,7 @@ export function FeeDisplay ({ accountId, balances_all = ZERO_BALANCE, balances_f
className={[className, feeClass, 'padded'].join(' ')}
key='txinfo'
>
{isSendable && (
{!isSendable && (
<div>
<Icon name='ban' />
{t('The selected account does not exist on your keyring')}