From 3c12f6f23beb9038934e85deea1829d85db2ff6c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 23 Nov 2016 11:23:32 +0100 Subject: [PATCH] Add content spoilers for media in sensitive-content statuses --- .../components/components/media_gallery.jsx | 164 ++++++++++++------ .../components/components/status.jsx | 4 +- .../components/components/video_player.jsx | 37 +++- 3 files changed, 144 insertions(+), 61 deletions(-) diff --git a/app/assets/javascripts/components/components/media_gallery.jsx b/app/assets/javascripts/components/components/media_gallery.jsx index bdb456a08d..e46933f7ba 100644 --- a/app/assets/javascripts/components/components/media_gallery.jsx +++ b/app/assets/javascripts/components/components/media_gallery.jsx @@ -1,9 +1,43 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; +import PureRenderMixin from 'react-addons-pure-render-mixin'; +import { FormattedMessage } from 'react-intl'; + +const outerStyle = { + marginTop: '8px', + overflow: 'hidden', + width: '100%', + boxSizing: 'border-box' +}; + +const spoilerStyle = { + background: '#000', + color: '#fff', + textAlign: 'center', + height: '100%', + cursor: 'pointer' +}; + +const spoilerSpanStyle = { + display: 'block', + fontSize: '14px', + paddingTop: '45%' +}; + +const spoilerSubSpanStyle = { + fontSize: '11px', + fontWeight: '500' +}; const MediaGallery = React.createClass({ + getInitialState () { + return { + visible: false + }; + }, + propTypes: { + sensitive: React.PropTypes.bool, media: ImmutablePropTypes.list.isRequired, height: React.PropTypes.number.isRequired, onOpenMedia: React.PropTypes.func.isRequired @@ -20,69 +54,85 @@ const MediaGallery = React.createClass({ e.stopPropagation(); }, + handleOpen () { + this.setState({ visible: true }); + }, + render () { - var children = this.props.media.take(4); - var size = children.size; + const { media, sensitive } = this.props; - children = children.map((attachment, i) => { - let width = 50; - let height = 100; - let top = 'auto'; - let left = 'auto'; - let bottom = 'auto'; - let right = 'auto'; + let children; - if (size === 1) { - width = 100; - } - - if (size === 4 || (size === 3 && i > 0)) { - height = 50; - } - - if (size === 2) { - if (i === 0) { - right = '2px'; - } else { - left = '2px'; - } - } else if (size === 3) { - if (i === 0) { - right = '2px'; - } else if (i > 0) { - left = '2px'; - } - - if (i === 1) { - bottom = '2px'; - } else if (i > 1) { - top = '2px'; - } - } else if (size === 4) { - if (i === 0 || i === 2) { - right = '2px'; - } - - if (i === 1 || i === 3) { - left = '2px'; - } - - if (i < 2) { - bottom = '2px'; - } else { - top = '2px'; - } - } - - return ( -
- + if (sensitive && !this.state.visible) { + children = ( +
+ +
); - }); + } else { + const size = media.take(4).size; + + children = media.take(4).map((attachment, i) => { + let width = 50; + let height = 100; + let top = 'auto'; + let left = 'auto'; + let bottom = 'auto'; + let right = 'auto'; + + if (size === 1) { + width = 100; + } + + if (size === 4 || (size === 3 && i > 0)) { + height = 50; + } + + if (size === 2) { + if (i === 0) { + right = '2px'; + } else { + left = '2px'; + } + } else if (size === 3) { + if (i === 0) { + right = '2px'; + } else if (i > 0) { + left = '2px'; + } + + if (i === 1) { + bottom = '2px'; + } else if (i > 1) { + top = '2px'; + } + } else if (size === 4) { + if (i === 0 || i === 2) { + right = '2px'; + } + + if (i === 1 || i === 3) { + left = '2px'; + } + + if (i < 2) { + bottom = '2px'; + } else { + top = '2px'; + } + } + + return ( +
+ +
+ ); + }); + } return ( -
+
{children}
); diff --git a/app/assets/javascripts/components/components/status.jsx b/app/assets/javascripts/components/components/status.jsx index 84cd075275..bf851e5bf4 100644 --- a/app/assets/javascripts/components/components/status.jsx +++ b/app/assets/javascripts/components/components/status.jsx @@ -83,9 +83,9 @@ const Status = React.createClass({ if (status.get('media_attachments').size > 0) { if (status.getIn(['media_attachments', 0, 'type']) === 'video') { - media = ; + media = ; } else { - media = ; + media = ; } } diff --git a/app/assets/javascripts/components/components/video_player.jsx b/app/assets/javascripts/components/components/video_player.jsx index 9b9b0a2e4f..a789f65e47 100644 --- a/app/assets/javascripts/components/components/video_player.jsx +++ b/app/assets/javascripts/components/components/video_player.jsx @@ -1,7 +1,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import PureRenderMixin from 'react-addons-pure-render-mixin'; import IconButton from './icon_button'; -import { defineMessages, injectIntl } from 'react-intl'; +import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; const messages = defineMessages({ toggle_sound: { id: 'video_player.toggle_sound', defaultMessage: 'Toggle sound' } @@ -25,6 +25,25 @@ const muteStyle = { zIndex: '5' }; +const spoilerStyle = { + background: '#000', + color: '#fff', + textAlign: 'center', + height: '100%', + cursor: 'pointer' +}; + +const spoilerSpanStyle = { + display: 'block', + fontSize: '14px', + paddingTop: '45%' +}; + +const spoilerSubSpanStyle = { + fontSize: '11px', + fontWeight: '500' +}; + const VideoPlayer = React.createClass({ propTypes: { media: ImmutablePropTypes.map.isRequired, @@ -41,6 +60,7 @@ const VideoPlayer = React.createClass({ getInitialState () { return { + visible: false, muted: true }; }, @@ -63,8 +83,21 @@ const VideoPlayer = React.createClass({ } }, + handleOpen () { + this.setState({ visible: true }); + }, + render () { - const { media, intl, width, height } = this.props; + const { media, intl, width, height, sensitive } = this.props; + + if (sensitive && !this.state.visible) { + return ( +
+ + +
+ ); + } return (