Logout Prompt Modal on Navigation from Send (#275)
* Add disclaimer modal to footer * Remove duplicate code & unnecessary styles * Fix formatting noise * remove un-used css style * Fix tslint error & add media query for modals * Nest Media Query * Add NavigationPrompt component * Fix types * Fix types * Extend History Types * break out logic into setupUnblock method
This commit is contained in:
parent
2e472e5c5a
commit
4858f96520
|
@ -99,3 +99,10 @@ export function broadCastTxFailed(
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
export type TResetWallet = typeof resetWallet;
|
||||
export function resetWallet() {
|
||||
return {
|
||||
type: constants.WALLET_RESET
|
||||
};
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ export interface SetWalletAction {
|
|||
payload: IWallet;
|
||||
}
|
||||
|
||||
/*** Reset Wallet ***/
|
||||
export interface ResetWalletAction {
|
||||
type: 'WALLET_RESET';
|
||||
}
|
||||
|
||||
/*** Set Balance ***/
|
||||
export interface SetBalanceAction {
|
||||
type: 'WALLET_SET_BALANCE';
|
||||
|
@ -84,6 +89,7 @@ export interface BroadcastTxFailedAction {
|
|||
export type WalletAction =
|
||||
| UnlockPrivateKeyAction
|
||||
| SetWalletAction
|
||||
| ResetWalletAction
|
||||
| SetBalanceAction
|
||||
| SetTokenBalancesAction
|
||||
| BroadcastTxRequestedAction
|
||||
|
|
|
@ -7,3 +7,4 @@ export const WALLET_SET_TOKEN_BALANCES = 'WALLET_SET_TOKEN_BALANCES';
|
|||
export const WALLET_BROADCAST_TX_REQUESTED = 'WALLET_BROADCAST_TX_REQUESTED';
|
||||
export const WALLET_BROADCAST_TX_FAILED = 'WALLET_BROADCAST_TX_FAILED';
|
||||
export const WALLET_BROADCAST_TX_SUCCEEDED = 'WALLET_BROADCAST_TX_SUCCEEDED';
|
||||
export const WALLET_RESET = 'WALLET_RESET';
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
import React from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import Modal, { IButton } from 'components/ui/Modal';
|
||||
import { Location, History as H } from 'history';
|
||||
|
||||
type UnregisterCallback = () => void;
|
||||
type BooleanCallback = (arg?: any) => boolean;
|
||||
interface History extends H {
|
||||
block(prompt?: boolean | BooleanCallback): UnregisterCallback;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
when: boolean;
|
||||
onConfirm?: any;
|
||||
onCancel?: any;
|
||||
}
|
||||
|
||||
interface InjectedProps extends Props {
|
||||
location: Location;
|
||||
history: History;
|
||||
}
|
||||
|
||||
interface State {
|
||||
nextLocation: Location | null;
|
||||
openModal: boolean;
|
||||
}
|
||||
|
||||
class NavigationPrompt extends React.Component<Props, State> {
|
||||
public unblock;
|
||||
get injected() {
|
||||
return this.props as InjectedProps;
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
nextLocation: null,
|
||||
openModal: false
|
||||
};
|
||||
}
|
||||
|
||||
public setupUnblock() {
|
||||
this.unblock = this.injected.history.block(nextLocation => {
|
||||
if (
|
||||
this.props.when &&
|
||||
nextLocation.pathname !== this.injected.location.pathname
|
||||
) {
|
||||
this.setState({
|
||||
openModal: true,
|
||||
nextLocation
|
||||
});
|
||||
}
|
||||
return !this.props.when;
|
||||
});
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
this.setupUnblock();
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.unblock();
|
||||
}
|
||||
|
||||
public onCancel = () => {
|
||||
if (this.props.onCancel) {
|
||||
this.props.onCancel();
|
||||
}
|
||||
this.setState({ nextLocation: null, openModal: false });
|
||||
};
|
||||
|
||||
public onConfirm = () => {
|
||||
if (this.props.onConfirm) {
|
||||
this.props.onConfirm();
|
||||
}
|
||||
// Lock Wallet
|
||||
this.navigateToNextLocation();
|
||||
};
|
||||
|
||||
public navigateToNextLocation() {
|
||||
this.unblock();
|
||||
if (this.state.nextLocation) {
|
||||
this.injected.history.push(this.state.nextLocation.pathname);
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const buttons: IButton[] = [
|
||||
{ text: 'Log Out', type: 'primary', onClick: this.onConfirm },
|
||||
{ text: 'Cancel', type: 'default', onClick: this.onCancel }
|
||||
];
|
||||
return (
|
||||
<Modal
|
||||
title="You are about to log out"
|
||||
isOpen={this.state.openModal}
|
||||
handleClose={this.onCancel}
|
||||
buttons={buttons}
|
||||
>
|
||||
<p>
|
||||
Leaving this page will log you out. Are you sure you want to continue?
|
||||
</p>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(NavigationPrompt);
|
|
@ -1,11 +1,17 @@
|
|||
import { showNotification, TShowNotification } from 'actions/notifications';
|
||||
import { broadcastTx, TBroadcastTx } from 'actions/wallet';
|
||||
import {
|
||||
broadcastTx,
|
||||
TBroadcastTx,
|
||||
resetWallet,
|
||||
TResetWallet
|
||||
} from 'actions/wallet';
|
||||
import Big from 'bignumber.js';
|
||||
import { BalanceSidebar } from 'components';
|
||||
// COMPONENTS
|
||||
import { UnlockHeader } from 'components/ui';
|
||||
import { donationAddressMap, NetworkConfig, NodeConfig } from 'config/data';
|
||||
import TabSection from 'containers/TabSection';
|
||||
import NavigationPrompt from './components/NavigationPrompt';
|
||||
// CONFIG
|
||||
import { TransactionWithoutGas } from 'libs/messages';
|
||||
import { RPCNode } from 'libs/nodes';
|
||||
|
@ -92,6 +98,7 @@ interface Props {
|
|||
transactions: BroadcastTransactionStatus[];
|
||||
showNotification: TShowNotification;
|
||||
broadcastTx: TBroadcastTx;
|
||||
resetWallet: TResetWallet;
|
||||
location: { search: string };
|
||||
}
|
||||
|
||||
|
@ -172,12 +179,14 @@ export class SendTransaction extends React.Component<Props, State> {
|
|||
transaction
|
||||
} = this.state;
|
||||
const customMessage = customMessages.find(m => m.to === to);
|
||||
|
||||
return (
|
||||
<TabSection>
|
||||
<section className="Tab-content">
|
||||
<UnlockHeader title={'NAV_SendEther'} />
|
||||
|
||||
<NavigationPrompt
|
||||
when={unlocked}
|
||||
onConfirm={this.props.resetWallet}
|
||||
/>
|
||||
<div className="row">
|
||||
{/* Send Form */}
|
||||
{unlocked && (
|
||||
|
@ -272,7 +281,6 @@ export class SendTransaction extends React.Component<Props, State> {
|
|||
</section>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{transaction &&
|
||||
showTxConfirm && (
|
||||
<ConfirmationModal
|
||||
|
@ -489,6 +497,8 @@ function mapStateToProps(state: AppState) {
|
|||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, { showNotification, broadcastTx })(
|
||||
SendTransaction
|
||||
);
|
||||
export default connect(mapStateToProps, {
|
||||
showNotification,
|
||||
broadcastTx,
|
||||
resetWallet
|
||||
})(SendTransaction);
|
||||
|
|
|
@ -109,6 +109,8 @@ export function wallet(
|
|||
switch (action.type) {
|
||||
case 'WALLET_SET':
|
||||
return setWallet(state, action);
|
||||
case 'WALLET_RESET':
|
||||
return INITIAL_STATE;
|
||||
case 'WALLET_SET_BALANCE':
|
||||
return setBalance(state, action);
|
||||
case 'WALLET_SET_TOKEN_BALANCES':
|
||||
|
|
Loading…
Reference in New Issue