import React from 'react'; import Page from './page'; import formatBytes from './format-bytes' import {List, ListItem} from 'material-ui/List'; import Subheader from 'material-ui/Subheader'; import {Tabs, Tab} from 'material-ui/Tabs'; import ActionInfo from 'material-ui/svg-icons/action/info'; import RaisedButton from 'material-ui/RaisedButton'; import Toggle from 'material-ui/Toggle'; import FileFolder from 'material-ui/svg-icons/file/folder'; import NoImage from './images/no-image-icon.png' var moment = require('moment'); import RefreshIndicator from 'material-ui/RefreshIndicator'; let rating = require('./rating'); import LinearProgress from './LinearProgress'; import FlatButton from 'material-ui/FlatButton'; import {fileTypeDetect} from './content' import {contentIcon} from './torrent' import TrackersImages from './trackers-images' import DownloadTorrentMenu from './download-torrent-menu' let parseDescriptionText = (text) => { return text.split("\n").map(function(item) { const text = /(.+?:)(.*)/.exec(item) return ( { text ? {`${text[1]} `}{text[2]} : item }
) }) } let buildFilesTree = (filesList) => { let rootTree = { __sizeBT: 0 }; filesList.forEach((file) => { let pathTree = file.path.split('/'); let currentItem = rootTree; pathTree.forEach((pathItem, index) => { if(!(pathItem in currentItem)) { // крайний индекс, значит это объект файла, объединяем объекты if(index === pathTree.length - 1) { file.__sizeBT = 0 file.__fileBT = true currentItem[pathItem] = file } else { currentItem[pathItem] = { __sizeBT: 0 } } } currentItem = currentItem[pathItem] currentItem.__sizeBT += file.size; }) rootTree.__sizeBT += file.size; }); return rootTree; } const treeToTorrentFiles = (tree, torrent, toggles) => { // toggles for button disable/enable torrent/directory in torrent client if(toggles) { if(tree.__fileBT && typeof tree.downloadIndex !== 'undefined') { toggles.push({ downloadIndex: tree.downloadIndex, selected: typeof tree.downloadSelected === 'undefined' || tree.downloadSelected }) } } // this is already file, return if(tree.__fileBT) return let arr = []; for(let file in tree) { if(file == '__sizeBT') continue; const newToggles = [] arr.push( : contentIcon(fileTypeDetect({path: file}))} rightToggle={ newToggles.length > 0 ? selected )} onToggle={(e, checked) => { e.preventDefault() e.stopPropagation() let toggleValues = {} newToggles.forEach(({downloadIndex}) => toggleValues[downloadIndex] = checked) window.torrentSocket.emit('downloadSelectFiles', torrent, toggleValues) }} /> : null } />); if(toggles) { for(const newToggle of newToggles) toggles.push(newToggle) } } return arr; } const TorrentFiles = (props) => { let filesList = props.torrent.filesList; let tree = buildFilesTree(filesList); return ( { filesList.length > 0 ?
{__('Content of the torrent')}: {treeToTorrentFiles(tree, {hash: props.torrent.hash})}
:
{__('Processing files')}...
}
); }; const TorrentInformation = (props) => { let torrent = props.torrent; return ( {__('Information about torrent')} } backgroundColor={blue500} />} rightIcon={} primaryText={__('Torrent Name')} secondaryText={{(torrent.info && torrent.info.name) || torrent.name}} /> } backgroundColor={yellow600} />} rightIcon={} id="torrentSizeId" primaryText={__('Torrent Size')} secondaryText={formatBytes(torrent.size)} onClick={() => { if(!props.parent) return props.parent.setState({ value: 'files' }) }} /> } backgroundColor={yellow600} />} rightIcon={} primaryText={__('Torrent contains files')} id="torrentFilesId" secondaryText={torrent.files} onClick={() => { if(!props.parent) return props.parent.setState({ value: 'files' }) }} /> } backgroundColor={yellow600} />} rightIcon={} primaryText={__('Indexed/Added torrent date')} secondaryText={moment(torrent.added * 1000).format('MMMM Do YYYY, hh:mm')} /> } backgroundColor={yellow600} />} rightIcon={} primaryText={__('Content type')} secondaryText={torrent.contentType || 'unknown'} /> } backgroundColor={yellow600} />} rightIcon={} primaryText={__('Category')} secondaryText={(torrent.info && torrent.info.contentCategory) || torrent.contentCategory || 'unknown'} /> ); } export default class TorrentPage extends Page { constructor(props) { super(props); this.state = { value: 'info', searchingIndicator: false, voting: false, voted: false, downloading: false, downloaded: false, startingDownloading: false, downloadProgress: {} }; this.setTitle('Information about torrent'); } changeTab(tab) { if(this.state.value != tab) { this.setState({ value: tab }); console.log('change'); } } onSwipeRight() { this.changeTab('files'); } onSwipeLeft() { this.changeTab('info'); } handleChange = (value) => { if(value == 'main') { window.routerOpenPrev(); return; } this.setState({ value: value, }); }; getTorrentInfo() { window.torrentSocket.emit('torrent', this.props.hash, {files: true, peer: this.props.peer}, window.customLoader((data) => { if(data) { this.torrent = data this.setTitle(this.torrent.name + ' - Rats On The Boat'); if(this.torrent.contentCategory == 'xxx') { this.setMetaTag('robots', 'noindex'); } //this.forceUpdate(); // вызывается через searchingIndicator // Получаем более новую статистику пира if((Date.now() / 1000) - this.torrent.trackersChecked > 10 * 60) { window.torrentSocket.emit('checkTrackers', this.torrent.hash); } } }, () => { this.setState({ searchingIndicator: true }); }, () => { this.setState({ searchingIndicator: false }); })); } componentDidMount() { super.componentDidMount(); this.filesUpdated = (hash, filesList) => { if(this.props.hash != hash) return; if(filesList) { if(this.torrent) { this.torrent.filesList = filesList this.forceUpdate() } } else this.getTorrentInfo(); } window.torrentSocket.on('filesReady', this.filesUpdated); this.trackerUpdate = (info) => { if(this.props.hash != info.hash) return; if(!this.torrent) return; this.torrent = Object.assign(this.torrent, info); this.forceUpdate(); } window.torrentSocket.on('trackerTorrentUpdate', this.trackerUpdate); this.onVotes = async ({hash, good, bad, selfVote}) => { if(this.props.hash != hash) return; if(!this.torrent) return this.torrent.good = good; this.torrent.bad = bad; this.state.voted = selfVote; this.forceUpdate(); } window.torrentSocket.on('votes', this.onVotes); this.downloading = (hash) => { if(this.props.hash != hash) return; this.setState({ downloading: true, startingDownloading: false }) } window.torrentSocket.on('downloading', this.downloading); this.downloadDone = (hash, canceled) => { if(this.props.hash != hash) return; this.setState({ downloading: false, startingDownloading: false, downloaded: !canceled }) } window.torrentSocket.on('downloadDone', this.downloadDone); this.downloadProgress = (hash, progress) => { if(this.props.hash != hash) return; this.setState({ downloading: true, startingDownloading: false, downloadProgress: progress }) } window.torrentSocket.on('downloadProgress', this.downloadProgress); this.getTorrentInfo(); } componentWillUnmount() { if(this.filesUpdated) window.torrentSocket.off('filesReady', this.filesUpdated); if(this.trackerUpdate) window.torrentSocket.off('trackerTorrentUpdate', this.trackerUpdate); if(this.onVotes) window.torrentSocket.off('votes', this.onVotes); if(this.torrent && this.torrent.contentCategory == 'xxx') { this.removeMetaTag('robots'); } if(this.downloading) window.torrentSocket.off('downloading', this.downloading); if(this.downloadDone) window.torrentSocket.off('downloadDone', this.downloadDone); if(this.downloadProgress) window.torrentSocket.off('downloadProgress', this.downloadProgress); } vote(good) { if(!this.torrent) return; this.setState({ voting: true }); window.torrentSocket.emit('vote', this.torrent.hash, !!good, window.customLoader((success) => { this.setState({ voted: true, voting: false }); })); } render() { const style = { refresh: { display: 'inline-block', position: 'relative', }, }; if(this.state.searchingIndicator) { return (
{ window.routerOpenPrev(); }} />
); } let torrentRating; if(this.torrent) { torrentRating = Math.round(rating(this.torrent.good, this.torrent.bad) * 100); } return (
{ this.torrent ?
{ e.preventDefault(); window.open(`magnet:?xt=urn:btih:${this.torrent.hash}`, '_self') }} icon={} /> { !this.state.downloaded && !this.state.downloading && !this.state.startingDownloading && { e.preventDefault(); }} icon={ } /> } { this.state.downloading &&
{__('downloading')} {this.state.downloadProgress && (this.state.downloadProgress.progress * 100).toFixed(1)}%
{ window.torrentSocket.emit('downloadCancel', this.torrent.hash) }} label={__('Cancel download')} secondary={true} icon={} />
}
BTIH:
{this.torrent.hash}
{ this.torrent.seeders || this.torrent.leechers || this.torrent.completed ?
{__('seeders')}: {this.torrent.seeders}
{__('leechers')}: {this.torrent.leechers}
{__('completed')}: {this.torrent.completed}
: null } { !this.state.voted && !this.state.voting ?
} onClick={() => this.vote(true)} /> } onClick={() => this.vote(false)} />
: this.state.voting ?
voting...
:
Thank you for voting!
} { this.torrent.good > 0 || this.torrent.bad > 0 ?
= 50 ? '#00E676' : '#FF3D00'} style={{ height: '5px', }} />
= 50 ? '#00E676' : '#FF3D00'}}>{__('Torrent rating')}: {torrentRating}%
: null }
{ this.torrent && this.torrent.info && this.torrent.info.description &&
{parseDescriptionText(this.torrent.info.description)}
}
: null }
); } }