Extract a Centered component.

nb/hide-http
Alex Kern 11 years ago
parent 1e1648410e
commit 5344bbda28

@ -14,13 +14,13 @@ export default class App extends React.Component {
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Quicksand:300,400,700" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Quicksand:300,400,700" />
<link rel="stylesheet" href="/css" /> <link rel="stylesheet" href="/css" />
<script src="/js" />
</FrozenHead> </FrozenHead>
<body> <body>
<div className="container"> <RouteHandler />
<RouteHandler /> <script>FilePizza()</script>
<script src="/js" />
</div>
</body> </body>
</html> </html>
} }

@ -0,0 +1,63 @@
import React from 'react'
export default class Centered extends React.Component {
render() {
const h = this.props.hor
const v = this.props.ver
if (h && v) {
return <div style={{
display: 'table',
width: '100%',
height: '100%'}}>
<div style={{
display: 'table-cell',
verticalAlign: 'middle',
textAlign: 'center'}}>
<div style={{display: 'inline-block'}}>
{this.props.children}
</div>
</div>
</div>
} else if (h && !v) {
return <div style={{textAlign: 'center'}}>
<div style={{display: 'inline-block'}}>
{this.props.children}
</div>
</div>
} else if (!h && v) {
return <div style={{
display: 'table',
width: '100%',
height: '100%'}}>
<div style={{
display: 'table-cell',
verticalAlign: 'middle'}}>
{this.props.children}
</div>
</div>
} else {
return this.props.children
}
}
}
Centered.propTypes = {
hor: React.PropTypes.bool,
ver: React.PropTypes.bool
}
Centered.defaultProps = {
hor: false,
ver: false
}

