Implement peer list

This commit is contained in:
Drew DeVault 2017-12-29 01:19:24 -05:00
parent 0316a22452
commit f6646451b2
3 changed files with 58 additions and 31 deletions

View File

@ -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;
}
} }
} }

View File

@ -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));

View File

@ -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>
); );
} }