diff --git a/app/javascript/flavours/glitch/components/autosuggest_textarea.jsx b/app/javascript/flavours/glitch/components/autosuggest_textarea.jsx index 137bad9b7e..a9acc87252 100644 --- a/app/javascript/flavours/glitch/components/autosuggest_textarea.jsx +++ b/app/javascript/flavours/glitch/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/flavours/glitch/features/compose/components/compose_form.jsx b/app/javascript/flavours/glitch/features/compose/components/compose_form.jsx index 84dfdacd38..f3f193aea3 100644 --- a/app/javascript/flavours/glitch/features/compose/components/compose_form.jsx +++ b/app/javascript/flavours/glitch/features/compose/components/compose_form.jsx @@ -71,6 +71,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, @@ -271,7 +272,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 ( @@ -327,6 +328,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/flavours/glitch/features/compose/containers/compose_form_container.js b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js index eb9efb2e32..92345febb9 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js @@ -36,6 +36,24 @@ const sideArmPrivacy = state => { return sideArmPrivacy || sideArmBasePrivacy; }; +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']), @@ -107,20 +125,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) {