mirror of
https://github.com/zoriya/flood.git
synced 2025-12-20 06:05:15 +00:00
Add priority meter to files
This commit is contained in:
@@ -58,9 +58,12 @@
|
|||||||
|
|
||||||
.file {
|
.file {
|
||||||
|
|
||||||
&__size,
|
&__detail {
|
||||||
&__priority {
|
|
||||||
color: $directory-tree--file-details--hover--foreground;
|
&--size,
|
||||||
|
&--priority {
|
||||||
|
color: $directory-tree--file-details--hover--foreground;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,21 +72,33 @@
|
|||||||
fill: $directory-tree--icon--file;
|
fill: $directory-tree--icon--file;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__name {
|
&__detail {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
overflow: hidden;
|
||||||
|
|
||||||
&__size,
|
|
||||||
&__priority {
|
|
||||||
color: $directory-tree--file-details--foreground;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
font-size: 0.95em;
|
|
||||||
text-align: right;
|
|
||||||
transition: color 0.25s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__size {
|
|
||||||
padding-right: $spacing-unit * 1/4;
|
padding-right: $spacing-unit * 1/4;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
|
&--size,
|
||||||
|
&--priority {
|
||||||
|
color: $directory-tree--file-details--foreground;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
font-size: 0.95em;
|
||||||
|
text-align: right;
|
||||||
|
transition: color 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--priority {
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
height: auto;
|
||||||
|
margin-right: 0;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +109,8 @@
|
|||||||
|
|
||||||
&__parent-directory {
|
&__parent-directory {
|
||||||
margin-left: -1px;
|
margin-left: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
fill: $torrent-details--directory-tree--parent-directory--icon--fill;
|
fill: $torrent-details--directory-tree--parent-directory--icon--fill;
|
||||||
|
|||||||
69
client/source/sass/components/_priority-meter.scss
Normal file
69
client/source/sass/components/_priority-meter.scss
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
.priority-meter {
|
||||||
|
height: 8px;
|
||||||
|
position: relative;
|
||||||
|
width: 17px;
|
||||||
|
|
||||||
|
&__wrapper {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 5px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
height: 2px;
|
||||||
|
left: 0;
|
||||||
|
top: 3px;
|
||||||
|
transition: background 0.25s;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
transition: background 0.25s, left 0.25s;
|
||||||
|
width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--level-0 {
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
background: $priority-meter--track--level-0--background;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
left: 0;
|
||||||
|
background: $priority-meter--bar--level-0--background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--level-1 {
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
background: $priority-meter--track--level-1--background;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
left: 8px;
|
||||||
|
background: $priority-meter--bar--level-1--background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--level-2 {
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
background: $priority-meter--track--level-2--background;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
background: $priority-meter--bar--level-2--background;
|
||||||
|
left: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
@import "components/icons";
|
@import "components/icons";
|
||||||
@import "components/loading-indicator";
|
@import "components/loading-indicator";
|
||||||
@import "components/modals";
|
@import "components/modals";
|
||||||
|
@import "components/priority-meter";
|
||||||
@import "components/progress-bar";
|
@import "components/progress-bar";
|
||||||
@import "components/scrollbars";
|
@import "components/scrollbars";
|
||||||
@import "components/sidebar";
|
@import "components/sidebar";
|
||||||
|
|||||||
@@ -201,3 +201,11 @@ $loading-indicator--bar--background: #e9eef2;
|
|||||||
$loading-indicator--bar--background--inverse: rgba(#38586d, 0.7);
|
$loading-indicator--bar--background--inverse: rgba(#38586d, 0.7);
|
||||||
$loading-indicator--tick--background: rgba($blue, 0.75);
|
$loading-indicator--tick--background: rgba($blue, 0.75);
|
||||||
$loading-indicator--tick--background--inverse: rgba($blue, 0.75);
|
$loading-indicator--tick--background--inverse: rgba($blue, 0.75);
|
||||||
|
|
||||||
|
// priority meter
|
||||||
|
$priority-meter--track--level-0--background: rgba(#436076, 0.2);
|
||||||
|
$priority-meter--bar--level-0--background: #436076;
|
||||||
|
$priority-meter--track--level-1--background: rgba($blue, 0.2);
|
||||||
|
$priority-meter--bar--level-1--background: $blue;
|
||||||
|
$priority-meter--track--level-2--background: rgba($green, 0.2);
|
||||||
|
$priority-meter--bar--level-2--background: $green;
|
||||||
|
|||||||
@@ -209,6 +209,31 @@ const TorrentActions = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
setFilePriority: function(hash, fileIndices, priority) {
|
||||||
|
console.log(hash, fileIndices, priority);
|
||||||
|
return axios.patch(`/client/torrents/${hash}/priority`, {
|
||||||
|
hash,
|
||||||
|
fileIndices,
|
||||||
|
priority
|
||||||
|
})
|
||||||
|
.then((json = {}) => {
|
||||||
|
return json.data;
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
AppDispatcher.dispatchServerAction({
|
||||||
|
type: ActionTypes.CLIENT_STOP_TORRENT_SUCCESS,
|
||||||
|
data
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
AppDispatcher.dispatchServerAction({
|
||||||
|
type: ActionTypes.CLIENT_STOP_TORRENT_ERROR,
|
||||||
|
error
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,61 @@ import React from 'react';
|
|||||||
|
|
||||||
import File from '../icons/File';
|
import File from '../icons/File';
|
||||||
import format from '../../util/formatData';
|
import format from '../../util/formatData';
|
||||||
|
import PriorityMeter from './PriorityMeter';
|
||||||
|
import TorrentActions from '../../actions/TorrentActions';
|
||||||
|
|
||||||
|
const MAX_LEVEL = 2;
|
||||||
|
const METHODS_TO_BIND = ['handlePriorityChange', 'processPriorities'];
|
||||||
|
|
||||||
export default class DirectoryFiles extends React.Component {
|
export default class DirectoryFiles extends React.Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
priorities: {},
|
||||||
|
files: null
|
||||||
|
};
|
||||||
|
|
||||||
|
METHODS_TO_BIND.forEach((method) => {
|
||||||
|
this[method] = this[method].bind(this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
this.processPriorities();
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePriorityChange(fileIndex) {
|
||||||
|
let priorities = this.state.priorities;
|
||||||
|
let priorityLevel = priorities[fileIndex];
|
||||||
|
|
||||||
|
if (priorityLevel == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priorityLevel++ >= MAX_LEVEL) {
|
||||||
|
priorityLevel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
priorities[fileIndex] = priorityLevel;
|
||||||
|
|
||||||
|
this.setState({priorities});
|
||||||
|
|
||||||
|
TorrentActions.setFilePriority(this.props.hash, [fileIndex], priorityLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
processPriorities() {
|
||||||
|
let priorities = this.state.priorities;
|
||||||
|
|
||||||
|
this.props.branch.forEach(function (file, index) {
|
||||||
|
if (priorities[file.index] == null) {
|
||||||
|
priorities[file.index] = Number(file.priority);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState({priorities});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let branch = Object.assign([], this.props.branch);
|
let branch = Object.assign([], this.props.branch);
|
||||||
|
|
||||||
@@ -11,22 +64,26 @@ export default class DirectoryFiles extends React.Component {
|
|||||||
return a.filename.localeCompare(b.filename);
|
return a.filename.localeCompare(b.filename);
|
||||||
});
|
});
|
||||||
|
|
||||||
let files = branch.map((file, fileIndex) => {
|
let files = branch.map((file, index) => {
|
||||||
let fileSize = format.data(file.sizeBytes, '', 1);
|
let fileSize = format.data(file.sizeBytes, '', 1);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="directory-tree__node directory-tree__node--file file"
|
<div className="directory-tree__node directory-tree__node--file file"
|
||||||
key={`${fileIndex}`} title={file.filename}>
|
key={`${index}`} title={file.filename}>
|
||||||
<div className="file__detail file__name">
|
<div className="file__detail file__name">
|
||||||
<File />
|
<File />
|
||||||
{file.filename}
|
{file.filename}
|
||||||
</div>
|
</div>
|
||||||
<div className="file__detail file__size">
|
<div className="file__detail file__detail--size">
|
||||||
{fileSize.value}
|
{fileSize.value}
|
||||||
<em className="unit">{fileSize.unit}</em>
|
<em className="unit">{fileSize.unit}</em>
|
||||||
</div>
|
</div>
|
||||||
<div className="file__detail file__priority">
|
<div className="file__detail file__detail--size">
|
||||||
{file.priority}
|
{file.percentComplete}%
|
||||||
|
</div>
|
||||||
|
<div className="file__detail file__detail--priority">
|
||||||
|
<PriorityMeter level={this.state.priorities[file.index]}
|
||||||
|
fileIndex={file.index} onChange={this.handlePriorityChange} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,9 +3,20 @@ import React from 'react';
|
|||||||
import DirectoryFileList from './DirectoryFileList';
|
import DirectoryFileList from './DirectoryFileList';
|
||||||
import DirectoryTreeNode from './DirectoryTreeNode';
|
import DirectoryTreeNode from './DirectoryTreeNode';
|
||||||
|
|
||||||
|
const METHODS_TO_BIND = ['getDirectoryTreeDomNodes'];
|
||||||
|
|
||||||
export default class DirectoryTree extends React.Component {
|
export default class DirectoryTree extends React.Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
METHODS_TO_BIND.forEach((method) => {
|
||||||
|
this[method] = this[method].bind(this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getDirectoryTreeDomNodes(tree, depth = 0) {
|
getDirectoryTreeDomNodes(tree, depth = 0) {
|
||||||
let index = 0;
|
let index = 0;
|
||||||
|
let hash = this.props.hash;
|
||||||
depth++;
|
depth++;
|
||||||
|
|
||||||
return Object.keys(tree).map((branchName) => {
|
return Object.keys(tree).map((branchName) => {
|
||||||
@@ -14,12 +25,13 @@ export default class DirectoryTree extends React.Component {
|
|||||||
|
|
||||||
if (branchName === 'files') {
|
if (branchName === 'files') {
|
||||||
return (
|
return (
|
||||||
<DirectoryFileList branch={branch} key={`${index}${depth}`} />
|
<DirectoryFileList branch={branch} hash={hash}
|
||||||
|
key={`${index}${depth}`} />
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<DirectoryTreeNode depth={depth} directoryName={branchName}
|
<DirectoryTreeNode depth={depth} directoryName={branchName}
|
||||||
subTree={branch} key={`${index}${depth}`} />
|
hash={hash} subTree={branch} key={`${index}${depth}`} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ export default class DirectoryTreeNode extends React.Component {
|
|||||||
if (this.state.expanded) {
|
if (this.state.expanded) {
|
||||||
return (
|
return (
|
||||||
<div className="directory-tree__node directory-tree__node--group">
|
<div className="directory-tree__node directory-tree__node--group">
|
||||||
<DirectoryTree tree={this.props.subTree} depth={this.props.depth} />
|
<DirectoryTree tree={this.props.subTree} depth={this.props.depth}
|
||||||
|
hash={this.props.hash} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
42
client/source/scripts/components/filesystem/PriorityMeter.js
Normal file
42
client/source/scripts/components/filesystem/PriorityMeter.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import classnames from 'classnames';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const MAX_LEVEL = 2;
|
||||||
|
|
||||||
|
const METHODS_TO_BIND = ['handleClick'];
|
||||||
|
|
||||||
|
export default class PriorityMeter extends React.Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
level: null
|
||||||
|
};
|
||||||
|
|
||||||
|
METHODS_TO_BIND.forEach((method) => {
|
||||||
|
this[method] = this[method].bind(this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getLevel() {
|
||||||
|
if (this.state.level == null) {
|
||||||
|
return this.props.level;
|
||||||
|
} else {
|
||||||
|
return this.state.level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClick() {
|
||||||
|
this.props.onChange(this.props.fileIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let level = this.props.level;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="priority-meter__wrapper" onClick={this.handleClick}>
|
||||||
|
<div className={`priority-meter priority-meter--level-${level}`}/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,6 @@ export default class BaseIcon extends React.Component {
|
|||||||
|
|
||||||
BaseIcon.defaultProps = {
|
BaseIcon.defaultProps = {
|
||||||
className: '',
|
className: '',
|
||||||
what: 'hello',
|
|
||||||
viewBox: '0 0 60 60'
|
viewBox: '0 0 60 60'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ export default class TorrentFiles extends React.Component {
|
|||||||
this.constructDirectoryTree(tree, file.pathComponents[0], file);
|
this.constructDirectoryTree(tree, file.pathComponents[0], file);
|
||||||
});
|
});
|
||||||
|
|
||||||
return <DirectoryTree tree={tree} depth={0} />;
|
return (
|
||||||
|
<DirectoryTree tree={tree} depth={0} hash={this.props.torrent.hash} />
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
isLoaded() {
|
isLoaded() {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -974,32 +974,41 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
width: 100%; }
|
width: 100%; }
|
||||||
.directory-tree__node .file:hover .file__size, .directory-tree__node .file:hover .file__priority {
|
.directory-tree__node .file:hover .file__detail--size, .directory-tree__node .file:hover .file__detail--priority {
|
||||||
color: #527893; }
|
color: #527893; }
|
||||||
.directory-tree__node .file .icon {
|
.directory-tree__node .file .icon {
|
||||||
fill: #344b5b; }
|
fill: #344b5b; }
|
||||||
.directory-tree__node .file__name {
|
.directory-tree__node .file__detail {
|
||||||
-webkit-box-flex: 1;
|
-webkit-box-flex: 1;
|
||||||
-webkit-flex: 1 1 auto;
|
-webkit-flex: 1 1 auto;
|
||||||
-ms-flex: 1 1 auto;
|
-ms-flex: 1 1 auto;
|
||||||
flex: 1 1 auto; }
|
flex: 1 1 auto;
|
||||||
.directory-tree__node .file__size, .directory-tree__node .file__priority {
|
overflow: hidden;
|
||||||
color: #2b4456;
|
padding-right: 6.25px;
|
||||||
-webkit-box-flex: 0;
|
text-overflow: ellipsis; }
|
||||||
-webkit-flex: 0 0 auto;
|
.directory-tree__node .file__detail--size, .directory-tree__node .file__detail--priority {
|
||||||
-ms-flex: 0 0 auto;
|
color: #2b4456;
|
||||||
flex: 0 0 auto;
|
-webkit-box-flex: 0;
|
||||||
font-size: 0.95em;
|
-webkit-flex: 0 0 auto;
|
||||||
text-align: right;
|
-ms-flex: 0 0 auto;
|
||||||
-webkit-transition: color 0.25s;
|
flex: 0 0 auto;
|
||||||
transition: color 0.25s; }
|
font-size: 0.95em;
|
||||||
.directory-tree__node .file__size {
|
text-align: right;
|
||||||
padding-right: 6.25px; }
|
-webkit-transition: color 0.25s;
|
||||||
|
transition: color 0.25s; }
|
||||||
|
.directory-tree__node .file__detail--priority .icon {
|
||||||
|
height: auto;
|
||||||
|
margin-right: 0;
|
||||||
|
width: 16px; }
|
||||||
|
.directory-tree__node .file__detail:last-child {
|
||||||
|
padding-right: 0; }
|
||||||
.directory-tree__node--file-list {
|
.directory-tree__node--file-list {
|
||||||
margin-bottom: 3px; }
|
margin-bottom: 3px; }
|
||||||
|
|
||||||
.directory-tree__parent-directory {
|
.directory-tree__parent-directory {
|
||||||
margin-left: -1px; }
|
margin-left: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis; }
|
||||||
.directory-tree__parent-directory .icon {
|
.directory-tree__parent-directory .icon {
|
||||||
fill: rgba(58, 92, 116, 0.5);
|
fill: rgba(58, 92, 116, 0.5);
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
@@ -1277,6 +1286,47 @@ body {
|
|||||||
.modal__animation-leave-active {
|
.modal__animation-leave-active {
|
||||||
opacity: 0; }
|
opacity: 0; }
|
||||||
|
|
||||||
|
.priority-meter {
|
||||||
|
height: 8px;
|
||||||
|
position: relative;
|
||||||
|
width: 17px; }
|
||||||
|
.priority-meter__wrapper {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 5px;
|
||||||
|
vertical-align: middle; }
|
||||||
|
.priority-meter:before, .priority-meter:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute; }
|
||||||
|
.priority-meter:before {
|
||||||
|
height: 2px;
|
||||||
|
left: 0;
|
||||||
|
top: 3px;
|
||||||
|
-webkit-transition: background 0.25s;
|
||||||
|
transition: background 0.25s;
|
||||||
|
width: 100%; }
|
||||||
|
.priority-meter:after {
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
-webkit-transition: background 0.25s, left 0.25s;
|
||||||
|
transition: background 0.25s, left 0.25s;
|
||||||
|
width: 2px; }
|
||||||
|
.priority-meter--level-0:before {
|
||||||
|
background: rgba(67, 96, 118, 0.2); }
|
||||||
|
.priority-meter--level-0:after {
|
||||||
|
left: 0;
|
||||||
|
background: #436076; }
|
||||||
|
.priority-meter--level-1:before {
|
||||||
|
background: rgba(37, 141, 229, 0.2); }
|
||||||
|
.priority-meter--level-1:after {
|
||||||
|
left: 8px;
|
||||||
|
background: #258de5; }
|
||||||
|
.priority-meter--level-2:before {
|
||||||
|
background: rgba(57, 206, 131, 0.2); }
|
||||||
|
.priority-meter--level-2:after {
|
||||||
|
background: #39ce83;
|
||||||
|
left: 15px; }
|
||||||
|
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
height: 3px;
|
height: 3px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -130,8 +130,12 @@ var client = {
|
|||||||
clientUtil.defaults.fileProperties,
|
clientUtil.defaults.fileProperties,
|
||||||
filesData
|
filesData
|
||||||
);
|
);
|
||||||
|
|
||||||
files = files.map(function (file) {
|
files = files.map(function (file) {
|
||||||
file.filename = file.pathComponents[file.pathComponents.length - 1];
|
file.filename = file.pathComponents[file.pathComponents.length - 1];
|
||||||
|
file.percentComplete = (file.completedChunks / file.sizeChunks * 100).toFixed(0);
|
||||||
|
delete(file.completedChunks);
|
||||||
|
delete(file.sizeChunks);
|
||||||
return file;
|
return file;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -180,6 +184,36 @@ var client = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setPriority: function (hash, data, callback) {
|
||||||
|
// TODO Add support for multiple hashes.
|
||||||
|
var fileIndex = data.fileIndices[0];
|
||||||
|
|
||||||
|
var multicall = [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
methodName: 'f.priority.set',
|
||||||
|
params: [
|
||||||
|
hash + ':f' + fileIndex,
|
||||||
|
data.priority
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
methodName: 'd.update_priorities',
|
||||||
|
params: [
|
||||||
|
hash
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
rTorrent.get('system.multicall', multicall)
|
||||||
|
.then(function(data) {
|
||||||
|
callback(null, data);
|
||||||
|
}, function(error) {
|
||||||
|
callback(error, null);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
setSpeedLimits: function(data, callback) {
|
setSpeedLimits: function(data, callback) {
|
||||||
var methodName = 'throttle.global_down.max_rate.set';
|
var methodName = 'throttle.global_down.max_rate.set';
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ router.get('/torrents', function(req, res, next) {
|
|||||||
client.getTorrentList(ajaxUtil.getResponseFn(res));
|
client.getTorrentList(ajaxUtil.getResponseFn(res));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.patch('/torrents/:hash/priority', function(req, res, next) {
|
||||||
|
client.setPriority(req.params.hash, req.body, ajaxUtil.getResponseFn(res));
|
||||||
|
});
|
||||||
|
|
||||||
router.get('/torrents/status-count', function(req, res, next) {
|
router.get('/torrents/status-count', function(req, res, next) {
|
||||||
client.getTorrentStatusCount(ajaxUtil.getResponseFn(res));
|
client.getTorrentStatusCount(ajaxUtil.getResponseFn(res));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -138,16 +138,18 @@ var clientUtil = {
|
|||||||
fileProperties: [
|
fileProperties: [
|
||||||
'path',
|
'path',
|
||||||
'pathComponents',
|
'pathComponents',
|
||||||
'pathDepth',
|
|
||||||
'priority',
|
'priority',
|
||||||
'sizeBytes'
|
'sizeBytes',
|
||||||
|
'sizeChunks',
|
||||||
|
'completedChunks'
|
||||||
],
|
],
|
||||||
filePropertyMethods: [
|
filePropertyMethods: [
|
||||||
'f.get_path=',
|
'f.get_path=',
|
||||||
'f.get_path_components=',
|
'f.get_path_components=',
|
||||||
'f.get_path_depth=',
|
|
||||||
'f.get_priority=',
|
'f.get_priority=',
|
||||||
'f.get_size_bytes='
|
'f.get_size_bytes=',
|
||||||
|
'f.get_size_chunks=',
|
||||||
|
'f.completed_chunks='
|
||||||
],
|
],
|
||||||
trackerProperties: [
|
trackerProperties: [
|
||||||
'group',
|
'group',
|
||||||
@@ -213,7 +215,9 @@ var clientUtil = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
mapClientProps: function(props, data) {
|
// TODO clean this up, write comments...
|
||||||
|
mapClientProps: function(props, data, includeIndex) {
|
||||||
|
var index = 0;
|
||||||
var mappedObject = [];
|
var mappedObject = [];
|
||||||
|
|
||||||
if (data[0].length === 1) {
|
if (data[0].length === 1) {
|
||||||
@@ -227,6 +231,8 @@ var clientUtil = {
|
|||||||
for (a = 0, lenA = props.length; a < lenA; a++) {
|
for (a = 0, lenA = props.length; a < lenA; a++) {
|
||||||
mappedObject[i][props[a]] = data[i][a];
|
mappedObject[i][props[a]] = data[i][a];
|
||||||
}
|
}
|
||||||
|
// Index is needed for setting a file's priorities.
|
||||||
|
mappedObject[i].index = index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user