diff --git a/app/javascript/gabsocial/components/avatar.js b/app/javascript/gabsocial/components/avatar.js index 8076aad7..46b20318 100644 --- a/app/javascript/gabsocial/components/avatar.js +++ b/app/javascript/gabsocial/components/avatar.js @@ -84,7 +84,11 @@ class Avatar extends ImmutablePureComponent { } render() { - const { account, size } = this.props + const { + account, + expandOnClick, + size, + } = this.props const { hovering, sameImg } = this.state const isPro = !!account ? account.get('is_pro') : false @@ -110,6 +114,7 @@ class Avatar extends ImmutablePureComponent { alt={alt} imageRef={this.setRef} className={classes.join(' ')} + expandOnClick={expandOnClick} {...options} /> ) @@ -130,6 +135,7 @@ Avatar.propTypes = { account: ImmutablePropTypes.map, noHover: PropTypes.bool, openUserInfoPopover: PropTypes.func.isRequired, + expandOnClick: PropTypes.bool, size: PropTypes.number, } diff --git a/app/javascript/gabsocial/components/image.js b/app/javascript/gabsocial/components/image.js index 77784eb9..554aecde 100644 --- a/app/javascript/gabsocial/components/image.js +++ b/app/javascript/gabsocial/components/image.js @@ -1,6 +1,11 @@ import React from 'react' import PropTypes from 'prop-types' -import { CX } from '../constants' +import { connect } from 'react-redux' +import { + CX, + MODAL_MEDIA, +} from '../constants' +import { openModal } from '../actions/modal' class Image extends React.PureComponent { @@ -12,6 +17,10 @@ class Image extends React.PureComponent { this.setState({ error: true }) } + handleOnClick = () => { + this.props.onOpenMediaModal() + } + render() { const { alt, @@ -21,6 +30,7 @@ class Image extends React.PureComponent { nullable, isLazy, imageRef, + expandOnClick, ...otherProps } = this.props const { error } = this.state @@ -37,9 +47,7 @@ class Image extends React.PureComponent { } if (!src) { - return ( -
- ) + return
} return ( @@ -50,6 +58,7 @@ class Image extends React.PureComponent { ref={imageRef} src={src} onError={this.handleOnError} + onClick={expandOnClick ? this.handleOnClick : undefined} loading={isLazy ? 'lazy' : undefined} /> ) @@ -57,6 +66,15 @@ class Image extends React.PureComponent { } +const mapDispatchToProps = (dispatch, { alt, src }) => ({ + onOpenMediaModal() { + dispatch(openModal(MODAL_MEDIA, { + alt, + src, + })) + }, +}); + Image.propTypes = { alt: PropTypes.string.isRequired, isLazy: PropTypes.string, @@ -73,6 +91,8 @@ Image.propTypes = { nullable: PropTypes.bool, lazy: PropTypes.bool, imageRef: PropTypes.func, + expandOnClick: PropTypes.bool, + onOpenMedia: PropTypes.func.isRequired, } Image.defaultProps = { @@ -80,4 +100,4 @@ Image.defaultProps = { fit: 'cover', } -export default Image \ No newline at end of file +export default connect(null, mapDispatchToProps)(Image) \ No newline at end of file diff --git a/app/javascript/gabsocial/components/modal/media_modal.js b/app/javascript/gabsocial/components/modal/media_modal.js index d6635ef8..791e0983 100644 --- a/app/javascript/gabsocial/components/modal/media_modal.js +++ b/app/javascript/gabsocial/components/modal/media_modal.js @@ -25,22 +25,32 @@ class MediaModal extends ImmutablePureComponent { } handleSwipe = (index) => { + if (!this.props.media) return + this.setState({ index: index % this.props.media.size }) } handleNextClick = () => { + if (!this.props.media) return + this.setState({ index: (this.getIndex() + 1) % this.props.media.size }) } handlePrevClick = () => { + if (!this.props.media) return + this.setState({ index: (this.props.media.size + this.getIndex() - 1) % this.props.media.size }) } handleChangeIndex = (i) => { + if (!this.props.media) return + this.setState({ index: i % this.props.media.size }) } handleKeyDown = (e) => { + if (!this.props.media) return + switch (e.key) { case 'ArrowLeft': this.handlePrevClick() @@ -101,6 +111,8 @@ class MediaModal extends ImmutablePureComponent { render() { const { media, + src, + alt, status, intl, onClose, @@ -109,56 +121,63 @@ class MediaModal extends ImmutablePureComponent { const index = this.getIndex() - const content = media.map((image) => { - const width = image.getIn(['meta', 'original', 'width']) || null - const height = image.getIn(['meta', 'original', 'height']) || null + const content = !media ? + : + media.map((image) => { + const width = image.getIn(['meta', 'original', 'width']) || null + const height = image.getIn(['meta', 'original', 'height']) || null - if (image.get('type') === 'image') { - return ( - - ) - } else if (image.get('type') === 'video') { - const { time } = this.props + if (image.get('type') === 'image') { + return ( + + ) + } else if (image.get('type') === 'video') { + const { time } = this.props - return ( -
{ - media.size > 1 && + !!media && media.size > 1 &&