diff --git a/app/javascript/mastodon/containers/media_container.jsx b/app/javascript/mastodon/containers/media_container.jsx index a4f79fcf94c..08e106e5d89 100644 --- a/app/javascript/mastodon/containers/media_container.jsx +++ b/app/javascript/mastodon/containers/media_container.jsx @@ -10,7 +10,7 @@ import ModalRoot from 'mastodon/components/modal_root'; import { Poll } from 'mastodon/components/poll'; import { Audio } from 'mastodon/features/audio'; import Card from 'mastodon/features/status/components/card'; -import MediaModal from 'mastodon/features/ui/components/media_modal'; +import { MediaModal } from 'mastodon/features/ui/components/media_modal'; import { Video } from 'mastodon/features/video'; import { IntlProvider } from 'mastodon/locales'; import { createPollFromServerJSON } from 'mastodon/models/poll'; diff --git a/app/javascript/mastodon/features/ui/components/media_modal.jsx b/app/javascript/mastodon/features/ui/components/media_modal.jsx deleted file mode 100644 index 2ce13bf1d39..00000000000 --- a/app/javascript/mastodon/features/ui/components/media_modal.jsx +++ /dev/null @@ -1,296 +0,0 @@ -import PropTypes from 'prop-types'; - -import { defineMessages, injectIntl } from 'react-intl'; - -import classNames from 'classnames'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -import ReactSwipeableViews from 'react-swipeable-views'; - -import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react'; -import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; -import CloseIcon from '@/material-icons/400-24px/close.svg?react'; -import FitScreenIcon from '@/material-icons/400-24px/fit_screen.svg?react'; -import ActualSizeIcon from '@/svg-icons/actual_size.svg?react'; -import { getAverageFromBlurhash } from 'mastodon/blurhash'; -import { GIFV } from 'mastodon/components/gifv'; -import { Icon } from 'mastodon/components/icon'; -import { IconButton } from 'mastodon/components/icon_button'; -import { Footer } from 'mastodon/features/picture_in_picture/components/footer'; -import { Video } from 'mastodon/features/video'; -import { disableSwiping } from 'mastodon/initial_state'; - -import { ZoomableImage } from './zoomable_image'; - -const messages = defineMessages({ - close: { id: 'lightbox.close', defaultMessage: 'Close' }, - previous: { id: 'lightbox.previous', defaultMessage: 'Previous' }, - next: { id: 'lightbox.next', defaultMessage: 'Next' }, - zoomIn: { id: 'lightbox.zoom_in', defaultMessage: 'Zoom to actual size' }, - zoomOut: { id: 'lightbox.zoom_out', defaultMessage: 'Zoom to fit' }, -}); - -class MediaModal extends ImmutablePureComponent { - - static propTypes = { - media: ImmutablePropTypes.list.isRequired, - statusId: PropTypes.string, - lang: PropTypes.string, - index: PropTypes.number.isRequired, - onClose: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - onChangeBackgroundColor: PropTypes.func.isRequired, - currentTime: PropTypes.number, - autoPlay: PropTypes.bool, - volume: PropTypes.number, - }; - - state = { - index: null, - navigationHidden: false, - zoomedIn: false, - }; - - handleZoomClick = () => { - this.setState(prevState => ({ - zoomedIn: !prevState.zoomedIn, - })); - }; - - handleZoomChange = (zoomedIn) => { - this.setState({ - zoomedIn, - }); - }; - - handleSwipe = (index) => { - this.setState({ - index: index % this.props.media.size, - zoomedIn: false, - }); - }; - - handleTransitionEnd = () => { - this.setState({ - zoomedIn: false, - }); - }; - - handleNextClick = () => { - this.setState({ - index: (this.getIndex() + 1) % this.props.media.size, - zoomedIn: false, - }); - }; - - handlePrevClick = () => { - this.setState({ - index: (this.props.media.size + this.getIndex() - 1) % this.props.media.size, - zoomedIn: false, - }); - }; - - handleChangeIndex = (e) => { - const index = Number(e.currentTarget.getAttribute('data-index')); - - this.setState({ - index: index % this.props.media.size, - zoomedIn: false, - }); - }; - - handleKeyDown = (e) => { - switch(e.key) { - case 'ArrowLeft': - this.handlePrevClick(); - e.preventDefault(); - e.stopPropagation(); - break; - case 'ArrowRight': - this.handleNextClick(); - e.preventDefault(); - e.stopPropagation(); - break; - } - }; - - componentDidMount () { - window.addEventListener('keydown', this.handleKeyDown, false); - - this._sendBackgroundColor(); - } - - componentDidUpdate (prevProps, prevState) { - if (prevState.index !== this.state.index) { - this._sendBackgroundColor(); - } - } - - _sendBackgroundColor () { - const { media, onChangeBackgroundColor } = this.props; - const index = this.getIndex(); - const blurhash = media.getIn([index, 'blurhash']); - - if (blurhash) { - const backgroundColor = getAverageFromBlurhash(blurhash); - onChangeBackgroundColor(backgroundColor); - } - } - - componentWillUnmount () { - window.removeEventListener('keydown', this.handleKeyDown); - - this.props.onChangeBackgroundColor(null); - } - - getIndex () { - return this.state.index !== null ? this.state.index : this.props.index; - } - - handleToggleNavigation = () => { - this.setState(prevState => ({ - navigationHidden: !prevState.navigationHidden, - })); - }; - - setRef = c => { - this.setState({ - viewportWidth: c?.clientWidth, - viewportHeight: c?.clientHeight, - }); - }; - - render () { - const { media, statusId, lang, intl, onClose } = this.props; - const { navigationHidden, zoomedIn, viewportWidth, viewportHeight } = this.state; - - const index = this.getIndex(); - - const leftNav = media.size > 1 && ; - const rightNav = media.size > 1 && ; - - const content = media.map((image, idx) => { - const width = image.getIn(['meta', 'original', 'width']) || null; - const height = image.getIn(['meta', 'original', 'height']) || null; - const description = image.getIn(['translation', 'description']) || image.get('description'); - - if (image.get('type') === 'image') { - return ( - - ); - } else if (image.get('type') === 'video') { - const { currentTime, autoPlay, volume } = this.props; - - return ( -