Implement peer list
This commit is contained in:
parent
0316a22452
commit
f6646451b2
|
@ -203,8 +203,8 @@ fieldset .form-check-input:only-child {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.files {
|
.flex-table {
|
||||||
.file {
|
& > div {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0.1rem 0.25rem;
|
padding: 0.1rem 0.25rem;
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ fieldset .form-check-input:only-child {
|
||||||
background: #dfdfdf;
|
background: #dfdfdf;
|
||||||
}
|
}
|
||||||
|
|
||||||
div {
|
& > div {
|
||||||
margin: 0 0.5rem;
|
margin: 0 0.5rem;
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
|
@ -223,27 +223,29 @@ fieldset .form-check-input:only-child {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.progress {
|
.files .file {
|
||||||
min-width: 3rem;
|
.progress {
|
||||||
align-self: center;
|
min-width: 3rem;
|
||||||
|
align-self: center;
|
||||||
|
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.path {
|
.path {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
min-width: 5rem;
|
min-width: 5rem;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,13 +39,13 @@ export default function selectTorrent(ids, action, navigate=true) {
|
||||||
const _ids = [
|
const _ids = [
|
||||||
...Object.values(files)
|
...Object.values(files)
|
||||||
.filter(file => file.torrent_id === t)
|
.filter(file => file.torrent_id === t)
|
||||||
.map(file => file.id)
|
.map(file => file.id),
|
||||||
//...Object.values(peers)
|
...Object.values(peers)
|
||||||
// .filter(peer => peer.torrent_id === t)
|
.filter(peer => peer.torrent_id === t)
|
||||||
// .map(peer => peer.id),
|
.map(peer => peer.id),
|
||||||
//...Object.values(trackers)
|
...Object.values(trackers)
|
||||||
// .filter(tracker => tracker.torrent_id === t)
|
.filter(tracker => tracker.torrent_id === t)
|
||||||
// .map(tracker => tracker.id),
|
.map(tracker => tracker.id)
|
||||||
];
|
];
|
||||||
if (_ids.length > 0) {
|
if (_ids.length > 0) {
|
||||||
dispatch(unsubscribe(..._ids));
|
dispatch(unsubscribe(..._ids));
|
||||||
|
|
|
@ -26,6 +26,7 @@ import selectTorrent, {
|
||||||
NONE
|
NONE
|
||||||
} from '../actions/selection';
|
} from '../actions/selection';
|
||||||
import { updateResource } from '../actions/resources';
|
import { updateResource } from '../actions/resources';
|
||||||
|
import { formatBitrate } from '../bitrate';
|
||||||
|
|
||||||
const dlURI = (uri, password, id) => `${uri.replace('ws', 'http')}/dl/${id}?password=${encodeURIComponent(password)}`;
|
const dlURI = (uri, password, id) => `${uri.replace('ws', 'http')}/dl/${id}?password=${encodeURIComponent(password)}`;
|
||||||
|
|
||||||
|
@ -35,7 +36,6 @@ function basename(path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function File({ dispatch, file }) {
|
function File({ dispatch, file }) {
|
||||||
// TODO: edit priority
|
|
||||||
const { uri, password } = store.getState().socket;
|
const { uri, password } = store.getState().socket;
|
||||||
return (
|
return (
|
||||||
<div className="file">
|
<div className="file">
|
||||||
|
@ -43,11 +43,11 @@ function File({ dispatch, file }) {
|
||||||
value={file.progress * 100}
|
value={file.progress * 100}
|
||||||
color={file.progress != 1.0 ? "success" : "primary"}
|
color={file.progress != 1.0 ? "success" : "primary"}
|
||||||
>
|
>
|
||||||
{file.progress == 1.0 ?
|
{file.progress === 1.0 ?
|
||||||
"done" : `${(file.progress * 100).toFixed(0)}%`}
|
"done" : `${(file.progress * 100).toFixed(0)}%`}
|
||||||
</Progress>
|
</Progress>
|
||||||
<div className="path" title={file.path}>
|
<div className="path" title={file.path}>
|
||||||
{file.progress == 1.0 ?
|
{file.progress === 1.0 ?
|
||||||
<a href={dlURI(uri, password, file.id)} target="_new">
|
<a href={dlURI(uri, password, file.id)} target="_new">
|
||||||
{basename(file.path)}
|
{basename(file.path)}
|
||||||
</a> : basename(file.path)}
|
</a> : basename(file.path)}
|
||||||
|
@ -62,6 +62,7 @@ function File({ dispatch, file }) {
|
||||||
priority: parseInt(e.target.value)
|
priority: parseInt(e.target.value)
|
||||||
}))}
|
}))}
|
||||||
>
|
>
|
||||||
|
<option value="0">Skip</option>
|
||||||
<option value="1">Lowest</option>
|
<option value="1">Lowest</option>
|
||||||
<option value="2">Low</option>
|
<option value="2">Low</option>
|
||||||
<option value="3">Normal</option>
|
<option value="3">Normal</option>
|
||||||
|
@ -73,6 +74,17 @@ function File({ dispatch, file }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Peer({ peer }) {
|
||||||
|
return (
|
||||||
|
<div className="peer">
|
||||||
|
<div style={{flexGrow: 1}}>{peer.ip}</div>
|
||||||
|
<div>{formatBitrate(peer.rate_up)} up</div>
|
||||||
|
<div>{formatBitrate(peer.rate_down)} down</div>
|
||||||
|
<div>has {`${(peer.availability * 100).toFixed(0)}%`}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: move to separate component
|
// TODO: move to separate component
|
||||||
function CollapseToggle({ text, onToggle, open }) {
|
function CollapseToggle({ text, onToggle, open }) {
|
||||||
return (
|
return (
|
||||||
|
@ -110,7 +122,7 @@ class Torrent extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { dispatch, torrent, files, trackers } = this.props;
|
const { dispatch, torrent, files, trackers, peers } = this.props;
|
||||||
const status = s => s[0].toUpperCase() + s.slice(1);
|
const status = s => s[0].toUpperCase() + s.slice(1);
|
||||||
|
|
||||||
if (!torrent || !files) {
|
if (!torrent || !files) {
|
||||||
|
@ -203,7 +215,7 @@ class Torrent extends Component {
|
||||||
<Collapse isOpen={this.state.filesShown}>
|
<Collapse isOpen={this.state.filesShown}>
|
||||||
<Card style={{marginBottom: "1rem"}}>
|
<Card style={{marginBottom: "1rem"}}>
|
||||||
<CardBlock style={{padding: "0"}}>
|
<CardBlock style={{padding: "0"}}>
|
||||||
<div className="files" style={{marginBottom: "0"}}>
|
<div className="files flex-table" style={{marginBottom: "0"}}>
|
||||||
{files.slice().sort((a, b) =>
|
{files.slice().sort((a, b) =>
|
||||||
a.path.localeCompare(b.path)).map(file =>
|
a.path.localeCompare(b.path)).map(file =>
|
||||||
<File dispatch={dispatch} file={file} />)}
|
<File dispatch={dispatch} file={file} />)}
|
||||||
|
@ -240,6 +252,19 @@ class Torrent extends Component {
|
||||||
</CardBlock>
|
</CardBlock>
|
||||||
</Card>
|
</Card>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
|
<Collapse isOpen={this.state.peersShown}>
|
||||||
|
<Card style={{marginBottom: "1rem"}}>
|
||||||
|
<CardBlock style={{padding: "0"}}>
|
||||||
|
<div className="peers flex-table" style={{marginBottom: "0"}}>
|
||||||
|
{peers.map(peer => <Peer peer={peer} />)}
|
||||||
|
</div>
|
||||||
|
{peers.length === 0 &&
|
||||||
|
<div style={{padding: "0.5rem 0 0 0.5rem"}}>
|
||||||
|
<p>No connected peers.</p>}
|
||||||
|
</div>}
|
||||||
|
</CardBlock>
|
||||||
|
</Card>
|
||||||
|
</Collapse>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user