mirror of
https://github.com/zoriya/flood.git
synced 2026-06-02 02:56:05 +00:00
Organize filestructure
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
|
||||
import Stop from '../icons/Stop';
|
||||
|
||||
export default class Action extends React.Component {
|
||||
render() {
|
||||
let classString = 'action action--' + this.props.slug;
|
||||
|
||||
return (
|
||||
<div className={classString} onClick={this.props.clickHandler}>
|
||||
{this.props.icon}
|
||||
<span className="action__label">{this.props.label}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import React from 'react';
|
||||
|
||||
import Action from './Action';
|
||||
import Add from '../icons/Add';
|
||||
import EventTypes from '../../constants/EventTypes';
|
||||
import Pause from '../icons/Pause';
|
||||
import SortDropdown from './SortDropdown';
|
||||
import Start from '../icons/Start';
|
||||
import Stop from '../icons/Stop';
|
||||
import TorrentActions from '../../actions/TorrentActions';
|
||||
import TorrentFilterStore from '../../stores/TorrentFilterStore';
|
||||
import TorrentStore from '../../stores/TorrentStore';
|
||||
import UIActions from '../../actions/UIActions';
|
||||
|
||||
const METHODS_TO_BIND = [
|
||||
'handleAddTorrents',
|
||||
'handleSortChange',
|
||||
'handleStart',
|
||||
'handleStop',
|
||||
'onSortChange'
|
||||
];
|
||||
|
||||
export default class ActionBar extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.state = {
|
||||
sortBy: TorrentFilterStore.getTorrentsSort()
|
||||
};
|
||||
|
||||
METHODS_TO_BIND.forEach((method) => {
|
||||
this[method] = this[method].bind(this);
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
TorrentFilterStore.listen(EventTypes.UI_TORRENTS_SORT_CHANGE, this.onSortChange);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_SORT_CHANGE, this.onSortChange);
|
||||
}
|
||||
|
||||
handleAddTorrents() {
|
||||
UIActions.displayModal('add-torrents');
|
||||
}
|
||||
|
||||
handleSortChange(sortBy) {
|
||||
UIActions.setTorrentsSort(sortBy);
|
||||
}
|
||||
|
||||
handleStart() {
|
||||
TorrentActions.startTorrents(TorrentStore.getSelectedTorrents());
|
||||
}
|
||||
|
||||
handleStop() {
|
||||
TorrentActions.stopTorrents(TorrentStore.getSelectedTorrents());
|
||||
}
|
||||
|
||||
onSortChange() {
|
||||
this.setState({
|
||||
sortBy: TorrentFilterStore.getTorrentsSort()
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<nav className="action-bar">
|
||||
<div className="actions action-bar__item action-bar__item--sort-torrents">
|
||||
<SortDropdown onSortChange={this.handleSortChange}
|
||||
selectedItem={this.state.sortBy} />
|
||||
</div>
|
||||
<div className="actions action-bar__item action-bar__item--torrent-operations">
|
||||
<div className="action-bar__group">
|
||||
<Action label="Start Torrent" slug="start-torrent" icon={<Start />}
|
||||
clickHandler={this.handleStart} />
|
||||
<Action label="Stop Torrent" slug="stop-torrent" icon={<Stop />}
|
||||
clickHandler={this.handleStop} />
|
||||
<Action label="Pause Torrent" slug="pause-torrent" icon={<Pause />}
|
||||
clickHandler={this.handlePause} />
|
||||
</div>
|
||||
<div className="action-bar__group action-bar__group--has-divider">
|
||||
<Action label="Add Torrent" slug="add-torrent" icon={<Add />}
|
||||
clickHandler={this.handleAddTorrents} />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import File from '../icons/File';
|
||||
|
||||
export default class DirectoryFiles extends React.Component {
|
||||
render() {
|
||||
let branch = Object.assign([], this.props.branch);
|
||||
|
||||
branch.sort((a, b) => {
|
||||
console.log(a, b);
|
||||
return a.filename.localeCompare(b.filename);
|
||||
});
|
||||
|
||||
let files = branch.map((file, fileIndex) => {
|
||||
return (
|
||||
<div className="directory-tree__node directory-tree__node--file"
|
||||
key={`${fileIndex}`} title={file.filename}>
|
||||
<File />
|
||||
{file.filename}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="directory-tree__node directory-tree__node--file-list">
|
||||
{files}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import DirectoryFileList from './DirectoryFileList';
|
||||
import DirectoryTreeNode from './DirectoryTreeNode';
|
||||
|
||||
export default class DirectoryTree extends React.Component {
|
||||
getDirectoryTreeDomNodes(tree, depth = 0) {
|
||||
let index = 0;
|
||||
depth++;
|
||||
|
||||
return Object.keys(tree).map((branchName) => {
|
||||
let branch = tree[branchName];
|
||||
index++;
|
||||
|
||||
if (branchName === 'files') {
|
||||
return <DirectoryFileList branch={branch} key={`${index}${depth}`} />;
|
||||
} else {
|
||||
return <DirectoryTreeNode depth={depth} directoryName={branchName}
|
||||
subTree={branch} key={`${index}${depth}`} />;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="directory-tree__tree">
|
||||
{this.getDirectoryTreeDomNodes(this.props.tree, this.props.depth)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import FolderClosedOutlined from '../icons/FolderClosedOutlined';
|
||||
import FolderOpenOutlined from '../icons/FolderOpenOutlined';
|
||||
import DirectoryTree from './DirectoryTree';
|
||||
|
||||
const METHODS_TO_BIND = ['handleDirectoryClick'];
|
||||
|
||||
export default class DirectoryTreeNode extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.state = {
|
||||
expanded: false
|
||||
};
|
||||
|
||||
METHODS_TO_BIND.forEach((method) => {
|
||||
this[method] = this[method].bind(this);
|
||||
});
|
||||
}
|
||||
|
||||
getSubTree() {
|
||||
if (this.state.expanded) {
|
||||
return (
|
||||
<div className="directory-tree__node directory-tree__node--group">
|
||||
<DirectoryTree tree={this.props.subTree} depth={this.props.depth} />
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
handleDirectoryClick() {
|
||||
this.setState({
|
||||
expanded: !this.state.expanded
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
let classes = `directory-tree__branch directory-tree__branch--depth-${this.props.depth}`;
|
||||
|
||||
let icon = <FolderClosedOutlined />;
|
||||
|
||||
if (this.state.expanded) {
|
||||
icon = <FolderOpenOutlined />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes}>
|
||||
<div className="directory-tree__node directory-tree__node--directory"
|
||||
onClick={this.handleDirectoryClick} title={this.props.directoryName}>
|
||||
{icon}
|
||||
{this.props.directoryName}
|
||||
</div>
|
||||
{this.getSubTree()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
export default class ProgressBar extends React.Component {
|
||||
render() {
|
||||
let percent = this.props.percent;
|
||||
let className = 'progress-bar';
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className="progress-bar__fill" style={{width: percent + '%'}}></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import classnames from 'classnames';
|
||||
import CSSTransitionGroup from 'react-addons-css-transition-group';
|
||||
import React from 'react';
|
||||
|
||||
import Dropdown from '../forms/Dropdown';
|
||||
import UIActions from '../../actions/UIActions';
|
||||
|
||||
const METHODS_TO_BIND = [
|
||||
'getDropdownHeader',
|
||||
'handleItemSelect'
|
||||
];
|
||||
|
||||
const SORT_PROPERTIES = [
|
||||
{
|
||||
displayName: 'Name',
|
||||
value: 'name'
|
||||
},
|
||||
{
|
||||
displayName: 'ETA',
|
||||
value: 'eta'
|
||||
},
|
||||
{
|
||||
displayName: 'Download Speed',
|
||||
value: 'downloadRate'
|
||||
},
|
||||
{
|
||||
displayName: 'Upload Speed',
|
||||
value: 'uploadRate'
|
||||
},
|
||||
{
|
||||
displayName: 'Ratio',
|
||||
value: 'ratio'
|
||||
},
|
||||
{
|
||||
displayName: 'Percent Complete',
|
||||
value: 'percentComplete'
|
||||
},
|
||||
{
|
||||
displayName: 'Downloaded',
|
||||
value: 'downloadTotal'
|
||||
},
|
||||
{
|
||||
displayName: 'Uploaded',
|
||||
value: 'uploadTotal'
|
||||
},
|
||||
{
|
||||
displayName: 'File Size',
|
||||
value: 'sizeBytes'
|
||||
},
|
||||
{
|
||||
displayName: 'Date Added',
|
||||
value: 'added'
|
||||
}
|
||||
];
|
||||
|
||||
export default class SortDropdown extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
METHODS_TO_BIND.forEach((method) => {
|
||||
this[method] = this[method].bind(this);
|
||||
});
|
||||
}
|
||||
|
||||
getDropdownHeader() {
|
||||
return (
|
||||
<a className="dropdown__button">
|
||||
<label className="dropdown__label">Sort By</label>
|
||||
<span className="dropdown__value">{this.props.selectedItem.displayName}</span>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
getDropdownMenus() {
|
||||
let items = SORT_PROPERTIES.map((sortProp) => {
|
||||
return {
|
||||
displayName: sortProp.displayName,
|
||||
property: 'sortBy',
|
||||
selected: this.props.selectedItem.value === sortProp.value,
|
||||
value: sortProp.value
|
||||
}
|
||||
});
|
||||
|
||||
// Dropdown expects an array of arrays.
|
||||
return [items];
|
||||
}
|
||||
|
||||
handleItemSelect(sortBy) {
|
||||
let direction = this.props.selectedItem.direction;
|
||||
|
||||
if (this.props.selectedItem.value === sortBy.value) {
|
||||
direction = direction === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
direction = 'asc';
|
||||
}
|
||||
|
||||
let sortProperty = {
|
||||
direction,
|
||||
displayName: sortBy.displayName,
|
||||
property: 'sortBy',
|
||||
value: sortBy.value
|
||||
};
|
||||
|
||||
this.props.onSortChange(sortProperty);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Dropdown
|
||||
handleItemSelect={this.handleItemSelect}
|
||||
header={this.getDropdownHeader()}
|
||||
menuItems={this.getDropdownMenus()}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import React from 'react';
|
||||
|
||||
import DotsMini from '../icons/DotsMini';
|
||||
import format from '../../util/formatData';
|
||||
import ProgressBar from './ProgressBar';
|
||||
import ProgressBar from '../ui/ProgressBar';
|
||||
|
||||
const METHODS_TO_BIND = [
|
||||
'handleClick',
|
||||
|
||||
@@ -1,239 +0,0 @@
|
||||
import _ from 'lodash';
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import CSSTransitionGroup from 'react-addons-css-transition-group';
|
||||
|
||||
import Download from '../../components/icons/Download';
|
||||
import TorrentFiles from './TorrentFiles';
|
||||
import EventTypes from '../../constants/EventTypes';
|
||||
import ETA from '../../components/icons/ETA';
|
||||
import format from '../../util/formatData';
|
||||
import Ratio from '../../components/icons/Ratio';
|
||||
import TorrentActions from '../../actions/TorrentActions';
|
||||
import TorrentStore from '../../stores/TorrentStore';
|
||||
import UIStore from '../../stores/UIStore';
|
||||
import Upload from '../../components/icons/Upload';
|
||||
|
||||
const METHODS_TO_BIND = [
|
||||
'onTorrentDetailsHashChange',
|
||||
'onOpenChange',
|
||||
'onTorrentDetailsChange',
|
||||
'getHeading',
|
||||
'getSidePanel'
|
||||
];
|
||||
|
||||
export default class TorrentDetails extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.state = {
|
||||
isOpen: false,
|
||||
torrentDetailsSuccess: false,
|
||||
torrentDetailsError: false,
|
||||
selectedTorrent: {},
|
||||
selectedTorrentHash: null,
|
||||
torrentDetails: {}
|
||||
};
|
||||
|
||||
METHODS_TO_BIND.forEach((method) => {
|
||||
this[method] = this[method].bind(this);
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
TorrentStore.listen(EventTypes.CLIENT_TORRENT_DETAILS_CHANGE, this.onTorrentDetailsChange);
|
||||
UIStore.listen(EventTypes.UI_TORRENT_DETAILS_OPEN_CHANGE, this.onOpenChange);
|
||||
UIStore.listen(EventTypes.UI_TORRENT_DETAILS_HASH_CHANGE, this.onTorrentDetailsHashChange);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
TorrentStore.stopPollingTorrentDetails();
|
||||
TorrentStore.unlisten(EventTypes.CLIENT_TORRENT_DETAILS_CHANGE, this.onTorrentDetailsChange);
|
||||
UIStore.unlisten(EventTypes.UI_TORRENT_DETAILS_OPEN_CHANGE, this.onOpenChange);
|
||||
UIStore.unlisten(EventTypes.UI_TORRENT_DETAILS_HASH_CHANGE, this.onTorrentDetailsHashChange);
|
||||
}
|
||||
|
||||
onTorrentDetailsHashChange() {
|
||||
if (UIStore.isTorrentDetailsOpen()) {
|
||||
TorrentStore.fetchTorrentDetails(UIStore.getTorrentDetailsHash());
|
||||
}
|
||||
}
|
||||
|
||||
onOpenChange() {
|
||||
if (!UIStore.isTorrentDetailsOpen()) {
|
||||
TorrentStore.stopPollingTorrentDetails();
|
||||
} else {
|
||||
TorrentStore.fetchTorrentDetails(UIStore.getTorrentDetailsHash());
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isOpen: UIStore.isTorrentDetailsOpen()
|
||||
});
|
||||
}
|
||||
|
||||
onTorrentDetailsChange() {
|
||||
this.setState({
|
||||
torrentDetails: TorrentStore.getTorrentDetails(UIStore.getTorrentDetailsHash())
|
||||
});
|
||||
}
|
||||
|
||||
getHeading() {
|
||||
// return (
|
||||
// <div className="torrent-details__actions torrent-details__section">
|
||||
// Dropdown
|
||||
// </div>
|
||||
// );
|
||||
}
|
||||
|
||||
getPeerList(peers) {
|
||||
if (peers) {
|
||||
let peerList = null;
|
||||
let peerCount = 0;
|
||||
|
||||
peerList = peers.map(function(peer, index) {
|
||||
let downloadRate = format.data(peer.downloadRate, '/s');
|
||||
let uploadRate = format.data(peer.uploadRate, '/s');
|
||||
return (
|
||||
<tr key={index}>
|
||||
<td>{peer.address}</td>
|
||||
<td>
|
||||
{downloadRate.value}
|
||||
<em className="unit">{downloadRate.unit}</em>
|
||||
</td>
|
||||
<td>
|
||||
{uploadRate.value}
|
||||
<em className="unit">{uploadRate.unit}</em>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
});
|
||||
peerCount = peerList.length;
|
||||
|
||||
return (
|
||||
<div className="torrent-details__peers torrent-details__section">
|
||||
<table className="torrent-details__table table">
|
||||
<thead className="torrent-details__table__heading">
|
||||
<tr>
|
||||
<th>
|
||||
Peers
|
||||
<span className="torrent-details__table__heading__count">
|
||||
{peerCount}
|
||||
</span>
|
||||
</th>
|
||||
<th>DL</th>
|
||||
<th>UL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{peerList}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
getSidePanel() {
|
||||
if (!this.state.isOpen) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let selectedHash = UIStore.getTorrentDetailsHash();
|
||||
let torrent = TorrentStore.getTorrent(selectedHash);
|
||||
let added = new Date(torrent.added * 1000);
|
||||
let addedString = (added.getMonth() + 1) + '/' + added.getDate() + '/' +
|
||||
added.getFullYear();
|
||||
let completed = format.data(torrent.bytesDone);
|
||||
let downloadRate = format.data(torrent.downloadRate, '/s');
|
||||
let downloadTotal = format.data(torrent.downloadTotal);
|
||||
let eta = format.eta(torrent.eta);
|
||||
let ratio = format.ratio(torrent.ratio);
|
||||
let totalSize = format.data(torrent.sizeBytes);
|
||||
let torrentDetails = this.state.torrentDetails || {};
|
||||
let uploadRate = format.data(torrent.uploadRate, '/s');
|
||||
let uploadTotal = format.data(torrent.uploadTotal);
|
||||
|
||||
return (
|
||||
<div className="torrent-details" key={this.state.isOpen}>
|
||||
{this.getHeading()}
|
||||
<ul className="torrent-details__transfer-data torrent-details__section">
|
||||
<li className="transfer-data transfer-data--download">
|
||||
<Download />
|
||||
{downloadRate.value}
|
||||
<em className="unit">{downloadRate.unit}</em>
|
||||
</li>
|
||||
<li className="transfer-data transfer-data--upload">
|
||||
<Upload />
|
||||
{uploadRate.value}
|
||||
<em className="unit">{uploadRate.unit}</em>
|
||||
</li>
|
||||
<li className="transfer-data transfer-data--ratio">
|
||||
<Ratio />
|
||||
{ratio}
|
||||
</li>
|
||||
<li className="transfer-data transfer-data--eta">
|
||||
<ETA />
|
||||
{eta}
|
||||
</li>
|
||||
</ul>
|
||||
{this.getTrackerList(torrentDetails.trackers)}
|
||||
<TorrentFiles files={torrentDetails.files} torrent={torrent} />
|
||||
{this.getPeerList(torrentDetails.peers)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
getTrackerList(trackers = []) {
|
||||
let trackerCount = trackers.length;
|
||||
let trackerTypes = ['http', 'udp', 'dht'];
|
||||
|
||||
let trackerDetails = trackers.map((tracker, index) => {
|
||||
return (
|
||||
<tr key={index}>
|
||||
<td>
|
||||
{tracker.url}
|
||||
</td>
|
||||
<td>
|
||||
{trackerTypes[tracker.type - 1]}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="torrent-details__peers torrent-details__section">
|
||||
<table className="torrent-details__table table">
|
||||
<thead className="torrent-details__table__heading">
|
||||
<tr>
|
||||
<th>
|
||||
Trackers
|
||||
<span className="torrent-details__table__heading__count">
|
||||
{trackerCount}
|
||||
</span>
|
||||
</th>
|
||||
<th>Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{trackerDetails}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
try {
|
||||
return (
|
||||
<CSSTransitionGroup
|
||||
transitionEnterTimeout={500}
|
||||
transitionLeaveTimeout={500}
|
||||
transitionName="torrent-details">
|
||||
{this.getSidePanel()}
|
||||
</CSSTransitionGroup>
|
||||
);
|
||||
} catch (err) {
|
||||
console.trace(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import FolderOpenSolid from '../icons/FolderOpenSolid';
|
||||
import DirectoryTree from './DirectoryTree';
|
||||
import File from '../icons/File';
|
||||
|
||||
const METHODS_TO_BIND = ['handleParentDirectoryClick'];
|
||||
|
||||
export default class TorrentFiles extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.state = {
|
||||
expanded: true
|
||||
};
|
||||
|
||||
METHODS_TO_BIND.forEach((method) => {
|
||||
this[method] = this[method].bind(this);
|
||||
});
|
||||
}
|
||||
|
||||
constructDirectoryTree(tree = {}, directory, file, depth = 0) {
|
||||
if (depth < file.pathComponents.length - 1) {
|
||||
depth++;
|
||||
tree[directory] = this.constructDirectoryTree(
|
||||
tree[directory],
|
||||
file.pathComponents[depth],
|
||||
file,
|
||||
depth
|
||||
);
|
||||
} else {
|
||||
if (!tree.files) {
|
||||
tree.files = [];
|
||||
}
|
||||
tree.files.push(file);
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
getFileList(files) {
|
||||
let tree = {};
|
||||
|
||||
files.forEach((file) => {
|
||||
this.constructDirectoryTree(tree, file.pathComponents[0], file);
|
||||
});
|
||||
|
||||
return <DirectoryTree tree={tree} depth={0} />;
|
||||
}
|
||||
|
||||
getFileData(torrent, files) {
|
||||
let parentDirectory = torrent.directory;
|
||||
let filename = torrent.filename;
|
||||
|
||||
if (files) {
|
||||
// We've received full file details from the client.
|
||||
let fileList = null;
|
||||
|
||||
if (this.state.expanded) {
|
||||
fileList = this.getFileList(files);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="directory-tree torrent-details__section">
|
||||
<div className="directory-tree__node directory-tree__parent-directory"
|
||||
onClick={this.handleParentDirectoryClick}>
|
||||
<FolderOpenSolid />
|
||||
{parentDirectory}
|
||||
</div>
|
||||
{fileList}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
// We've only received the top-level file details from the torrent list.
|
||||
return (
|
||||
<div className="directory-tree torrent-details__section">
|
||||
<div className="directory-tree__node directory-tree__parent-directory">
|
||||
<FolderOpenSolid />
|
||||
{parentDirectory}
|
||||
</div>
|
||||
<div className="directory-tree__node directory-tree__node--file">
|
||||
<File />
|
||||
{filename}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
handleParentDirectoryClick() {
|
||||
this.setState({
|
||||
expanded: !this.state.expanded
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.getFileData(this.props.torrent, this.props.files);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,8 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import EventTypes from '../../constants/EventTypes';
|
||||
import LoadingIndicator from '../generic/LoadingIndicator';
|
||||
import LoadingIndicator from '../ui/LoadingIndicator';
|
||||
import Torrent from './Torrent';
|
||||
import TorrentDetails from './TorrentDetails';
|
||||
import TorrentFilterStore from '../../stores/TorrentFilterStore';
|
||||
import TorrentStore from '../../stores/TorrentStore';
|
||||
import UIActions from '../../actions/UIActions';
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
|
||||
import TorrentDetails from './TorrentDetails';
|
||||
import TorrentList from './TorrentList';
|
||||
|
||||
export default class TorrentListContainer extends React.Component {
|
||||
@@ -8,7 +7,6 @@ export default class TorrentListContainer extends React.Component {
|
||||
return (
|
||||
<div className="torrents">
|
||||
<TorrentList />
|
||||
<TorrentDetails />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user