@ -1,7 +1,8 @@
import Centered from './Centered'
import DownloadActions from '../actions/DownloadActions' import DownloadActions from '../actions/DownloadActions'
import DownloadButton from './DownloadButton' import DownloadButton from './DownloadButton'
import ProgressBar from './ProgressBar'
import DownloadStore from '../stores/DownloadStore' import DownloadStore from '../stores/DownloadStore'
import ProgressBar from './ProgressBar'
import React from 'react' import React from 'react'
import Spinner from './Spinner' import Spinner from './Spinner'
import peer from '../peer' import peer from '../peer'
@ -37,7 +38,8 @@ export default class DownloadPage extends React.Component {
render() { render() {
switch (this.state.status) { switch (this.state.status) {
case 'ready': case 'ready':
return <div className="page"> return <Centered ver>
<h1>FilePizza</h1> <h1>FilePizza</h1>
<Spinner dir="down" <Spinner dir="down"
name={this.state.file.name} name={this.state.file.name}
@ -45,11 +47,12 @@ export default class DownloadPage extends React.Component {
<DownloadButton onClick={this.downloadFile.bind(this)} /> <DownloadButton onClick={this.downloadFile.bind(this)} />
</div> </Centered>
case 'requesting': case 'requesting':
case 'downloading': case 'downloading':
return <div className="page"> return <Centered ver>
<h1>FilePizza</h1> <h1>FilePizza</h1>
<Spinner dir="down" animated <Spinner dir="down" animated
name={this.state.file.name} name={this.state.file.name}
@ -57,10 +60,11 @@ export default class DownloadPage extends React.Component {
<ProgressBar value={this.state.progress} /> <ProgressBar value={this.state.progress} />
</div> </Centered>
case 'cancelled': case 'cancelled':
return <div className="page"> return <Centered ver>
<h1>FilePizza</h1> <h1>FilePizza</h1>
<Spinner dir="down" <Spinner dir="down"
name={this.state.file.name} name={this.state.file.name}
@ -68,10 +72,11 @@ export default class DownloadPage extends React.Component {
<ProgressBar value={-1} /> <ProgressBar value={-1} />
</div> </Centered>
case 'done': case 'done':
return <div className="page"> return <Centered ver>
<h1>FilePizza</h1> <h1>FilePizza</h1>
<Spinner dir="down" <Spinner dir="down"
name={this.state.file.name} name={this.state.file.name}
@ -79,7 +84,7 @@ export default class DownloadPage extends React.Component {
<ProgressBar value={1} /> <ProgressBar value={1} />
</div> </Centered>
} }
} }

@ -1,43 +1,52 @@
import React from 'react'; import React from 'react'
import classnames from 'classnames'; import Centered from './Centered'
export default class DropZone extends React.Component { export default class DropZone extends React.Component {
constructor() { constructor() {
this.state = { focus: false }; this.state = { focus: false }
} }
onDragEnter() { onDragEnter() {
this.setState({ focus: true }); this.setState({ focus: true })
} }
onDragLeave() { onDragLeave(e) {
this.setState({ focus: false }); if (e.target !== this.refs.overlay.getDOMNode()) return
this.setState({ focus: false })
} }
onDragOver(e) { onDragOver(e) {
e.preventDefault(); e.preventDefault()
e.dataTransfer.dropEffect = 'copy'; e.dataTransfer.dropEffect = 'copy'
} }
onDrop(e) { onDrop(e) {
e.preventDefault(); e.preventDefault()
this.setState({ focus: false }); this.setState({ focus: false })
let file = e.dataTransfer.files[0]; let file = e.dataTransfer.files[0]
if (this.props.onDrop && file) this.props.onDrop(file); if (this.props.onDrop && file) this.props.onDrop(file)
} }
render() { render() {
let classes = classnames('drop-zone', { return <div className="drop-zone" ref="root"
'drop-zone-focus': this.state.focus
});
return <div className={classes}
onDragEnter={this.onDragEnter.bind(this)} onDragEnter={this.onDragEnter.bind(this)}
onDragLeave={this.onDragLeave.bind(this)} onDragLeave={this.onDragLeave.bind(this)}
onDragOver={this.onDragOver.bind(this)} onDragOver={this.onDragOver.bind(this)}
onDrop={this.onDrop.bind(this)} />; onDrop={this.onDrop.bind(this)}>
<div className="drop-zone-overlay"
hidden={!this.state.focus}
ref="overlay" />
{this.props.children}
</div>
} }
} }
DropZone.propTypes = {
onDrop: React.PropTypes.func.isRequired
}

@ -1,7 +1,8 @@
import Spinner from './Spinner' import Centered from './Centered'
import DropZone from './DropZone' import DropZone from './DropZone'
import ProgressBar from './ProgressBar' import ProgressBar from './ProgressBar'
import React from 'react' import React from 'react'
import Spinner from './Spinner'
import Tempalink from './Tempalink' import Tempalink from './Tempalink'
import UploadActions from '../actions/UploadActions' import UploadActions from '../actions/UploadActions'
import UploadStore from '../stores/UploadStore' import UploadStore from '../stores/UploadStore'
@ -38,31 +39,34 @@ export default class UploadPage extends React.Component {
render() { render() {
switch (this.state.status) { switch (this.state.status) {
case 'ready': case 'ready':
return <div className="page">
<DropZone onDrop={this.uploadFile.bind(this)} /> return <DropZone onDrop={this.uploadFile.bind(this)}>
<Spinner dir="up" /> <Centered ver>
<h1>FilePizza</h1> <Spinner dir="up" />
<p>The easiest way to send someone a file.</p>
<p>Drag the file into this window to get started.</p>
</div> <h1>FilePizza</h1>
<p>The easiest way to send someone a file.</p>
<p>Drag the file into this window to get started.</p>
</Centered>
</DropZone>
case 'processing': case 'processing':
return <div className="page"> return <Centered ver>
<Spinner dir="up" animated /> <Spinner dir="up" animated />
<h1>FilePizza</h1> <h1>FilePizza</h1>
<p>Processing...</p> <p>Processing...</p>
</div> </Centered>
case 'uploading': case 'uploading':
var keys = Object.keys(this.state.peerProgress) var keys = Object.keys(this.state.peerProgress)
keys.reverse() keys.reverse()
return <div className="page"> return <Centered ver>
<h1>FilePizza</h1> <h1>FilePizza</h1>
<Spinner dir="up" animated {...this.state.file} /> <Spinner dir="up" animated {...this.state.file} />
@ -70,14 +74,14 @@ export default class UploadPage extends React.Component {
<p>This link will work as long as this page is open.</p> <p>This link will work as long as this page is open.</p>
<Tempalink token={this.state.token} /> <Tempalink token={this.state.token} />
{keys.length > 0 ? <p>People Downloading Your File</p> : <p></p>} {keys.length > 0 ? <p>Download Progress</p> : null}
<div className="data"> <div className="data">
{ keys.map((key) => { {keys.map((key) => {
return <ProgressBar value={this.state.peerProgress[key]} small /> return <ProgressBar small value={this.state.peerProgress[key]} />
})} })}
</div> </div>
</div> </Centered>
} }
} }

@ -6,6 +6,8 @@ import alt from './alt'
let bootstrap = document.documentElement.getAttribute('data-bootstrap') let bootstrap = document.documentElement.getAttribute('data-bootstrap')
alt.bootstrap(bootstrap) alt.bootstrap(bootstrap)
ReactRouter.run(routes, ReactRouter.HistoryLocation, function (Handler) { window.FilePizza = () => {
React.render(<Handler data={bootstrap} />, document) ReactRouter.run(routes, ReactRouter.HistoryLocation, function (Handler) {
}) React.render(<Handler data={bootstrap} />, document)
})
}

@ -33,38 +33,28 @@ p {
margin: 0 0 margin: 0 0
} }
.container {
display: table
width: 100%
height: 100%
}
.page {
display: table-cell
vertical-align: middle
}
.drop-zone { .drop-zone {
position: absolute
top: 0
left: 0
width: 100% width: 100%
height: 100% height: 100%
display: table
background: rgba(0, 0, 0, 0)
&.drop-zone-focus { .drop-zone-overlay {
z-index: 1 position: fixed
top: 0
left: 0
width: 100%
height: 100%
background: rgba(0, 0, 0, 0.5) background: rgba(0, 0, 0, 0.5)
text-align: center
&:after { &:after {
color: white color: white
content: 'DROP TO UPLOAD' content: 'DROP TO UPLOAD'
display: table-cell display: block
font: 24px/40px "Quicksand", sans-serif font: 24px/40px "Quicksand", sans-serif
text-align: center margin-top: -20px
position: relative
text-shadow: 0 1px dark-gray text-shadow: 0 1px dark-gray
vertical-align: middle top: 50%
} }
} }
} }

Loading…
Cancel
Save