Conflicts:
	src/components/App.js
pull/51/head
rugk 9 years ago
commit 44fbfa9b23
No known key found for this signature in database
GPG Key ID: 05D40A636AFAB34D

@ -13,6 +13,10 @@ A hosted instance of FilePizza is available at [file.pizza](http://file.pizza).
## Installation ## Installation
The recommended way to deploy FilePizza is as a [Docker container](https://hub.docker.com/r/kern/filepizza).
You can also install FilePizza via the command-line:
$ npm install filepizza -g $ npm install filepizza -g
$ filepizza $ filepizza

@ -34,10 +34,12 @@
"dependencies": { "dependencies": {
"alt": "^0.14.4", "alt": "^0.14.4",
"babel-cli": "^6.6.5", "babel-cli": "^6.6.5",
"babel-core": "^6.14.0",
"babel-loader": "^6.2.4", "babel-loader": "^6.2.4",
"babel-plugin-add-module-exports": "^0.1.2", "babel-plugin-add-module-exports": "^0.1.2",
"babel-plugin-transform-react-jsx": "^6.7.4", "babel-plugin-transform-react-jsx": "^6.7.4",
"babel-preset-es2015": "^6.6.0", "babel-polyfill": "^6.16.0",
"babel-preset-es2015": "^6.14.0",
"babel-preset-stage-0": "^6.5.0", "babel-preset-stage-0": "^6.5.0",
"classnames": "^1.2.0", "classnames": "^1.2.0",
"express": "^4.12.0", "express": "^4.12.0",
@ -56,12 +58,18 @@
"stylus": "^0.50.0", "stylus": "^0.50.0",
"twilio": "^2.9.1", "twilio": "^2.9.1",
"webpack": "^1.12.14", "webpack": "^1.12.14",
"webrtcsupport": "^2.1.2", "webrtcsupport": "^2.2.0",
"webtorrent": "^0.90.3",
"winston": "^1.0.1", "winston": "^1.0.1",
"xkcd-password": "^1.2.0" "xkcd-password": "^1.2.0"
}, },
"devDependencies": { "devDependencies": {
"babel-cli": "^6.16.0",
"babel-core": "^6.17.0",
"babel-loader": "^6.2.5",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-react-jsx": "^6.8.0",
"babel-preset-es2015": "^6.16.0",
"babel-preset-stage-0": "^6.16.0",
"json-loader": "^0.5.4", "json-loader": "^0.5.4",
"nodemon": "^1.4.1", "nodemon": "^1.4.1",
"webpack-dev-middleware": "^1.6.1" "webpack-dev-middleware": "^1.6.1"

@ -1,3 +1,4 @@
import 'babel-polyfill'
import React from 'react' import React from 'react'
import ReactRouter from 'react-router' import ReactRouter from 'react-router'
import routes from './routes' import routes from './routes'

@ -24,7 +24,7 @@ export default class App extends React.Component {
SupportStore.listen(this._onChange) SupportStore.listen(this._onChange)
} }
componentDidUnmount() { componentWillUnmount() {
SupportStore.unlisten(this._onChange) SupportStore.unlisten(this._onChange)
} }
@ -39,12 +39,11 @@ export default class App extends React.Component {
<meta property="og:description" content="Peer-to-peer file transfers in your web browser." /> <meta property="og:description" content="Peer-to-peer file transfers in your web browser." />
<meta property="og:image" content="http://file.pizza/images/fb.png" /> <meta property="og:image" content="http://file.pizza/images/fb.png" />
<title>FilePizza - Your files, delivered.</title> <title>FilePizza - Your files, delivered.</title>
<link rel="stylesheet" href="/fonts/fonts.css" /> <link rel="stylesheet" href="/fonts/fonts.css" />
<link rel="stylesheet" href="/css" /> <link rel="stylesheet" href="/app.css" />
<Bootstrap data={this.props.data} /> <Bootstrap data={this.props.data} />
<script src="/js" /> <script src="https://cdn.jsdelivr.net/webtorrent/latest/webtorrent.min.js" />
<script src="/app.js" />
</FrozenHead> </FrozenHead>

@ -4,7 +4,7 @@ import SupportStore from '../stores/SupportStore'
function getState() { function getState() {
return { return {
active: SupportStore.getState().isChrome && DownloadStore.getState().fileSize >= 500000000 active: SupportStore.getState().isChrome && DownloadStore.getState().fileSize >= 500000000
} }
} }
@ -24,7 +24,7 @@ export default class ChromeNotice extends React.Component {
SupportStore.listen(this._onChange) SupportStore.listen(this._onChange)
} }
componentDidUnmount() { componentWillUnmount() {
DownloadStore.unlisten(this._onChange) DownloadStore.unlisten(this._onChange)
SupportStore.unlisten(this._onChange) SupportStore.unlisten(this._onChange)
} }

@ -1,6 +1,10 @@
import React from 'react' import React from 'react'
export default class DownloadButton extends React.Component { export default class DownloadButton extends React.Component {
constructor() {
super()
this.onClick = this.onClick.bind(this)
}
onClick(e) { onClick(e) {
this.props.onClick(e) this.props.onClick(e)
@ -9,7 +13,7 @@ export default class DownloadButton extends React.Component {
render() { render() {
return <button return <button
className="download-button" className="download-button"
onClick={this.onClick.bind(this)}> onClick={this.onClick}>
Download Download
</button> </button>
} }

@ -17,13 +17,15 @@ export default class DownloadPage extends React.Component {
this._onChange = () => { this._onChange = () => {
this.setState(DownloadStore.getState()) this.setState(DownloadStore.getState())
} }
this.downloadFile = this.downloadFile.bind(this)
} }
componentDidMount() { componentDidMount() {
DownloadStore.listen(this._onChange) DownloadStore.listen(this._onChange)
} }
componentDidUnmount() { componentWillUnmount() {
DownloadStore.unlisten(this._onChange) DownloadStore.unlisten(this._onChange)
} }
@ -43,7 +45,7 @@ export default class DownloadPage extends React.Component {
<ChromeNotice /> <ChromeNotice />
<p className="notice">Peers: {this.state.peers} &middot; Up: {formatSize(this.state.speedUp)} &middot; Down: {formatSize(this.state.speedDown)}</p> <p className="notice">Peers: {this.state.peers} &middot; Up: {formatSize(this.state.speedUp)} &middot; Down: {formatSize(this.state.speedDown)}</p>
<DownloadButton onClick={this.downloadFile.bind(this)} /> <DownloadButton onClick={this.downloadFile} />
</div> </div>

@ -5,6 +5,11 @@ export default class DropZone extends React.Component {
constructor() { constructor() {
super() super()
this.state = { focus: false } this.state = { focus: false }
this.onDragEnter = this.onDragEnter.bind(this)
this.onDragLeave = this.onDragLeave.bind(this)
this.onDragOver = this.onDragOver.bind(this)
this.onDrop = this.onDrop.bind(this)
} }
onDragEnter() { onDragEnter() {
@ -31,10 +36,10 @@ export default class DropZone extends React.Component {
render() { render() {
return <div className="drop-zone" ref="root" return <div className="drop-zone" ref="root"
onDragEnter={this.onDragEnter.bind(this)} onDragEnter={this.onDragEnter}
onDragLeave={this.onDragLeave.bind(this)} onDragLeave={this.onDragLeave}
onDragOver={this.onDragOver.bind(this)} onDragOver={this.onDragOver}
onDrop={this.onDrop.bind(this)}> onDrop={this.onDrop}>
<div className="drop-zone-overlay" <div className="drop-zone-overlay"
hidden={!this.state.focus} hidden={!this.state.focus}

@ -17,7 +17,7 @@ export default class ErrorPage extends React.Component {
ErrorStore.listen(this._onChange) ErrorStore.listen(this._onChange)
} }
componentDidUnmount() { componentWillUnmount() {
ErrorStore.unlisten(this._onChange) ErrorStore.unlisten(this._onChange)
} }

@ -1,6 +1,10 @@
import React from 'react' import React from 'react'
export default class Tempalink extends React.Component { export default class Tempalink extends React.Component {
constructor() {
super()
this.onClick = this.onClick.bind(this)
}
onClick() { onClick() {
this.refs.input.getDOMNode().setSelectionRange(0, 9999) this.refs.input.getDOMNode().setSelectionRange(0, 9999)
@ -10,7 +14,7 @@ export default class Tempalink extends React.Component {
var url = window.location.origin + '/' + this.props.token var url = window.location.origin + '/' + this.props.token
return <input return <input
className="tempalink" className="tempalink"
onClick={this.onClick.bind(this)} onClick={this.onClick}
readOnly readOnly
ref="input" ref="input"
type="text" type="text"

@ -12,40 +12,42 @@ export default class UploadPage extends React.Component {
constructor() { constructor() {
super() super()
this.state = UploadStore.getState() this.state = UploadStore.getState()
this._onChange = () => { this._onChange = () => {
this.setState(UploadStore.getState()) this.setState(UploadStore.getState())
} }
this.uploadFile = this.uploadFile.bind(this)
} }
componentDidMount() { componentDidMount() {
UploadStore.listen(this._onChange) UploadStore.listen(this._onChange)
} }
componentDidUnmount() { componentWillUnmount() {
UploadStore.unlisten(this._onChange) UploadStore.unlisten(this._onChange)
} }
uploadFile(file) { uploadFile(file) {
UploadActions.uploadFile(file) UploadActions.uploadFile(file)
} }
handleSelectedFile(event) { handleSelectedFile(event) {
let files = event.target.files let files = event.target.files
if (files.length > 0) { if (files.length > 0) {
UploadActions.uploadFile(files[0]) UploadActions.uploadFile(files[0])
} }
} }
render() { render() {
switch (this.state.status) { switch (this.state.status) {
case 'ready': case 'ready':
return <DropZone onDrop={this.uploadFile.bind(this)}> return <DropZone onDrop={this.uploadFile}>
<div className="page"> <div className="page">
<Spinner dir="up" /> <Spinner dir="up" />
<h1>FilePizza</h1> <h1>FilePizza</h1>
<p>Free peer-to-peer file transfers in your browser.</p> <p>Free peer-to-peer file transfers in your browser.</p>
<p>We never store anything. Files only served fresh.</p> <p>We never store anything. Files only served fresh.</p>
@ -57,30 +59,30 @@ export default class UploadPage extends React.Component {
</p> </p>
</div> </div>
</DropZone> </DropZone>
case 'processing': case 'processing':
return <div className="page"> return <div className="page">
<Spinner dir="up" animated /> <Spinner dir="up" animated />
<h1>FilePizza</h1> <h1>FilePizza</h1>
<p>Processing...</p> <p>Processing...</p>
</div> </div>
case 'uploading': case 'uploading':
return <div className="page"> return <div className="page">
<h1>FilePizza</h1> <h1>FilePizza</h1>
<Spinner dir="up" animated <Spinner dir="up" animated
name={this.state.fileName} name={this.state.fileName}
size={this.state.fileSize} /> size={this.state.fileSize} />
<p>Send someone this link to download.</p> <p>Send someone this link to download.</p>
<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>
<p>Peers: {this.state.peers} &middot; Up: {formatSize(this.state.speedUp)}</p> <p>Peers: {this.state.peers} &middot; Up: {formatSize(this.state.speedUp)}</p>
<Tempalink token={this.state.token} /> <Tempalink token={this.state.token} />
</div> </div>
} }
} }

@ -3,6 +3,10 @@ import React from 'react';
import UploadActions from '@app/actions/UploadActions'; import UploadActions from '@app/actions/UploadActions';
export default class UploadPage extends React.Component { export default class UploadPage extends React.Component {
constructor() {
super()
this.uploadFile = this.uploadFile.bind(this)
}
uploadFile(file) { uploadFile(file) {
UploadActions.uploadFile(file); UploadActions.uploadFile(file);
@ -12,7 +16,7 @@ export default class UploadPage extends React.Component {
switch (this.props.status) { switch (this.props.status) {
case 'ready': case 'ready':
return <div> return <div>
<DropZone onDrop={this.uploadFile.bind(this)} /> <DropZone onDrop={this.uploadFile} />
<Arrow dir="up" /> <Arrow dir="up" />
</div>; </div>;
break; break;

@ -10,7 +10,7 @@ if (process.env.NODE_ENV === 'production') {
const webpackMiddleware = require('webpack-dev-middleware') const webpackMiddleware = require('webpack-dev-middleware')
const webpack = require('webpack') const webpack = require('webpack')
const config = require('../../webpack.config.js') const config = require('../../webpack.config.js')
config.output.filename = '/js' config.output.filename = '/app.js'
config.output.path = '/' config.output.path = '/'
module.exports = webpackMiddleware(webpack(config)) module.exports = webpackMiddleware(webpack(config))
} }

@ -20,6 +20,7 @@ module.exports = function (req, res) {
var html = React.renderToString(<Handler data={alt.takeSnapshot()} />) var html = React.renderToString(<Handler data={alt.takeSnapshot()} />)
alt.flush() alt.flush()
res.setHeader('Content-Type', 'text/html');
if (isNotFound(state)) res.status(404) if (isNotFound(state)) res.status(404)
res.write('<!DOCTYPE html>\n') res.write('<!DOCTYPE html>\n')
res.end(html) res.end(html)

@ -26,6 +26,7 @@ if (process.env.SECURE) {
} }
var io = socketIO(server) var io = socketIO(server)
io.set('transports', ['polling'])
var logDir = path.resolve(__dirname, '../log') var logDir = path.resolve(__dirname, '../log')
@ -79,8 +80,8 @@ if (process.env.FORCE_SSL) {
app.use(forceSSL) app.use(forceSSL)
} }
app.get('/js', require('./middleware/javascript')) app.get('/app.js', require('./middleware/javascript'))
app.get('/css', require('./middleware/css')) app.get('/app.css', require('./middleware/css'))
app.use(require('./middleware/static')) app.use(require('./middleware/static'))
app.use([ app.use([

@ -40,9 +40,9 @@ export default alt.createStore(class DownloadStore {
const updateSpeed = () => { const updateSpeed = () => {
this.setState({ this.setState({
speedUp: torrent.swarm.uploadSpeed(), speedUp: torrent.uploadSpeed,
speedDown: torrent.swarm.downloadSpeed(), speedDown: torrent.downloadSpeed,
peers: torrent.swarm.wires.length peers: torrent.numPeers
}) })
} }

@ -29,8 +29,8 @@ export default alt.createStore(class UploadStore {
const updateSpeed = () => { const updateSpeed = () => {
this.setState({ this.setState({
speedUp: torrent.swarm.uploadSpeed(), speedUp: torrent.uploadSpeed,
peers: torrent.swarm.wires.length peers: torrent.numPeers
}) })
} }

@ -1,10 +1,11 @@
import WebTorrent from 'webtorrent'
import socket from 'filepizza-socket' import socket from 'filepizza-socket'
export function getClient() { export function getClient() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
socket.emit('rtcConfig', {}, (rtcConfig) => { socket.emit('rtcConfig', {}, (rtcConfig) => {
const client = new WebTorrent({ rtcConfig: rtcConfig }) const client = new WebTorrent({
tracker: { rtcConfig }
})
resolve(client) resolve(client)
}) })
}) })

Loading…
Cancel
Save