import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import magnet from 'magnet-uri'; import WebTorrent from 'webtorrent'; import * as requestActions from '../../redux/requestActions'; import { saveAs } from 'file-saver/FileSaver'; import { client } from './index'; const DEFAULT_PICTURE = 'resources/images/avatar-empty.jpeg'; class FileEntry extends Component { state = { active : false, numPeers : 0, progress : 0, files : null }; saveFile = (file) => { file.getBlob((err, blob) => { if (err) { return this.props.notify({ text : 'An error occurred while saving a file' }); } saveAs(blob, file.name); }); }; handleTorrent = (torrent) => { // Torrent already done, this can happen if the // same file was sent multiple times. if (torrent.progress === 1) { this.setState({ files : torrent.files, numPeers : torrent.numPeers, progress : 1, active : false, timeout : false }); return; } const onProgress = () => { this.setState({ numPeers : torrent.numPeers, progress : torrent.progress }); }; onProgress(); setInterval(onProgress, 500); torrent.on('done', () => { onProgress(); clearInterval(onProgress); this.setState({ files : torrent.files, active : false }); }); }; handleDownload = () => { this.setState({ active : true }); const magnetURI = this.props.data.file.magnet; const existingTorrent = client.get(magnetURI); if (existingTorrent) { // Never add duplicate torrents, use the existing one instead. return this.handleTorrent(existingTorrent); } client.add(magnetURI, this.handleTorrent); setTimeout(() => { if (this.state.active && this.state.numPeers === 0) { this.setState({ timeout : true }); } }, 10 * 1000); } render() { return (
{this.props.data.me ? (

You shared a file.

) : (

{this.props.data.name} shared a file.

)} {!this.state.active && !this.state.files && (
{WebTorrent.WEBRTC_SUPPORT ? ( ) : (

Your browser does not support downloading files using WebTorrent.

)}

{magnet.decode(this.props.data.file.magnet).dn}

)} {this.state.active && this.state.numPeers === 0 && (

Locating peers

{this.state.timeout && (

If this process takes a long time, there might not be anyone seeding this torrent. Try asking someone to reupload the file that you want.

)}
)} {this.state.active && this.state.numPeers > 0 && ( )} {this.state.files && (

Torrent finished downloading.

{this.state.files.map((file, i) => (
this.saveFile(file)}>

{file.name}

))}
)}
); } } export const FileEntryProps = { data : PropTypes.shape({ name : PropTypes.string.isRequired, picture : PropTypes.string, file : PropTypes.shape({ magnet : PropTypes.string.isRequired }).isRequired, me : PropTypes.bool }).isRequired, notify : PropTypes.func.isRequired }; FileEntry.propTypes = FileEntryProps; const mapDispatchToProps = { notify : requestActions.notify }; export default connect( undefined, mapDispatchToProps )(FileEntry);