move dnd to MessagesView, otherwise problems with layout
This commit is contained in:
+2
-12
@@ -2976,19 +2976,9 @@ ul.tabbar li.active > a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Drag-and-drop container.
|
Drag-and-drop area.
|
||||||
*/
|
*/
|
||||||
.drag-and-drop {
|
.drag-n-drop {
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drag-and-drop .banner {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
border: dashed grey 0.15rem;
|
border: dashed grey 0.15rem;
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import CallPanel from '../widgets/call-panel.jsx';
|
|||||||
import ChatMessage from '../widgets/chat-message.jsx';
|
import ChatMessage from '../widgets/chat-message.jsx';
|
||||||
import ContactBadges from '../widgets/contact-badges.jsx';
|
import ContactBadges from '../widgets/contact-badges.jsx';
|
||||||
import DocPreview from '../widgets/doc-preview.jsx';
|
import DocPreview from '../widgets/doc-preview.jsx';
|
||||||
import DragAndDrop from '../widgets/drag-and-drop.jsx'
|
|
||||||
import ErrorPanel from '../widgets/error-panel.jsx';
|
import ErrorPanel from '../widgets/error-panel.jsx';
|
||||||
import GroupSubs from '../widgets/group-subs.jsx';
|
import GroupSubs from '../widgets/group-subs.jsx';
|
||||||
import ImagePreview from '../widgets/image-preview.jsx';
|
import ImagePreview from '../widgets/image-preview.jsx';
|
||||||
@@ -117,6 +116,7 @@ class MessagesView extends React.Component {
|
|||||||
this.sendKeyPress = this.sendKeyPress.bind(this);
|
this.sendKeyPress = this.sendKeyPress.bind(this);
|
||||||
this.subscribe = this.subscribe.bind(this);
|
this.subscribe = this.subscribe.bind(this);
|
||||||
this.handleScrollReference = this.handleScrollReference.bind(this);
|
this.handleScrollReference = this.handleScrollReference.bind(this);
|
||||||
|
this.mountDnDEvents = this.mountDnDEvents.bind(this);
|
||||||
this.handleScrollEvent = this.handleScrollEvent.bind(this);
|
this.handleScrollEvent = this.handleScrollEvent.bind(this);
|
||||||
this.handleDescChange = this.handleDescChange.bind(this);
|
this.handleDescChange = this.handleDescChange.bind(this);
|
||||||
this.handleSubsUpdated = this.handleSubsUpdated.bind(this);
|
this.handleSubsUpdated = this.handleSubsUpdated.bind(this);
|
||||||
@@ -144,9 +144,22 @@ class MessagesView extends React.Component {
|
|||||||
this.handleQuoteClick = this.handleQuoteClick.bind(this);
|
this.handleQuoteClick = this.handleQuoteClick.bind(this);
|
||||||
this.handleCallHangup = this.handleCallHangup.bind(this);
|
this.handleCallHangup = this.handleCallHangup.bind(this);
|
||||||
|
|
||||||
|
this.isDragEnabled = this.isDragEnabled.bind(this);
|
||||||
|
this.handleDragIn = this.handleDragIn.bind(this);
|
||||||
|
this.handleDragOut = this.handleDragOut.bind(this);
|
||||||
|
this.handleDrag = this.handleDrag.bind(this);
|
||||||
|
this.handleDrop = this.handleDrop.bind(this);
|
||||||
|
|
||||||
this.chatMessageRefs = {};
|
this.chatMessageRefs = {};
|
||||||
this.getOrCreateMessageRef = this.getOrCreateMessageRef.bind(this);
|
this.getOrCreateMessageRef = this.getOrCreateMessageRef.bind(this);
|
||||||
|
|
||||||
|
// Keeps track of the drag event.
|
||||||
|
// Need a counter b/c the browser's 'drag' events may fire multiple times
|
||||||
|
// when the user takes the mouse pointer over the container:
|
||||||
|
// for the component itself and for all nested/child elements.
|
||||||
|
this.dragCounter = 0;
|
||||||
|
this.dndRef = null;
|
||||||
|
|
||||||
this.readNotificationQueue = [];
|
this.readNotificationQueue = [];
|
||||||
this.readNotificationTimer = null;
|
this.readNotificationTimer = null;
|
||||||
|
|
||||||
@@ -166,6 +179,14 @@ class MessagesView extends React.Component {
|
|||||||
if (this.messagesScroller) {
|
if (this.messagesScroller) {
|
||||||
this.messagesScroller.addEventListener('scroll', this.handleScrollEvent);
|
this.messagesScroller.addEventListener('scroll', this.handleScrollEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drag and drop events
|
||||||
|
if (this.dndRef) {
|
||||||
|
this.dndRef.addEventListener('dragenter', this.handleDragIn);
|
||||||
|
this.dndRef.addEventListener('dragleave', this.handleDragOut);
|
||||||
|
this.dndRef.addEventListener('dragover', this.handleDrag);
|
||||||
|
this.dndRef.addEventListener('drop', this.handleDrop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
@@ -175,6 +196,14 @@ class MessagesView extends React.Component {
|
|||||||
|
|
||||||
// Flush all notifications.
|
// Flush all notifications.
|
||||||
this.clearNotificationQueue();
|
this.clearNotificationQueue();
|
||||||
|
|
||||||
|
// Drag and drop events
|
||||||
|
if (this.dndRef) {
|
||||||
|
this.dndRef.removeEventListener('dragenter', this.handleDragIn);
|
||||||
|
this.dndRef.removeEventListener('dragleave', this.handleDragOut);
|
||||||
|
this.dndRef.removeEventListener('dragover', this.handleDrag);
|
||||||
|
this.dndRef.removeEventListener('drop', this.handleDrop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scroll last message into view on component update e.g. on message received
|
// Scroll last message into view on component update e.g. on message received
|
||||||
@@ -505,6 +534,17 @@ class MessagesView extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mound draf and drop events */
|
||||||
|
mountDnDEvents(dnd) {
|
||||||
|
if (dnd) {
|
||||||
|
dnd.addEventListener('dragenter', this.handleDragIn);
|
||||||
|
dnd.addEventListener('dragleave', this.handleDragOut);
|
||||||
|
dnd.addEventListener('dragover', this.handleDrag);
|
||||||
|
dnd.addEventListener('drop', this.handleDrop);
|
||||||
|
this.dndRef = dnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
goToLatestMessage() {
|
goToLatestMessage() {
|
||||||
this.setState({scrollPosition: 0});
|
this.setState({scrollPosition: 0});
|
||||||
if (this.messagesScroller) {
|
if (this.messagesScroller) {
|
||||||
@@ -1188,6 +1228,44 @@ class MessagesView extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isDragEnabled() {
|
||||||
|
return this.state.isWriter && !this.state.unconfirmed && !this.props.forwardMessage && !this.state.peerMessagingDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDrag(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDragIn(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
this.dragCounter++;
|
||||||
|
if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
|
||||||
|
this.setState({dragging: true});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDragOut(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
this.dragCounter--;
|
||||||
|
if (this.dragCounter <= 0) {
|
||||||
|
this.setState({dragging: false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDrop(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
this.setState({dragging: false});
|
||||||
|
if (this.isDragEnabled() && e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
||||||
|
this.handleFileDrop(e.dataTransfer.files);
|
||||||
|
e.dataTransfer.clearData();
|
||||||
|
this.dragCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {formatMessage} = this.props.intl;
|
const {formatMessage} = this.props.intl;
|
||||||
|
|
||||||
@@ -1486,14 +1564,14 @@ class MessagesView extends React.Component {
|
|||||||
onClearError={this.props.onError} />
|
onClearError={this.props.onError} />
|
||||||
: null}
|
: null}
|
||||||
<LoadSpinner show={this.state.fetchingMessages} />
|
<LoadSpinner show={this.state.fetchingMessages} />
|
||||||
{!this.state.unconfirmed && !this.props.forwardMessage && this.state.isWriter && !this.state.peerMessagingDisabled ?
|
{messagesComponent}
|
||||||
<DragAndDrop actionPrompt={this.props.intl.formatMessage(messages.drag_file)}
|
{this.state.dragging && this.isDragEnabled() ?
|
||||||
onDrop={this.handleFileDrop} >{messagesComponent}</DragAndDrop>
|
<div className="drag-n-drop">{formatMessage(messages.drag_file)}</div>
|
||||||
: messagesComponent}
|
: null}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
component = <div id="topic-view">{component2}</div>
|
component = <div id="topic-view" ref={this.mountDnDEvents}>{component2}</div>
|
||||||
}
|
}
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
// Drag & drop container: displays a banner on drag and calls a handler on drop.
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
export default class DragAndDrop extends React.PureComponent {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
// A file is being dragged over the container.
|
|
||||||
dragging: false
|
|
||||||
};
|
|
||||||
this.dropRef = React.createRef();
|
|
||||||
// Keeps track of the drag event.
|
|
||||||
// Need a counter b/c the browser's 'drag' events may fire multiple times
|
|
||||||
// when the user takes the mouse pointer over the container:
|
|
||||||
// for the component itself and for all nested/child elements.
|
|
||||||
this.dragCounter = 0;
|
|
||||||
|
|
||||||
this.handleDrag = this.handleDrag.bind(this);
|
|
||||||
this.handleDragIn = this.handleDragIn.bind(this);
|
|
||||||
this.handleDragOut = this.handleDragOut.bind(this);
|
|
||||||
this.handleDrop = this.handleDrop.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
const div = this.dropRef.current;
|
|
||||||
div.addEventListener('dragenter', this.handleDragIn);
|
|
||||||
div.addEventListener('dragleave', this.handleDragOut);
|
|
||||||
div.addEventListener('dragover', this.handleDrag);
|
|
||||||
div.addEventListener('drop', this.handleDrop);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
const div = this.dropRef.current;
|
|
||||||
div.removeEventListener('dragenter', this.handleDragIn);
|
|
||||||
div.removeEventListener('dragleave', this.handleDragOut);
|
|
||||||
div.removeEventListener('dragover', this.handleDrag);
|
|
||||||
div.removeEventListener('drop', this.handleDrop);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDrag(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDragIn(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
this.dragCounter++;
|
|
||||||
if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
|
|
||||||
this.setState({dragging: true});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDragOut(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
this.dragCounter--;
|
|
||||||
if (this.dragCounter <= 0) {
|
|
||||||
this.setState({dragging: false});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDrop(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
this.setState({dragging: false});
|
|
||||||
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
|
||||||
this.props.onDrop(e.dataTransfer.files);
|
|
||||||
e.dataTransfer.clearData();
|
|
||||||
this.dragCounter = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className="drag-and-drop" ref={this.dropRef}>
|
|
||||||
{this.state.dragging ?
|
|
||||||
<div className="banner">{this.props.actionPrompt}</div>
|
|
||||||
: null}
|
|
||||||
{this.props.children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user