Add overlay when holding file above drop element
parent
60c6221af7
commit
b3c45d004b
|
|
@ -0,0 +1,14 @@
|
||||||
|
import React from 'react';
|
||||||
|
import dragDrop from 'drag-drop';
|
||||||
|
import { shareFiles } from './index';
|
||||||
|
|
||||||
|
export const configureDragDrop = () =>
|
||||||
|
{
|
||||||
|
dragDrop('body', async(files) => await shareFiles(files));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const HoldingOverlay = () => (
|
||||||
|
<div id='holding-overlay'>
|
||||||
|
Drop files here to share them
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import WebTorrent from 'webtorrent';
|
import WebTorrent from 'webtorrent';
|
||||||
import createTorrent from 'create-torrent';
|
import createTorrent from 'create-torrent';
|
||||||
import dragDrop from 'drag-drop';
|
|
||||||
import randomString from 'random-string';
|
import randomString from 'random-string';
|
||||||
import * as stateActions from '../../redux/stateActions';
|
import * as stateActions from '../../redux/stateActions';
|
||||||
import * as requestActions from '../../redux/requestActions';
|
import * as requestActions from '../../redux/requestActions';
|
||||||
|
|
@ -26,7 +25,7 @@ const notifyPeers = (file) =>
|
||||||
store.dispatch(requestActions.sendFile(file, displayName, picture));
|
store.dispatch(requestActions.sendFile(file, displayName, picture));
|
||||||
};
|
};
|
||||||
|
|
||||||
const shareFiles = async(files) =>
|
export const shareFiles = async(files) =>
|
||||||
{
|
{
|
||||||
const notification =
|
const notification =
|
||||||
{
|
{
|
||||||
|
|
@ -70,8 +69,6 @@ const shareFiles = async(files) =>
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
dragDrop('body', async(files) => await shareFiles(files));
|
|
||||||
|
|
||||||
class FileSharing extends Component
|
class FileSharing extends Component
|
||||||
{
|
{
|
||||||
constructor(props)
|
constructor(props)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import ReactTooltip from 'react-tooltip';
|
import ReactTooltip from 'react-tooltip';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
@ -18,6 +18,9 @@ import Draggable from 'react-draggable';
|
||||||
import { idle } from '../utils';
|
import { idle } from '../utils';
|
||||||
import Sidebar from './Sidebar';
|
import Sidebar from './Sidebar';
|
||||||
import Filmstrip from './Filmstrip';
|
import Filmstrip from './Filmstrip';
|
||||||
|
import { configureDragDrop, HoldingOverlay } from './FileSharing/DragDropSharing';
|
||||||
|
|
||||||
|
configureDragDrop();
|
||||||
|
|
||||||
// Hide toolbars after 10 seconds of inactivity.
|
// Hide toolbars after 10 seconds of inactivity.
|
||||||
const TIMEOUT = 10 * 1000;
|
const TIMEOUT = 10 * 1000;
|
||||||
|
|
@ -73,102 +76,106 @@ class Room extends React.Component
|
||||||
}[room.mode];
|
}[room.mode];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Appear duration={300}>
|
<Fragment>
|
||||||
<div data-component='Room'>
|
<HoldingOverlay />
|
||||||
<FullScreenView advancedMode={room.advancedMode} />
|
|
||||||
<div
|
|
||||||
className='room-wrapper'
|
|
||||||
style={{
|
|
||||||
width : toolAreaOpen ? '80%' : '100%'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Notifications />
|
|
||||||
|
|
||||||
<ToolAreaButton />
|
<Appear duration={300}>
|
||||||
|
<div data-component='Room'>
|
||||||
{room.advancedMode ?
|
<FullScreenView advancedMode={room.advancedMode} />
|
||||||
<div className='state' data-tip='Server status'>
|
|
||||||
<div className={classnames('icon', room.state)} />
|
|
||||||
<p className={classnames('text', room.state)}>{room.state}</p>
|
|
||||||
</div>
|
|
||||||
:null
|
|
||||||
}
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={classnames('room-link-wrapper room-controls', {
|
className='room-wrapper'
|
||||||
'visible' : this.props.room.toolbarsVisible
|
style={{
|
||||||
})}
|
width : toolAreaOpen ? '80%' : '100%'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className='room-link'>
|
<Notifications />
|
||||||
<CopyToClipboard
|
|
||||||
text={room.url}
|
|
||||||
onCopy={onRoomLinkCopy}
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
className='link'
|
|
||||||
href={room.url}
|
|
||||||
target='_blank'
|
|
||||||
data-tip='Click to copy room link'
|
|
||||||
rel='noopener noreferrer'
|
|
||||||
onClick={(event) =>
|
|
||||||
{
|
|
||||||
// If this is a 'Open in new window/tab' don't prevent
|
|
||||||
// click default action.
|
|
||||||
if (
|
|
||||||
event.ctrlKey || event.shiftKey || event.metaKey ||
|
|
||||||
// Middle click (IE > 9 and everyone else).
|
|
||||||
(event.button && event.button === 1)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
invitation link
|
|
||||||
</a>
|
|
||||||
</CopyToClipboard>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<View advancedMode={room.advancedMode} />
|
<ToolAreaButton />
|
||||||
|
|
||||||
<Draggable handle='.me-container' bounds='body' cancel='.display-name'>
|
{room.advancedMode ?
|
||||||
|
<div className='state' data-tip='Server status'>
|
||||||
|
<div className={classnames('icon', room.state)} />
|
||||||
|
<p className={classnames('text', room.state)}>{room.state}</p>
|
||||||
|
</div>
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={classnames('me-container', {
|
className={classnames('room-link-wrapper room-controls', {
|
||||||
'active-speaker' : amActiveSpeaker
|
'visible' : this.props.room.toolbarsVisible
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Me
|
<div className='room-link'>
|
||||||
|
<CopyToClipboard
|
||||||
|
text={room.url}
|
||||||
|
onCopy={onRoomLinkCopy}
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
className='link'
|
||||||
|
href={room.url}
|
||||||
|
target='_blank'
|
||||||
|
data-tip='Click to copy room link'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
onClick={(event) =>
|
||||||
|
{
|
||||||
|
// If this is a 'Open in new window/tab' don't prevent
|
||||||
|
// click default action.
|
||||||
|
if (
|
||||||
|
event.ctrlKey || event.shiftKey || event.metaKey ||
|
||||||
|
// Middle click (IE > 9 and everyone else).
|
||||||
|
(event.button && event.button === 1)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
invitation link
|
||||||
|
</a>
|
||||||
|
</CopyToClipboard>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<View advancedMode={room.advancedMode} />
|
||||||
|
|
||||||
|
<Draggable handle='.me-container' bounds='body' cancel='.display-name'>
|
||||||
|
<div
|
||||||
|
className={classnames('me-container', {
|
||||||
|
'active-speaker' : amActiveSpeaker
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Me
|
||||||
|
advancedMode={room.advancedMode}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Draggable>
|
||||||
|
|
||||||
|
<Sidebar />
|
||||||
|
|
||||||
|
<ReactTooltip
|
||||||
|
effect='solid'
|
||||||
|
delayShow={100}
|
||||||
|
delayHide={100}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='toolarea-wrapper'
|
||||||
|
style={{
|
||||||
|
width : toolAreaOpen ? '20%' : '0%'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{toolAreaOpen ?
|
||||||
|
<ToolArea
|
||||||
advancedMode={room.advancedMode}
|
advancedMode={room.advancedMode}
|
||||||
/>
|
/>
|
||||||
</div>
|
:null
|
||||||
</Draggable>
|
}
|
||||||
|
</div>
|
||||||
<Sidebar />
|
|
||||||
|
|
||||||
<ReactTooltip
|
|
||||||
effect='solid'
|
|
||||||
delayShow={100}
|
|
||||||
delayHide={100}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
</Appear>
|
||||||
className='toolarea-wrapper'
|
</Fragment>
|
||||||
style={{
|
|
||||||
width : toolAreaOpen ? '20%' : '0%'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{toolAreaOpen ?
|
|
||||||
<ToolArea
|
|
||||||
advancedMode={room.advancedMode}
|
|
||||||
/>
|
|
||||||
:null
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Appear>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,4 +58,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#holding-overlay {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drag #holding-overlay {
|
||||||
|
display: flex;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
color: #FFF;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 2rem;
|
||||||
|
z-index: 2000;
|
||||||
}
|
}
|
||||||
|
|
@ -34,26 +34,26 @@ body {
|
||||||
#multiparty-meeting {
|
#multiparty-meeting {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
// Components
|
|
||||||
@import './components/Room';
|
|
||||||
@import './components/Sidebar';
|
|
||||||
@import './components/Me';
|
|
||||||
@import './components/Peers';
|
|
||||||
@import './components/Peer';
|
|
||||||
@import './components/PeerView';
|
|
||||||
@import './components/ScreenView';
|
|
||||||
@import './components/Notifications';
|
|
||||||
@import './components/Chat';
|
|
||||||
@import './components/Settings';
|
|
||||||
@import './components/ToolArea';
|
|
||||||
@import './components/ParticipantList';
|
|
||||||
@import './components/FullScreenView';
|
|
||||||
@import './components/FullView';
|
|
||||||
@import './components/Filmstrip';
|
|
||||||
@import './components/FileSharing';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Components
|
||||||
|
@import './components/Room';
|
||||||
|
@import './components/Sidebar';
|
||||||
|
@import './components/Me';
|
||||||
|
@import './components/Peers';
|
||||||
|
@import './components/Peer';
|
||||||
|
@import './components/PeerView';
|
||||||
|
@import './components/ScreenView';
|
||||||
|
@import './components/Notifications';
|
||||||
|
@import './components/Chat';
|
||||||
|
@import './components/Settings';
|
||||||
|
@import './components/ToolArea';
|
||||||
|
@import './components/ParticipantList';
|
||||||
|
@import './components/FullScreenView';
|
||||||
|
@import './components/FullView';
|
||||||
|
@import './components/Filmstrip';
|
||||||
|
@import './components/FileSharing';
|
||||||
|
|
||||||
// Hack to detect in JS the current media query
|
// Hack to detect in JS the current media query
|
||||||
#multiparty-meeting-media-query-detector {
|
#multiparty-meeting-media-query-detector {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue