Progress
This commit is contained in:
@@ -24,6 +24,8 @@ import StatusContainer from '../../../containers/status_container'
|
||||
import StatusVisibilityButton from './status_visibility_button'
|
||||
import UploadButton from './media_upload_button'
|
||||
import UploadForm from './upload_form'
|
||||
import GifForm from './gif_form'
|
||||
import Input from '../../../components/input'
|
||||
|
||||
const messages = defineMessages({
|
||||
placeholder: { id: 'compose_form.placeholder', defaultMessage: "What's on your mind?" },
|
||||
@@ -78,6 +80,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
replyToId: PropTypes.string,
|
||||
reduxReplyToId: PropTypes.string,
|
||||
hasPoll: PropTypes.bool,
|
||||
selectedGifSrc: PropTypes.string,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
@@ -85,7 +88,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
handleChange = (e, markdown) => {
|
||||
this.props.onChange(e.target.value, markdown);
|
||||
this.props.onChange(e.target.value, markdown, this.props.replyToId)
|
||||
}
|
||||
|
||||
handleComposeFocus = () => {
|
||||
@@ -156,8 +159,8 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
this.props.onSuggestionSelected(tokenStart, token, value, ['spoiler_text']);
|
||||
}
|
||||
|
||||
handleChangeSpoilerText = (e) => {
|
||||
this.props.onChangeSpoilerText(e.target.value);
|
||||
handleChangeSpoilerText = (value) => {
|
||||
this.props.onChangeSpoilerText(value)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -169,7 +172,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (!this.autosuggestTextarea) return;
|
||||
if (!this.autosuggestTextarea) return
|
||||
|
||||
// This statement does several things:
|
||||
// - If we're beginning a reply, and,
|
||||
@@ -196,17 +199,13 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
setAutosuggestTextarea = (c) => {
|
||||
this.autosuggestTextarea = c;
|
||||
this.autosuggestTextarea = c
|
||||
}
|
||||
|
||||
setForm = (c) => {
|
||||
this.form = c
|
||||
}
|
||||
|
||||
setSpoilerText = (c) => {
|
||||
this.spoilerText = c
|
||||
}
|
||||
|
||||
handleEmojiPick = (data) => {
|
||||
const { text } = this.props
|
||||
const position = this.autosuggestTextarea.textbox.selectionStart
|
||||
@@ -236,12 +235,13 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
isMatch,
|
||||
isChangingUpload,
|
||||
isSubmitting,
|
||||
selectedGifSrc,
|
||||
} = this.props
|
||||
const disabled = isSubmitting
|
||||
const text = [this.props.spoilerText, countableText(this.props.text)].join('');
|
||||
const disabledButton = disabled || isUploading || isChangingUpload || length(text) > MAX_POST_CHARACTER_COUNT || (length(text) !== 0 && length(text.trim()) === 0 && !anyMedia);
|
||||
const shouldAutoFocus = autoFocus && !showSearch && !isMobile(window.innerWidth)
|
||||
|
||||
|
||||
const parentContainerClasses = CX({
|
||||
default: 1,
|
||||
width100PC: 1,
|
||||
@@ -294,7 +294,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
>
|
||||
|
||||
{
|
||||
!!reduxReplyToId && !shouldCondense &&
|
||||
!!reduxReplyToId && !shouldCondense && isModalOpen &&
|
||||
<div className={[_s.default, _s.px15, _s.py10, _s.mt5].join(' ')}>
|
||||
<StatusContainer
|
||||
id={reduxReplyToId}
|
||||
@@ -306,19 +306,13 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
{
|
||||
!!spoiler &&
|
||||
<div className={[_s.default, _s.px15, _s.py10, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
|
||||
<AutosuggestTextbox
|
||||
<Input
|
||||
placeholder={intl.formatMessage(messages.spoiler_placeholder)}
|
||||
value={this.props.spoilerText}
|
||||
onChange={this.handleChangeSpoilerText}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
disabled={!this.props.spoiler}
|
||||
ref={this.setSpoilerText}
|
||||
suggestions={this.props.suggestions}
|
||||
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
|
||||
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
|
||||
onSuggestionSelected={this.onSpoilerSuggestionSelected}
|
||||
searchTokens={[':']}
|
||||
prependIcon='warning'
|
||||
maxLength={256}
|
||||
id='cw-spoiler-input'
|
||||
/>
|
||||
</div>
|
||||
@@ -349,12 +343,17 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
</div>
|
||||
}
|
||||
|
||||
{ /* : todo : for gif
|
||||
(isUploading || hasGif) &&
|
||||
{
|
||||
/*
|
||||
!!selectedGifSrc && !anyMedia &&
|
||||
<div className={[_s.default, _s.px15].join(' ')}>
|
||||
<UploadForm replyToId={replyToId} />
|
||||
<GifForm
|
||||
replyToId={replyToId}
|
||||
small={shouldCondense}
|
||||
selectedGifSrc={selectedGifSrc}
|
||||
/>
|
||||
</div>
|
||||
*/
|
||||
*/
|
||||
}
|
||||
|
||||
{
|
||||
@@ -365,7 +364,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
{
|
||||
!!quoteOfId &&
|
||||
!!quoteOfId && isModalOpen &&
|
||||
<div className={[_s.default, _s.px15, _s.py10, _s.mt5].join(' ')}>
|
||||
<StatusContainer
|
||||
id={quoteOfId}
|
||||
@@ -376,29 +375,21 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
|
||||
<div className={actionsContainerClasses}>
|
||||
<div className={[_s.default, _s.flexRow, _s.mrAuto].join(' ')}>
|
||||
{
|
||||
!shouldCondense &&
|
||||
<RichTextEditorButton />
|
||||
}
|
||||
|
||||
<EmojiPickerButton small={shouldCondense} isMatch={isMatch} />
|
||||
|
||||
<UploadButton small={shouldCondense} />
|
||||
{ /* <GifSelectorButton small={shouldCondense} /> */ }
|
||||
|
||||
{
|
||||
!edit && !shouldCondense &&
|
||||
<PollButton />
|
||||
}
|
||||
{
|
||||
!shouldCondense &&
|
||||
<StatusVisibilityButton />
|
||||
}
|
||||
{
|
||||
!shouldCondense &&
|
||||
<SpoilerButton />
|
||||
}
|
||||
{
|
||||
!shouldCondense &&
|
||||
<SchedulePostButton />
|
||||
}
|
||||
<GifSelectorButton small={shouldCondense} />
|
||||
<EmojiPickerButton small={shouldCondense} isMatch={isMatch} />
|
||||
|
||||
{ !shouldCondense && <StatusVisibilityButton /> }
|
||||
{ !shouldCondense && <SpoilerButton /> }
|
||||
{ !shouldCondense && <SchedulePostButton /> }
|
||||
{ /* !shouldCondense && <RichTextEditorButton /> */ }
|
||||
|
||||
{
|
||||
shouldCondense &&
|
||||
|
||||
@@ -1,36 +1,39 @@
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ProgressBar from '../../../../components/progress_bar'
|
||||
import Upload from '../media_upload_item'
|
||||
import SensitiveMediaButton from '../sensitive_media_button'
|
||||
import { clearSelectedGif } from '../../../actions/tenor'
|
||||
import Image from '../../../components/image'
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
mediaIds: state.getIn(['compose', 'media_attachments']).map(item => item.get('id')),
|
||||
isUploading: state.getIn(['compose', 'is_uploading']),
|
||||
uploadProgress: state.getIn(['compose', 'progress']),
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
onClearSelectedGif() {
|
||||
dispatch(clearSelectedGif())
|
||||
},
|
||||
})
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps)
|
||||
class GifForm extends ImmutablePureComponent {
|
||||
@connect(null, mapDispatchToProps)
|
||||
class GifForm extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
mediaIds: ImmutablePropTypes.list.isRequired,
|
||||
isUploading: PropTypes.bool,
|
||||
uploadProgress: PropTypes.number,
|
||||
};
|
||||
onClearSelectedGif: PropTypes.func.isRequired,
|
||||
replyToId: PropTypes.string,
|
||||
small: PropTypes.bool,
|
||||
selectedGifSrc: PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
render () {
|
||||
const {
|
||||
mediaIds,
|
||||
isUploading,
|
||||
uploadProgress,
|
||||
selectedGifSrc,
|
||||
small,
|
||||
} = this.props
|
||||
|
||||
if (!selectedGifSrc) return null
|
||||
|
||||
return (
|
||||
<div className={_s.default}>
|
||||
<div className={[_s.default, _s.flexRow, _s.flexWrap].join(' ')}>
|
||||
<Upload id={id} key={id} />
|
||||
<Image
|
||||
width='auto'
|
||||
src={selectedGifSrc}
|
||||
className={[_s.maxWidth100PC, _s.radiusSmall, _s.height260PX].join(' ')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -12,7 +12,7 @@ const messages = defineMessages({
|
||||
const makeMapStateToProps = () => {
|
||||
const mapStateToProps = (state) => ({
|
||||
acceptContentTypes: state.getIn(['media_attachments', 'accept_content_types']),
|
||||
disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size + state.getIn(['compose', 'pending_media_attachments']) > 3 || state.getIn(['compose', 'media_attachments']).some(m => m.get('type') === 'video')),
|
||||
disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size + state.getIn(['compose', 'pending_media_attachments']) > 3 || state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio', 'gifv'].includes(m.get('type')))),
|
||||
unavailable: state.getIn(['compose', 'poll']) !== null,
|
||||
resetFileKey: state.getIn(['compose', 'resetFileKey']),
|
||||
})
|
||||
|
||||
@@ -7,6 +7,7 @@ import { submitCompose } from '../../../actions/compose';
|
||||
import Button from '../../../components/button'
|
||||
import Image from '../../../components/image'
|
||||
import Input from '../../../components/input'
|
||||
import Text from '../../../components/text'
|
||||
|
||||
const cx = classNames.bind(_s)
|
||||
|
||||
@@ -15,27 +16,20 @@ const messages = defineMessages({
|
||||
delete: { id: 'upload_form.undo', defaultMessage: 'Delete' },
|
||||
})
|
||||
|
||||
const mapStateToProps = (state, { id, otherProps }) => {
|
||||
console.log("otherProps:", otherProps)
|
||||
return {
|
||||
media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id),
|
||||
}
|
||||
}
|
||||
const mapStateToProps = (state, { id }) => ({
|
||||
media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id),
|
||||
})
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
|
||||
onUndo: id => {
|
||||
dispatch(undoUploadCompose(id));
|
||||
onUndo: (id) => {
|
||||
dispatch(undoUploadCompose(id))
|
||||
},
|
||||
|
||||
onDescriptionChange: (id, description) => {
|
||||
dispatch(changeUploadCompose(id, { description }));
|
||||
dispatch(changeUploadCompose(id, { description }))
|
||||
},
|
||||
|
||||
onSubmit () {
|
||||
dispatch(submitCompose());
|
||||
dispatch(submitCompose())
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
export default
|
||||
@@ -72,13 +66,13 @@ class Upload extends ImmutablePureComponent {
|
||||
this.props.onSubmit()
|
||||
}
|
||||
|
||||
handleUndoClick = e => {
|
||||
handleUndoClick = (e) => {
|
||||
e.stopPropagation()
|
||||
this.props.onUndo(this.props.media.get('id'))
|
||||
}
|
||||
|
||||
handleInputChange = e => {
|
||||
this.setState({ dirtyDescription: e.target.value })
|
||||
handleInputChange = (value) => {
|
||||
this.setState({ dirtyDescription: value })
|
||||
}
|
||||
|
||||
handleMouseEnter = () => {
|
||||
@@ -128,8 +122,6 @@ class Upload extends ImmutablePureComponent {
|
||||
displayNone: !active,
|
||||
})
|
||||
|
||||
console.log("media:", media)
|
||||
|
||||
return (
|
||||
<div
|
||||
tabIndex='0'
|
||||
@@ -144,6 +136,12 @@ class Upload extends ImmutablePureComponent {
|
||||
className={[_s.default, _s.height158PX].join(' ')}
|
||||
src={media.get('preview_url')}
|
||||
/>
|
||||
{
|
||||
media.get('type') === 'gifv' &&
|
||||
<div className={[_s.default, _s.posAbs, _s.z2, _s.radiusSmall, _s.bgBlackOpaque, _s.px5, _s.py5, _s.ml10, _s.mt10, _s.top0, _s.left0].join(' ')}>
|
||||
<Text size='extraSmall' color='white' weight='medium'>GIF</Text>
|
||||
</div>
|
||||
}
|
||||
<Button
|
||||
backgroundColor='black'
|
||||
color='white'
|
||||
|
||||
@@ -7,14 +7,11 @@ import {
|
||||
removePollOption,
|
||||
changePollOption,
|
||||
changePollSettings,
|
||||
clearComposeSuggestions,
|
||||
fetchComposeSuggestions,
|
||||
selectComposeSuggestion,
|
||||
} from '../../../actions/compose'
|
||||
import Button from '../../../components/button'
|
||||
import Text from '../../../components/text'
|
||||
import Select from '../../../components/select'
|
||||
import AutosuggestTextbox from '../../../components/autosuggest_textbox'
|
||||
import Input from '../../../components/input'
|
||||
|
||||
const cx = classNames.bind(_s)
|
||||
|
||||
@@ -29,7 +26,6 @@ const messages = defineMessages({
|
||||
})
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
suggestions: state.getIn(['compose', 'suggestions']),
|
||||
options: state.getIn(['compose', 'poll', 'options']),
|
||||
expiresIn: state.getIn(['compose', 'poll', 'expires_in']),
|
||||
isMultiple: state.getIn(['compose', 'poll', 'multiple']),
|
||||
@@ -52,18 +48,6 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
dispatch(changePollSettings(expiresIn, isMultiple))
|
||||
},
|
||||
|
||||
onClearSuggestions () {
|
||||
dispatch(clearComposeSuggestions())
|
||||
},
|
||||
|
||||
onFetchSuggestions (token) {
|
||||
dispatch(fetchComposeSuggestions(token))
|
||||
},
|
||||
|
||||
onSuggestionSelected (position, token, accountId, path) {
|
||||
dispatch(selectComposeSuggestion(position, token, accountId, path))
|
||||
},
|
||||
|
||||
})
|
||||
|
||||
export default
|
||||
@@ -79,10 +63,6 @@ class PollForm extends ImmutablePureComponent {
|
||||
onAddOption: PropTypes.func.isRequired,
|
||||
onRemoveOption: PropTypes.func.isRequired,
|
||||
onChangeSettings: PropTypes.func.isRequired,
|
||||
suggestions: ImmutablePropTypes.list,
|
||||
onClearSuggestions: PropTypes.func.isRequired,
|
||||
onFetchSuggestions: PropTypes.func.isRequired,
|
||||
onSuggestionSelected: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
@@ -200,15 +180,11 @@ class PollFormOption extends ImmutablePureComponent {
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onRemove: PropTypes.func.isRequired,
|
||||
onToggleMultiple: PropTypes.func.isRequired,
|
||||
suggestions: ImmutablePropTypes.list,
|
||||
onClearSuggestions: PropTypes.func.isRequired,
|
||||
onFetchSuggestions: PropTypes.func.isRequired,
|
||||
onSuggestionSelected: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
handleOptionTitleChange = e => {
|
||||
this.props.onChange(this.props.index, e.target.value)
|
||||
handleOptionTitleChange = (value) => {
|
||||
this.props.onChange(this.props.index, value)
|
||||
}
|
||||
|
||||
handleOptionRemove = () => {
|
||||
@@ -221,18 +197,6 @@ class PollFormOption extends ImmutablePureComponent {
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
||||
onSuggestionsClearRequested = () => {
|
||||
this.props.onClearSuggestions()
|
||||
}
|
||||
|
||||
onSuggestionsFetchRequested = (token) => {
|
||||
this.props.onFetchSuggestions(token)
|
||||
}
|
||||
|
||||
onSuggestionSelected = (tokenStart, token, value) => {
|
||||
this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index])
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isPollMultiple, title, index, intl } = this.props
|
||||
|
||||
@@ -257,16 +221,11 @@ class PollFormOption extends ImmutablePureComponent {
|
||||
tabIndex='0'
|
||||
/>
|
||||
|
||||
<AutosuggestTextbox
|
||||
<Input
|
||||
placeholder={intl.formatMessage(messages.option_placeholder, { number: index + 1 })}
|
||||
maxLength={25}
|
||||
maxLength={64}
|
||||
value={title}
|
||||
onChange={this.handleOptionTitleChange}
|
||||
suggestions={this.props.suggestions}
|
||||
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
|
||||
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
|
||||
onSuggestionSelected={this.onSuggestionSelected}
|
||||
searchTokens={[':']}
|
||||
/>
|
||||
</label>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user