mirror of https://github.com/kern/filepizza
Clean up
parent
2b1c473e45
commit
981bd31253
@ -1,25 +0,0 @@
|
||||
import 'babel-polyfill'
|
||||
import './index.styl'
|
||||
import React from 'react'
|
||||
import ReactRouter from 'react-router'
|
||||
import webrtcSupport from 'webrtcsupport'
|
||||
import routes from './routes'
|
||||
import alt from './alt'
|
||||
import SupportActions from './actions/SupportActions'
|
||||
|
||||
const bootstrap = document.getElementById('bootstrap').innerHTML
|
||||
alt.bootstrap(bootstrap)
|
||||
|
||||
window.FilePizza = () => {
|
||||
ReactRouter.run(routes, ReactRouter.HistoryLocation, Handler => {
|
||||
React.render(<Handler data={bootstrap} />, document)
|
||||
})
|
||||
if (!webrtcSupport.support) {
|
||||
SupportActions.noSupport()
|
||||
}
|
||||
|
||||
const isChrome = navigator.userAgent.toLowerCase().includes('chrome')
|
||||
if (isChrome) {
|
||||
SupportActions.isChrome()
|
||||
}
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
import xkcdPassword from "xkcd-password";
|
||||
import toppings from "./toppings";
|
||||
|
||||
const TOKEN_OPTIONS = {
|
||||
numWords: 4,
|
||||
minLength: 3,
|
||||
maxLength: 20,
|
||||
}
|
||||
|
||||
const SHORT_TOKEN_OPTIONS = {
|
||||
length: 8,
|
||||
chars: '0123456789abcdefghijklmnopqrstuvwxyz',
|
||||
}
|
||||
|
||||
const tokens = {}
|
||||
const shortTokens = {}
|
||||
|
||||
const tokenGenerator = new xkcdPassword()
|
||||
tokenGenerator.initWithWordList(toppings)
|
||||
|
||||
function generateShortToken() {
|
||||
let result = '';
|
||||
for (let i = SHORT_TOKEN_OPTIONS.length; i > 0; --i) {
|
||||
{ result += SHORT_TOKEN_OPTIONS.chars[Math.floor(Math.random() * SHORT_TOKEN_OPTIONS.chars.length)]}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function create(socket) {
|
||||
return tokenGenerator.generate(TOKEN_OPTIONS).then((parts) => {
|
||||
const token = parts.join('/')
|
||||
;const shortToken = generateShortToken()
|
||||
const result = {
|
||||
token,
|
||||
shortToken,
|
||||
socket,
|
||||
}
|
||||
|
||||
tokens[token] = result
|
||||
shortTokens[shortToken] = result
|
||||
return result
|
||||
});
|
||||
}
|
||||
|
||||
export function find(token) {
|
||||
return tokens[token]
|
||||
}
|
||||
|
||||
export function findShort(shortToken) {
|
||||
return shortTokens[shortToken.toLowerCase()]
|
||||
}
|
||||
@ -1,419 +0,0 @@
|
||||
@import "nib";
|
||||
|
||||
beige = #F9F2E7
|
||||
dark-gray = #333
|
||||
gray = #777
|
||||
green = #3F6B29
|
||||
light-blue = #40C0CB
|
||||
light-gray = #EEE
|
||||
light-green = #4BB74C
|
||||
light-red = #E23430
|
||||
light-yellow = #FFE476
|
||||
red = #B11C17
|
||||
yellow = #DEAC11
|
||||
|
||||
@keyframes rotate {
|
||||
from { transform: rotate(0deg) }
|
||||
to { transform: rotate(360deg) }
|
||||
}
|
||||
|
||||
global-reset()
|
||||
* { box-sizing: border-box }
|
||||
html, body { height: 100% }
|
||||
|
||||
h1 {
|
||||
color: red;
|
||||
font: bold 56px/64px "Lobster Two", sans-serif;
|
||||
text-align: center;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: gray
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
p {
|
||||
color: gray;
|
||||
font: 18px/22px "Quicksand", sans-serif;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
|
||||
&.notice {
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
small {
|
||||
color: gray;
|
||||
font: 12px/22px "Quicksand", sans-serif;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
|
||||
&.notice {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: 100%
|
||||
text-align: center
|
||||
color: gray
|
||||
padding: 10px 0 10px
|
||||
position: fixed
|
||||
bottom: 0
|
||||
border-radius: 5px 5px 0 0
|
||||
background white
|
||||
box-shadow 0 -2px 4px light-gray
|
||||
|
||||
iframe {
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
font: 12px/20px "Quicksand", sans-serif;
|
||||
@media (max-width: 600px) {
|
||||
font-size 14px
|
||||
}
|
||||
}
|
||||
|
||||
form p {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.byline {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
position: relative
|
||||
}
|
||||
}
|
||||
|
||||
.page {
|
||||
display: flex
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
min-height: 640px;
|
||||
padding: 40px 0 80px;
|
||||
}
|
||||
|
||||
.drop-zone {
|
||||
|
||||
.drop-zone-overlay {
|
||||
position: fixed
|
||||
top: 0
|
||||
left: 0
|
||||
width: 100%
|
||||
height: 100%
|
||||
background: rgba(0, 0, 0, 0.5)
|
||||
text-align: center
|
||||
|
||||
&:after {
|
||||
color: white
|
||||
content: 'DROP TO UPLOAD'
|
||||
display: block
|
||||
font: 24px/40px "Quicksand", sans-serif
|
||||
margin-top: -20px
|
||||
position: relative
|
||||
text-shadow: 0 1px dark-gray
|
||||
top: 50%
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 300px
|
||||
min-height: 300px
|
||||
margin: 0 auto 20px
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: center
|
||||
align-content: center
|
||||
justify-content: center
|
||||
|
||||
@media (max-width: 600px) {
|
||||
width: 150px
|
||||
min-height: 150px
|
||||
}
|
||||
|
||||
&:before {
|
||||
background: url(/images/pizza.png) center center / 300px 300px no-repeat
|
||||
content: ""
|
||||
position: absolute
|
||||
width: 300px
|
||||
height: 300px
|
||||
transition: transform 1s
|
||||
z-index: -1
|
||||
|
||||
@media (max-width: 600px) {
|
||||
width: 150px
|
||||
height: 150px
|
||||
background-size: 150px 150px
|
||||
}
|
||||
}
|
||||
|
||||
&.spinner-animated:before {
|
||||
animation: rotate 5s infinite linear
|
||||
}
|
||||
|
||||
.spinner-image {
|
||||
display: block;
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.spinner-name {
|
||||
font: bold 18px/20px "Quicksand", sans-serif
|
||||
text-align: center
|
||||
color: white
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
margin-top: 10px
|
||||
text-shadow: 0 0 3px #333
|
||||
}
|
||||
|
||||
.spinner-size {
|
||||
font: italic 12px/20px "Quicksand", sans-serif
|
||||
text-align: center
|
||||
color: white
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
text-shadow: 0 0 3px #333
|
||||
}
|
||||
}
|
||||
|
||||
.tempalink {
|
||||
display: flex
|
||||
width: calc(100vw - 40px)
|
||||
max-width: 1024px
|
||||
margin 20px auto
|
||||
|
||||
.long-url input {
|
||||
background: beige
|
||||
color: dark-gray
|
||||
border: 0
|
||||
margin: 0
|
||||
font: 18px/1 monospace
|
||||
height: 60px
|
||||
padding: 20px
|
||||
text-align: center
|
||||
width: 100%
|
||||
border-radius: 4px 4px 0 0
|
||||
}
|
||||
|
||||
.short-url {
|
||||
background: light-gray
|
||||
color: dark-gray
|
||||
height: 40px
|
||||
padding: 10px 20px
|
||||
text-align: center
|
||||
width: 100%
|
||||
font: 14px/1 "Quicksand", sans-serif;
|
||||
border-radius: 0 0 4px 4px
|
||||
|
||||
span {
|
||||
font: 14px/1 monospace
|
||||
}
|
||||
}
|
||||
|
||||
.qr {
|
||||
flex: none
|
||||
padding-right: 40px
|
||||
}
|
||||
|
||||
.urls {
|
||||
flex: auto
|
||||
}
|
||||
|
||||
img {
|
||||
height: 100px
|
||||
width: 100px
|
||||
display: block
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 850px) {
|
||||
.tempalink {
|
||||
display: flex
|
||||
flex-direction: column;
|
||||
width: calc(100vw - 40px)
|
||||
max-width: 1024px
|
||||
margin 20px auto
|
||||
|
||||
.qr {
|
||||
margin: auto;
|
||||
justify-content: center
|
||||
padding: 20px
|
||||
}
|
||||
|
||||
.short-url {
|
||||
display: flex
|
||||
flex-direction: column
|
||||
height: 70px
|
||||
|
||||
span {
|
||||
word-break: break-all
|
||||
padding: 2px
|
||||
}
|
||||
}
|
||||
|
||||
.long-url input {
|
||||
rows: auto
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-height: 360px) {
|
||||
.container {
|
||||
margin-bottom: 60px
|
||||
}
|
||||
}
|
||||
|
||||
.data {
|
||||
color: gray
|
||||
font: 14px/20px "Quicksand", sans-serif
|
||||
text-align: center
|
||||
overflow: hidden
|
||||
|
||||
.datum {
|
||||
float: left
|
||||
width: 50%
|
||||
}
|
||||
}
|
||||
|
||||
.download-button {
|
||||
display: block
|
||||
box-shadow: inset 0 1px 1px green
|
||||
padding: 20px
|
||||
background: light-green
|
||||
border: none
|
||||
color: white
|
||||
width: calc(100vw - 40px)
|
||||
max-width: 800px
|
||||
margin: 0 auto
|
||||
border-radius: 4px
|
||||
font: bold 18px/20px "Quicksand", sans-serif
|
||||
transition: 0.25s
|
||||
cursor: pointer
|
||||
text-transform: uppercase
|
||||
|
||||
&:hover, &:focus {
|
||||
box-shadow: inset 0 1px 1px lighten(green, 10%)
|
||||
background: lighten(light-green, 10%)
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: light-green
|
||||
}
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 60px
|
||||
overflow: hidden
|
||||
background: light-green
|
||||
transition: all 1s ease
|
||||
width: calc(100vw - 40px)
|
||||
max-width: 800px
|
||||
margin: 0 auto
|
||||
border-radius: 4px
|
||||
|
||||
.progress-bar-inner {
|
||||
float: left
|
||||
height: 100%
|
||||
background: light-green
|
||||
box-shadow: inset 0 1px 1px green
|
||||
overflow: hidden
|
||||
border-radius: 4px
|
||||
}
|
||||
|
||||
.progress-bar-text {
|
||||
font: 14px/60px "Quicksand", sans-serif
|
||||
color: white
|
||||
text-align: center
|
||||
text-transform: uppercase
|
||||
}
|
||||
|
||||
&.progress-bar-failed {
|
||||
background: red
|
||||
box-shadow: inset 0 1px 1px light-red
|
||||
|
||||
.progress-bar-text {
|
||||
text-align: center
|
||||
}
|
||||
}
|
||||
|
||||
&.progress-bar-in-progress {
|
||||
background: beige
|
||||
.progress-bar-inner {
|
||||
background: #FFCC00
|
||||
box-shadow: inset 0 1px 1px light-yellow
|
||||
}
|
||||
|
||||
.progress-bar-text {
|
||||
color: black
|
||||
float: right
|
||||
margin-right: 5px
|
||||
}
|
||||
}
|
||||
|
||||
&.progress-bar-small {
|
||||
height: 30px
|
||||
width: 50%
|
||||
margin: 8px auto
|
||||
border-radius: 5px
|
||||
|
||||
.progress-bar-text {
|
||||
line-height: 30px
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-file-label {
|
||||
border: 2px solid gray
|
||||
border-radius: 4px
|
||||
padding: 2px 5px
|
||||
margin-top: 10px
|
||||
background: light-gray
|
||||
display: inline-block
|
||||
cursor: pointer
|
||||
transition: all 0.25s ease
|
||||
|
||||
&:hover, &:active {
|
||||
border-color: yellow
|
||||
background: white
|
||||
color: red
|
||||
}
|
||||
|
||||
input[type="file"] {
|
||||
position: fixed
|
||||
top: -1000px
|
||||
}
|
||||
}
|
||||
|
||||
.donate-button {
|
||||
border: 2px solid green
|
||||
border-radius: 4px
|
||||
padding: 2px 5px
|
||||
margin-right: 10px
|
||||
background: light-green
|
||||
display: inline-block
|
||||
cursor: pointer
|
||||
transition: all 0.25s ease
|
||||
font: 12px/1 "Quicksand", sans-serif
|
||||
color: white
|
||||
text-decoration: none
|
||||
|
||||
&:hover, &:active {
|
||||
border-color: light-green
|
||||
color: white
|
||||
}
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
#! /usr/bin/env node
|
||||
|
||||
try {
|
||||
require('../newrelic')
|
||||
require('newrelic')
|
||||
} catch (ex) {
|
||||
// Don't load New Relic if the configuration file doesn't exist.
|
||||
}
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
p.catch(err => {
|
||||
console.error('Exiting due to unhandled rejection!')
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
})
|
||||
|
||||
process.on('uncaughtException', err => {
|
||||
console.error('Exiting due to uncaught exception!')
|
||||
console.error(err.stack)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
module.exports = require('./server')
|
||||
@ -1,82 +0,0 @@
|
||||
import socket from 'filepizza-socket'
|
||||
import DownloadActions from '../actions/DownloadActions'
|
||||
import alt from '../alt'
|
||||
import { getClient } from '../wt'
|
||||
|
||||
const SPEED_REFRESH_TIME = 2000
|
||||
|
||||
function downloadBlobURL(name, blobURL) {
|
||||
const a = document.createElement('a')
|
||||
document.body.appendChild(a)
|
||||
a.download = name
|
||||
a.href = blobURL
|
||||
a.click()
|
||||
}
|
||||
|
||||
export default alt.createStore(
|
||||
class DownloadStore {
|
||||
constructor() {
|
||||
this.bindActions(DownloadActions)
|
||||
|
||||
this.fileName = ''
|
||||
this.fileSize = 0
|
||||
this.fileType = ''
|
||||
this.infoHash = null
|
||||
this.peers = 0
|
||||
this.progress = 0
|
||||
this.speedDown = 0
|
||||
this.speedUp = 0
|
||||
this.status = 'uninitialized'
|
||||
this.token = null
|
||||
}
|
||||
|
||||
onRequestDownload() {
|
||||
if (this.status !== 'ready') {
|
||||
return
|
||||
}
|
||||
this.status = 'requesting'
|
||||
|
||||
getClient().then(client => {
|
||||
client.add(
|
||||
this.infoHash,
|
||||
{ announce: client.tracker.announce },
|
||||
(torrent) => {
|
||||
this.setState({ status: 'downloading' })
|
||||
|
||||
const updateSpeed = () => {
|
||||
this.setState({
|
||||
speedUp: torrent.uploadSpeed,
|
||||
speedDown: torrent.downloadSpeed,
|
||||
peers: torrent.numPeers,
|
||||
})
|
||||
}
|
||||
torrent.on('upload', updateSpeed)
|
||||
torrent.on('download', updateSpeed)
|
||||
setInterval(updateSpeed, SPEED_REFRESH_TIME)
|
||||
|
||||
const file = torrent.files[0]
|
||||
const stream = file.createReadStream()
|
||||
stream.on('data', (chunk) => {
|
||||
if (this.status !== 'downloading') {
|
||||
return
|
||||
}
|
||||
|
||||
if (torrent.progress === 1) {
|
||||
this.setState({ status: 'done', progress: 1 })
|
||||
file.getBlobURL((err, blobURL) => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
downloadBlobURL(this.fileName, blobURL)
|
||||
})
|
||||
} else {
|
||||
this.setState({ progress: torrent.progress })
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
'DownloadStore',
|
||||
)
|
||||
@ -1,21 +0,0 @@
|
||||
import SupportActions from '../actions/SupportActions'
|
||||
import alt from '../alt'
|
||||
|
||||
export default alt.createStore(
|
||||
class ErrorStore {
|
||||
constructor() {
|
||||
this.bindActions(SupportActions)
|
||||
|
||||
this.status = 404
|
||||
this.message = 'Not Found'
|
||||
this.stack = null
|
||||
}
|
||||
|
||||
onNoSupport() {
|
||||
this.status = 400
|
||||
this.message = 'No WebRTC Support. Please use Chrome or Firefox.'
|
||||
this.stack = null
|
||||
}
|
||||
},
|
||||
'ErrorStore',
|
||||
)
|
||||
@ -1,21 +0,0 @@
|
||||
import SupportActions from '../actions/SupportActions'
|
||||
import alt from '../alt'
|
||||
|
||||
export default alt.createStore(
|
||||
class SupportStore {
|
||||
constructor() {
|
||||
this.bindActions(SupportActions)
|
||||
this.isSupported = true
|
||||
this.isChrome = false
|
||||
}
|
||||
|
||||
onNoSupport() {
|
||||
this.isSupported = false
|
||||
}
|
||||
|
||||
onIsChrome() {
|
||||
this.isChrome = true
|
||||
}
|
||||
},
|
||||
'SupportStore',
|
||||
)
|
||||
@ -1,68 +0,0 @@
|
||||
import socket from 'filepizza-socket'
|
||||
import UploadActions from '../actions/UploadActions'
|
||||
import alt from '../alt'
|
||||
import { getClient } from '../wt'
|
||||
|
||||
const SPEED_REFRESH_TIME = 2000
|
||||
|
||||
export default alt.createStore(
|
||||
class UploadStore {
|
||||
constructor() {
|
||||
this.bindActions(UploadActions)
|
||||
|
||||
this.fileName = ''
|
||||
this.fileSize = 0
|
||||
this.fileType = ''
|
||||
this.infoHash = null
|
||||
this.peers = 0
|
||||
this.speedUp = 0
|
||||
this.status = 'ready'
|
||||
this.token = null
|
||||
this.shortToken = null
|
||||
}
|
||||
|
||||
onUploadFile(file) {
|
||||
if (this.status !== 'ready') {
|
||||
return
|
||||
}
|
||||
this.status = 'processing'
|
||||
|
||||
getClient().then(client => {
|
||||
client.seed(file, { announce: client.tracker.announce }, torrent => {
|
||||
const updateSpeed = () => {
|
||||
this.setState({
|
||||
speedUp: torrent.uploadSpeed,
|
||||
peers: torrent.numPeers,
|
||||
})
|
||||
}
|
||||
|
||||
torrent.on('upload', updateSpeed)
|
||||
torrent.on('download', updateSpeed)
|
||||
setInterval(updateSpeed, SPEED_REFRESH_TIME)
|
||||
|
||||
socket.emit(
|
||||
'upload',
|
||||
{
|
||||
fileName: file.name,
|
||||
fileSize: file.size,
|
||||
fileType: file.type,
|
||||
infoHash: torrent.magnetURI,
|
||||
},
|
||||
(res) => {
|
||||
this.setState({
|
||||
status: 'uploading',
|
||||
token: res.token,
|
||||
shortToken: res.shortToken,
|
||||
fileName: file.name,
|
||||
fileSize: file.size,
|
||||
fileType: file.type,
|
||||
infoHash: torrent.magnetURI,
|
||||
})
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
'UploadStore',
|
||||
)
|
||||
Loading…
Reference in New Issue