From 5379e830bb6aaa733a73f2719ee0c893bff81305 Mon Sep 17 00:00:00 2001 From: John Furrow Date: Sat, 21 Nov 2015 14:16:00 -0800 Subject: [PATCH] Add torrent details panel --- .../sass/objects/_torrent-details-panel.scss | 51 ++++ .../components/torrent-list/TorrentDetails.js | 241 ++++++++++++++++++ 2 files changed, 292 insertions(+) create mode 100644 client/source/sass/objects/_torrent-details-panel.scss create mode 100644 client/source/scripts/components/torrent-list/TorrentDetails.js diff --git a/client/source/sass/objects/_torrent-details-panel.scss b/client/source/sass/objects/_torrent-details-panel.scss new file mode 100644 index 00000000..1cc1c649 --- /dev/null +++ b/client/source/sass/objects/_torrent-details-panel.scss @@ -0,0 +1,51 @@ +.torrent-details { + background: $torrent-details--background; + box-shadow: -1px 0 0 $torrent-details--border; + height: 100%; + width: 40%; + overflow: auto; + padding: $spacing-unit; + position: absolute; + right: 0; + top: 0; + transform: translateX(0); + transition: transform 0.5s; + z-index: 2; + + &.torrent-details-enter { + transform: translateX(100%); + } + + &.torrent-details-enter-active { + transform: translateX(0); + } + + &.torrent-details-leave { + transform: translateX(100%); + } + + &__transfer-data { + + .transfer-data { + display: inline-block; + margin-right: 10px; + + &:last-child { + margin-right: 0; + } + } + + .icon { + height: 12px; + width: 12px; + } + } + + &__table { + width: 100%; + + thead { + text-align: left; + } + } +} diff --git a/client/source/scripts/components/torrent-list/TorrentDetails.js b/client/source/scripts/components/torrent-list/TorrentDetails.js new file mode 100644 index 00000000..269567be --- /dev/null +++ b/client/source/scripts/components/torrent-list/TorrentDetails.js @@ -0,0 +1,241 @@ +import _ from 'lodash'; +import classNames from 'classnames'; +import {connect} from 'react-redux'; +import React from 'react'; +import CSSTransitionGroup from 'react-addons-css-transition-group'; + +import format from '../../util/formatData'; +import Icon from '../icons/Icon'; +import clientSelector from '../../selectors/clientSelector'; + +const methodsToBind = [ + 'getSidePanel', + 'getEta', + 'getRatio' +]; + +class TorrentDetails extends React.Component { + + constructor() { + super(); + + this.state = { + selectedTorrentHash: null + }; + + methodsToBind.forEach((method) => { + this[method] = this[method].bind(this); + }); + } + + componentWillReceiveProps(nextProps) { + if (nextProps.visible === true) { + let nextHash = nextProps.selectedTorrents[0]; + if (this.state.selectedTorrentHash !== nextHash) { + this.setState({ + selectedTorrentHash: nextHash, + selectedTorrent: _.find(nextProps.torrents, torrent => { + return torrent.hash === nextHash; + }) + }); + } + } + } + + shouldComponentUpdate(nextProps) { + if (nextProps.visible === true || (nextProps.visible !== this.props.visible)) { + return true; + } else { + return false; + } + } + + getPeerList() { + let torrentDetails = this.props.torrentDetails[ + this.state.selectedTorrentHash + ]; + + let peerList = null; + let peerCount = 0; + + if (torrentDetails) { + peerList = torrentDetails.map(function(peer, index) { + let downloadRate = format.data(peer.downloadRate, '/s'); + let uploadRate = format.data(peer.uploadRate, '/s'); + return ( + + {peer.address} + + {downloadRate.value} + {downloadRate.unit} + + + {uploadRate.value} + {uploadRate.unit} + + + ); + }); + peerCount = peerList.length; + } + + return ( + + + + + + + + + + {peerList} + +
Peers {peerCount}DLUL
+ ) + } + + getEta(eta) { + if (eta === 'Infinity') { + return '∞'; + } else if (eta.years > 0) { + return ( + + + {eta.years}yr + + + {eta.weeks}wk + + + ); + } else if (eta.weeks > 0) { + return ( + + + {eta.weeks}wk + + + {eta.days}d + + + ); + } else if (eta.days > 0) { + return ( + + + {eta.days}d + + + {eta.hours}hr + + + ); + } else if (eta.hours > 0) { + return ( + + + {eta.hours}hr + + + {eta.minutes}m + + + ); + } else if (eta.minutes > 0) { + return ( + + + {eta.minutes}m + + + {eta.seconds}s + + + ); + } else { + return ( + + {eta.seconds}s + + ); + } + } + + getRatio(ratio) { + ratio = ratio / 1000; + let precision = 1; + + if (ratio < 10) { + precision = 2; + } else if (ratio < 100) { + precision = 0; + } + + return ratio.toFixed(precision); + } + + getSidePanel() { + if (!this.props.visible) { + return null; + } + + let torrent = this.state.selectedTorrent; + 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 = this.getEta(torrent.eta); + let ratio = this.getRatio(torrent.ratio); + let totalSize = format.data(torrent.sizeBytes); + let uploadRate = format.data(torrent.uploadRate, '/s'); + let uploadTotal = format.data(torrent.uploadTotal); + + return ( +
+
+ Dropdown +
+ +
+ {this.getPeerList()} +
+
+ ); + } + + render() { + return ( + + {this.getSidePanel()} + + ); + } + +} + +export default connect(clientSelector)(TorrentDetails);