2019-08-07 06:02:36 +01:00
|
|
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
2019-08-13 16:54:29 +01:00
|
|
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
2019-08-07 06:02:36 +01:00
|
|
|
import { is } from 'immutable';
|
2019-08-09 17:06:27 +01:00
|
|
|
import { defineMessages, injectIntl } from 'react-intl';
|
2020-02-17 17:50:29 +00:00
|
|
|
import classNames from 'classnames/bind'
|
2019-08-07 06:02:36 +01:00
|
|
|
import { decode } from 'blurhash';
|
2020-04-11 23:29:19 +01:00
|
|
|
import { autoPlayGif, displayMedia } from '../initial_state';
|
|
|
|
import { isIOS } from '../utils/is_mobile';
|
|
|
|
import { isPanoramic, isPortrait, isNonConformingRatio, minimumAspectRatio, maximumAspectRatio } from '../utils/media_aspect_ratio';
|
|
|
|
import Button from './button'
|
|
|
|
import SensitiveMediaItem from './sensitive_media_item'
|
|
|
|
import Text from './text'
|
2019-08-07 06:02:36 +01:00
|
|
|
|
|
|
|
const messages = defineMessages({
|
2020-05-01 06:50:27 +01:00
|
|
|
toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Hide media' },
|
2019-08-09 17:06:27 +01:00
|
|
|
warning: { id: 'status.sensitive_warning', defaultMessage: 'Sensitive content' },
|
|
|
|
hidden: { id: 'status.media_hidden', defaultMessage: 'Media hidden' },
|
2019-08-07 06:02:36 +01:00
|
|
|
});
|
|
|
|
|
2020-02-19 23:57:07 +00:00
|
|
|
const cx = classNames.bind(_s)
|
2020-04-08 02:06:59 +01:00
|
|
|
|
2019-08-13 16:54:29 +01:00
|
|
|
class Item extends ImmutablePureComponent {
|
2019-08-07 06:02:36 +01:00
|
|
|
|
|
|
|
static propTypes = {
|
|
|
|
attachment: ImmutablePropTypes.map.isRequired,
|
|
|
|
standalone: PropTypes.bool,
|
|
|
|
index: PropTypes.number.isRequired,
|
|
|
|
size: PropTypes.number.isRequired,
|
|
|
|
onClick: PropTypes.func.isRequired,
|
|
|
|
displayWidth: PropTypes.number,
|
|
|
|
visible: PropTypes.bool.isRequired,
|
2019-08-23 05:04:32 +01:00
|
|
|
dimensions: PropTypes.object,
|
2020-03-06 15:38:22 +00:00
|
|
|
}
|
2019-08-07 06:02:36 +01:00
|
|
|
|
|
|
|
static defaultProps = {
|
|
|
|
standalone: false,
|
|
|
|
index: 0,
|
|
|
|
size: 1,
|
2020-03-06 15:38:22 +00:00
|
|
|
}
|
2019-08-07 06:02:36 +01:00
|
|
|
|
|
|
|
state = {
|
|
|
|
loaded: false,
|
2020-03-06 15:38:22 +00:00
|
|
|
}
|
2019-08-07 06:02:36 +01:00
|
|
|
|
|
|
|
handleMouseEnter = (e) => {
|
|
|
|
if (this.hoverToPlay()) {
|
|
|
|
e.target.play();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
handleMouseLeave = (e) => {
|
|
|
|
if (this.hoverToPlay()) {
|
|
|
|
e.target.pause();
|
|
|
|
e.target.currentTime = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-21 21:57:21 +00:00
|
|
|
handleLoadedMetaData = (e) => {
|
2020-01-21 22:06:33 +00:00
|
|
|
if (!this.hoverToPlay()) {
|
|
|
|
e.target.play();
|
|
|
|
}
|
2020-01-21 21:57:21 +00:00
|
|
|
}
|
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
hoverToPlay() {
|
2019-08-07 06:02:36 +01:00
|
|
|
const { attachment } = this.props;
|
2020-01-17 23:24:10 +00:00
|
|
|
return autoPlayGif === false && attachment.get('type') === 'gifv';
|
2019-08-07 06:02:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
handleClick = (e) => {
|
|
|
|
const { index, onClick } = this.props;
|
|
|
|
|
|
|
|
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
|
|
|
if (this.hoverToPlay()) {
|
|
|
|
e.target.pause();
|
|
|
|
e.target.currentTime = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
onClick(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
e.stopPropagation();
|
|
|
|
}
|
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
componentDidMount() {
|
2019-08-07 06:02:36 +01:00
|
|
|
if (this.props.attachment.get('blurhash')) {
|
|
|
|
this._decode();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
componentDidUpdate(prevProps) {
|
2019-08-07 06:02:36 +01:00
|
|
|
if (prevProps.attachment.get('blurhash') !== this.props.attachment.get('blurhash') && this.props.attachment.get('blurhash')) {
|
|
|
|
this._decode();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
_decode() {
|
2019-08-07 06:02:36 +01:00
|
|
|
const hash = this.props.attachment.get('blurhash');
|
|
|
|
const pixels = decode(hash, 32, 32);
|
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
if (pixels && this.canvas) {
|
2019-08-07 06:02:36 +01:00
|
|
|
const ctx = this.canvas.getContext('2d');
|
|
|
|
const imageData = new ImageData(pixels, 32, 32);
|
|
|
|
|
|
|
|
ctx.putImageData(imageData, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setCanvasRef = c => {
|
|
|
|
this.canvas = c;
|
|
|
|
}
|
|
|
|
|
|
|
|
handleImageLoad = () => {
|
|
|
|
this.setState({ loaded: true });
|
|
|
|
}
|
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
render() {
|
2019-08-23 05:04:32 +01:00
|
|
|
const { attachment, index, size, standalone, displayWidth, visible, dimensions } = this.props;
|
2019-08-07 06:02:36 +01:00
|
|
|
|
2019-08-23 05:04:32 +01:00
|
|
|
const ar = attachment.getIn(['meta', 'small', 'aspect']);
|
2019-08-07 06:02:36 +01:00
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
let width = 100;
|
2019-08-23 05:04:32 +01:00
|
|
|
let height = '100%';
|
2020-04-08 02:06:59 +01:00
|
|
|
let top = '0';
|
|
|
|
let left = 'auto';
|
2020-02-17 17:50:29 +00:00
|
|
|
let bottom = '0';
|
2020-04-08 02:06:59 +01:00
|
|
|
let right = 'auto';
|
2019-08-23 05:04:32 +01:00
|
|
|
let float = 'left';
|
|
|
|
let position = 'relative';
|
2020-04-02 04:17:21 +01:00
|
|
|
let borderRadius = '0 0 0 0';
|
2019-08-23 05:04:32 +01:00
|
|
|
|
|
|
|
if (dimensions) {
|
|
|
|
width = dimensions.w;
|
|
|
|
height = dimensions.h;
|
2020-02-17 17:50:29 +00:00
|
|
|
top = dimensions.t || '0';
|
2019-08-23 05:04:32 +01:00
|
|
|
right = dimensions.r || 'auto';
|
2020-02-17 17:50:29 +00:00
|
|
|
bottom = dimensions.b || '0';
|
2019-08-23 05:04:32 +01:00
|
|
|
left = dimensions.l || 'auto';
|
|
|
|
float = dimensions.float || 'left';
|
|
|
|
position = dimensions.pos || 'relative';
|
2020-04-02 04:17:21 +01:00
|
|
|
|
|
|
|
const br = dimensions.br || []
|
|
|
|
const hasTL = br.indexOf('tl') > -1
|
|
|
|
const hasTR = br.indexOf('tr') > -1
|
|
|
|
const hasBR = br.indexOf('br') > -1
|
|
|
|
const hasBL = br.indexOf('bl') > -1
|
|
|
|
borderRadius = `${hasTL ? '8px' : '0'} ${hasTR ? '8px' : '0'} ${hasBR ? '8px' : '0'} ${hasBL ? '8px' : '0'}`
|
2019-08-07 06:02:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
let thumbnail = '';
|
|
|
|
|
|
|
|
if (attachment.get('type') === 'unknown') {
|
|
|
|
return (
|
2020-04-23 07:13:29 +01:00
|
|
|
<div className={[_s.default, _s.posAbs].join(' ')} key={attachment.get('id')} style={{ position, float, left, top, right, bottom, height, borderRadius, width: `${width}%` }}>
|
2020-04-08 02:06:59 +01:00
|
|
|
<a className={[_s.default, _s.heigh100PC, _s.width100PC, _s.cursorPointer].join(' ')} href={attachment.get('remote_url')} target='_blank' rel='noreferrer noopener'>
|
|
|
|
<canvas width={32} height={32} ref={this.setCanvasRef} className={[_s.default, _s.heigh100PC, _s.width100PC].join(' ')} />
|
2019-08-07 06:02:36 +01:00
|
|
|
</a>
|
|
|
|
</div>
|
2020-04-08 02:06:59 +01:00
|
|
|
)
|
2019-08-07 06:02:36 +01:00
|
|
|
} else if (attachment.get('type') === 'image') {
|
|
|
|
const previewUrl = attachment.get('preview_url');
|
|
|
|
const previewWidth = attachment.getIn(['meta', 'small', 'width']);
|
|
|
|
|
|
|
|
const originalUrl = attachment.get('url');
|
|
|
|
const originalWidth = attachment.getIn(['meta', 'original', 'width']);
|
|
|
|
|
|
|
|
const hasSize = typeof originalWidth === 'number' && typeof previewWidth === 'number';
|
|
|
|
|
|
|
|
const srcSet = hasSize ? `${originalUrl} ${originalWidth}w, ${previewUrl} ${previewWidth}w` : null;
|
|
|
|
const sizes = hasSize && (displayWidth > 0) ? `${displayWidth * (width / 100)}px` : null;
|
|
|
|
|
|
|
|
const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;
|
|
|
|
const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;
|
2020-04-08 02:06:59 +01:00
|
|
|
const x = ((focusX / 2) + .5) * 100;
|
2019-08-07 06:02:36 +01:00
|
|
|
const y = ((focusY / -2) + .5) * 100;
|
|
|
|
|
|
|
|
thumbnail = (
|
|
|
|
<a
|
2020-02-19 23:57:07 +00:00
|
|
|
className={[_s.default, _s.overflowHidden, _s.height100PC, _s.width100PC, _s.cursorPointer].join(' ')}
|
2019-08-07 06:02:36 +01:00
|
|
|
href={attachment.get('remote_url') || originalUrl}
|
|
|
|
onClick={this.handleClick}
|
|
|
|
target='_blank'
|
2020-04-02 04:17:21 +01:00
|
|
|
style={{ borderRadius }}
|
2019-08-07 06:02:36 +01:00
|
|
|
>
|
|
|
|
<img
|
|
|
|
src={previewUrl}
|
|
|
|
srcSet={srcSet}
|
|
|
|
sizes={sizes}
|
2020-02-19 23:57:07 +00:00
|
|
|
className={[_s.height100PC, _s.width100PC, _s.objectFitCover].join(' ')}
|
2019-08-07 06:02:36 +01:00
|
|
|
alt={attachment.get('description')}
|
|
|
|
title={attachment.get('description')}
|
|
|
|
style={{ objectPosition: `${x}% ${y}%` }}
|
|
|
|
onLoad={this.handleImageLoad}
|
|
|
|
/>
|
|
|
|
</a>
|
|
|
|
);
|
|
|
|
} else if (attachment.get('type') === 'gifv') {
|
2020-01-17 23:24:10 +00:00
|
|
|
const autoPlay = !isIOS() && autoPlayGif !== false;
|
2019-08-07 06:02:36 +01:00
|
|
|
|
|
|
|
thumbnail = (
|
2020-02-19 23:57:07 +00:00
|
|
|
<div className={[_s.default, _s.overflowHidden, _s.heigh100PC, _s.width100PC].join(' ')}>
|
2019-08-07 06:02:36 +01:00
|
|
|
<video
|
2020-02-19 23:57:07 +00:00
|
|
|
className={[_s.default, _s.cursorPointer, _s.objectFitCover, _s.width100PC, _s.height100PC, _s.z1].join(' ')}
|
2019-08-07 06:02:36 +01:00
|
|
|
aria-label={attachment.get('description')}
|
|
|
|
title={attachment.get('description')}
|
|
|
|
role='application'
|
|
|
|
src={attachment.get('url')}
|
|
|
|
onClick={this.handleClick}
|
|
|
|
onMouseEnter={this.handleMouseEnter}
|
|
|
|
onMouseLeave={this.handleMouseLeave}
|
2020-01-21 22:02:34 +00:00
|
|
|
onLoadedMetadata={this.handleLoadedMetaData}
|
2019-08-07 06:02:36 +01:00
|
|
|
autoPlay={autoPlay}
|
2020-01-17 22:55:00 +00:00
|
|
|
type='video/mp4'
|
2019-08-07 06:02:36 +01:00
|
|
|
loop
|
|
|
|
muted
|
2019-08-27 19:22:35 +01:00
|
|
|
playsInline
|
2019-08-07 06:02:36 +01:00
|
|
|
/>
|
|
|
|
|
2020-04-29 23:32:49 +01:00
|
|
|
<div className={[_s.default, _s.posAbs, _s.z2, _s.radiusSmall, _s.bgBlackOpaque, _s.px5, _s.py5, _s.mr10, _s.mb10, _s.bottom0, _s.right0].join(' ')}>
|
2020-04-08 02:06:59 +01:00
|
|
|
<Text size='extraSmall' color='white' weight='medium'>GIF</Text>
|
|
|
|
</div>
|
2019-08-07 06:02:36 +01:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2020-04-23 07:13:29 +01:00
|
|
|
<div className={[_s.defeault, _s.posAbs].join(' ')} key={attachment.get('id')} style={{ position, float, left, top, right, bottom, height, width: `${width}%` }}>
|
2020-04-08 02:06:59 +01:00
|
|
|
{
|
|
|
|
!visible && !this.state.loaded &&
|
|
|
|
<canvas width={32} height={32} ref={this.setCanvasRef} className={[_s.default, _s.heigh100PC, _s.width100PC].join(' ')} />
|
|
|
|
}
|
2019-08-07 06:02:36 +01:00
|
|
|
{visible && thumbnail}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-02-25 16:04:44 +00:00
|
|
|
export default
|
|
|
|
@injectIntl
|
2019-08-07 06:02:36 +01:00
|
|
|
class MediaGallery extends PureComponent {
|
|
|
|
|
|
|
|
static propTypes = {
|
|
|
|
sensitive: PropTypes.bool,
|
|
|
|
standalone: PropTypes.bool,
|
|
|
|
media: ImmutablePropTypes.list.isRequired,
|
|
|
|
size: PropTypes.object,
|
|
|
|
height: PropTypes.number.isRequired,
|
|
|
|
onOpenMedia: PropTypes.func.isRequired,
|
|
|
|
intl: PropTypes.object.isRequired,
|
|
|
|
defaultWidth: PropTypes.number,
|
|
|
|
cacheWidth: PropTypes.func,
|
|
|
|
visible: PropTypes.bool,
|
|
|
|
onToggleVisibility: PropTypes.func,
|
2020-04-02 04:17:21 +01:00
|
|
|
reduced: PropTypes.bool,
|
2019-08-07 06:02:36 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static defaultProps = {
|
|
|
|
standalone: false,
|
2020-04-23 07:13:29 +01:00
|
|
|
height: 110,
|
2019-08-07 06:02:36 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
state = {
|
|
|
|
visible: this.props.visible !== undefined ? this.props.visible : (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all'),
|
|
|
|
width: this.props.defaultWidth,
|
|
|
|
};
|
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
componentWillReceiveProps(nextProps) {
|
2019-08-07 06:02:36 +01:00
|
|
|
if (!is(nextProps.media, this.props.media) && nextProps.visible === undefined) {
|
2020-04-08 02:06:59 +01:00
|
|
|
this.setState({
|
|
|
|
visible: displayMedia !== 'hide_all' && !nextProps.sensitive || displayMedia === 'show_all',
|
|
|
|
})
|
2019-08-07 06:02:36 +01:00
|
|
|
} else if (!is(nextProps.visible, this.props.visible) && nextProps.visible !== undefined) {
|
|
|
|
this.setState({ visible: nextProps.visible });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
handleOpen = () => {
|
|
|
|
if (this.props.onToggleVisibility) {
|
|
|
|
this.props.onToggleVisibility();
|
|
|
|
} else {
|
|
|
|
this.setState({ visible: !this.state.visible });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
handleClick = (index) => {
|
|
|
|
this.props.onOpenMedia(this.props.media, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleRef = (node) => {
|
2019-08-23 05:04:32 +01:00
|
|
|
if (node) {
|
2019-08-07 06:02:36 +01:00
|
|
|
// offsetWidth triggers a layout, so only calculate when we need to
|
|
|
|
if (this.props.cacheWidth) this.props.cacheWidth(node.offsetWidth);
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
width: node.offsetWidth,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
render() {
|
2020-04-02 04:17:21 +01:00
|
|
|
const {
|
|
|
|
media,
|
|
|
|
intl,
|
|
|
|
sensitive,
|
|
|
|
height,
|
|
|
|
defaultWidth,
|
2020-04-08 02:06:59 +01:00
|
|
|
reduced,
|
2020-04-02 04:17:21 +01:00
|
|
|
} = this.props
|
|
|
|
const { visible } = this.state
|
2019-08-07 06:02:36 +01:00
|
|
|
|
|
|
|
const width = this.state.width || defaultWidth;
|
|
|
|
|
|
|
|
const style = {};
|
2019-08-23 05:04:32 +01:00
|
|
|
const size = media.take(4).size;
|
2019-08-07 06:02:36 +01:00
|
|
|
|
2019-08-23 05:04:32 +01:00
|
|
|
const standard169 = width / (16 / 9);
|
|
|
|
const standard169_percent = 100 / (16 / 9);
|
|
|
|
const standard169_px = `${standard169}px`;
|
|
|
|
const panoSize = Math.floor(width / maximumAspectRatio);
|
|
|
|
const panoSize_px = `${Math.floor(width / maximumAspectRatio)}px`;
|
|
|
|
let itemsDimensions = [];
|
2019-07-02 08:10:25 +01:00
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
if (size === 1 && width && visible) {
|
2019-08-23 05:04:32 +01:00
|
|
|
const aspectRatio = media.getIn([0, 'meta', 'small', 'aspect']);
|
|
|
|
|
|
|
|
if (isPanoramic(aspectRatio)) {
|
|
|
|
style.height = Math.floor(width / maximumAspectRatio);
|
|
|
|
} else if (isPortrait(aspectRatio)) {
|
|
|
|
style.height = Math.floor(width / minimumAspectRatio);
|
|
|
|
} else {
|
|
|
|
style.height = Math.floor(width / aspectRatio);
|
|
|
|
}
|
2020-04-08 02:06:59 +01:00
|
|
|
} else if (size > 1 && width && visible) {
|
2019-08-23 05:04:32 +01:00
|
|
|
const ar1 = media.getIn([0, 'meta', 'small', 'aspect']);
|
|
|
|
const ar2 = media.getIn([1, 'meta', 'small', 'aspect']);
|
|
|
|
const ar3 = media.getIn([2, 'meta', 'small', 'aspect']);
|
|
|
|
const ar4 = media.getIn([3, 'meta', 'small', 'aspect']);
|
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
if (size === 2) {
|
2019-08-23 05:04:32 +01:00
|
|
|
if (isPortrait(ar1) && isPortrait(ar2)) {
|
|
|
|
style.height = width - (width / maximumAspectRatio);
|
|
|
|
} else if (isPanoramic(ar1) && isPanoramic(ar2)) {
|
|
|
|
style.height = panoSize * 2;
|
|
|
|
} else if (
|
|
|
|
(isPanoramic(ar1) && isPortrait(ar2)) ||
|
|
|
|
(isPortrait(ar1) && isPanoramic(ar2)) ||
|
|
|
|
(isPanoramic(ar1) && isNonConformingRatio(ar2)) ||
|
|
|
|
(isNonConformingRatio(ar1) && isPanoramic(ar2))
|
|
|
|
) {
|
|
|
|
style.height = (width * 0.6) + (width / maximumAspectRatio);
|
|
|
|
} else {
|
|
|
|
style.height = width / 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
if (isPortrait(ar1) && isPortrait(ar2)) {
|
|
|
|
itemsDimensions = [
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 50, h: '100%', r: '2px', br: ['tl', 'bl'] },
|
|
|
|
{ w: 50, h: '100%', l: '2px', br: ['tr', 'br'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
} else if (isPanoramic(ar1) && isPanoramic(ar2)) {
|
|
|
|
itemsDimensions = [
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 100, h: panoSize_px, b: '2px', br: ['tl', 'tr'] },
|
|
|
|
{ w: 100, h: panoSize_px, t: '2px', br: ['bl', 'br'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
} else if (
|
|
|
|
(isPanoramic(ar1) && isPortrait(ar2)) ||
|
|
|
|
(isPanoramic(ar1) && isNonConformingRatio(ar2))
|
|
|
|
) {
|
|
|
|
itemsDimensions = [
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 100, h: `${(width / maximumAspectRatio)}px`, b: '2px', br: ['tl', 'tr'] },
|
|
|
|
{ w: 100, h: `${(width * 0.6)}px`, t: '2px', br: ['bl', 'br'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
} else if (
|
|
|
|
(isPortrait(ar1) && isPanoramic(ar2)) ||
|
|
|
|
(isNonConformingRatio(ar1) && isPanoramic(ar2))
|
|
|
|
) {
|
|
|
|
itemsDimensions = [
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 100, h: `${(width * 0.6)}px`, b: '2px', br: ['tl', 'tr'] },
|
|
|
|
{ w: 100, h: `${(width / maximumAspectRatio)}px`, t: '2px', br: ['bl', 'br'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
} else {
|
|
|
|
itemsDimensions = [
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 50, h: '100%', r: '2px', br: ['tl', 'bl'] },
|
|
|
|
{ w: 50, h: '100%', l: '2px', br: ['tr', 'br'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
}
|
2020-04-08 02:06:59 +01:00
|
|
|
} else if (size === 3) {
|
2019-08-23 05:04:32 +01:00
|
|
|
if (isPanoramic(ar1) && isPanoramic(ar2) && isPanoramic(ar3)) {
|
|
|
|
style.height = panoSize * 3;
|
|
|
|
} else if (isPortrait(ar1) && isPortrait(ar2) && isPortrait(ar3)) {
|
|
|
|
style.height = Math.floor(width / minimumAspectRatio);
|
|
|
|
} else {
|
|
|
|
style.height = width;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
if (isPanoramic(ar1) && isNonConformingRatio(ar2) && isNonConformingRatio(ar3)) {
|
|
|
|
itemsDimensions = [
|
2020-04-08 02:06:59 +01:00
|
|
|
{ w: 100, h: '50%', b: '2px', br: ['tl', 'tr'] },
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 50, h: '50%', t: '2px', r: '2px', br: ['bl'] },
|
|
|
|
{ w: 50, h: '50%', t: '2px', l: '2px', br: ['br'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
} else if (isPanoramic(ar1) && isPanoramic(ar2) && isPanoramic(ar3)) {
|
|
|
|
itemsDimensions = [
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 100, h: panoSize_px, b: '4px', br: ['tl', 'tr'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
{ w: 100, h: panoSize_px },
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 100, h: panoSize_px, t: '4px', br: ['bl', 'br'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
} else if (isPortrait(ar1) && isNonConformingRatio(ar2) && isNonConformingRatio(ar3)) {
|
|
|
|
itemsDimensions = [
|
2020-04-08 02:06:59 +01:00
|
|
|
{ w: 50, h: '100%', r: '2px', br: ['tl', 'bl'] },
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 50, h: '50%', b: '2px', l: '2px', br: ['tr'] },
|
|
|
|
{ w: 50, h: '50%', t: '2px', l: '2px', br: ['br'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
} else if (isNonConformingRatio(ar1) && isNonConformingRatio(ar2) && isPortrait(ar3)) {
|
|
|
|
itemsDimensions = [
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 50, h: '50%', b: '2px', r: '2px', br: ['tl'] },
|
|
|
|
{ w: 50, h: '50%', l: '-2px', b: '-2px', pos: 'absolute', float: 'none', br: ['bl'] },
|
2020-04-08 02:06:59 +01:00
|
|
|
{ w: 50, h: '100%', r: '-2px', t: '0px', b: '0px', pos: 'absolute', float: 'none', br: ['tr', 'br'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
} else if (
|
|
|
|
(isNonConformingRatio(ar1) && isPortrait(ar2) && isNonConformingRatio(ar3)) ||
|
|
|
|
(isPortrait(ar1) && isPortrait(ar2) && isPortrait(ar3))
|
|
|
|
) {
|
|
|
|
itemsDimensions = [
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 50, h: '50%', b: '2px', r: '2px', br: ['tl'] },
|
2020-04-08 02:06:59 +01:00
|
|
|
{ w: 50, h: '100%', l: '2px', float: 'right', br: ['tr', 'br'] },
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 50, h: '50%', t: '2px', r: '2px', br: ['bl'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
} else if (
|
|
|
|
(isPanoramic(ar1) && isPanoramic(ar2) && isNonConformingRatio(ar3)) ||
|
|
|
|
(isPanoramic(ar1) && isPanoramic(ar2) && isPortrait(ar3))
|
|
|
|
) {
|
|
|
|
itemsDimensions = [
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 50, h: panoSize_px, b: '2px', r: '2px', br: ['tl'] },
|
|
|
|
{ w: 50, h: panoSize_px, b: '2px', l: '2px', br: ['tr'] },
|
|
|
|
{ w: 100, h: `${width - panoSize}px`, t: '2px', br: ['bl', 'br'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
} else if (
|
|
|
|
(isNonConformingRatio(ar1) && isPanoramic(ar2) && isPanoramic(ar3)) ||
|
|
|
|
(isPortrait(ar1) && isPanoramic(ar2) && isPanoramic(ar3))
|
|
|
|
) {
|
|
|
|
itemsDimensions = [
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 100, h: `${width - panoSize}px`, b: '2px', br: ['tl', 'tr'] },
|
|
|
|
{ w: 50, h: panoSize_px, t: '2px', r: '2px', br: ['bl'] },
|
|
|
|
{ w: 50, h: panoSize_px, t: '2px', l: '2px', br: ['br'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
} else {
|
|
|
|
itemsDimensions = [
|
2020-04-02 04:17:21 +01:00
|
|
|
{ w: 50, h: '50%', b: '2px', r: '2px', br: ['tl'] },
|
|
|
|
{ w: 50, h: '50%', b: '2px', l: '2px', br: ['tr'] },
|
2020-04-08 02:06:59 +01:00
|
|
|
{ w: 100, h: '50%', t: '2px', br: ['bl', 'br'] },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
}
|
2020-04-08 02:06:59 +01:00
|
|
|
} else if (size === 4) {
|
2019-08-23 05:04:32 +01:00
|
|
|
if (
|
|
|
|
(isPortrait(ar1) && isPortrait(ar2) && isPortrait(ar3) && isPortrait(ar4)) ||
|
|
|
|
(isPortrait(ar1) && isPortrait(ar2) && isPortrait(ar3) && isNonConformingRatio(ar4)) ||
|
|
|
|
(isPortrait(ar1) && isPortrait(ar2) && isNonConformingRatio(ar3) && isPortrait(ar4)) ||
|
|
|
|
(isPortrait(ar1) && isNonConformingRatio(ar2) && isPortrait(ar3) && isPortrait(ar4)) ||
|
|
|
|
(isNonConformingRatio(ar1) && isPortrait(ar2) && isPortrait(ar3) && isPortrait(ar4))
|
|
|
|
) {
|
|
|
|
style.height = Math.floor(width / minimumAspectRatio);
|
|
|
|
} else if (isPanoramic(ar1) && isPanoramic(ar2) && isPanoramic(ar3) && isPanoramic(ar4)) {
|
|
|
|
style.height = panoSize * 2;
|
|
|
|
} else if (
|
|
|
|
(isPanoramic(ar1) && isPanoramic(ar2) && isNonConformingRatio(ar3) && isNonConformingRatio(ar4)) ||
|
|
|
|
(isNonConformingRatio(ar1) && isNonConformingRatio(ar2) && isPanoramic(ar3) && isPanoramic(ar4))
|
|
|
|
) {
|
|
|
|
style.height = panoSize + (width / 2);
|
|
|
|
} else {
|
|
|
|
style.height = width;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
if (isPanoramic(ar1) && isPanoramic(ar2) && isNonConformingRatio(ar3) && isNonConformingRatio(ar4)) {
|
|
|
|
itemsDimensions = [
|
|
|
|
{ w: 50, h: panoSize_px, b: '2px', r: '2px' },
|
|
|
|
{ w: 50, h: panoSize_px, b: '2px', l: '2px' },
|
|
|
|
{ w: 50, h: `${(width / 2)}px`, t: '2px', r: '2px' },
|
|
|
|
{ w: 50, h: `${(width / 2)}px`, t: '2px', l: '2px' },
|
|
|
|
];
|
|
|
|
} else if (isNonConformingRatio(ar1) && isNonConformingRatio(ar2) && isPanoramic(ar3) && isPanoramic(ar4)) {
|
|
|
|
itemsDimensions = [
|
|
|
|
{ w: 50, h: `${(width / 2)}px`, b: '2px', r: '2px' },
|
|
|
|
{ w: 50, h: `${(width / 2)}px`, b: '2px', l: '2px' },
|
|
|
|
{ w: 50, h: panoSize_px, t: '2px', r: '2px' },
|
|
|
|
{ w: 50, h: panoSize_px, t: '2px', l: '2px' },
|
|
|
|
];
|
|
|
|
} else if (
|
|
|
|
(isPortrait(ar1) && isNonConformingRatio(ar2) && isNonConformingRatio(ar3) && isNonConformingRatio(ar4)) ||
|
|
|
|
(isPortrait(ar1) && isPanoramic(ar2) && isPanoramic(ar3) && isPanoramic(ar4))
|
|
|
|
) {
|
|
|
|
itemsDimensions = [
|
|
|
|
{ w: 67, h: '100%', r: '2px' },
|
|
|
|
{ w: 33, h: '33%', b: '4px', l: '2px' },
|
|
|
|
{ w: 33, h: '33%', l: '2px' },
|
2020-04-08 02:06:59 +01:00
|
|
|
{ w: 33, h: '33%', t: '4px', l: '2px' },
|
2019-08-23 05:04:32 +01:00
|
|
|
];
|
|
|
|
} else {
|
|
|
|
itemsDimensions = [
|
|
|
|
{ w: 50, h: '50%', b: '2px', r: '2px' },
|
|
|
|
{ w: 50, h: '50%', b: '2px', l: '2px' },
|
|
|
|
{ w: 50, h: '50%', t: '2px', r: '2px' },
|
|
|
|
{ w: 50, h: '50%', t: '2px', l: '2px' },
|
|
|
|
];
|
|
|
|
}
|
2019-08-07 06:02:36 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
style.height = height;
|
|
|
|
}
|
|
|
|
|
2020-04-02 04:17:21 +01:00
|
|
|
//If reduced (i.e. like in a quoted post)
|
|
|
|
//then we need to make media smaller
|
|
|
|
if (reduced) {
|
2020-04-23 07:13:29 +01:00
|
|
|
style.height = width / 2 || '50%'
|
2020-04-02 04:17:21 +01:00
|
|
|
}
|
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
if (!visible) {
|
|
|
|
style.height = 'auto'
|
|
|
|
}
|
|
|
|
|
|
|
|
const children = media.take(4).map((attachment, i) => (
|
2019-08-23 05:04:32 +01:00
|
|
|
<Item
|
|
|
|
key={attachment.get('id')}
|
|
|
|
onClick={this.handleClick}
|
|
|
|
attachment={attachment}
|
|
|
|
index={i}
|
|
|
|
size={size}
|
|
|
|
displayWidth={width}
|
|
|
|
visible={visible}
|
|
|
|
dimensions={itemsDimensions[i]}
|
|
|
|
/>
|
2020-04-08 02:06:59 +01:00
|
|
|
))
|
2019-08-07 06:02:36 +01:00
|
|
|
|
2020-02-17 17:50:29 +00:00
|
|
|
const containerClasses = cx({
|
|
|
|
default: 1,
|
|
|
|
displayBlock: 1,
|
|
|
|
overflowHidden: 1,
|
2020-04-08 02:06:59 +01:00
|
|
|
borderColorSecondary: size === 1 && visible,
|
|
|
|
borderTop1PX: size === 1 && visible,
|
|
|
|
borderBottom1PX: size === 1 && visible,
|
|
|
|
px5: size > 1 && visible,
|
2020-02-17 17:50:29 +00:00
|
|
|
})
|
|
|
|
|
2019-08-07 06:02:36 +01:00
|
|
|
return (
|
2020-02-14 00:40:04 +00:00
|
|
|
<div
|
2020-02-17 17:50:29 +00:00
|
|
|
className={containerClasses}
|
2020-02-14 00:40:04 +00:00
|
|
|
style={style}
|
|
|
|
ref={this.handleRef}
|
|
|
|
>
|
2020-04-02 04:17:21 +01:00
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
{
|
|
|
|
!visible && sensitive &&
|
|
|
|
<SensitiveMediaItem onClick={this.handleOpen} />
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
visible &&
|
|
|
|
<div className={[_s.default, _s.displayBlock, _s.width100PC, _s.height100PC, _s.overflowHidden].join(' ')}>
|
|
|
|
{children}
|
|
|
|
</div>
|
|
|
|
}
|
2019-08-07 06:02:36 +01:00
|
|
|
|
2020-04-08 02:06:59 +01:00
|
|
|
{
|
|
|
|
visible && sensitive &&
|
2020-04-23 07:13:29 +01:00
|
|
|
<div className={[_s.posAbs, _s.z2, _s.top0, _s.right0, _s.mt10, _s.mr10].join(' ')}>
|
2020-04-08 02:06:59 +01:00
|
|
|
<Button
|
|
|
|
title={intl.formatMessage(messages.toggle_visible)}
|
|
|
|
icon='hidden'
|
|
|
|
backgroundColor='none'
|
2020-04-29 23:32:49 +01:00
|
|
|
className={[_s.px10, _s.bgBlackOpaque_onHover].join(' ')}
|
2020-04-08 02:06:59 +01:00
|
|
|
onClick={this.handleOpen}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
}
|
2019-08-07 06:02:36 +01:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|