import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { connect } from 'react-redux'; import * as actions from '../../../store/actions'; import isMobileView from '../../../helpers/utils/is-mobile-view'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; // Modal Components import AddNetworkModal from '../../../pages/onboarding-flow/add-network-modal'; import AccountDetailsModal from './account-details-modal'; import ExportPrivateKeyModal from './export-private-key-modal'; import HideTokenConfirmationModal from './hide-token-confirmation-modal'; import QRScanner from './qr-scanner'; import ConfirmRemoveAccount from './confirm-remove-account'; import ConfirmResetAccount from './confirm-reset-account'; import TransactionConfirmed from './transaction-confirmed'; import CancelTransaction from './cancel-transaction'; import FadeModal from './fade-modal'; import MetaMetricsOptInModal from './metametrics-opt-in-modal'; import RejectTransactions from './reject-transactions'; import ConfirmDeleteNetwork from './confirm-delete-network'; import EditApprovalPermission from './edit-approval-permission'; import NewAccountModal from './new-account-modal'; import CustomizeNonceModal from './customize-nonce'; import ConvertTokenToNftModal from './convert-token-to-nft-modal/convert-token-to-nft-modal'; const modalContainerBaseStyle = { transform: 'translate3d(-50%, 0, 0px)', border: '1px solid var(--color-border-default)', borderRadius: '8px', backgroundColor: 'var(--color-background-default)', boxShadow: 'var(--shadow-size-sm) var(--color-shadow-default)', }; const modalContainerLaptopStyle = { ...modalContainerBaseStyle, width: '344px', top: '15%', }; const modalContainerMobileStyle = { ...modalContainerBaseStyle, width: '309px', top: '12.5%', }; const accountModalStyle = { mobileModalStyle: { width: '95%', // top: isPopupOrNotification() === 'popup' ? '52vh' : '36.5vh', boxShadow: 'var(--shadow-size-xs) var(--color-shadow-default)', borderRadius: '4px', top: '10%', transform: 'none', left: '0', right: '0', margin: '0 auto', }, laptopModalStyle: { width: '335px', // top: 'calc(33% + 45px)', boxShadow: 'var(--shadow-size-xs) var(--color-shadow-default)', borderRadius: '4px', top: '10%', transform: 'none', left: '0', right: '0', margin: '0 auto', }, contentStyle: { borderRadius: '4px', }, }; const MODALS = { ONBOARDING_ADD_NETWORK: { contents: , ...accountModalStyle, }, NEW_ACCOUNT: { contents: , mobileModalStyle: { width: '95%', top: '10%', boxShadow: 'var(--shadow-size-xs) var(--color-shadow-default)', transform: 'none', left: '0', right: '0', margin: '0 auto', borderRadius: '10px', }, laptopModalStyle: { width: '375px', top: '10%', boxShadow: 'var(--shadow-size-xs) var(--color-shadow-default)', transform: 'none', left: '0', right: '0', margin: '0 auto', borderRadius: '10px', }, contentStyle: { borderRadius: '10px', }, }, ACCOUNT_DETAILS: { contents: , ...accountModalStyle, }, EXPORT_PRIVATE_KEY: { contents: , ...accountModalStyle, }, HIDE_TOKEN_CONFIRMATION: { contents: , mobileModalStyle: { width: '95%', top: getEnvironmentType() === ENVIRONMENT_TYPE_POPUP ? '52vh' : '36.5vh', }, laptopModalStyle: { width: getEnvironmentType() === ENVIRONMENT_TYPE_POPUP ? '357px' : '449px', top: 'calc(33% + 45px)', paddingLeft: getEnvironmentType() === ENVIRONMENT_TYPE_POPUP ? '16px' : null, paddingRight: getEnvironmentType() === ENVIRONMENT_TYPE_POPUP ? '16px' : null, }, }, METAMETRICS_OPT_IN_MODAL: { contents: , mobileModalStyle: { ...modalContainerMobileStyle, width: '100%', height: '100%', top: '0px', }, laptopModalStyle: { ...modalContainerLaptopStyle, top: '10%', }, contentStyle: { borderRadius: '8px', }, }, CONFIRM_RESET_ACCOUNT: { contents: , mobileModalStyle: { ...modalContainerMobileStyle, }, laptopModalStyle: { ...modalContainerLaptopStyle, }, contentStyle: { borderRadius: '8px', }, }, CONFIRM_REMOVE_ACCOUNT: { contents: , mobileModalStyle: { ...modalContainerMobileStyle, }, laptopModalStyle: { ...modalContainerLaptopStyle, }, contentStyle: { borderRadius: '8px', }, }, CONVERT_TOKEN_TO_NFT: { contents: , mobileModalStyle: { ...modalContainerMobileStyle, }, laptopModalStyle: { ...modalContainerLaptopStyle, }, contentStyle: { borderRadius: '8px', }, }, CONFIRM_DELETE_NETWORK: { contents: , mobileModalStyle: { ...modalContainerMobileStyle, }, laptopModalStyle: { ...modalContainerLaptopStyle, }, contentStyle: { borderRadius: '8px', }, }, EDIT_APPROVAL_PERMISSION: { contents: , mobileModalStyle: { width: '95vw', height: '100vh', top: '50px', transform: 'none', left: '0', right: '0', margin: '0 auto', }, laptopModalStyle: { width: 'auto', height: '0px', top: '80px', left: '0px', transform: 'none', margin: '0 auto', position: 'relative', }, contentStyle: { borderRadius: '8px', }, }, TRANSACTION_CONFIRMED: { disableBackdropClick: true, contents: , mobileModalStyle: { ...modalContainerMobileStyle, }, laptopModalStyle: { ...modalContainerLaptopStyle, }, contentStyle: { borderRadius: '8px', }, }, QR_SCANNER: { contents: , mobileModalStyle: { ...modalContainerMobileStyle, }, laptopModalStyle: { ...modalContainerLaptopStyle, }, contentStyle: { borderRadius: '8px', }, }, CANCEL_TRANSACTION: { contents: , mobileModalStyle: { ...modalContainerMobileStyle, }, laptopModalStyle: { ...modalContainerLaptopStyle, }, contentStyle: { borderRadius: '8px', }, }, REJECT_TRANSACTIONS: { contents: , mobileModalStyle: { ...modalContainerMobileStyle, }, laptopModalStyle: { ...modalContainerLaptopStyle, }, contentStyle: { borderRadius: '8px', }, }, CUSTOMIZE_NONCE: { contents: , mobileModalStyle: { ...modalContainerMobileStyle, }, laptopModalStyle: { ...modalContainerLaptopStyle, }, contentStyle: { borderRadius: '8px', }, }, DEFAULT: { contents: [], mobileModalStyle: {}, laptopModalStyle: {}, }, }; const BACKDROPSTYLE = { backgroundColor: 'var(--color-overlay-default)', }; function mapStateToProps(state) { return { active: state.appState.modal.open, modalState: state.appState.modal.modalState, }; } function mapDispatchToProps(dispatch) { return { hideModal: (customOnHideOpts) => { dispatch(actions.hideModal()); if (customOnHideOpts && customOnHideOpts.action) { dispatch(customOnHideOpts.action(...customOnHideOpts.args)); } }, hideWarning: () => { dispatch(actions.hideWarning()); }, }; } class Modal extends Component { static propTypes = { active: PropTypes.bool.isRequired, hideModal: PropTypes.func.isRequired, hideWarning: PropTypes.func.isRequired, modalState: PropTypes.object.isRequired, }; hide() { this.modalRef.hide(); } show() { this.modalRef.show(); } UNSAFE_componentWillReceiveProps(nextProps, _) { if (nextProps.active) { this.show(); } else if (this.props.active) { this.hide(); } } render() { const modal = MODALS[this.props.modalState.name || 'DEFAULT']; const { contents: children, disableBackdropClick = false } = modal; const modalStyle = modal[isMobileView() ? 'mobileModalStyle' : 'laptopModalStyle']; const contentStyle = modal.contentStyle || {}; return ( { if (modal.onHide) { modal.onHide({ hideWarning: this.props.hideWarning, }); } this.props.hideModal(modal.customOnHideOpts); }} ref={(ref) => { this.modalRef = ref; }} modalStyle={modalStyle} contentStyle={contentStyle} backdropStyle={BACKDROPSTYLE} closeOnClick={!disableBackdropClick} > {children} ); } } export default connect(mapStateToProps, mapDispatchToProps)(Modal);