Merge branch 'media-upload-preview' into 'develop'
Media upload preview See merge request soapbox-pub/soapbox-fe!508
This commit is contained in:
commit
2898f8b129
|
@ -99,6 +99,11 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
return clickableAreaRef ? clickableAreaRef.current : this.form;
|
return clickableAreaRef ? clickableAreaRef.current : this.form;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isEmpty = () => {
|
||||||
|
const { text, spoilerText, anyMedia } = this.props;
|
||||||
|
return !(text || spoilerText || anyMedia);
|
||||||
|
}
|
||||||
|
|
||||||
isClickOutside = (e) => {
|
isClickOutside = (e) => {
|
||||||
return ![
|
return ![
|
||||||
// List of elements that shouldn't collapse the composer when clicked
|
// List of elements that shouldn't collapse the composer when clicked
|
||||||
|
@ -111,7 +116,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClick = (e) => {
|
handleClick = (e) => {
|
||||||
if (this.isClickOutside(e)) {
|
if (this.isEmpty() && this.isClickOutside(e)) {
|
||||||
this.handleClickOutside();
|
this.handleClickOutside();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +243,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { intl, onPaste, showSearch, anyMedia, shouldCondense, autoFocus, isModalOpen, maxTootChars } = this.props;
|
const { intl, onPaste, showSearch, anyMedia, shouldCondense, autoFocus, isModalOpen, maxTootChars } = this.props;
|
||||||
const condensed = shouldCondense && !this.props.text && !this.state.composeFocused;
|
const condensed = shouldCondense && !this.state.composeFocused && this.isEmpty() && !this.props.isUploading;
|
||||||
const disabled = this.props.isSubmitting;
|
const disabled = this.props.isSubmitting;
|
||||||
const text = [this.props.spoilerText, countableText(this.props.text)].join('');
|
const text = [this.props.spoilerText, countableText(this.props.text)].join('');
|
||||||
const disabledButton = disabled || this.props.isUploading || this.props.isChangingUpload || length(text) > maxTootChars || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
|
const disabledButton = disabled || this.props.isUploading || this.props.isChangingUpload || length(text) > maxTootChars || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
|
||||||
|
|
|
@ -27,7 +27,6 @@ class Upload extends ImmutablePureComponent {
|
||||||
onDescriptionChange: PropTypes.func.isRequired,
|
onDescriptionChange: PropTypes.func.isRequired,
|
||||||
onOpenFocalPoint: PropTypes.func.isRequired,
|
onOpenFocalPoint: PropTypes.func.isRequired,
|
||||||
onSubmit: PropTypes.func.isRequired,
|
onSubmit: PropTypes.func.isRequired,
|
||||||
features: PropTypes.object,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
|
@ -87,6 +86,10 @@ class Upload extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleOpenModal = () => {
|
||||||
|
this.props.onOpenModal(this.props.media);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { intl, media } = this.props;
|
const { intl, media } = this.props;
|
||||||
const active = this.state.hovered || this.state.focused;
|
const active = this.state.hovered || this.state.focused;
|
||||||
|
@ -105,12 +108,12 @@ class Upload extends ImmutablePureComponent {
|
||||||
className={classNames('compose-form__upload-thumbnail', `${mediaType}`)}
|
className={classNames('compose-form__upload-thumbnail', `${mediaType}`)}
|
||||||
style={{
|
style={{
|
||||||
transform: `scale(${scale})`,
|
transform: `scale(${scale})`,
|
||||||
backgroundImage: (mediaType !== 'video' && mediaType !== 'audio' ? `url(${media.get('preview_url')})` : null),
|
backgroundImage: mediaType === 'image' ? `url(${media.get('preview_url')})`: null,
|
||||||
backgroundPosition: `${x}% ${y}%` }}
|
backgroundPosition: `${x}% ${y}%` }}
|
||||||
>
|
>
|
||||||
<div className={classNames('compose-form__upload__actions', { active })}>
|
<div className={classNames('compose-form__upload__actions', { active })}>
|
||||||
<button className='icon-button' onClick={this.handleUndoClick}><Icon id='times' /> <FormattedMessage id='upload_form.undo' defaultMessage='Delete' /></button>
|
<button className='icon-button' onClick={this.handleUndoClick}><Icon id='times' /> <FormattedMessage id='upload_form.undo' defaultMessage='Delete' /></button>
|
||||||
{this.props.features.focalPoint && media.get('type') === 'image' && <button className='icon-button' onClick={this.handleFocalPointClick}><Icon id='crosshairs' /> <FormattedMessage id='upload_form.focus' defaultMessage='Change preview' /></button>}
|
<button className='icon-button' onClick={this.handleOpenModal}><Icon id='search-plus' /> <FormattedMessage id='upload_form.preview' defaultMessage='Preview' /></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={classNames('compose-form__upload-description', { active })}>
|
<div className={classNames('compose-form__upload-description', { active })}>
|
||||||
|
@ -128,6 +131,14 @@ class Upload extends ImmutablePureComponent {
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className='compose-form__upload-preview'>
|
||||||
|
{mediaType === 'video' && (
|
||||||
|
<video autoPlay playsInline muted loop>
|
||||||
|
<source src={media.get('preview_url')} />
|
||||||
|
</video>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Motion>
|
</Motion>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import UploadButton from '../components/upload_button';
|
||||||
import { uploadCompose } from '../../../actions/compose';
|
import { uploadCompose } from '../../../actions/compose';
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 3 || state.getIn(['compose', 'media_attachments']).some(m => m.get('type') === 'video')),
|
disabled: state.getIn(['compose', 'is_uploading']),
|
||||||
resetFileKey: state.getIn(['compose', 'resetFileKey']),
|
resetFileKey: state.getIn(['compose', 'resetFileKey']),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,10 @@ import Upload from '../components/upload';
|
||||||
import { undoUploadCompose, changeUploadCompose } from '../../../actions/compose';
|
import { undoUploadCompose, changeUploadCompose } from '../../../actions/compose';
|
||||||
import { openModal } from '../../../actions/modal';
|
import { openModal } from '../../../actions/modal';
|
||||||
import { submitCompose } from '../../../actions/compose';
|
import { submitCompose } from '../../../actions/compose';
|
||||||
import { getFeatures } from 'soapbox/utils/features';
|
import { List as ImmutableList } from 'immutable';
|
||||||
|
|
||||||
const mapStateToProps = (state, { id }) => ({
|
const mapStateToProps = (state, { id }) => ({
|
||||||
media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id),
|
media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id),
|
||||||
features: getFeatures(state.get('instance')),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
@ -24,6 +23,10 @@ const mapDispatchToProps = dispatch => ({
|
||||||
dispatch(openModal('FOCAL_POINT', { id }));
|
dispatch(openModal('FOCAL_POINT', { id }));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onOpenModal: media => {
|
||||||
|
dispatch(openModal('MEDIA', { media: ImmutableList.of(media), index: 0 }));
|
||||||
|
},
|
||||||
|
|
||||||
onSubmit(router) {
|
onSubmit(router) {
|
||||||
dispatch(submitCompose(router));
|
dispatch(submitCompose(router));
|
||||||
},
|
},
|
||||||
|
|
|
@ -277,16 +277,33 @@
|
||||||
}
|
}
|
||||||
&.active { opacity: 1; }
|
&.active { opacity: 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-preview {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: -1;
|
||||||
|
|
||||||
|
video {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.compose-form__upload-thumbnail {
|
.compose-form__upload-thumbnail {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-size: contain;
|
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
height: 140px;
|
height: 160px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
&.video {
|
&.video {
|
||||||
background-image: url('../images/video-placeholder.png');
|
background-image: url('../images/video-placeholder.png');
|
||||||
|
|
Loading…
Reference in New Issue