1
0
mirror of https://github.com/trezor/trezor-wallet synced 2025-01-07 06:40:54 +00:00

flowtype for Notification components

This commit is contained in:
Szymon Lesisz 2018-10-10 09:31:26 +02:00
parent f5cdbde796
commit 99da71c25d
13 changed files with 59 additions and 55 deletions

View File

@ -1,10 +1,23 @@
import React from 'react'; /* @flow */
import * as React from 'react';
import styled, { css } from 'styled-components'; import styled, { css } from 'styled-components';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Icon from 'components/Icon'; import Icon from 'components/Icon';
import colors from 'config/colors'; import colors from 'config/colors';
import { TRANSITION } from 'config/variables'; import { TRANSITION } from 'config/variables';
type Props = {
type: string;
icon?: {
type: Array<string>;
color: string;
size: number;
};
onClick: () => void;
children: React.Node;
};
const Wrapper = styled.button` const Wrapper = styled.button`
padding: 12px 58px; padding: 12px 58px;
border-radius: 3px; border-radius: 3px;
@ -62,10 +75,9 @@ const IconWrapper = styled.span`
`; `;
const NotificationButton = ({ const NotificationButton = ({
children, className, icon, onClick = () => { }, type = null, type, icon, onClick, children,
}) => ( }: Props) => (
<Wrapper <Wrapper
className={className}
icon={icon} icon={icon}
onClick={onClick} onClick={onClick}
type={type} type={type}
@ -84,15 +96,14 @@ const NotificationButton = ({
); );
NotificationButton.propTypes = { NotificationButton.propTypes = {
children: PropTypes.node.isRequired,
type: PropTypes.string.isRequired, type: PropTypes.string.isRequired,
className: PropTypes.string,
onClick: PropTypes.func,
icon: PropTypes.shape({ icon: PropTypes.shape({
type: PropTypes.arrayOf(PropTypes.string).isRequired, type: PropTypes.arrayOf(PropTypes.string).isRequired,
color: PropTypes.string, color: PropTypes.string,
size: PropTypes.number, size: PropTypes.number,
}), }),
onClick: PropTypes.func,
children: PropTypes.node.isRequired,
}; };
export default NotificationButton; export default NotificationButton;

View File

@ -1,9 +1,8 @@
/* @flow */ /* @flow */
import React from 'react'; import * as React from 'react';
import PropTypes from 'prop-types';
import media from 'styled-media-query'; import media from 'styled-media-query';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import styled, { css } from 'styled-components'; import styled, { css } from 'styled-components';
import colors from 'config/colors'; import colors from 'config/colors';
import { getColor, getIcon } from 'utils/notification'; import { getColor, getIcon } from 'utils/notification';
@ -13,16 +12,11 @@ import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import * as NotificationActions from 'actions/NotificationActions'; import * as NotificationActions from 'actions/NotificationActions';
import Loader from 'components/Loader'; import Loader from 'components/Loader';
import type { Action, State } from 'flowtype';
import NotificationButton from './components/NotificationButton'; import NotificationButton from './components/NotificationButton';
type Props = { type Props = {
key?: number, key?: React.Key,
notifications: $ElementType<State, 'notifications'>,
close: (notif?: any) => Action,
};
type NProps = {
type: string, type: string,
cancelable?: boolean; cancelable?: boolean;
title: string; title: string;
@ -128,12 +122,11 @@ const ActionContent = styled.div`
`} `}
`; `;
export const Notification = (props: NProps): React$Element<string> => { const Notification = (props: Props): React$Element<string> => {
const close: Function = typeof props.close === 'function' ? props.close : () => {}; // TODO: add default close action const close: Function = typeof props.close === 'function' ? props.close : () => {}; // TODO: add default close action
return ( return (
<Wrapper type={props.type}> <Wrapper key={props.key} type={props.type}>
{props.loading && <Loader size={50} /> } {props.loading && <Loader size={50} /> }
{props.cancelable && ( {props.cancelable && (
<CloseClick onClick={() => close()}> <CloseClick onClick={() => close()}>
@ -167,7 +160,6 @@ export const Notification = (props: NProps): React$Element<string> => {
<NotificationButton <NotificationButton
key={action.label} key={action.label}
type={props.type} type={props.type}
text={action.label}
onClick={() => { close(); action.callback(); }} onClick={() => { close(); action.callback(); }}
>{action.label} >{action.label}
</NotificationButton> </NotificationButton>
@ -179,26 +171,15 @@ export const Notification = (props: NProps): React$Element<string> => {
); );
}; };
export const NotificationGroup = (props: Props) => { Notification.propTypes = {
const { notifications, close } = props; key: PropTypes.string,
return notifications.map(n => ( type: PropTypes.string.isRequired,
<Notification cancelable: PropTypes.bool,
key={n.title} title: PropTypes.string.isRequired,
type={n.type} message: PropTypes.string,
title={n.title} actions: PropTypes.arrayOf(PropTypes.func),
message={n.message} close: PropTypes.func,
cancelable={n.cancelable} loading: PropTypes.bool,
actions={n.actions}
close={close}
/>
));
}; };
export default connect( export default Notification;
state => ({
notifications: state.notifications,
}),
dispatch => ({
close: bindActionCreators(NotificationActions.close, dispatch),
}),
)(NotificationGroup);

View File

@ -1,11 +1,11 @@
/* @flow */ /* @flow */
import * as React from 'react'; import * as React from 'react';
import { Notification } from 'components/Notification'; import Notification from 'components/Notification';
import type { Props } from '../../index'; import type { Props } from '../../index';
export default (props: Props) => { export default (props: Props) => {
const { online } = props.wallet; const { online } = props.wallet;
if (online) return null; if (online) return null;
return (<Notification type="error" title="Wallet is offline" />); return (<Notification key="wallet-offline" type="error" title="Wallet is offline" />);
}; };

View File

@ -1,6 +1,6 @@
/* @flow */ /* @flow */
import * as React from 'react'; import * as React from 'react';
import { Notification } from 'components/Notification'; import Notification from 'components/Notification';
import type { Props } from '../../index'; import type { Props } from '../../index';
@ -8,6 +8,7 @@ export default (props: Props) => {
if (props.connect.transport && props.connect.transport.outdated) { if (props.connect.transport && props.connect.transport.outdated) {
return ( return (
<Notification <Notification
key="update-bridge"
type="warning" type="warning"
title="New Trezor Bridge is available" title="New Trezor Bridge is available"
actions={ actions={

View File

@ -1,6 +1,6 @@
/* @flow */ /* @flow */
import * as React from 'react'; import * as React from 'react';
import { Notification } from 'components/Notification'; import Notification from 'components/Notification';
import type { Props } from '../../index'; import type { Props } from '../../index';
@ -10,6 +10,7 @@ export default (props: Props) => {
if (!outdated) return null; if (!outdated) return null;
return ( return (
<Notification <Notification
key="update-firmware"
type="warning" type="warning"
title="Firmware update" title="Firmware update"
actions={ actions={

View File

@ -1,6 +1,6 @@
/* @flow */ /* @flow */
import * as React from 'react'; import * as React from 'react';
import { Notification } from 'components/Notification'; import Notification from 'components/Notification';
import type { Props } from '../../index'; import type { Props } from '../../index';

View File

@ -4,7 +4,7 @@ import styled from 'styled-components';
import Icon from 'components/Icon'; import Icon from 'components/Icon';
import ICONS from 'config/icons'; import ICONS from 'config/icons';
import colors from 'config/colors'; import colors from 'config/colors';
import { Notification } from 'components/Notification'; import Notification from 'components/Notification';
import { getIcon, getColor } from 'utils/notification'; import { getIcon, getColor } from 'utils/notification';
const Wrapper = styled.div``; const Wrapper = styled.div``;

View File

@ -1,5 +1,7 @@
/* @flow */ /* @flow */
import { Notification } from 'components/Notification';
import * as React from 'react';
import Notification from 'components/Notification';
import type { Props } from '../../index'; import type { Props } from '../../index';
@ -8,9 +10,14 @@ export default (props: Props) => {
if (!location) return null; if (!location) return null;
const notifications: Array<Notification> = []; const notifications: Array<Notification> = [];
// Example:
// if (location.state.device) { // if (location.state.device) {
// notifications.push(<Notification key="example" type="info" title="Static example" />); // notifications.push(<Notification key="example" type="info" title="Static example" />);
// } // }
return notifications; return (
<React.Fragment>
{notifications}
</React.Fragment>
);
}; };

View File

@ -13,6 +13,7 @@ export type CallbackAction = {
} }
export type NotificationEntry = { export type NotificationEntry = {
+key: string; // React.Key
+id: ?string; +id: ?string;
+devicePath: ?string; +devicePath: ?string;
+type: string; +type: string;
@ -38,6 +39,7 @@ const initialState: State = [
const addNotification = (state: State, payload: any): State => { const addNotification = (state: State, payload: any): State => {
const newState: State = state.filter(e => !e.cancelable); const newState: State = state.filter(e => !e.cancelable);
newState.push({ newState.push({
key: new Date().getTime().toString(),
id: payload.id, id: payload.id,
devicePath: payload.devicePath, devicePath: payload.devicePath,
type: payload.type, type: payload.type,

View File

@ -2,7 +2,7 @@
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { Notification } from 'components/Notification'; import Notification from 'components/Notification';
const Wrapper = styled.div` const Wrapper = styled.div`
min-width: 720px; min-width: 720px;

View File

@ -7,7 +7,8 @@ import Footer from 'components/Footer';
import Log from 'components/Log'; import Log from 'components/Log';
import Link from 'components/Link'; import Link from 'components/Link';
import Loader from 'components/Loader'; import Loader from 'components/Loader';
import Notifications, { Notification } from 'components/Notification'; import Notification from 'components/Notification';
import ContextNotifications from 'components/notifications/Context';
import colors from 'config/colors'; import colors from 'config/colors';
import P from 'components/Paragraph'; import P from 'components/Paragraph';
import { H2 } from 'components/Heading'; import { H2 } from 'components/Heading';
@ -98,7 +99,7 @@ export default (props: Props) => {
type="error" type="error"
/> />
)} )}
<Notifications /> <ContextNotifications />
{shouldShowInitializationError && <InitializationError error={connectError} />} {shouldShowInitializationError && <InitializationError error={connectError} />}
<Log /> <Log />
<LandingContent> <LandingContent>

View File

@ -4,7 +4,7 @@ import styled from 'styled-components';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import colors from 'config/colors'; import colors from 'config/colors';
import { Notification } from 'components/Notification'; import Notification from 'components/Notification';
import * as TrezorConnectActions from 'actions/TrezorConnectActions'; import * as TrezorConnectActions from 'actions/TrezorConnectActions';
import type { State, Dispatch } from 'flowtype'; import type { State, Dispatch } from 'flowtype';

View File

@ -2,7 +2,7 @@
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { Notification } from 'components/Notification'; import Notification from 'components/Notification';
const Wrapper = styled.div``; const Wrapper = styled.div``;