diff options
author | Renaud Chaput <renchap@gmail.com> | 2023-02-20 03:20:59 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-20 03:20:59 +0100 |
commit | 44a7d87cb1f5df953b6c14c16c59e2e4ead1bcb9 (patch) | |
tree | 71b60ccd9b23ec8f8d72fa3562f0bc343c6e456e /app/javascript/mastodon/features/compose/components/compose_form.js | |
parent | f0e1b12c101e0dd0ddaaef8bdcc166624dba62d5 (diff) |
Rename JSX files with proper `.jsx` extension (#23733)
Diffstat (limited to 'app/javascript/mastodon/features/compose/components/compose_form.js')
-rw-r--r-- | app/javascript/mastodon/features/compose/components/compose_form.js | 301 |
1 files changed, 0 insertions, 301 deletions
diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js deleted file mode 100644 index e641d59f4..000000000 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ /dev/null @@ -1,301 +0,0 @@ -import React from 'react'; -import CharacterCounter from './character_counter'; -import Button from '../../../components/button'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import PropTypes from 'prop-types'; -import ReplyIndicatorContainer from '../containers/reply_indicator_container'; -import AutosuggestTextarea from '../../../components/autosuggest_textarea'; -import AutosuggestInput from '../../../components/autosuggest_input'; -import PollButtonContainer from '../containers/poll_button_container'; -import UploadButtonContainer from '../containers/upload_button_container'; -import { defineMessages, injectIntl } from 'react-intl'; -import SpoilerButtonContainer from '../containers/spoiler_button_container'; -import PrivacyDropdownContainer from '../containers/privacy_dropdown_container'; -import EmojiPickerDropdown from '../containers/emoji_picker_dropdown_container'; -import PollFormContainer from '../containers/poll_form_container'; -import UploadFormContainer from '../containers/upload_form_container'; -import WarningContainer from '../containers/warning_container'; -import LanguageDropdown from '../containers/language_dropdown_container'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { length } from 'stringz'; -import { countableText } from '../util/counter'; -import Icon from 'mastodon/components/icon'; - -const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d'; - -const messages = defineMessages({ - placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' }, - spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' }, - publish: { id: 'compose_form.publish', defaultMessage: 'Publish' }, - publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' }, - saveChanges: { id: 'compose_form.save_changes', defaultMessage: 'Save changes' }, -}); - -export default @injectIntl -class ComposeForm extends ImmutablePureComponent { - - static contextTypes = { - router: PropTypes.object, - }; - - static propTypes = { - intl: PropTypes.object.isRequired, - text: PropTypes.string.isRequired, - suggestions: ImmutablePropTypes.list, - spoiler: PropTypes.bool, - privacy: PropTypes.string, - spoilerText: PropTypes.string, - focusDate: PropTypes.instanceOf(Date), - caretPosition: PropTypes.number, - preselectDate: PropTypes.instanceOf(Date), - isSubmitting: PropTypes.bool, - isChangingUpload: PropTypes.bool, - isEditing: PropTypes.bool, - isUploading: PropTypes.bool, - onChange: PropTypes.func.isRequired, - onSubmit: PropTypes.func.isRequired, - onClearSuggestions: PropTypes.func.isRequired, - onFetchSuggestions: PropTypes.func.isRequired, - onSuggestionSelected: PropTypes.func.isRequired, - onChangeSpoilerText: PropTypes.func.isRequired, - onPaste: PropTypes.func.isRequired, - onPickEmoji: PropTypes.func.isRequired, - autoFocus: PropTypes.bool, - anyMedia: PropTypes.bool, - isInReply: PropTypes.bool, - singleColumn: PropTypes.bool, - lang: PropTypes.string, - }; - - static defaultProps = { - autoFocus: false, - }; - - handleChange = (e) => { - this.props.onChange(e.target.value); - }; - - handleKeyDown = (e) => { - if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) { - this.handleSubmit(); - } - }; - - getFulltextForCharacterCounting = () => { - return [this.props.spoiler? this.props.spoilerText: '', countableText(this.props.text)].join(''); - }; - - canSubmit = () => { - const { isSubmitting, isChangingUpload, isUploading, anyMedia } = this.props; - const fulltext = this.getFulltextForCharacterCounting(); - const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0; - - return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 500 || (isOnlyWhitespace && !anyMedia)); - }; - - handleSubmit = (e) => { - if (this.props.text !== this.autosuggestTextarea.textarea.value) { - // Something changed the text inside the textarea (e.g. browser extensions like Grammarly) - // Update the state to match the current text - this.props.onChange(this.autosuggestTextarea.textarea.value); - } - - if (!this.canSubmit()) { - return; - } - - this.props.onSubmit(this.context.router ? this.context.router.history : null); - - if (e) { - e.preventDefault(); - } - }; - - onSuggestionsClearRequested = () => { - this.props.onClearSuggestions(); - }; - - onSuggestionsFetchRequested = (token) => { - this.props.onFetchSuggestions(token); - }; - - onSuggestionSelected = (tokenStart, token, value) => { - this.props.onSuggestionSelected(tokenStart, token, value, ['text']); - }; - - onSpoilerSuggestionSelected = (tokenStart, token, value) => { - this.props.onSuggestionSelected(tokenStart, token, value, ['spoiler_text']); - }; - - handleChangeSpoilerText = (e) => { - this.props.onChangeSpoilerText(e.target.value); - }; - - handleFocus = () => { - if (this.composeForm && !this.props.singleColumn) { - const { left, right } = this.composeForm.getBoundingClientRect(); - if (left < 0 || right > (window.innerWidth || document.documentElement.clientWidth)) { - this.composeForm.scrollIntoView(); - } - } - }; - - componentDidMount () { - this._updateFocusAndSelection({ }); - } - - componentDidUpdate (prevProps) { - this._updateFocusAndSelection(prevProps); - } - - _updateFocusAndSelection = (prevProps) => { - // This statement does several things: - // - If we're beginning a reply, and, - // - Replying to zero or one users, places the cursor at the end of the textbox. - // - Replying to more than one user, selects any usernames past the first; - // this provides a convenient shortcut to drop everyone else from the conversation. - if (this.props.focusDate && this.props.focusDate !== prevProps.focusDate) { - let selectionEnd, selectionStart; - - if (this.props.preselectDate !== prevProps.preselectDate && this.props.isInReply) { - selectionEnd = this.props.text.length; - selectionStart = this.props.text.search(/\s/) + 1; - } else if (typeof this.props.caretPosition === 'number') { - selectionStart = this.props.caretPosition; - selectionEnd = this.props.caretPosition; - } else { - selectionEnd = this.props.text.length; - selectionStart = selectionEnd; - } - - // Because of the wicg-inert polyfill, the activeElement may not be - // immediately selectable, we have to wait for observers to run, as - // described in https://github.com/WICG/inert#performance-and-gotchas - Promise.resolve().then(() => { - this.autosuggestTextarea.textarea.setSelectionRange(selectionStart, selectionEnd); - this.autosuggestTextarea.textarea.focus(); - }).catch(console.error); - } else if(prevProps.isSubmitting && !this.props.isSubmitting) { - this.autosuggestTextarea.textarea.focus(); - } else if (this.props.spoiler !== prevProps.spoiler) { - if (this.props.spoiler) { - this.spoilerText.input.focus(); - } else if (prevProps.spoiler) { - this.autosuggestTextarea.textarea.focus(); - } - } - }; - - setAutosuggestTextarea = (c) => { - this.autosuggestTextarea = c; - }; - - setSpoilerText = (c) => { - this.spoilerText = c; - }; - - setRef = c => { - this.composeForm = c; - }; - - handleEmojiPick = (data) => { - const { text } = this.props; - const position = this.autosuggestTextarea.textarea.selectionStart; - const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1]); - - this.props.onPickEmoji(position, data, needsSpace); - }; - - render () { - const { intl, onPaste, autoFocus } = this.props; - const disabled = this.props.isSubmitting; - - let publishText = ''; - - if (this.props.isEditing) { - publishText = intl.formatMessage(messages.saveChanges); - } else if (this.props.privacy === 'private' || this.props.privacy === 'direct') { - publishText = <span className='compose-form__publish-private'><Icon id='lock' /> {intl.formatMessage(messages.publish)}</span>; - } else { - publishText = this.props.privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish); - } - - return ( - <form className='compose-form' onSubmit={this.handleSubmit}> - <WarningContainer /> - - <ReplyIndicatorContainer /> - - <div className={`spoiler-input ${this.props.spoiler ? 'spoiler-input--visible' : ''}`} ref={this.setRef} aria-hidden={!this.props.spoiler}> - <AutosuggestInput - 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={[':']} - id='cw-spoiler-input' - className='spoiler-input__input' - lang={this.props.lang} - spellCheck - /> - </div> - - <AutosuggestTextarea - ref={this.setAutosuggestTextarea} - placeholder={intl.formatMessage(messages.placeholder)} - disabled={disabled} - value={this.props.text} - onChange={this.handleChange} - suggestions={this.props.suggestions} - onFocus={this.handleFocus} - onKeyDown={this.handleKeyDown} - onSuggestionsFetchRequested={this.onSuggestionsFetchRequested} - onSuggestionsClearRequested={this.onSuggestionsClearRequested} - onSuggestionSelected={this.onSuggestionSelected} - onPaste={onPaste} - autoFocus={autoFocus} - lang={this.props.lang} - > - <EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} /> - - <div className='compose-form__modifiers'> - <UploadFormContainer /> - <PollFormContainer /> - </div> - </AutosuggestTextarea> - - <div className='compose-form__buttons-wrapper'> - <div className='compose-form__buttons'> - <UploadButtonContainer /> - <PollButtonContainer /> - <PrivacyDropdownContainer disabled={this.props.isEditing} /> - <SpoilerButtonContainer /> - <LanguageDropdown /> - </div> - - <div className='character-counter__wrapper'> - <CharacterCounter max={500} text={this.getFulltextForCharacterCounting()} /> - </div> - </div> - - <div className='compose-form__publish'> - <div className='compose-form__publish-button-wrapper'> - <Button - type='submit' - text={publishText} - disabled={!this.canSubmit()} - block - /> - </div> - </div> - </form> - ); - } - -} |