mirror of
https://github.com/trezor/trezor-wallet
synced 2024-12-01 04:38:15 +00:00
Merge branch 'feature/accounts-loader' into sign/verify
This commit is contained in:
commit
d8762ec76f
@ -28,9 +28,9 @@ export type SelectedAccountAction = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type AccountStatus = {
|
type AccountStatus = {
|
||||||
type: string; // notification type
|
type: ?string; // notification type
|
||||||
title: string; // notification title
|
title: ?string; // notification title
|
||||||
message?: string; // notification message
|
message?: ?string; // notification message
|
||||||
shouldRender: boolean; // should render account page
|
shouldRender: boolean; // should render account page
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ const getAccountStatus = (state: State, selectedAccount: SelectedAccountState):
|
|||||||
const device = state.wallet.selectedDevice;
|
const device = state.wallet.selectedDevice;
|
||||||
if (!device || !device.state) {
|
if (!device || !device.state) {
|
||||||
return {
|
return {
|
||||||
type: 'info',
|
type: 'loader-progress',
|
||||||
title: 'Loading device...',
|
title: 'Loading device...',
|
||||||
shouldRender: false,
|
shouldRender: false,
|
||||||
};
|
};
|
||||||
@ -57,7 +57,7 @@ const getAccountStatus = (state: State, selectedAccount: SelectedAccountState):
|
|||||||
// corner case: accountState didn't finish loading state after LOCATION_CHANGE action
|
// corner case: accountState didn't finish loading state after LOCATION_CHANGE action
|
||||||
if (!network) {
|
if (!network) {
|
||||||
return {
|
return {
|
||||||
type: 'info',
|
type: 'loader-progress',
|
||||||
title: 'Loading account state...',
|
title: 'Loading account state...',
|
||||||
shouldRender: false,
|
shouldRender: false,
|
||||||
};
|
};
|
||||||
@ -79,14 +79,14 @@ const getAccountStatus = (state: State, selectedAccount: SelectedAccountState):
|
|||||||
// case 1: device is connected but discovery not started yet (probably waiting for auth)
|
// case 1: device is connected but discovery not started yet (probably waiting for auth)
|
||||||
if (device.available) {
|
if (device.available) {
|
||||||
return {
|
return {
|
||||||
type: 'info',
|
type: 'loader-progress',
|
||||||
title: 'Authenticating device...',
|
title: 'Authenticating device...',
|
||||||
shouldRender: false,
|
shouldRender: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// case 2: device is unavailable (created with different passphrase settings) account cannot be accessed
|
// case 2: device is unavailable (created with different passphrase settings) account cannot be accessed
|
||||||
return {
|
return {
|
||||||
type: 'info',
|
type: 'loader-info',
|
||||||
title: `Device ${device.instanceLabel} is unavailable`,
|
title: `Device ${device.instanceLabel} is unavailable`,
|
||||||
message: 'Change passphrase settings to use this device',
|
message: 'Change passphrase settings to use this device',
|
||||||
shouldRender: false,
|
shouldRender: false,
|
||||||
@ -95,7 +95,7 @@ const getAccountStatus = (state: State, selectedAccount: SelectedAccountState):
|
|||||||
|
|
||||||
// case 3: device is disconnected
|
// case 3: device is disconnected
|
||||||
return {
|
return {
|
||||||
type: 'info',
|
type: 'loader-info',
|
||||||
title: `Device ${device.instanceLabel} is disconnected`,
|
title: `Device ${device.instanceLabel} is disconnected`,
|
||||||
message: 'Connect device to load accounts',
|
message: 'Connect device to load accounts',
|
||||||
shouldRender: false,
|
shouldRender: false,
|
||||||
@ -105,18 +105,11 @@ const getAccountStatus = (state: State, selectedAccount: SelectedAccountState):
|
|||||||
if (discovery.completed) {
|
if (discovery.completed) {
|
||||||
// case 4: account not found and discovery is completed
|
// case 4: account not found and discovery is completed
|
||||||
return {
|
return {
|
||||||
type: 'warning',
|
type: 'loader-info',
|
||||||
title: 'Account does not exist',
|
title: 'Account does not exist',
|
||||||
shouldRender: false,
|
shouldRender: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// case 6: discovery is not completed yet
|
|
||||||
return {
|
|
||||||
type: 'info',
|
|
||||||
title: 'Loading accounts...',
|
|
||||||
shouldRender: false,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional status: account does exists and it's visible but shouldn't be active
|
// Additional status: account does exists and it's visible but shouldn't be active
|
||||||
@ -137,15 +130,6 @@ const getAccountStatus = (state: State, selectedAccount: SelectedAccountState):
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional status: account does exists, but waiting for discovery to complete
|
|
||||||
if (discovery && !discovery.completed) {
|
|
||||||
return {
|
|
||||||
type: 'info',
|
|
||||||
title: 'Loading accounts...',
|
|
||||||
shouldRender: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -171,6 +155,11 @@ export const observe = (prevState: State, action: Action): PayloadAction<boolean
|
|||||||
if (actions.indexOf(action.type) < 0) return false;
|
if (actions.indexOf(action.type) < 0) return false;
|
||||||
|
|
||||||
const state: State = getState();
|
const state: State = getState();
|
||||||
|
const notification = {
|
||||||
|
type: null,
|
||||||
|
message: null,
|
||||||
|
title: null,
|
||||||
|
};
|
||||||
const { location } = state.router;
|
const { location } = state.router;
|
||||||
// displayed route is not an account route
|
// displayed route is not an account route
|
||||||
if (!location.state.account) return false;
|
if (!location.state.account) return false;
|
||||||
@ -190,13 +179,13 @@ export const observe = (prevState: State, action: Action): PayloadAction<boolean
|
|||||||
discovery,
|
discovery,
|
||||||
tokens,
|
tokens,
|
||||||
pending,
|
pending,
|
||||||
notification: null,
|
notification,
|
||||||
shouldRender: false,
|
shouldRender: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
// get "selectedAccount" status from newState
|
// get "selectedAccount" status from newState
|
||||||
const status = getAccountStatus(state, newState);
|
const status = getAccountStatus(state, newState);
|
||||||
newState.notification = status || null;
|
newState.notification = status || notification;
|
||||||
newState.shouldRender = status ? status.shouldRender : true;
|
newState.shouldRender = status ? status.shouldRender : true;
|
||||||
// check if newState is different than previous state
|
// check if newState is different than previous state
|
||||||
const stateChanged = reducerUtils.observeChanges(prevState.selectedAccount, newState, {
|
const stateChanged = reducerUtils.observeChanges(prevState.selectedAccount, newState, {
|
||||||
|
@ -17,7 +17,7 @@ type Props = {
|
|||||||
cancelable?: boolean;
|
cancelable?: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
message?: string;
|
message?: ?string;
|
||||||
actions?: Array<CallbackAction>;
|
actions?: Array<CallbackAction>;
|
||||||
close?: typeof NotificationActions.close,
|
close?: typeof NotificationActions.close,
|
||||||
loading?: boolean
|
loading?: boolean
|
||||||
|
@ -7,7 +7,7 @@ import type { Props } from '../../index';
|
|||||||
// There could be only one account notification
|
// There could be only one account notification
|
||||||
export default (props: Props) => {
|
export default (props: Props) => {
|
||||||
const { network, notification } = props.selectedAccount;
|
const { network, notification } = props.selectedAccount;
|
||||||
if (network && notification) {
|
if (network && notification.type && notification.title && notification.type !== 'loader-progress' && notification.type !== 'loader-info') {
|
||||||
if (notification.type === 'backend') {
|
if (notification.type === 'backend') {
|
||||||
// special case: backend is down
|
// special case: backend is down
|
||||||
// TODO: this is a different component with "auto resolve" button
|
// TODO: this is a different component with "auto resolve" button
|
||||||
@ -27,7 +27,14 @@ export default (props: Props) => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (<Notification type={notification.type} title={notification.title} message={notification.message} />);
|
return (
|
||||||
|
<Notification
|
||||||
|
type={notification.type}
|
||||||
|
title={notification.title}
|
||||||
|
message={notification.message}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
@ -17,10 +17,10 @@ export type State = {
|
|||||||
tokens: Array<Token>,
|
tokens: Array<Token>,
|
||||||
pending: Array<PendingTx>,
|
pending: Array<PendingTx>,
|
||||||
discovery: ?Discovery,
|
discovery: ?Discovery,
|
||||||
notification: ?{
|
notification: {
|
||||||
type: string,
|
type: ?string,
|
||||||
title: string,
|
title: ?string,
|
||||||
message?: string,
|
message: ?string,
|
||||||
},
|
},
|
||||||
shouldRender: boolean,
|
shouldRender: boolean,
|
||||||
};
|
};
|
||||||
@ -32,7 +32,11 @@ export const initialState: State = {
|
|||||||
tokens: [],
|
tokens: [],
|
||||||
pending: [],
|
pending: [],
|
||||||
discovery: null,
|
discovery: null,
|
||||||
notification: null,
|
notification: {
|
||||||
|
type: null,
|
||||||
|
title: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
shouldRender: false,
|
shouldRender: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import Loader from 'components/Loader';
|
||||||
|
import { FONT_SIZE } from 'config/variables';
|
||||||
|
import colors from 'config/colors';
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
const Wrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -9,16 +12,57 @@ const Wrapper = styled.div`
|
|||||||
padding: 40px 35px 40px 35px;
|
padding: 40px 35px 40px 35px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const Loading = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Text = styled.div`
|
||||||
|
font-size: ${FONT_SIZE.BIG};
|
||||||
|
color: ${colors.TEXT_SECONDARY};
|
||||||
|
margin-left: 10px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Message = styled.div`
|
||||||
|
font-size: ${FONT_SIZE.SMALL};
|
||||||
|
color: ${colors.TEXT_PRIMARY};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Row = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
`;
|
||||||
|
|
||||||
const Content = ({
|
const Content = ({
|
||||||
children,
|
children,
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
type,
|
||||||
|
isLoading = false,
|
||||||
}) => (
|
}) => (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
{children}
|
{(!isLoading) && children}
|
||||||
|
{isLoading && (type === 'loader-progress' || type === 'loader-info') && (
|
||||||
|
<Loading>
|
||||||
|
<Row>
|
||||||
|
{type === 'loader-progress' && <Loader size={30} />}
|
||||||
|
<Text>{title || 'Initializing accounts'}</Text>
|
||||||
|
</Row>
|
||||||
|
{message && <Message>{message}</Message>}
|
||||||
|
</Loading>
|
||||||
|
)}
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
|
|
||||||
Content.propTypes = {
|
Content.propTypes = {
|
||||||
children: PropTypes.element,
|
children: PropTypes.element,
|
||||||
|
isLoading: PropTypes.bool,
|
||||||
|
title: PropTypes.string,
|
||||||
|
message: PropTypes.string,
|
||||||
|
type: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Content;
|
export default Content;
|
||||||
|
@ -93,9 +93,10 @@ const AccountReceive = (props: Props) => {
|
|||||||
account,
|
account,
|
||||||
discovery,
|
discovery,
|
||||||
shouldRender,
|
shouldRender,
|
||||||
|
notification,
|
||||||
} = props.selectedAccount;
|
} = props.selectedAccount;
|
||||||
|
const { type, title, message } = notification;
|
||||||
if (!device || !account || !discovery || !shouldRender) return null;
|
if (!device || !account || !discovery || !shouldRender) return <Content type={type} title={title} message={message} isLoading />;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
addressVerified,
|
addressVerified,
|
||||||
|
@ -185,6 +185,7 @@ const AccountSend = (props: Props) => {
|
|||||||
discovery,
|
discovery,
|
||||||
tokens,
|
tokens,
|
||||||
shouldRender,
|
shouldRender,
|
||||||
|
notification,
|
||||||
} = props.selectedAccount;
|
} = props.selectedAccount;
|
||||||
const {
|
const {
|
||||||
address,
|
address,
|
||||||
@ -213,8 +214,8 @@ const AccountSend = (props: Props) => {
|
|||||||
updateFeeLevels,
|
updateFeeLevels,
|
||||||
onSend,
|
onSend,
|
||||||
} = props.sendFormActions;
|
} = props.sendFormActions;
|
||||||
|
const { type, title, message } = notification;
|
||||||
if (!device || !account || !discovery || !network || !shouldRender) return null;
|
if (!device || !account || !discovery || !network || !shouldRender) return <Content type={type} title={title} message={message} isLoading />;
|
||||||
|
|
||||||
const isCurrentCurrencyToken = networkSymbol !== currency;
|
const isCurrentCurrencyToken = networkSymbol !== currency;
|
||||||
|
|
||||||
|
@ -75,11 +75,12 @@ const AccountSummary = (props: Props) => {
|
|||||||
network,
|
network,
|
||||||
tokens,
|
tokens,
|
||||||
pending,
|
pending,
|
||||||
|
notification,
|
||||||
shouldRender,
|
shouldRender,
|
||||||
} = props.selectedAccount;
|
} = props.selectedAccount;
|
||||||
|
|
||||||
// flow
|
const { type, title, message } = notification;
|
||||||
if (!device || !account || !network || !shouldRender) return null;
|
if (!device || !account || !network || !shouldRender) return <Content type={type} title={title} message={message} isLoading />;
|
||||||
|
|
||||||
const explorerLink: string = `${network.explorer.address}${account.address}`;
|
const explorerLink: string = `${network.explorer.address}${account.address}`;
|
||||||
const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, network.symbol);
|
const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, network.symbol);
|
||||||
|
Loading…
Reference in New Issue
Block a user