import React, { Component } from 'react'; import SearchResults from './search-results' import AdvancedSearch from './search-advanced-controls' import TextField from 'material-ui/TextField'; import RaisedButton from 'material-ui/RaisedButton'; import RefreshIndicator from 'material-ui/RefreshIndicator'; import Checkbox from 'material-ui/Checkbox'; import Visibility from 'material-ui/svg-icons/action/visibility'; import VisibilityOff from 'material-ui/svg-icons/action/visibility-off'; import AddIcon from 'material-ui/svg-icons/content/add'; import RemoveIcon from 'material-ui/svg-icons/content/remove'; import SelectField from 'material-ui/SelectField'; import MenuItem from 'material-ui/MenuItem'; import formatBytes from './format-bytes' import _ from 'lodash' let session; class TorrentsStatistic extends Component { constructor(props) { super(props) this.stats = props.stats || {} } componentDidMount() { this.newTorrentFunc = (torrent) => { this.stats.size += torrent.size; this.stats.torrents++; this.stats.files += torrent.files; this.forceUpdate() } window.torrentSocket.on('newTorrent', this.newTorrentFunc); } componentWillUnmount() { if(this.newTorrentFunc) window.torrentSocket.off('newTorrent', this.newTorrentFunc); } render() { return (
you have information about {this.stats.torrents} torrents and around {this.stats.files} files and { formatBytes(this.stats.size, 1) } of data
) } } export default class Search extends Component { constructor(props) { super(props) this.state = { searchingIndicator: false, safeSearchText: 'safe search enabled', safeSearchColor: 'rgb(0, 188, 212)', moreTorrentsIndicator: false, moreFilesIndicator: false, orderBy: null, orderDesc: false, advancedSearch: false, } this.searchLimit = 10 this.advanced = {} this.searchError = undefined; if(session) { this.searchTorrents = session.searchTorrents; this.searchFiles = session.searchFiles; this.moreSearchTorrents = session.moreSearchTorrents; this.moreSearchFiles = session.moreSearchFiles; this.currentSearch = session.currentSearch; this.searchValue = session.searchValue; Object.assign(this.state, this.setSafeSearch(session.notSafeSearch)) this.state.orderBy = session.orderBy; this.state.orderDesc = session.orderDesc; this.state.advancedSearch = session.advancedSearch; this.advanced = session.advanced; this.searchError = session.searchError; } } search(oldSearch) { this.setState({ searchingIndicator: true }); this.searchTorrents = []; this.moreSearchTorrents = true; this.searchFiles = []; this.moreSearchFiles = true; this.currentSearch = this.searchValue; let queries = 2; let searchTorrentsParams = { limit: this.searchLimit, safeSearch: !this.notSafeSearch, orderBy: this.state.orderBy, orderDesc: this.state.orderDesc, }; if(this.state.advancedSearch && this.advanced) searchTorrentsParams = Object.assign(searchTorrentsParams, this.advanced); window.torrentSocket.emit('searchTorrent', oldSearch ? this.currentSearch : this.searchValue, searchTorrentsParams, window.customLoader((torrents) => { if(torrents) { this.searchTorrents = torrents; if(torrents.length != this.searchLimit) this.moreSearchTorrents = false; } else { this.moreSearchTorrents = false; } if(--queries == 0) { this.setState({ searchingIndicator: false }); } else { this.forceUpdate(); } })); let searchFilesParams = { limit: this.searchLimit, safeSearch: !this.notSafeSearch, orderBy: this.state.orderBy, orderDesc: this.state.orderDesc, }; if(this.state.advancedSearch && this.advanced) searchFilesParams = Object.assign(searchFilesParams, this.advanced); window.torrentSocket.emit('searchFiles', oldSearch ? this.currentSearch : this.searchValue, searchFilesParams, window.customLoader((torrents) => { if(torrents) { console.log('back torrents') this.searchFiles = torrents; let files = 0; torrents.forEach((torrent) => { if(torrent.path && torrent.path.length > 0) files += torrent.path.length }); if(files != this.searchLimit) this.moreSearchFiles = false; } else { this.moreSearchFiles = false; } if(--queries == 0) { this.setState({ searchingIndicator: false }); } else { this.forceUpdate(); } })); } moreTorrents() { this.setState({moreTorrentsIndicator: true}); window.torrentSocket.emit('searchTorrent', this.currentSearch, { index: this.searchTorrents.length, limit: this.searchLimit, safeSearch: !this.notSafeSearch, orderBy: this.state.orderBy, orderDesc: this.state.orderDesc, }, window.customLoader((torrents) => { if(torrents) { console.log('back torrents') this.searchTorrents = this.searchTorrents.concat(torrents); if(torrents.length != this.searchLimit) this.moreSearchTorrents = false; this.setState({moreTorrentsIndicator: false}); } })); } moreFiles() { let index = 0; this.searchFiles.forEach((torrent) => { if(torrent.path && torrent.path.length > 0) index += torrent.path.length; }); this.setState({moreFilesIndicator: true}); window.torrentSocket.emit('searchFiles', this.currentSearch, { index: index, limit: this.searchLimit, safeSearch: !this.notSafeSearch, orderBy: this.state.orderBy, orderDesc: this.state.orderDesc, }, window.customLoader((torrents) => { if(torrents) { this.searchFiles = this.searchFiles.concat(torrents); let files = 0; torrents.forEach((torrent) => { if(torrent.path && torrent.path.length > 0) files += torrent.path.length }); if(files != this.searchLimit) this.moreSearchFiles = false; this.mergeFiles() this.setState({moreFilesIndicator: false}); } })); } mergeFiles() { for(let i = 0; i < this.searchFiles.length; i++) { for(let j = i + 1; j < this.searchFiles.length; j++) { if(this.searchFiles[i].hash != this.searchFiles[j].hash) continue if(!this.searchFiles[i].remove) { this.searchFiles[i].path = this.searchFiles[i].path.concat(this.searchFiles[j].path) } this.searchFiles[j].remove = true } } this.searchFiles = this.searchFiles.filter(torrent => !torrent.remove) } componentDidMount() { this.newStatisticFunc = (statistic) => { if(statistic) { this.stats = statistic; this.forceUpdate(); } }; window.torrentSocket.emit('statistic', window.customLoader(this.newStatisticFunc)); window.torrentSocket.on('newStatistic', this.newStatisticFunc); this.remoteSearchTorrent = (torrents) => { if(!torrents) return this.searchTorrents = _.unionBy(this.searchTorrents, torrents, 'hash') this.forceUpdate(); } window.torrentSocket.on('remoteSearchTorrent', this.remoteSearchTorrent); this.remoteSearchFiles = (torrents) => { if(!torrents) return this.searchFiles = _.unionBy(this.searchFiles, torrents, 'hash') this.mergeFiles() this.forceUpdate(); } window.torrentSocket.on('remoteSearchFiles', this.remoteSearchFiles); } componentWillUnmount() { if(this.newStatisticFunc) window.torrentSocket.off('newStatistic', this.newStatisticFunc); if(this.remoteSearchTorrent) window.torrentSocket.off('remoteSearchTorrent', this.remoteSearchTorrent); if(this.remoteSearchFiles) window.torrentSocket.off('remoteSearchFiles', this.remoteSearchFiles); session = { searchTorrents: this.searchTorrents, searchFiles: this.searchFiles, moreSearchTorrents: this.moreSearchTorrents, moreSearchFiles: this.moreSearchFiles, currentSearch: this.currentSearch, searchValue: this.searchValue, notSafeSearch: this.notSafeSearch, orderBy: this.state.orderBy, orderDesc: this.state.orderDesc, advancedSearch: this.state.advancedSearch, advanced: this.advanced, searchError: this.searchError, } } setSafeSearch(ch) { this.notSafeSearch = ch; if(ch) { return {safeSearchText: 'safe search disabled', safeSearchColor: '#EC407A'} } else { return {safeSearchText: 'safe search enabled', safeSearchColor: 'rgb(0, 188, 212)'} } } render() { const style = { refresh: { display: 'inline-block', position: 'relative', }, }; const orderText = (text, field) => { if(field !== this.state.orderBy) return text; if(this.state.orderDesc) return text + ' ⇩' else return text + ' ⇧' } return (
{ if (e.key === 'Enter') { this.search(); } }} onChange={e => { this.searchValue = e.target.value if(this.searchValue.length < 3 && this.searchValue.length > 0) this.searchError = 'too short string for search'; else this.searchError = undefined; this.forceUpdate() }} /> { this.search() }} />
} uncheckedIcon={} label={{this.state.safeSearchText}} iconStyle={{fill: this.state.safeSearchColor}} onCheck={(ev, ch) => { this.setState(this.setSafeSearch(ch)); }} style={{paddingBottom: '0.8em'}} />
} uncheckedIcon={} label={advanced search} iconStyle={{fill: 'black'}} onCheck={(ev, ch) => { this.setState({advancedSearch: ch}); }} style={{paddingBottom: '0.8em'}} />
{ this.state.advancedSearch && { this.advanced = state; }} state={this.advanced} /> } { this.stats && } { this.state.searchingIndicator ?
: null } { event.preventDefault(); // fix overclick on torrent if(value === 'none') { this.setState({orderBy: null}, () => { this.search(true) }) return; } if(value === this.state.orderBy) { this.setState({orderDesc: !this.state.orderDesc}, () => { this.search(true) }) return; } this.setState({ orderBy: value, orderDesc: (value === 'seeders' || value === 'completed' || value === 'added') ? true : this.state.orderDesc }, () => { this.search(true) }) }} > } moreTorrentsEnabled={this.moreSearchTorrents && !this.state.searchingIndicator} moreFilesEnabled={this.moreSearchFiles && !this.state.searchingIndicator} onMoreTorrents={() => this.moreTorrents()} onMoreFiles={() => this.moreFiles()} moreTorrentsIndicator={this.state.moreTorrentsIndicator} moreFilesIndicator={this.state.moreFilesIndicator} />
); } }