mirror of https://github.com/kern/filepizza
Just keep going
parent
b601c89eeb
commit
6a0ab981f0
@ -0,0 +1,58 @@
|
|||||||
|
import React, { useEffect, useRef } from 'react'
|
||||||
|
import { usePeerData } from 'react-peer-data'
|
||||||
|
import { Room } from 'peer-data'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
roomName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const Downloader: React.FC<Props> = ({ roomName }: Props) => {
|
||||||
|
const room = useRef<Room | null>(null)
|
||||||
|
const peerData = usePeerData()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (room.current) return
|
||||||
|
|
||||||
|
room.current = peerData.connect(roomName)
|
||||||
|
console.log(room.current)
|
||||||
|
setInterval(() => console.log(room.current), 1000)
|
||||||
|
room.current
|
||||||
|
.on('participant', (participant) => {
|
||||||
|
console.log(participant.getId() + ' joined')
|
||||||
|
participant.newDataChannel()
|
||||||
|
|
||||||
|
participant
|
||||||
|
.on('connected', () => {
|
||||||
|
console.log('connected', participant.id)
|
||||||
|
})
|
||||||
|
.on('disconnected', () => {
|
||||||
|
console.log('disconnected', participant.id)
|
||||||
|
})
|
||||||
|
.on('track', (event) => {
|
||||||
|
console.log('stream', participant.id, event.streams[0])
|
||||||
|
})
|
||||||
|
.on('message', (payload) => {
|
||||||
|
console.log(participant.id, payload)
|
||||||
|
})
|
||||||
|
.on('error', (event) => {
|
||||||
|
console.error('peer', participant.id, event)
|
||||||
|
participant.renegotiate()
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(participant)
|
||||||
|
participant.send(`hello there, I'm the downloader`)
|
||||||
|
})
|
||||||
|
.on('error', (event) => {
|
||||||
|
console.error('room', roomName, event)
|
||||||
|
})
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
room.current.disconnect()
|
||||||
|
room.current = null
|
||||||
|
}
|
||||||
|
}, [peerData])
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Downloader
|
||||||
@ -1,64 +1,66 @@
|
|||||||
import React from 'react'
|
import React, { useState, useRef, useCallback } from 'react'
|
||||||
|
import styled from 'styled-components'
|
||||||
|
import { extractFileList } from '../fs'
|
||||||
|
|
||||||
export default class DropZone extends React.Component {
|
const Wrapper = styled.div`
|
||||||
constructor() {
|
display: block;
|
||||||
super()
|
`
|
||||||
this.state = { focus: false }
|
|
||||||
|
|
||||||
this.onDragEnter = this.onDragEnter.bind(this)
|
const Overlay = styled.div`
|
||||||
this.onDragLeave = this.onDragLeave.bind(this)
|
display: block;
|
||||||
this.onDragOver = this.onDragOver.bind(this)
|
`
|
||||||
this.onDrop = this.onDrop.bind(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
onDragEnter() {
|
interface Props {
|
||||||
this.setState({ focus: true })
|
onDrop: (files: any) => void
|
||||||
|
children?: React.ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
onDragLeave(e) {
|
const Dropzone: React.FC<Props> = ({ children, onDrop }: Props) => {
|
||||||
if (e.target !== this.refs.overlay.getDOMNode()) {
|
const overlay = useRef()
|
||||||
|
const [focus, setFocus] = useState(false)
|
||||||
|
|
||||||
|
const handleDragEnter = useCallback(() => {
|
||||||
|
setFocus(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleDragLeave = useCallback(
|
||||||
|
(e: React.DragEvent) => {
|
||||||
|
if (e.target !== overlay.current) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.setState({ focus: false })
|
|
||||||
}
|
|
||||||
|
|
||||||
onDragOver(e) {
|
setFocus(false)
|
||||||
|
},
|
||||||
|
[overlay.current],
|
||||||
|
)
|
||||||
|
|
||||||
|
const handleDragOver = useCallback((e: React.DragEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.dataTransfer.dropEffect = 'copy'
|
e.dataTransfer.dropEffect = 'copy'
|
||||||
}
|
}, [])
|
||||||
|
|
||||||
onDrop(e) {
|
const handleDrop = useCallback(
|
||||||
|
async (e: React.DragEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
this.setState({ focus: false })
|
setFocus(false)
|
||||||
|
|
||||||
const file = e.dataTransfer.files[0]
|
const files = await extractFileList(e)
|
||||||
if (this.props.onDrop && file) {
|
onDrop(files)
|
||||||
this.props.onDrop(file)
|
},
|
||||||
}
|
[onDrop],
|
||||||
}
|
)
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
return (
|
||||||
<div
|
<Wrapper
|
||||||
className="drop-zone"
|
onDragEnter={handleDragEnter}
|
||||||
ref="root"
|
onDragLeave={handleDragLeave}
|
||||||
onDragEnter={this.onDragEnter}
|
onDragOver={handleDragOver}
|
||||||
onDragLeave={this.onDragLeave}
|
onDrop={handleDrop}
|
||||||
onDragOver={this.onDragOver}
|
|
||||||
onDrop={this.onDrop}
|
|
||||||
>
|
>
|
||||||
<div
|
<Overlay ref={overlay} hidden={!focus} />
|
||||||
className="drop-zone-overlay"
|
{children}
|
||||||
hidden={!this.state.focus}
|
</Wrapper>
|
||||||
ref="overlay"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{this.props.children}
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DropZone.propTypes = {
|
export default Dropzone
|
||||||
onDrop: React.PropTypes.func.isRequired,
|
|
||||||
}
|
|
||||||
|
|||||||
@ -0,0 +1,27 @@
|
|||||||
|
import React, { useCallback } from 'react'
|
||||||
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
const StyledPasswordInput = styled.input`
|
||||||
|
background: red;
|
||||||
|
`
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
value: string
|
||||||
|
onChange: (value: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PasswordField: React.FC<Props> = ({ value, onChange }: Props) => {
|
||||||
|
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
onChange(e.target.value)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledPasswordInput
|
||||||
|
type="password"
|
||||||
|
value={value}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PasswordField
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
const StyledStartButton = styled.button`
|
||||||
|
background: green;
|
||||||
|
`
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
onClick: React.MouseEventHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
const StartButton: React.FC<Props> = ({ onClick }: Props) => {
|
||||||
|
return <StyledStartButton onClick={onClick}>Start</StyledStartButton>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default StartButton
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
const StyledStopButton = styled.button`
|
||||||
|
background: blue;
|
||||||
|
`
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
onClick: React.MouseEventHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
const StopButton: React.FC<Props> = ({ onClick }: Props) => {
|
||||||
|
return <StyledStopButton onClick={onClick}>Stop</StyledStopButton>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default StopButton
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { UploadedFile } from '../types'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
files: UploadedFile[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const UploadFileList: React.FC<Props> = ({ files }: Props) => {
|
||||||
|
const items = files.map((f) => <li key={f.fullPath}>{f.fullPath}</li>)
|
||||||
|
return <ul>{items}</ul>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UploadFileList
|
||||||
@ -1,46 +1,54 @@
|
|||||||
import Arrow from '@app/components/Arrow'
|
import React, { useRef, useEffect } from 'react'
|
||||||
import React from 'react'
|
import { usePeerData } from 'react-peer-data'
|
||||||
import UploadActions from '@app/actions/UploadActions'
|
import { UploadedFile } from '../types'
|
||||||
|
import { Room } from 'peer-data'
|
||||||
|
|
||||||
export default class UploadPage extends React.Component {
|
interface Props {
|
||||||
constructor() {
|
roomName: string
|
||||||
super()
|
files: UploadedFile[]
|
||||||
this.uploadFile = this.uploadFile.bind(this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadFile(file) {
|
const Uploader: React.FC<Props> = ({ roomName, files }: Props) => {
|
||||||
UploadActions.uploadFile(file)
|
const room = useRef<Room | null>(null)
|
||||||
}
|
const peerData = usePeerData()
|
||||||
|
|
||||||
render() {
|
useEffect(() => {
|
||||||
switch (this.props.status) {
|
room.current = peerData.connect(roomName)
|
||||||
case 'ready':
|
room.current
|
||||||
return (
|
.on('participant', (participant) => {
|
||||||
<div>
|
console.log(participant.getId() + ' joined')
|
||||||
<DropZone onDrop={this.uploadFile} />
|
|
||||||
<Arrow dir="up" />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'processing':
|
participant
|
||||||
return (
|
.on('connected', () => {
|
||||||
<div>
|
console.log('connected', participant.id)
|
||||||
<Arrow dir="up" animated />
|
})
|
||||||
<FileDescription file={this.props.file} />
|
.on('disconnected', () => {
|
||||||
</div>
|
console.log('disconnected', participant.id)
|
||||||
)
|
})
|
||||||
break
|
.on('track', (event) => {
|
||||||
|
console.log('stream', participant.id, event.streams[0])
|
||||||
|
})
|
||||||
|
.on('message', (payload) => {
|
||||||
|
console.log(participant.id, payload)
|
||||||
|
})
|
||||||
|
.on('error', (event) => {
|
||||||
|
console.error('peer', participant.id, event)
|
||||||
|
participant.renegotiate()
|
||||||
|
})
|
||||||
|
participant.send(`hello there, I'm the uploader`)
|
||||||
|
})
|
||||||
|
.on('error', (event) => {
|
||||||
|
console.error('room', roomName, event)
|
||||||
|
})
|
||||||
|
|
||||||
case 'uploading':
|
return () => {
|
||||||
return (
|
room.current.disconnect()
|
||||||
<div>
|
room.current = null
|
||||||
<Arrow dir="up" animated />
|
|
||||||
<FileDescription file={this.props.file} />
|
|
||||||
<Temaplink token={this.props.token} />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}, [peerData])
|
||||||
|
|
||||||
|
const items = files.map((f) => <li key={f.fullPath}>{f.fullPath}</li>)
|
||||||
|
return <ul>{items}</ul>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default Uploader
|
||||||
|
|||||||
@ -0,0 +1,60 @@
|
|||||||
|
const getAsFile = (entry: any): Promise<File> =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
entry.file((file: File) => {
|
||||||
|
file.fullPath = entry.fullPath
|
||||||
|
resolve(file)
|
||||||
|
}, reject)
|
||||||
|
})
|
||||||
|
|
||||||
|
const readDirectoryEntries = (reader: any): Promise<any[]> =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
reader.readEntries((entries) => {
|
||||||
|
resolve(entries)
|
||||||
|
}, reject)
|
||||||
|
})
|
||||||
|
|
||||||
|
const scanDirectoryEntry = async (entry: any): Promise<File[]> => {
|
||||||
|
const directoryReader = entry.createReader()
|
||||||
|
const result = []
|
||||||
|
// eslint-disable-next-line no-constant-condition
|
||||||
|
while (true) {
|
||||||
|
const subentries = await readDirectoryEntries(directoryReader)
|
||||||
|
if (!subentries.length) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const se of subentries) {
|
||||||
|
if (se.isDirectory) {
|
||||||
|
const ses = await scanDirectoryEntry(se)
|
||||||
|
result.push(...ses)
|
||||||
|
} else {
|
||||||
|
const file = await getAsFile(se)
|
||||||
|
result.push(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const extractFileList = async (e: React.DragEvent): Promise<File[]> => {
|
||||||
|
if (!e.dataTransfer.items.length) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = e.dataTransfer.items
|
||||||
|
const scans = []
|
||||||
|
const files = []
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
const entry = item.webkitGetAsEntry()
|
||||||
|
if (entry.isDirectory) {
|
||||||
|
scans.push(scanDirectoryEntry(entry))
|
||||||
|
} else {
|
||||||
|
files.push(getAsFile(entry))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const scanResults = await Promise.all(scans)
|
||||||
|
const fileResults = await Promise.all(files)
|
||||||
|
|
||||||
|
return [scanResults, fileResults].flat(2)
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import debug from 'debug'
|
||||||
|
|
||||||
|
export const error = debug('filepizza:error')
|
||||||
|
|
||||||
|
export const info = debug('filepizza:info')
|
||||||
|
|
||||||
|
export const warn = debug('filepizza:warn')
|
||||||
@ -1,11 +1,25 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import WebRTCProvider from '../../components/WebRTCProvider'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
|
import Downloader from '../../components/Downloader'
|
||||||
|
import { NextPage } from 'next'
|
||||||
|
|
||||||
const DownloadPage: React.FC = () => {
|
const DownloadPage: NextPage = () => {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { slug } = router.query
|
const { slug } = router.query
|
||||||
|
|
||||||
return <div>{JSON.stringify(slug)}</div>
|
return (
|
||||||
|
<WebRTCProvider>
|
||||||
|
<>
|
||||||
|
<div>{JSON.stringify(slug)}</div>
|
||||||
|
<Downloader roomName="my-room" />
|
||||||
|
</>
|
||||||
|
</WebRTCProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadPage.getInitialProps = () => {
|
||||||
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DownloadPage
|
export default DownloadPage
|
||||||
|
|||||||
@ -1,10 +1,67 @@
|
|||||||
import React from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
import WebRTCProvider from '../components/WebRTCProvider'
|
import WebRTCProvider from '../components/WebRTCProvider'
|
||||||
|
import Dropzone from '../components/Dropzone'
|
||||||
|
import UploadFileList from '../components/UploadFileList'
|
||||||
|
import Uploader from '../components/Uploader'
|
||||||
|
import PasswordField from '../components/PasswordField'
|
||||||
|
import StartButton from '../components/StartButton'
|
||||||
|
import StopButton from '../components/StopButton'
|
||||||
|
import { UploadedFile } from '../types'
|
||||||
|
import { NextPage } from 'next'
|
||||||
|
|
||||||
export const IndexPage: React.FC = () => (
|
export const IndexPage: NextPage = () => {
|
||||||
|
const [uploadedFiles, setUploadedFiles] = useState<UploadedFile[]>([])
|
||||||
|
const [password, setPassword] = useState('')
|
||||||
|
const [uploading, setUploading] = useState(false)
|
||||||
|
|
||||||
|
const handleDrop = useCallback((files: UploadedFile[]): void => {
|
||||||
|
console.log('Received files', files)
|
||||||
|
setUploadedFiles(files)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleChangePassword = useCallback((pw: string) => {
|
||||||
|
setPassword(pw)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleStart = useCallback(() => {
|
||||||
|
setUploading(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleStop = useCallback(() => {
|
||||||
|
setUploading(false)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
if (!uploadedFiles.length) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Dropzone onDrop={handleDrop}>Drop a file to get started.</Dropzone>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uploading) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<UploadFileList files={uploadedFiles} />
|
||||||
|
<PasswordField value={password} onChange={handleChangePassword} />
|
||||||
|
<StartButton onClick={handleStart} />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
<WebRTCProvider>
|
<WebRTCProvider>
|
||||||
<>Index page</>
|
<>
|
||||||
|
<UploadFileList files={uploadedFiles} />
|
||||||
|
<StopButton onClick={handleStop} />
|
||||||
|
<Uploader roomName={'my-room'} files={uploadedFiles} />
|
||||||
|
</>
|
||||||
</WebRTCProvider>
|
</WebRTCProvider>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexPage.getInitialProps = () => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
export default IndexPage
|
export default IndexPage
|
||||||
|
|||||||
@ -0,0 +1,26 @@
|
|||||||
|
const { createServer } = require('http')
|
||||||
|
const { parse } = require('url')
|
||||||
|
const next = require('next')
|
||||||
|
const PeerDataServer = require('peer-data-server')
|
||||||
|
|
||||||
|
const appendPeerDataServer = PeerDataServer.default || PeerDataServer
|
||||||
|
const dev = process.env.NODE_ENV !== 'production'
|
||||||
|
const app = next({ dev })
|
||||||
|
const handle = app.getRequestHandler()
|
||||||
|
|
||||||
|
app.prepare().then(() => {
|
||||||
|
const server = createServer((req, res) => {
|
||||||
|
const parsedUrl = parse(req.url, true)
|
||||||
|
handle(req, res, parsedUrl)
|
||||||
|
})
|
||||||
|
|
||||||
|
appendPeerDataServer(server)
|
||||||
|
|
||||||
|
server.listen(3000, (err) => {
|
||||||
|
if (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('> Ready on http://localhost:3000')
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -1,112 +0,0 @@
|
|||||||
const fs = require('fs')
|
|
||||||
const express = require('express')
|
|
||||||
const expressWinston = require('express-winston')
|
|
||||||
const socketIO = require('socket.io')
|
|
||||||
const winston = require('winston')
|
|
||||||
const ice = require('./ice')
|
|
||||||
const db = require('./db')
|
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
|
||||||
p.catch(err => {
|
|
||||||
log.error('Exiting due to unhandled rejection!')
|
|
||||||
log.error(err)
|
|
||||||
process.exit(1)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
process.on('uncaughtException', (err) => {
|
|
||||||
log.error('Exiting due to uncaught exception!')
|
|
||||||
log.error(err)
|
|
||||||
process.exit(1)
|
|
||||||
})
|
|
||||||
const app = express()
|
|
||||||
let port
|
|
||||||
process.env.PORT || (process.env.NODE_ENV === 'production' ? 80 : 3000)
|
|
||||||
|
|
||||||
if (!process.env.QUIET) {
|
|
||||||
app.use(
|
|
||||||
expressWinston.logger({
|
|
||||||
winstonInstance: winston,
|
|
||||||
expressFormat: true,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
app.get('/app.js', require('./middleware/javascript'))
|
|
||||||
app.use(require('./middleware/static'))
|
|
||||||
|
|
||||||
app.use([
|
|
||||||
require('./middleware/bootstrap'),
|
|
||||||
require('./middleware/error'),
|
|
||||||
require('./middleware/react'),
|
|
||||||
])
|
|
||||||
|
|
||||||
const TRACKERS = process.env.WEBTORRENT_TRACKERS
|
|
||||||
? process.env.WEBTORRENT_TRACKERS.split(',').map(t => [t.trim()])
|
|
||||||
: [
|
|
||||||
['wss://tracker.openwebtorrent.com'],
|
|
||||||
['wss://tracker.btorrent.xyz'],
|
|
||||||
['wss://tracker.fastcast.nz'],
|
|
||||||
]
|
|
||||||
|
|
||||||
function bootServer(server) {
|
|
||||||
const io = socketIO(server)
|
|
||||||
io.set('transports', ['polling'])
|
|
||||||
|
|
||||||
io.on('connection', (socket) => {
|
|
||||||
let upload = null
|
|
||||||
|
|
||||||
socket.on('upload', (metadata, res) => {
|
|
||||||
if (upload) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
db.create(socket).then(u => {
|
|
||||||
upload = u
|
|
||||||
upload.fileName = metadata.fileName
|
|
||||||
upload.fileSize = metadata.fileSize
|
|
||||||
upload.fileType = metadata.fileType
|
|
||||||
upload.infoHash = metadata.infoHash
|
|
||||||
res({ token: upload.token, shortToken: upload.shortToken })
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
socket.on('trackerConfig', (_, res) => {
|
|
||||||
ice.getICEServers().then(iceServers => {
|
|
||||||
res({ rtcConfig: { iceServers }, announce: TRACKERS })
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
socket.on('disconnect', () => {
|
|
||||||
db.remove(upload)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
server.on('error', (err) => {
|
|
||||||
winston.error(err.message)
|
|
||||||
process.exit(1)
|
|
||||||
})
|
|
||||||
server.listen(port, (err) => {
|
|
||||||
const host = server.address().address
|
|
||||||
const port = server.address().port
|
|
||||||
winston.info('FilePizza listening on %s:%s', host, port)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.env.HTTPS_KEY && process.env.HTTPS_CERT) {
|
|
||||||
// user-supplied HTTPS key/cert
|
|
||||||
const https = require('https')
|
|
||||||
|
|
||||||
var server = https.createServer(
|
|
||||||
{
|
|
||||||
key: fs.readFileSync(process.env.HTTPS_KEY),
|
|
||||||
cert: fs.readFileSync(process.env.HTTPS_CERT),
|
|
||||||
},
|
|
||||||
app,
|
|
||||||
)
|
|
||||||
bootServer(server)
|
|
||||||
} else {
|
|
||||||
// no HTTPS
|
|
||||||
const http = require('http')
|
|
||||||
|
|
||||||
var server = http.Server(app)
|
|
||||||
bootServer(server)
|
|
||||||
}
|
|
||||||
@ -0,0 +1 @@
|
|||||||
|
export type UploadedFile = File & { fullPath: string }
|
||||||
@ -1,51 +0,0 @@
|
|||||||
const nib = require("nib");
|
|
||||||
const webpack = require('webpack')
|
|
||||||
;module.exports = {
|
|
||||||
entry: "./src/client",
|
|
||||||
target: "web",
|
|
||||||
|
|
||||||
output: {
|
|
||||||
filename: "dist/bundle.js",
|
|
||||||
},
|
|
||||||
|
|
||||||
module: {
|
|
||||||
loaders: [
|
|
||||||
{
|
|
||||||
test: /\.js$/,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
loader: "babel-loader",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.json$/,
|
|
||||||
loader: "json",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.styl$/,
|
|
||||||
loader: "style-loader!css-loader!stylus-loader",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
plugins: [
|
|
||||||
new webpack.DefinePlugin({
|
|
||||||
'process.env': {
|
|
||||||
GA_ACCESS_TOKEN: JSON.stringify(process.env.GA_ACCESS_TOKEN),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
|
|
||||||
node: {
|
|
||||||
fs: "empty",
|
|
||||||
},
|
|
||||||
|
|
||||||
stylus: {
|
|
||||||
use: [nib()],
|
|
||||||
},
|
|
||||||
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /react-google-analytics/,
|
|
||||||
use: process.env.GA_ACCESS_TOKEN ? 'null-loader' : 'noop-loader',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
Loading…
Reference in New Issue