2017-08-22 21:49:48 +02:00
|
|
|
import React, { Component } from 'react';
|
2017-08-25 02:01:15 +02:00
|
|
|
import { push } from 'react-router-redux';
|
2017-08-22 21:49:48 +02:00
|
|
|
import { connect } from 'react-redux';
|
|
|
|
|
2017-08-23 14:52:08 +02:00
|
|
|
function formatBitrate(bitrate) {
|
|
|
|
if (bitrate > 1000000000) {
|
|
|
|
return `${(bitrate / 1000000000).toFixed(2)} Gb/s`;
|
|
|
|
} else if (bitrate > 1000000) {
|
|
|
|
return `${(bitrate / 1000000).toFixed(2)} Mb/s`;
|
|
|
|
} else if (bitrate > 1000) {
|
|
|
|
return `${(bitrate / 1000).toFixed(2)} Kb/s`;
|
|
|
|
} else {
|
|
|
|
return `${bitrate} b/s`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-25 02:01:15 +02:00
|
|
|
function activeTorrents(router) {
|
|
|
|
const { pathname } = router.location;
|
|
|
|
if (pathname.indexOf("/torrents/") !== 0) {
|
|
|
|
return [];
|
|
|
|
} else {
|
|
|
|
return pathname.slice("/torrents/".length).split(",");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const EXCLUSIVE = 1, UNION = 2, SUBTRACT = 3;
|
|
|
|
|
|
|
|
function selectTorrent(dispatch, t, router, action = UNION) {
|
|
|
|
let active = activeTorrents(router);
|
|
|
|
switch (action) {
|
|
|
|
case EXCLUSIVE:
|
|
|
|
active = [t.id];
|
|
|
|
break;
|
|
|
|
case UNION:
|
|
|
|
if (active.indexOf(t.id) === -1) {
|
|
|
|
active = [...active, t.id];
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SUBTRACT:
|
|
|
|
if (active.indexOf(t.id) !== -1) {
|
|
|
|
active = active.filter(a => a != t.id);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
const url = active.length === 0 ? "/" : `/torrents/${active.join(',')}`;
|
|
|
|
if (url !== router.location) {
|
|
|
|
dispatch(push(url));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-22 21:49:48 +02:00
|
|
|
class TorrentTable extends Component {
|
|
|
|
render() {
|
2017-08-25 02:01:15 +02:00
|
|
|
const { torrents, router, dispatch } = this.props;
|
|
|
|
const active = activeTorrents(router);
|
2017-08-22 21:49:48 +02:00
|
|
|
return (
|
|
|
|
<table className="table">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
2017-08-23 14:42:00 +02:00
|
|
|
<th style={{width: "1px"}}></th>
|
2017-08-22 21:49:48 +02:00
|
|
|
<th>name</th>
|
|
|
|
<th>up</th>
|
|
|
|
<th>down</th>
|
2017-08-25 02:01:15 +02:00
|
|
|
<th>ratio</th>
|
2017-08-22 21:49:48 +02:00
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{Object.values(torrents).map(t =>
|
|
|
|
<tr
|
|
|
|
key={t.id}
|
2017-08-25 02:01:15 +02:00
|
|
|
className={`torrent ${
|
|
|
|
t.status
|
|
|
|
} ${
|
|
|
|
active.indexOf(t.id) !== -1 ? "selected" : ""
|
|
|
|
}`}
|
2017-08-22 21:49:48 +02:00
|
|
|
style={{
|
2017-08-23 14:27:08 +02:00
|
|
|
backgroundSize: `${t.progress * 100}% 3px`
|
2017-08-22 21:49:48 +02:00
|
|
|
}}
|
|
|
|
>
|
2017-08-23 14:42:00 +02:00
|
|
|
<td>
|
2017-08-25 02:01:15 +02:00
|
|
|
<input
|
|
|
|
type="checkbox"
|
|
|
|
checked={active.indexOf(t.id) !== -1}
|
|
|
|
onChange={e =>
|
|
|
|
selectTorrent(dispatch,
|
|
|
|
t, router, e.target.checked ? UNION : SUBTRACT)}
|
|
|
|
/>
|
2017-08-23 14:42:00 +02:00
|
|
|
</td>
|
2017-08-22 21:49:48 +02:00
|
|
|
<td>
|
2017-08-25 02:01:15 +02:00
|
|
|
<a
|
|
|
|
href="#"
|
|
|
|
onClick={e => {
|
|
|
|
e.preventDefault();
|
|
|
|
selectTorrent(dispatch, t, router, EXCLUSIVE);
|
|
|
|
}}
|
|
|
|
>
|
2017-08-22 21:49:48 +02:00
|
|
|
{t.name}
|
|
|
|
</a>
|
|
|
|
</td>
|
2017-08-23 14:52:08 +02:00
|
|
|
<td>{formatBitrate(t.rate_up)}</td>
|
|
|
|
<td>{formatBitrate(t.rate_down)}</td>
|
2017-08-25 02:01:15 +02:00
|
|
|
<td>{(t.transferred_up / t.transferred_down).toFixed(2)}</td>
|
2017-08-22 21:49:48 +02:00
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-25 02:01:15 +02:00
|
|
|
export default connect(state => ({
|
|
|
|
torrents: state.torrents,
|
|
|
|
router: state.router
|
|
|
|
}))(TorrentTable);
|