diff --git a/app/javascript/mastodon/components/autosuggest_textarea.jsx b/app/javascript/mastodon/components/autosuggest_textarea.jsx index 137bad9b7e..a9acc87252 100644 --- a/app/javascript/mastodon/components/autosuggest_textarea.jsx +++ b/app/javascript/mastodon/components/autosuggest_textarea.jsx @@ -50,6 +50,7 @@ const AutosuggestTextarea = forwardRef(({ onKeyUp, onKeyDown, onPaste, + onDrop, onFocus, autoFocus = true, lang, @@ -153,6 +154,12 @@ const AutosuggestTextarea = forwardRef(({ onPaste(e); }, [onPaste]); + const handleDrop = useCallback((e) => { + if (onDrop) { + onDrop(e); + } + }, [onDrop]); + // Show the suggestions again whenever they change and the textarea is focused useEffect(() => { if (suggestions.size > 0 && textareaRef.current === document.activeElement) { @@ -204,6 +211,7 @@ const AutosuggestTextarea = forwardRef(({ onFocus={handleFocus} onBlur={handleBlur} onPaste={handlePaste} + onDrop={handleDrop} dir='auto' aria-autocomplete='list' aria-label={placeholder} @@ -235,6 +243,7 @@ AutosuggestTextarea.propTypes = { onKeyUp: PropTypes.func, onKeyDown: PropTypes.func, onPaste: PropTypes.func.isRequired, + onDrop: PropTypes.func, onFocus:PropTypes.func, autoFocus: PropTypes.bool, lang: PropTypes.string, diff --git a/app/javascript/mastodon/features/compose/components/compose_form.jsx b/app/javascript/mastodon/features/compose/components/compose_form.jsx index 7f86f8fd84..ec2b531b5f 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.jsx +++ b/app/javascript/mastodon/features/compose/components/compose_form.jsx @@ -64,6 +64,7 @@ class ComposeForm extends ImmutablePureComponent { onSuggestionSelected: PropTypes.func.isRequired, onChangeSpoilerText: PropTypes.func.isRequired, onPaste: PropTypes.func.isRequired, + onDrop: PropTypes.func.isRequired, onPickEmoji: PropTypes.func.isRequired, autoFocus: PropTypes.bool, withoutNavigation: PropTypes.bool, @@ -249,7 +250,7 @@ class ComposeForm extends ImmutablePureComponent { }; render () { - const { intl, onPaste, autoFocus, withoutNavigation, maxChars, isSubmitting } = this.props; + const { intl, onPaste, onDrop, autoFocus, withoutNavigation, maxChars, isSubmitting } = this.props; const { highlighted } = this.state; return ( @@ -305,6 +306,7 @@ class ComposeForm extends ImmutablePureComponent { onSuggestionsClearRequested={this.onSuggestionsClearRequested} onSuggestionSelected={this.onSuggestionSelected} onPaste={onPaste} + onDrop={onDrop} autoFocus={autoFocus} lang={this.props.lang} className='compose-form__input' diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js index 15b1c7cc41..637ef21c3e 100644 --- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js +++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js @@ -18,6 +18,24 @@ import ComposeForm from '../components/compose_form'; const urlLikeRegex = /^https?:\/\/[^\s]+\/[^\s]+$/i; +const processPasteOrDrop = (transfer, e, dispatch) => { + if (transfer && transfer.files.length === 1) { + dispatch(uploadCompose(transfer.files)); + e.preventDefault(); + } else if (transfer && transfer.files.length === 0) { + const data = transfer.getData('text/plain'); + if (!data.match(urlLikeRegex)) return; + + try { + const url = new URL(data); + dispatch(pasteLinkCompose({ url })); + e.preventDefault(); + } catch { + return; + } + } +}; + const mapStateToProps = state => ({ text: state.getIn(['compose', 'text']), suggestions: state.getIn(['compose', 'suggestions']), @@ -85,20 +103,11 @@ const mapDispatchToProps = (dispatch, props) => ({ }, onPaste (e) { - if (e.clipboardData && e.clipboardData.files.length === 1) { - dispatch(uploadCompose(e.clipboardData.files)); - e.preventDefault(); - } else if (e.clipboardData && e.clipboardData.files.length === 0) { - const data = e.clipboardData.getData('text/plain'); - if (!data.match(urlLikeRegex)) return; + processPasteOrDrop(e.clipboardData, e, dispatch); + }, - try { - const url = new URL(data); - dispatch(pasteLinkCompose({ url })); - } catch { - return; - } - } + onDrop (e) { + processPasteOrDrop(e.dataTransfer, e, dispatch); }, onPickEmoji (position, data, needsSpace) {