diff options
Diffstat (limited to 'app/assets/javascripts/components/features/ui')
-rw-r--r-- | app/assets/javascripts/components/features/ui/components/upload_area.jsx | 32 | ||||
-rw-r--r-- | app/assets/javascripts/components/features/ui/index.jsx | 23 |
2 files changed, 49 insertions, 6 deletions
diff --git a/app/assets/javascripts/components/features/ui/components/upload_area.jsx b/app/assets/javascripts/components/features/ui/components/upload_area.jsx new file mode 100644 index 000000000..70b687019 --- /dev/null +++ b/app/assets/javascripts/components/features/ui/components/upload_area.jsx @@ -0,0 +1,32 @@ +import PureRenderMixin from 'react-addons-pure-render-mixin'; +import { Motion, spring } from 'react-motion'; +import { FormattedMessage } from 'react-intl'; + +const UploadArea = React.createClass({ + + propTypes: { + active: React.PropTypes.bool + }, + + mixins: [PureRenderMixin], + + render () { + const { active } = this.props; + + return ( + <Motion defaultStyle={{ backgroundOpacity: 0, backgroundScale: 0.95 }} style={{ backgroundOpacity: spring(active ? 1 : 0, { stiffness: 150, damping: 15 }), backgroundScale: spring(active ? 1 : 0.95, { stiffness: 200, damping: 3 }) }}> + {({ backgroundOpacity, backgroundScale }) => + <div className='upload-area' style={{ visibility: active ? 'visible' : 'hidden', opacity: backgroundOpacity }}> + <div className='upload-area__drop'> + <div className='upload-area__background' style={{ transform: `translateZ(0) scale(${backgroundScale})` }} /> + <div className='upload-area__content'><FormattedMessage id='upload_area.title' defaultMessage='Drag & drop to upload' /></div> + </div> + </div> + } + </Motion> + ); + } + +}); + +export default UploadArea; diff --git a/app/assets/javascripts/components/features/ui/index.jsx b/app/assets/javascripts/components/features/ui/index.jsx index 900d83dba..10e989b2a 100644 --- a/app/assets/javascripts/components/features/ui/index.jsx +++ b/app/assets/javascripts/components/features/ui/index.jsx @@ -13,6 +13,7 @@ import { debounce } from 'react-decoration'; import { uploadCompose } from '../../actions/compose'; import { refreshTimeline } from '../../actions/timelines'; import { refreshNotifications } from '../../actions/notifications'; +import UploadArea from './components/upload_area'; const UI = React.createClass({ @@ -23,7 +24,8 @@ const UI = React.createClass({ getInitialState () { return { - width: window.innerWidth + width: window.innerWidth, + draggingOver: false }; }, @@ -41,7 +43,7 @@ const UI = React.createClass({ e.dataTransfer.dropEffect = 'copy'; if (e.dataTransfer.effectAllowed === 'all' || e.dataTransfer.effectAllowed === 'uninitialized') { - // + this.setState({ draggingOver: true }); } }, @@ -49,10 +51,15 @@ const UI = React.createClass({ e.preventDefault(); if (e.dataTransfer && e.dataTransfer.files.length === 1) { + this.setState({ draggingOver: false }); this.props.dispatch(uploadCompose(e.dataTransfer.files)); } }, + handleDragLeave () { + this.setState({ draggingOver: false }); + }, + componentWillMount () { window.addEventListener('resize', this.handleResize, { passive: true }); window.addEventListener('dragover', this.handleDragOver); @@ -69,12 +76,15 @@ const UI = React.createClass({ }, render () { + const { width, draggingOver } = this.state; + const { children } = this.props; + let mountedColumns; - if (isMobile(this.state.width)) { + if (isMobile(width)) { mountedColumns = ( <ColumnsArea> - {this.props.children} + {children} </ColumnsArea> ); } else { @@ -83,13 +93,13 @@ const UI = React.createClass({ <Compose withHeader={true} /> <HomeTimeline trackScroll={false} /> <Notifications trackScroll={false} /> - {this.props.children} + {children} </ColumnsArea> ); } return ( - <div className='ui'> + <div className='ui' onDragLeave={this.handleDragLeave}> <TabsBar /> {mountedColumns} @@ -97,6 +107,7 @@ const UI = React.createClass({ <NotificationsContainer /> <LoadingBarContainer style={{ backgroundColor: '#2b90d9', left: '0', top: '0' }} /> <ModalContainer /> + <UploadArea active={draggingOver} /> </div> ); } |