about summary refs log tree commit diff
path: root/app/javascript/mastodon/features/compose/components/compose_form.js
diff options
context:
space:
mode:
authorRenaud Chaput <renchap@gmail.com>2023-02-20 03:20:59 +0100
committerGitHub <noreply@github.com>2023-02-20 03:20:59 +0100
commit44a7d87cb1f5df953b6c14c16c59e2e4ead1bcb9 (patch)
tree71b60ccd9b23ec8f8d72fa3562f0bc343c6e456e /app/javascript/mastodon/features/compose/components/compose_form.js
parentf0e1b12c101e0dd0ddaaef8bdcc166624dba62d5 (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.js301
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>
-    );
-  }
-
-}