123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- import React from 'react';
- import PropTypes from 'prop-types';
- import { getScrollbarWidth } from 'mastodon/utils/scrollbar';
- import Base from 'mastodon/components/modal_root';
- import BundleContainer from '../containers/bundle_container';
- import BundleModalError from './bundle_modal_error';
- import ModalLoading from './modal_loading';
- import ActionsModal from './actions_modal';
- import MediaModal from './media_modal';
- import VideoModal from './video_modal';
- import BoostModal from './boost_modal';
- import AudioModal from './audio_modal';
- import ConfirmationModal from './confirmation_modal';
- import FocalPointModal from './focal_point_modal';
- import {
- MuteModal,
- BlockModal,
- ReportModal,
- EmbedModal,
- ListEditor,
- ListAdder,
- CompareHistoryModal,
- FilterModal,
- InteractionModal,
- SubscribedLanguagesModal,
- ClosedRegistrationsModal,
- } from 'mastodon/features/ui/util/async-components';
- import { Helmet } from 'react-helmet';
- const MODAL_COMPONENTS = {
- 'MEDIA': () => Promise.resolve({ default: MediaModal }),
- 'VIDEO': () => Promise.resolve({ default: VideoModal }),
- 'AUDIO': () => Promise.resolve({ default: AudioModal }),
- 'BOOST': () => Promise.resolve({ default: BoostModal }),
- 'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }),
- 'MUTE': MuteModal,
- 'BLOCK': BlockModal,
- 'REPORT': ReportModal,
- 'ACTIONS': () => Promise.resolve({ default: ActionsModal }),
- 'EMBED': EmbedModal,
- 'LIST_EDITOR': ListEditor,
- 'FOCAL_POINT': () => Promise.resolve({ default: FocalPointModal }),
- 'LIST_ADDER': ListAdder,
- 'COMPARE_HISTORY': CompareHistoryModal,
- 'FILTER': FilterModal,
- 'SUBSCRIBED_LANGUAGES': SubscribedLanguagesModal,
- 'INTERACTION': InteractionModal,
- 'CLOSED_REGISTRATIONS': ClosedRegistrationsModal,
- };
- export default class ModalRoot extends React.PureComponent {
- static propTypes = {
- type: PropTypes.string,
- props: PropTypes.object,
- onClose: PropTypes.func.isRequired,
- ignoreFocus: PropTypes.bool,
- };
- state = {
- backgroundColor: null,
- };
- getSnapshotBeforeUpdate () {
- return { visible: !!this.props.type };
- }
- componentDidUpdate (prevProps, prevState, { visible }) {
- if (visible) {
- document.body.classList.add('with-modals--active');
- document.documentElement.style.marginRight = `${getScrollbarWidth()}px`;
- } else {
- document.body.classList.remove('with-modals--active');
- document.documentElement.style.marginRight = 0;
- }
- }
- setBackgroundColor = color => {
- this.setState({ backgroundColor: color });
- }
- renderLoading = modalId => () => {
- return ['MEDIA', 'VIDEO', 'BOOST', 'CONFIRM', 'ACTIONS'].indexOf(modalId) === -1 ? <ModalLoading /> : null;
- }
- renderError = (props) => {
- const { onClose } = this.props;
- return <BundleModalError {...props} onClose={onClose} />;
- }
- handleClose = (ignoreFocus = false) => {
- const { onClose } = this.props;
- let message = null;
- try {
- message = this._modal?.getWrappedInstance?.().getCloseConfirmationMessage?.();
- } catch (_) {
- // injectIntl defines `getWrappedInstance` but errors out if `withRef`
- // isn't set.
- // This would be much smoother with react-intl 3+ and `forwardRef`.
- }
- onClose(message, ignoreFocus);
- }
- setModalRef = (c) => {
- this._modal = c;
- }
- render () {
- const { type, props, ignoreFocus } = this.props;
- const { backgroundColor } = this.state;
- const visible = !!type;
- return (
- <Base backgroundColor={backgroundColor} onClose={this.handleClose} ignoreFocus={ignoreFocus}>
- {visible && (
- <>
- <BundleContainer fetchComponent={MODAL_COMPONENTS[type]} loading={this.renderLoading(type)} error={this.renderError} renderDelay={200}>
- {(SpecificComponent) => <SpecificComponent {...props} onChangeBackgroundColor={this.setBackgroundColor} onClose={this.handleClose} ref={this.setModalRef} />}
- </BundleContainer>
- <Helmet>
- <meta name='robots' content='noindex' />
- </Helmet>
- </>
- )}
- </Base>
- );
- }
- }
|