sforkowany z mirror/soapbox
Fixed problem with drag/drop in compose form. Need to try to uncondense compose form when dropping file onto it
rodzic
6ab8461551
commit
65e45e136a
|
@ -1,5 +1,4 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container';
|
||||
import AutosuggestEmoji from './autosuggest_emoji';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
|
@ -8,8 +7,6 @@ import { isRtl } from '../rtl';
|
|||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import Textarea from 'react-textarea-autosize';
|
||||
import classNames from 'classnames';
|
||||
import UploadArea from 'soapbox/features/ui/components/upload_area';
|
||||
import { uploadCompose } from 'soapbox/actions/compose';
|
||||
|
||||
const textAtCursorMatchesToken = (str, caretPosition) => {
|
||||
let word;
|
||||
|
@ -36,11 +33,9 @@ const textAtCursorMatchesToken = (str, caretPosition) => {
|
|||
}
|
||||
};
|
||||
|
||||
export default @connect()
|
||||
class AutosuggestTextarea extends ImmutablePureComponent {
|
||||
export default class AutosuggestTextarea extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
value: PropTypes.string,
|
||||
suggestions: ImmutablePropTypes.list,
|
||||
disabled: PropTypes.bool,
|
||||
|
@ -55,7 +50,6 @@ class AutosuggestTextarea extends ImmutablePureComponent {
|
|||
autoFocus: PropTypes.bool,
|
||||
onFocus: PropTypes.func,
|
||||
onBlur: PropTypes.func,
|
||||
onAttachment: PropTypes.func,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
@ -68,25 +62,8 @@ class AutosuggestTextarea extends ImmutablePureComponent {
|
|||
selectedSuggestion: 0,
|
||||
lastToken: null,
|
||||
tokenStart: 0,
|
||||
draggingOver: false,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.node.addEventListener('dragenter', this.handleDragEnter, false);
|
||||
this.node.addEventListener('dragover', this.handleDragOver, false);
|
||||
this.node.addEventListener('drop', this.handleDrop, false);
|
||||
this.node.addEventListener('dragleave', this.handleDragLeave, false);
|
||||
this.node.addEventListener('dragend', this.handleDragEnd, false);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.node.removeEventListener('dragenter', this.handleDragEnter);
|
||||
this.node.removeEventListener('dragover', this.handleDragOver);
|
||||
this.node.removeEventListener('drop', this.handleDrop);
|
||||
this.node.removeEventListener('dragleave', this.handleDragLeave);
|
||||
this.node.removeEventListener('dragend', this.handleDragEnd);
|
||||
}
|
||||
|
||||
onChange = (e) => {
|
||||
const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart);
|
||||
|
||||
|
@ -193,96 +170,6 @@ class AutosuggestTextarea extends ImmutablePureComponent {
|
|||
this.textarea = c;
|
||||
}
|
||||
|
||||
setRef = c => {
|
||||
this.node = c;
|
||||
}
|
||||
|
||||
dataTransferIsText = (dataTransfer) => {
|
||||
return (dataTransfer && Array.from(dataTransfer.types).includes('text/plain') && dataTransfer.items.length === 1);
|
||||
}
|
||||
|
||||
handleDragEnter = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!this.dragTargets) {
|
||||
this.dragTargets = [];
|
||||
}
|
||||
|
||||
if (this.dragTargets.indexOf(e.target) === -1) {
|
||||
this.dragTargets.push(e.target);
|
||||
}
|
||||
|
||||
if (e.dataTransfer && Array.from(e.dataTransfer.types).includes('Files')) {
|
||||
this.setState({ draggingOver: true });
|
||||
}
|
||||
}
|
||||
|
||||
handleDragOver = (e) => {
|
||||
if (this.dataTransferIsText(e.dataTransfer)) return false;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
try {
|
||||
e.dataTransfer.dropEffect = 'copy';
|
||||
} catch (err) {
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
handleAttachment = () => {
|
||||
const { onAttachment } = this.props;
|
||||
onAttachment(true);
|
||||
}
|
||||
|
||||
handleFiles = (files) => {
|
||||
const { dispatch } = this.props;
|
||||
|
||||
this.setState({ isUploading: true });
|
||||
|
||||
// const data = new FormData();
|
||||
// data.append('file', files[0]);
|
||||
dispatch(uploadCompose(files));
|
||||
dispatch(this.handleAttachment());
|
||||
// dispatch(uploadMedia(data, this.onUploadProgress)).then(response => {
|
||||
// this.setState({ attachment: response.data, isUploading: false });
|
||||
// this.handleAttachment();
|
||||
// }).catch(() => {
|
||||
// this.setState({ isUploading: false });
|
||||
// });
|
||||
}
|
||||
|
||||
handleDrop = (e) => {
|
||||
if (this.dataTransferIsText(e.dataTransfer)) return;
|
||||
e.preventDefault();
|
||||
|
||||
this.setState({ draggingOver: false });
|
||||
this.dragTargets = [];
|
||||
|
||||
if (e.dataTransfer && e.dataTransfer.files.length >= 1) {
|
||||
this.handleFiles(e.dataTransfer.files);
|
||||
// this.props.dispatch(uploadCompose(e.dataTransfer.files));
|
||||
}
|
||||
}
|
||||
|
||||
handleDragLeave = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
this.dragTargets = this.dragTargets.filter(el => el !== e.target && this.node.contains(el));
|
||||
|
||||
if (this.dragTargets.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ draggingOver: false });
|
||||
}
|
||||
|
||||
closeUploadModal = () => {
|
||||
this.setState({ draggingOver: false });
|
||||
}
|
||||
|
||||
onPaste = (e) => {
|
||||
if (e.clipboardData && e.clipboardData.files.length === 1) {
|
||||
this.props.onPaste(e.clipboardData.files);
|
||||
|
@ -314,7 +201,7 @@ class AutosuggestTextarea extends ImmutablePureComponent {
|
|||
|
||||
render() {
|
||||
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, children } = this.props;
|
||||
const { draggingOver, suggestionsHidden } = this.state;
|
||||
const { suggestionsHidden } = this.state;
|
||||
const style = { direction: 'ltr' };
|
||||
|
||||
if (isRtl(value)) {
|
||||
|
@ -322,9 +209,8 @@ class AutosuggestTextarea extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
return [
|
||||
<div className='compose-form__autosuggest-wrapper' key='compose-form__autosuggest-wrapper' ref={this.setRef}>
|
||||
<div className='compose-form__autosuggest-wrapper' key='compose-form__autosuggest-wrapper'>
|
||||
<div className='autosuggest-textarea'>
|
||||
<UploadArea active={draggingOver} onClose={this.closeUploadModal} />
|
||||
<label>
|
||||
<span style={{ display: 'none' }}>{placeholder}</span>
|
||||
|
||||
|
|
|
@ -281,9 +281,8 @@ class ChatBox extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { chatMessageIds, chatId, intl, windowState } = this.props;
|
||||
const { chatMessageIds, chatId, intl } = this.props;
|
||||
const { content, isUploading, uploadProgress } = this.state;
|
||||
console.log('window state: ' + windowState + ', chatID: ' + chatId);
|
||||
if (!chatMessageIds) return null;
|
||||
|
||||
return (
|
||||
|
|
|
@ -10,6 +10,7 @@ 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 { connect } from 'react-redux';
|
||||
import SpoilerButtonContainer from '../containers/spoiler_button_container';
|
||||
import MarkdownButtonContainer from '../containers/markdown_button_container';
|
||||
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
|
||||
|
@ -23,6 +24,8 @@ import { length } from 'stringz';
|
|||
import { countableText } from '../util/counter';
|
||||
import Icon from 'soapbox/components/icon';
|
||||
import { get } from 'lodash';
|
||||
import UploadArea from 'soapbox/features/ui/components/upload_area';
|
||||
import { uploadCompose } from 'soapbox/actions/compose';
|
||||
|
||||
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';
|
||||
|
||||
|
@ -33,7 +36,8 @@ const messages = defineMessages({
|
|||
publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' },
|
||||
});
|
||||
|
||||
export default @injectIntl
|
||||
export default @connect()
|
||||
@injectIntl
|
||||
class ComposeForm extends ImmutablePureComponent {
|
||||
|
||||
state = {
|
||||
|
@ -46,6 +50,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
text: PropTypes.string.isRequired,
|
||||
suggestions: ImmutablePropTypes.list,
|
||||
spoiler: PropTypes.bool,
|
||||
|
@ -87,12 +92,6 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
handleAttachment = () => {
|
||||
this.setState({
|
||||
shouldCondense: false,
|
||||
});
|
||||
}
|
||||
|
||||
handleKeyDown = (e) => {
|
||||
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
|
||||
this.handleSubmit();
|
||||
|
@ -179,13 +178,83 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
componentDidMount() {
|
||||
document.addEventListener('click', this.handleClick, true);
|
||||
this.setCursor(this.props.text.length); // Set cursor at end
|
||||
this.setState({
|
||||
shouldCondense: this.props.shouldCondense,
|
||||
});
|
||||
const composeForm = document.getElementById('compose-form');
|
||||
composeForm.addEventListener('dragenter', this.handleDragEnter, false);
|
||||
composeForm.addEventListener('dragover', this.handleDragOver, false);
|
||||
composeForm.addEventListener('drop', this.handleDrop, false);
|
||||
composeForm.addEventListener('dragleave', this.handleDragLeave, false);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('click', this.handleClick, true);
|
||||
const composeForm = document.getElementById('compose-form');
|
||||
composeForm.removeEventListener('dragenter', this.handleDragEnter);
|
||||
composeForm.removeEventListener('dragover', this.handleDragOver);
|
||||
composeForm.removeEventListener('drop', this.handleDrop);
|
||||
composeForm.removeEventListener('dragleave', this.handleDragLeave);
|
||||
}
|
||||
|
||||
handleDragEnter = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!this.dragTargets) {
|
||||
this.dragTargets = [];
|
||||
}
|
||||
|
||||
if (this.dragTargets.indexOf(e.target) === -1) {
|
||||
this.dragTargets.push(e.target);
|
||||
}
|
||||
|
||||
if (e.dataTransfer && Array.from(e.dataTransfer.types).includes('Files')) {
|
||||
this.setState({ draggingOver: true });
|
||||
}
|
||||
}
|
||||
|
||||
handleDragOver = (e) => {
|
||||
if (this.dataTransferIsText(e.dataTransfer)) return false;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
try {
|
||||
e.dataTransfer.dropEffect = 'copy';
|
||||
} catch (err) {
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
handleDrop = (e) => {
|
||||
if (this.dataTransferIsText(e.dataTransfer)) return;
|
||||
e.preventDefault();
|
||||
|
||||
this.setState({ draggingOver: false });
|
||||
this.dragTargets = [];
|
||||
|
||||
if (e.dataTransfer && e.dataTransfer.files.length >= 1) {
|
||||
this.props.dispatch(uploadCompose(e.dataTransfer.files));
|
||||
}
|
||||
}
|
||||
|
||||
handleDragLeave = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
this.dragTargets = this.dragTargets.filter(el => el !== e.target && this.form.contains(el));
|
||||
|
||||
if (this.dragTargets.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ draggingOver: false });
|
||||
}
|
||||
|
||||
dataTransferIsText = (dataTransfer) => {
|
||||
return (dataTransfer && Array.from(dataTransfer.types).includes('text/plain') && dataTransfer.items.length === 1);
|
||||
}
|
||||
|
||||
closeUploadModal = () => {
|
||||
this.setState({ draggingOver: false });
|
||||
}
|
||||
|
||||
setAutosuggestTextarea = (c) => {
|
||||
|
@ -233,8 +302,8 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { intl, onPaste, showSearch, anyMedia, autoFocus, isModalOpen, maxTootChars } = this.props;
|
||||
const { shouldCondense } = this.state;
|
||||
const { intl, onPaste, showSearch, anyMedia, shouldCondense, autoFocus, isModalOpen, maxTootChars } = this.props;
|
||||
const { draggingOver } = this.state;
|
||||
const condensed = shouldCondense && !this.props.text && !this.state.composeFocused;
|
||||
const disabled = this.props.isSubmitting;
|
||||
const text = [this.props.spoilerText, countableText(this.props.text)].join('');
|
||||
|
@ -255,7 +324,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
});
|
||||
|
||||
return (
|
||||
<div className={composeClassNames} ref={this.setForm} onClick={this.handleClick}>
|
||||
<div className={composeClassNames} ref={this.setForm} onClick={this.handleClick} id='compose-form'>
|
||||
<WarningContainer />
|
||||
|
||||
{ !shouldCondense && <ReplyIndicatorContainer /> }
|
||||
|
@ -281,6 +350,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
<div className='emoji-picker-wrapper'>
|
||||
<EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} />
|
||||
</div>
|
||||
<UploadArea active={draggingOver} onClose={this.closeUploadModal} />
|
||||
|
||||
<AutosuggestTextarea
|
||||
ref={(isModalOpen && shouldCondense) ? null : this.setAutosuggestTextarea}
|
||||
|
@ -295,7 +365,6 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
|
||||
onSuggestionSelected={this.onSuggestionSelected}
|
||||
onPaste={onPaste}
|
||||
onAttachment={this.handleAttachment}
|
||||
autoFocus={shouldAutoFocus}
|
||||
>
|
||||
{
|
||||
|
|
|
@ -295,6 +295,7 @@ class UI extends React.PureComponent {
|
|||
};
|
||||
|
||||
state = {
|
||||
draggingOver: false,
|
||||
mobile: isMobile(window.innerWidth),
|
||||
};
|
||||
|
||||
|
@ -314,6 +315,72 @@ class UI extends React.PureComponent {
|
|||
this.props.dispatch(clearHeight());
|
||||
}
|
||||
|
||||
// handleDragEnter = (e) => {
|
||||
// e.preventDefault();
|
||||
//
|
||||
// if (!this.dragTargets) {
|
||||
// this.dragTargets = [];
|
||||
// }
|
||||
//
|
||||
// if (this.dragTargets.indexOf(e.target) === -1) {
|
||||
// this.dragTargets.push(e.target);
|
||||
// }
|
||||
//
|
||||
// if (e.dataTransfer && Array.from(e.dataTransfer.types).includes('Files')) {
|
||||
// this.setState({ draggingOver: true });
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// handleDragOver = (e) => {
|
||||
// if (this.dataTransferIsText(e.dataTransfer)) return false;
|
||||
// e.preventDefault();
|
||||
// e.stopPropagation();
|
||||
//
|
||||
// try {
|
||||
// e.dataTransfer.dropEffect = 'copy';
|
||||
// } catch (err) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// handleDrop = (e) => {
|
||||
// const { me } = this.props;
|
||||
// if (!me) return;
|
||||
//
|
||||
// if (this.dataTransferIsText(e.dataTransfer)) return;
|
||||
// e.preventDefault();
|
||||
//
|
||||
// this.setState({ draggingOver: false });
|
||||
// this.dragTargets = [];
|
||||
//
|
||||
// if (e.dataTransfer && e.dataTransfer.files.length >= 1) {
|
||||
// this.props.dispatch(uploadCompose(e.dataTransfer.files));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// handleDragLeave = (e) => {
|
||||
// e.preventDefault();
|
||||
// e.stopPropagation();
|
||||
//
|
||||
// this.dragTargets = this.dragTargets.filter(el => el !== e.target && this.node.contains(el));
|
||||
//
|
||||
// if (this.dragTargets.length > 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// this.setState({ draggingOver: false });
|
||||
// }
|
||||
//
|
||||
// dataTransferIsText = (dataTransfer) => {
|
||||
// return (dataTransfer && Array.from(dataTransfer.types).includes('text/plain') && dataTransfer.items.length === 1);
|
||||
// }
|
||||
//
|
||||
// closeUploadModal = () => {
|
||||
// this.setState({ draggingOver: false });
|
||||
// }
|
||||
|
||||
handleServiceWorkerPostMessage = ({ data }) => {
|
||||
if (data.type === 'navigate') {
|
||||
this.context.router.history.push(data.path);
|
||||
|
@ -378,11 +445,6 @@ class UI extends React.PureComponent {
|
|||
componentWillUnmount() {
|
||||
window.removeEventListener('beforeunload', this.handleBeforeUnload);
|
||||
window.removeEventListener('resize', this.handleResize);
|
||||
document.removeEventListener('dragenter', this.handleDragEnter);
|
||||
document.removeEventListener('dragover', this.handleDragOver);
|
||||
document.removeEventListener('drop', this.handleDrop);
|
||||
document.removeEventListener('dragleave', this.handleDragLeave);
|
||||
document.removeEventListener('dragend', this.handleDragEnd);
|
||||
this.disconnectStreaming();
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue