diff --git a/src/bitrate.js b/src/bitrate.js index 91b89f6..9523230 100644 --- a/src/bitrate.js +++ b/src/bitrate.js @@ -25,3 +25,15 @@ export function formatBitrate(bitrate) { return `${bitrate} b/s`; } } + +export function formatAmount(amount) { + if (amount > Rates["GiB/s"]) { + return `${(amount / Rates["GiB/s"]).toFixed(2)} GiB`; + } else if (amount > Rates["MiB/s"]) { + return `${(amount / Rates["MiB/s"]).toFixed(2)} MiB`; + } else if (amount > Rates["KiB/s"]) { + return `${(amount / Rates["KiB/s"]).toFixed(2)} KiB`; + } else { + return `${amount} bytes`; + } +} diff --git a/src/ui/add_torrent.js b/src/ui/add_torrent.js index 958d41b..f4c9610 100644 --- a/src/ui/add_torrent.js +++ b/src/ui/add_torrent.js @@ -177,6 +177,7 @@ class AddTorrent extends Component { this.setState({ start })} priority={priority} diff --git a/src/ui/server.js b/src/ui/server.js index 785b1a7..84fe088 100644 --- a/src/ui/server.js +++ b/src/ui/server.js @@ -1,44 +1,100 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; import moment from 'moment'; -import { formatBitrate } from '../bitrate'; +import { formatBitrate, formatAmount } from '../bitrate'; import { ws_disconnect } from '../socket'; import date from '../date'; +import Throttle from './throttle'; +import { updateResource } from '../actions/resources'; -const throttle = _ => _ === null ? "Unlimited" : formatBitrate(_); - -function Server({ server }) { - if (!server.id) { - return null; +const ratio = (up, down) => { + const ratio = up / down; + if (isNaN(ratio)) { + return
0
; } return ( -
-

- Server - -

-
-
Running since
-
{date(moment(server.started))}
-
Rate up
-
{formatBitrate(server.rate_up)}
-
Rate down
-
{formatBitrate(server.rate_down)}
- {/* TODO: Editable */} -
Throttle up
-
{throttle(server.throttle_up)}
-
Throttle down
-
{throttle(server.throttle_down)}
-
-
+
+ {`${ + ratio.toFixed(3) + } (${ + formatAmount(up) + } up, ${ + formatAmount(down) + } down)`} +
); +}; + +class Server extends Component { + componentDidMount() { + this.interval = setInterval(this.forceUpdate, 1000); + } + + componentWillUnmount() { + clearInterval(this.interval); + } + + render() { + const { server, dispatch } = this.props; + if (!server.id) { + return null; + } + return ( +
+

+ Synapse + +

+
+
Running since
+
{date(moment(server.started))}
+
Current network use
+
+ {`${ + formatBitrate(server.rate_up) + } up, ${ + formatBitrate(server.rate_down) + } down`} +
+
Global download throttle
+
+ dispatch(updateResource({ + id: server.id, + throttle_down + }))} + /> +
+
Global upload throttle
+
+ dispatch(updateResource({ + id: server.id, + throttle_up + }))} + /> +
+
Lifetime ratio
+ {ratio(server.transferred_up, server.transferred_down)} +
Session ratio
+ {ratio(server.ses_transferred_up, server.ses_transferred_down)} +
+
+ ); + } } export default connect(state => ({ server: state.server }))(Server); diff --git a/src/ui/throttle.js b/src/ui/throttle.js new file mode 100644 index 0000000..ab6a1f2 --- /dev/null +++ b/src/ui/throttle.js @@ -0,0 +1,101 @@ +import React, { Component } from 'react'; +import { + FormGroup, + Label, + Input +} from 'reactstrap'; +import { convertFromBitrate, convertToBitrate } from '../bitrate'; + +export default class Throttle extends Component { + constructor() { + super(); + this.setLimit = this.setLimit.bind(this); + this.setUnit = this.setUnit.bind(this); + this.state = { unit: "MiB/s" }; + } + + setLimit(limit) { + const { onChange } = this.props; + const { unit } = this.state; + const converted = limit <= 0 || limit === null ? + limit : convertToBitrate(limit, unit); + onChange && onChange(converted); + } + + setUnit(unit) { + const limit = convertFromBitrate(this.props.limit, this.state.unit); + this.setState({ unit }); + this.setLimit(limit); + } + + render() { + const { global, limit, legend, prop } = this.props; + const { unit } = this.state; + return ( +
+ + {legend} + {typeof global === "undefined" || global && + + + + } + + + + + + + + {limit !== -1 && limit !== null && +
+ + this.setLimit(parseFloat(e.target.value))} + /> + + + this.setUnit(e.target.value)} + > + + + + + + +
+ } +
+ ); + } +} diff --git a/src/ui/torrent_details.js b/src/ui/torrent_details.js index ce071f6..61518be 100644 --- a/src/ui/torrent_details.js +++ b/src/ui/torrent_details.js @@ -151,6 +151,7 @@ class Torrent extends Component {
{date(moment(torrent.created))}
dispatch(updateResource({ id: torrent.id, priority }))} diff --git a/src/ui/torrent_options.js b/src/ui/torrent_options.js index 0722eb7..81cb673 100644 --- a/src/ui/torrent_options.js +++ b/src/ui/torrent_options.js @@ -4,103 +4,12 @@ import { Label, Input } from 'reactstrap'; -import { convertFromBitrate, convertToBitrate } from '../bitrate'; - -class Throttle extends Component { - constructor() { - super(); - this.setLimit = this.setLimit.bind(this); - this.setUnit = this.setUnit.bind(this); - this.state = { unit: "MiB/s" }; - } - - setLimit(limit) { - const { onChange } = this.props; - const { unit } = this.state; - const converted = limit <= 0 || limit === null ? - limit : convertToBitrate(limit, unit); - onChange && onChange(converted); - } - - setUnit(unit) { - const limit = convertFromBitrate(this.props.limit, this.state.unit); - this.setState({ unit }); - this.setLimit(limit); - } - - render() { - const { limit, legend, prop } = this.props; - const { unit } = this.state; - return ( -
- - {legend} - - - - - - - - - - - {limit !== -1 && limit !== null && -
- - this.setLimit(parseFloat(e.target.value))} - /> - - - this.setUnit(e.target.value)} - > - - - - - - -
- } -
- ); - } -} +import Throttle from './throttle'; export default class TorrentOptions extends Component { render() { const { + id, start, startChanged, priority, @@ -140,13 +49,13 @@ export default class TorrentOptions extends Component { downloadThrottleChanged(limit)} /> uploadThrottleChanged(limit)}