Make torrent options reusable
This commit is contained in:
parent
a6dd7cc8bc
commit
176312617c
|
@ -10,6 +10,10 @@ export function convertToBitrate(value, unit) {
|
||||||
return value * Rates[unit];
|
return value * Rates[unit];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function convertFromBitrate(value, unit) {
|
||||||
|
return value / Rates[unit];
|
||||||
|
}
|
||||||
|
|
||||||
export function formatBitrate(bitrate) {
|
export function formatBitrate(bitrate) {
|
||||||
if (bitrate > Rates["GiB/s"]) {
|
if (bitrate > Rates["GiB/s"]) {
|
||||||
return `${(bitrate / Rates["GiB/s"]).toFixed(2)} GiB/s`;
|
return `${(bitrate / Rates["GiB/s"]).toFixed(2)} GiB/s`;
|
||||||
|
|
|
@ -16,129 +16,10 @@ import fetch from 'isomorphic-fetch';
|
||||||
import bencode from 'bencode';
|
import bencode from 'bencode';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import ToggleContainer from './toggle_container';
|
import ToggleContainer from './toggle_container';
|
||||||
|
import TorrentOptions from './torrent_options';
|
||||||
import ws_send from '../socket';
|
import ws_send from '../socket';
|
||||||
import { convertToBitrate } from '../bitrate';
|
|
||||||
import date from '../date';
|
import date from '../date';
|
||||||
|
|
||||||
class Throttle extends Component {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.state = {
|
|
||||||
strategy: "global",
|
|
||||||
unit: "MiB/s",
|
|
||||||
limit: 1
|
|
||||||
};
|
|
||||||
this.setStrategy = this.setStrategy.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
invokeChange() {
|
|
||||||
const { onChange } = this.props;
|
|
||||||
if (!onChange) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { strategy, limit, unit } = this.state;
|
|
||||||
switch (strategy) {
|
|
||||||
case "global":
|
|
||||||
onChange(null);
|
|
||||||
break;
|
|
||||||
case "unlimited":
|
|
||||||
onChange(-1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
onChange(convertToBitrate(limit, unit));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setStrategy(strategy) {
|
|
||||||
this.setState({ strategy });
|
|
||||||
this.invokeChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
setLimit(limit) {
|
|
||||||
if (limit <= 0) {
|
|
||||||
this.setState({ limit: this.state.limit });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setState({ limit });
|
|
||||||
this.invokeChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
setUnit(unit) {
|
|
||||||
this.setState({ unit });
|
|
||||||
this.invokeChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { legend, prop } = this.props;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<FormGroup tag="fieldset">
|
|
||||||
<legend>{legend}</legend>
|
|
||||||
<FormGroup check className="form-check-inline">
|
|
||||||
<Label for={`${prop}-global`} check>
|
|
||||||
<Input
|
|
||||||
type="radio"
|
|
||||||
name={prop}
|
|
||||||
id={`${prop}-global`}
|
|
||||||
onChange={e => this.setStrategy("global")}
|
|
||||||
checked={this.state.strategy === "global"}
|
|
||||||
/> Global
|
|
||||||
</Label>
|
|
||||||
</FormGroup>
|
|
||||||
<FormGroup check className="form-check-inline">
|
|
||||||
<Label for={`${prop}-unlimited`} check>
|
|
||||||
<Input
|
|
||||||
type="radio"
|
|
||||||
name={prop}
|
|
||||||
id={`${prop}-unlimited`}
|
|
||||||
onChange={e => this.setStrategy("unlimited")}
|
|
||||||
checked={this.state.strategy === "unlimited"}
|
|
||||||
/> Unlimited
|
|
||||||
</Label>
|
|
||||||
</FormGroup>
|
|
||||||
<FormGroup check className="form-check-inline">
|
|
||||||
<Label for={`${prop}-custom`} check>
|
|
||||||
<Input
|
|
||||||
type="radio"
|
|
||||||
name={prop}
|
|
||||||
id={`${prop}-custom`}
|
|
||||||
onChange={e => this.setStrategy("custom")}
|
|
||||||
checked={this.state.strategy === "custom"}
|
|
||||||
/> Custom
|
|
||||||
</Label>
|
|
||||||
</FormGroup>
|
|
||||||
</FormGroup>
|
|
||||||
{this.state.strategy === "custom" &&
|
|
||||||
<div className="row">
|
|
||||||
<FormGroup className="col-md-6">
|
|
||||||
<Input
|
|
||||||
type="number"
|
|
||||||
value={this.state.limit}
|
|
||||||
onChange={e => this.setLimit(parseFloat(e.target.value))}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
<FormGroup className="col-md-6">
|
|
||||||
<Input
|
|
||||||
type="select"
|
|
||||||
id="unit"
|
|
||||||
value={this.state.unit}
|
|
||||||
onChange={e => this.setUnit(e.target.value)}
|
|
||||||
>
|
|
||||||
<option value="b/s">b/s</option>
|
|
||||||
<option value="KiB/s">KiB/s</option>
|
|
||||||
<option value="MiB/s">MiB/s</option>
|
|
||||||
<option value="GiB/s">GiB/s</option>
|
|
||||||
</Input>
|
|
||||||
</FormGroup>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AddTorrent extends Component {
|
class AddTorrent extends Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
@ -150,9 +31,9 @@ class AddTorrent extends Component {
|
||||||
useMagnet: false,
|
useMagnet: false,
|
||||||
torrent: null,
|
torrent: null,
|
||||||
files: [],
|
files: [],
|
||||||
startImmediately: true,
|
start: true,
|
||||||
uploadThrottle: -1,
|
uploadThrottle: null,
|
||||||
downloadThrottle: -1,
|
downloadThrottle: null,
|
||||||
priority: 3,
|
priority: 3,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -210,7 +91,7 @@ class AddTorrent extends Component {
|
||||||
throttle_down: downloadThrottle
|
throttle_down: downloadThrottle
|
||||||
}
|
}
|
||||||
}, async done => {
|
}, async done => {
|
||||||
if (this.state.startImmediately) {
|
if (this.state.start) {
|
||||||
ws_send("RESUME_TORRENT", { id });
|
ws_send("RESUME_TORRENT", { id });
|
||||||
}
|
}
|
||||||
dispatch(push(`/torrents/${id}`));
|
dispatch(push(`/torrents/${id}`));
|
||||||
|
@ -219,7 +100,7 @@ class AddTorrent extends Component {
|
||||||
|
|
||||||
uploadFile() {
|
uploadFile() {
|
||||||
this.setState({ loading: true });
|
this.setState({ loading: true });
|
||||||
const { magnet, file, startImmediately } = this.state;
|
const { magnet, file, start } = this.state;
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
const customize = // TODO: File options
|
const customize = // TODO: File options
|
||||||
this.state.priority !== 3 ||
|
this.state.priority !== 3 ||
|
||||||
|
@ -238,12 +119,12 @@ class AddTorrent extends Component {
|
||||||
if (magnet) {
|
if (magnet) {
|
||||||
ws_send("UPLOAD_MAGNET", {
|
ws_send("UPLOAD_MAGNET", {
|
||||||
uri: magnet,
|
uri: magnet,
|
||||||
start: startImmediately && !customize
|
start: start && !customize
|
||||||
}, handleOffer);
|
}, handleOffer);
|
||||||
} else {
|
} else {
|
||||||
ws_send("UPLOAD_TORRENT", {
|
ws_send("UPLOAD_TORRENT", {
|
||||||
size: file.size,
|
size: file.size,
|
||||||
start: startImmediately && !customize
|
start: start && !customize
|
||||||
}, handleOffer);
|
}, handleOffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,47 +166,27 @@ class AddTorrent extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderOptions() {
|
renderOptions() {
|
||||||
|
const {
|
||||||
|
start,
|
||||||
|
priority,
|
||||||
|
downloadThrottle,
|
||||||
|
uploadThrottle
|
||||||
|
} = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardBlock>
|
<CardBlock>
|
||||||
<FormGroup>
|
<TorrentOptions
|
||||||
<Label for="start-immediately" check style={{paddingLeft: 0}}>
|
start={start}
|
||||||
<input
|
startChanged={start => this.setState({ start })}
|
||||||
type="checkbox"
|
priority={priority}
|
||||||
checked={this.state.startImmediately}
|
priorityChanged={priority => this.setState({ priority })}
|
||||||
onChange={e => this.setState({
|
downloadThrottle={downloadThrottle}
|
||||||
startImmediately: !this.state.startImmediately
|
downloadThrottleChanged={downloadThrottle =>
|
||||||
})}
|
this.setState({ downloadThrottle })}
|
||||||
id="start-immediately"
|
uploadThrottle={uploadThrottle}
|
||||||
/> Start immediately
|
uploadThrottleChanged={uploadThrottle =>
|
||||||
</Label>
|
{ console.log(uploadThrottle); this.setState({ uploadThrottle }); }}
|
||||||
</FormGroup>
|
|
||||||
<FormGroup>
|
|
||||||
<Label for="priority">Priority</Label>
|
|
||||||
<Input
|
|
||||||
type="select"
|
|
||||||
id="priority"
|
|
||||||
value={this.state.priority}
|
|
||||||
onChange={e =>
|
|
||||||
this.setState({ priority: parseInt(e.target.value)})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<option value="1">Lowest</option>
|
|
||||||
<option value="2">Low</option>
|
|
||||||
<option value="3">Normal</option>
|
|
||||||
<option value="4">High</option>
|
|
||||||
<option value="5">Highest</option>
|
|
||||||
</Input>
|
|
||||||
</FormGroup>
|
|
||||||
<Throttle
|
|
||||||
prop="dl-throttle"
|
|
||||||
legend="Download throttle"
|
|
||||||
onChange={limit => this.setState({ downloadThrottle: limit })}
|
|
||||||
/>
|
|
||||||
<Throttle
|
|
||||||
prop="ul-throttle"
|
|
||||||
legend="Upload throttle"
|
|
||||||
onChange={limit => this.setState({ uploadThrottle: limit })}
|
|
||||||
/>
|
/>
|
||||||
</CardBlock>
|
</CardBlock>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
157
src/ui/torrent_options.js
Normal file
157
src/ui/torrent_options.js
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import {
|
||||||
|
FormGroup,
|
||||||
|
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 (
|
||||||
|
<div>
|
||||||
|
<FormGroup tag="fieldset">
|
||||||
|
<legend>{legend}</legend>
|
||||||
|
<FormGroup check className="form-check-inline">
|
||||||
|
<Label for={`${prop}-global`} check>
|
||||||
|
<Input
|
||||||
|
type="radio"
|
||||||
|
name={prop}
|
||||||
|
id={`${prop}-global`}
|
||||||
|
onChange={e => this.setLimit(null)}
|
||||||
|
checked={limit === null}
|
||||||
|
/> Global
|
||||||
|
</Label>
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup check className="form-check-inline">
|
||||||
|
<Label for={`${prop}-unlimited`} check>
|
||||||
|
<Input
|
||||||
|
type="radio"
|
||||||
|
name={prop}
|
||||||
|
id={`${prop}-unlimited`}
|
||||||
|
onChange={e => this.setLimit(-1)}
|
||||||
|
checked={limit === -1}
|
||||||
|
/> Unlimited
|
||||||
|
</Label>
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup check className="form-check-inline">
|
||||||
|
<Label for={`${prop}-custom`} check>
|
||||||
|
<Input
|
||||||
|
type="radio"
|
||||||
|
name={prop}
|
||||||
|
id={`${prop}-custom`}
|
||||||
|
onChange={e => this.setLimit(1)}
|
||||||
|
checked={limit !== -1 && limit !== null}
|
||||||
|
/> Custom
|
||||||
|
</Label>
|
||||||
|
</FormGroup>
|
||||||
|
</FormGroup>
|
||||||
|
{limit !== -1 && limit !== null &&
|
||||||
|
<div className="row">
|
||||||
|
<FormGroup className="col-md-6">
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
value={convertFromBitrate(limit, unit)}
|
||||||
|
onChange={e => this.setLimit(parseFloat(e.target.value))}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup className="col-md-6">
|
||||||
|
<Input
|
||||||
|
type="select"
|
||||||
|
id="unit"
|
||||||
|
value={unit}
|
||||||
|
onChange={e => this.setUnit(e.target.value)}
|
||||||
|
>
|
||||||
|
<option value="b/s">b/s</option>
|
||||||
|
<option value="KiB/s">KiB/s</option>
|
||||||
|
<option value="MiB/s">MiB/s</option>
|
||||||
|
<option value="GiB/s">GiB/s</option>
|
||||||
|
</Input>
|
||||||
|
</FormGroup>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class TorrentOptions extends Component {
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
start,
|
||||||
|
startChanged,
|
||||||
|
priority,
|
||||||
|
priorityChanged,
|
||||||
|
downloadThrottle,
|
||||||
|
downloadThrottleChanged,
|
||||||
|
uploadThrottle,
|
||||||
|
uploadThrottleChanged,
|
||||||
|
} = this.props;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{typeof start !== undefined &&
|
||||||
|
<FormGroup>
|
||||||
|
<Label for="start-immediately" check style={{paddingLeft: 0}}>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={start}
|
||||||
|
onChange={e => startChanged(!start)}
|
||||||
|
id="start-immediately"
|
||||||
|
/> Start immediately
|
||||||
|
</Label>
|
||||||
|
</FormGroup>
|
||||||
|
}
|
||||||
|
<FormGroup>
|
||||||
|
<Label for="priority">Priority</Label>
|
||||||
|
<Input
|
||||||
|
type="select"
|
||||||
|
id="priority"
|
||||||
|
value={priority}
|
||||||
|
onChange={e => priorityChanged(parseInt(e.target.value))}
|
||||||
|
>
|
||||||
|
<option value="1">Lowest</option>
|
||||||
|
<option value="2">Low</option>
|
||||||
|
<option value="3">Normal</option>
|
||||||
|
<option value="4">High</option>
|
||||||
|
<option value="5">Highest</option>
|
||||||
|
</Input>
|
||||||
|
</FormGroup>
|
||||||
|
<Throttle
|
||||||
|
prop="dl-throttle"
|
||||||
|
legend="Download throttle"
|
||||||
|
limit={downloadThrottle}
|
||||||
|
onChange={limit => downloadThrottleChanged(limit)}
|
||||||
|
/>
|
||||||
|
<Throttle
|
||||||
|
prop="ul-throttle"
|
||||||
|
legend="Upload throttle"
|
||||||
|
limit={uploadThrottle}
|
||||||
|
onChange={limit => uploadThrottleChanged(limit)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user