Fancier drag & drop indicator, emoji icon for emoji, upload progress (fix #295)
This commit is contained in:
parent
3e2d6ea408
commit
d7c6c6dbe1
13 changed files with 244 additions and 75 deletions
|
@ -34,7 +34,6 @@ const ComposeForm = React.createClass({
|
|||
private: React.PropTypes.bool,
|
||||
unlisted: React.PropTypes.bool,
|
||||
spoiler_text: React.PropTypes.string,
|
||||
fileDropDate: React.PropTypes.instanceOf(Date),
|
||||
focusDate: React.PropTypes.instanceOf(Date),
|
||||
preselectDate: React.PropTypes.instanceOf(Date),
|
||||
is_submitting: React.PropTypes.bool,
|
||||
|
@ -161,7 +160,6 @@ const ComposeForm = React.createClass({
|
|||
ref={this.setAutosuggestTextarea}
|
||||
placeholder={intl.formatMessage(messages.placeholder)}
|
||||
disabled={disabled}
|
||||
fileDropDate={this.props.fileDropDate}
|
||||
value={this.props.text}
|
||||
onChange={this.handleChange}
|
||||
suggestions={this.props.suggestions}
|
||||
|
|
|
@ -4,7 +4,7 @@ import PureRenderMixin from 'react-addons-pure-render-mixin';
|
|||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
emoji: { id: 'emoji_button.label', defaultMessage: 'Emoji' }
|
||||
emoji: { id: 'emoji_button.label', defaultMessage: 'Insert emoji' }
|
||||
});
|
||||
|
||||
const settings = {
|
||||
|
@ -36,8 +36,8 @@ const EmojiPickerDropdown = React.createClass({
|
|||
|
||||
return (
|
||||
<Dropdown ref={this.setRef} style={{ marginLeft: '5px' }}>
|
||||
<DropdownTrigger className='icon-button' title={intl.formatMessage(messages.emoji)} style={{ fontSize: `24px`, width: `24px`, lineHeight: `24px`, display: 'block', marginLeft: '2px' }}>
|
||||
<i className={`fa fa-smile-o`} style={{ verticalAlign: 'middle' }} />
|
||||
<DropdownTrigger className='icon-button emoji-button' title={intl.formatMessage(messages.emoji)} style={{ fontSize: `24px`, width: `24px`, lineHeight: `24px`, display: 'block', marginLeft: '2px' }}>
|
||||
<img className="emojione" alt="🙂" src="/emoji/1f642.png" />
|
||||
</DropdownTrigger>
|
||||
|
||||
<DropdownContent>
|
||||
|
|
|
@ -2,6 +2,8 @@ import PureRenderMixin from 'react-addons-pure-render-mixin';
|
|||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import IconButton from '../../../components/icon_button';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import UploadProgressContainer from '../containers/upload_progress_container';
|
||||
import { Motion, spring } from 'react-motion';
|
||||
|
||||
const messages = defineMessages({
|
||||
undo: { id: 'upload_form.undo', defaultMessage: 'Undo' }
|
||||
|
@ -11,7 +13,6 @@ const UploadForm = React.createClass({
|
|||
|
||||
propTypes: {
|
||||
media: ImmutablePropTypes.list.isRequired,
|
||||
is_uploading: React.PropTypes.bool,
|
||||
onRemoveFile: React.PropTypes.func.isRequired,
|
||||
intl: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
@ -21,20 +22,21 @@ const UploadForm = React.createClass({
|
|||
render () {
|
||||
const { intl, media } = this.props;
|
||||
|
||||
if (!media.size) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const uploads = media.map(attachment => (
|
||||
<div key={attachment.get('id')} style={{ borderRadius: '4px', marginBottom: '10px' }} className='transparent-background'>
|
||||
<div style={{ width: '100%', height: '100px', borderRadius: '4px', background: `url(${attachment.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }}>
|
||||
<IconButton icon='times' title={intl.formatMessage(messages.undo)} size={36} onClick={this.props.onRemoveFile.bind(this, attachment.get('id'))} />
|
||||
</div>
|
||||
const uploads = media.map(attachment =>
|
||||
<div key={attachment.get('id')} style={{ marginBottom: '10px' }}>
|
||||
<Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}>
|
||||
{({ scale }) =>
|
||||
<div style={{ transform: `translateZ(0) scale(${scale})`, width: '100%', height: '100px', borderRadius: '4px', background: `url(${attachment.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }}>
|
||||
<IconButton icon='times' title={intl.formatMessage(messages.undo)} size={36} onClick={this.props.onRemoveFile.bind(this, attachment.get('id'))} />
|
||||
</div>
|
||||
}
|
||||
</Motion>
|
||||
</div>
|
||||
));
|
||||
);
|
||||
|
||||
return (
|
||||
<div style={{ marginBottom: '20px', padding: '10px', overflow: 'hidden', flexShrink: '0' }}>
|
||||
<UploadProgressContainer />
|
||||
{uploads}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||
import { Motion, spring } from 'react-motion';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
const UploadProgress = React.createClass({
|
||||
|
||||
propTypes: {
|
||||
active: React.PropTypes.bool,
|
||||
progress: React.PropTypes.number
|
||||
},
|
||||
|
||||
mixins: [PureRenderMixin],
|
||||
|
||||
render () {
|
||||
const { active, progress } = this.props;
|
||||
|
||||
if (!active) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='upload-progress'>
|
||||
<div>
|
||||
<i className='fa fa-upload' />
|
||||
</div>
|
||||
|
||||
<div style={{ flex: '1 1 auto' }}>
|
||||
<FormattedMessage id='upload_progress.label' defaultMessage='Uploading...' />
|
||||
|
||||
<div className='upload-progress__backdrop'>
|
||||
<Motion defaultStyle={{ width: 0 }} style={{ width: spring(progress) }}>
|
||||
{({ width }) =>
|
||||
<div className='upload-progress__tracker' style={{ width: `${width}%` }} />
|
||||
}
|
||||
</Motion>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
export default UploadProgress;
|
|
@ -30,7 +30,6 @@ const mapStateToProps = (state, props) => {
|
|||
spoiler_text: state.getIn(['compose', 'spoiler_text']),
|
||||
unlisted: state.getIn(['compose', 'unlisted'], ),
|
||||
private: state.getIn(['compose', 'private']),
|
||||
fileDropDate: state.getIn(['compose', 'fileDropDate']),
|
||||
focusDate: state.getIn(['compose', 'focusDate']),
|
||||
preselectDate: state.getIn(['compose', 'preselectDate']),
|
||||
is_submitting: state.getIn(['compose', 'is_submitting']),
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import { connect } from 'react-redux';
|
||||
import UploadProgress from '../components/upload_progress';
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
active: state.getIn(['compose', 'is_uploading']),
|
||||
progress: state.getIn(['compose', 'progress'])
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(UploadProgress);
|
Loading…
Add table
Add a link
Reference in a new issue