Add more settings to the modal, including:

* Global upload/download throttles mirrored in modal and dropdown
* Max client memory usage
* Verify hash after downloading flag
This commit is contained in:
John Furrow
2016-06-18 00:47:52 -07:00
parent 542093269a
commit a72fb8acb4
10 changed files with 151 additions and 63 deletions

View File

@@ -1,4 +1,4 @@
$form--label--foreground: #5c7087;
$form--label--foreground: desaturate(lighten(#5c7087, 3%), 3%);
$textbox--background: #242b36;
$textbox--foreground: #5e728c;

View File

@@ -4,7 +4,7 @@ $modal--heading--background: #303845;
$modal--heading--foreground: #a3bad4;
$modal--heading--border: #1a232c;
$modal--sub-heading--foreground: desaturate(darken($modal--heading--foreground, 15%), 10%);
$modal--sub-heading--foreground: desaturate(darken($modal--heading--foreground, 15%), 15%);
$modal--transition--duration: 0.5s;
$modal--transition--scale: 0.85;
@@ -379,13 +379,13 @@ $modal--tabs--in-body--background: #2a323e;
&__heading {
color: $modal--heading--foreground;
font-size: 0.9em;
font-size: 0.925em;
font-weight: 500;
}
&__sub-heading {
color: $modal--sub-heading--foreground;
font-size: 0.8em;
font-size: 0.875em;
}
}
}

View File

@@ -6,8 +6,8 @@ import ConnectivityTab from '../settings/ConnectivityTab';
import EventTypes from '../../constants/EventTypes';
import LoadingIndicatorDots from '../icons/LoadingIndicatorDots';
import Modal from './Modal';
import ResourcesTab from '../settings/ResourcesTab';
import SettingsStore from '../../stores/SettingsStore';
import StorageTab from '../settings/StorageTab';
const METHODS_TO_BIND = [
'handleClientSettingsChange',
@@ -177,13 +177,13 @@ export default class SettingsModal extends React.Component {
},
label: 'Connectivity'
},
storage: {
content: StorageTab,
resources: {
content: ResourcesTab,
props: {
onClientSettingsChange: this.handleClientSettingsChange,
settings: this.state.clientSettings
},
label: 'Storage'
label: 'Resources'
}
};

View File

@@ -108,29 +108,46 @@ export default class BandwidthTab extends SettingsTab {
<div className="form">
<div className="form__section">
<p className="form__section__heading">
Speed Limit Dropdown Presets
</p>
<p className="form__section__sub-heading">
Enter a comma-separated list of speeds in kB. 0 represents unlimited.
Transfer Rate Throttles
</p>
<div className="form__row">
<div className="form__column">
<label className="form__label">
Download Presets
Dropdown Presets: Download
</label>
<input className="textbox" type="text"
onChange={this.handleDownloadTextChange}
value={downloadValue} />
</div>
</div>
<div className="form__row">
<div className="form__column">
<label className="form__label">
Upload Presets
Dropdown Presets: Upload
</label>
<input className="textbox" type="text"
onChange={this.handleUploadTextChange}
value={uploadValue} />
</div>
</div>
<div className="form__row">
<div className="form__column">
<label className="form__label">
Global Download Rate Throttle
</label>
<input className="textbox" type="text"
onChange={this.handleClientSettingFieldChange.bind(this, 'throttleGlobalDownMax')}
value={this.getFieldValue('throttleGlobalDownMax')} />
</div>
<div className="form__column">
<label className="form__label">
Global Upload Rate Throttle
</label>
<input className="textbox" type="text"
onChange={this.handleClientSettingFieldChange.bind(this, 'throttleGlobalUpMax')}
value={this.getFieldValue('throttleGlobalUpMax')} />
</div>
</div>
</div>
<div className="form__section">
<div className="form__section__heading">

View File

@@ -0,0 +1,59 @@
import _ from 'lodash';
import React from 'react';
import Checkbox from '../forms/Checkbox';
import SettingsTab from './SettingsTab';
export default class ResourcesTab extends SettingsTab {
constructor() {
super(...arguments);
this.state = {};
}
render() {
return (
<div className="form">
<div className="form__section">
<div className="form__section__heading">
Disk
</div>
<div className="form__row">
<div className="form__column">
<label className="form__label">
Default Download Directory
</label>
<input className="textbox" type="text"
onChange={this.handleClientSettingFieldChange.bind(this, 'directoryDefault')}
value={this.getFieldValue('directoryDefault')} />
</div>
</div>
<div className="form__row">
<div className="form__column form__column--auto">
<Checkbox
checked={this.getFieldValue('piecesHashOnCompletion') === '1'}
onChange={this.handleClientSettingCheckboxChange.bind(this, 'piecesHashOnCompletion')}>
Verify Hash on Completion
</Checkbox>
</div>
</div>
</div>
<div className="form__section">
<div className="form__section__heading">
Memory
</div>
<div className="form__row">
<div className="form__column">
<label className="form__label">
Max Memory Usage <em className="unit">(MB)</em>
</label>
<input className="textbox" type="text"
onChange={this.handleClientSettingFieldChange.bind(this, 'piecesMemoryMax')}
value={this.getFieldValue('piecesMemoryMax')} />
</div>
</div>
</div>
</div>
);
}
}

View File

@@ -1,35 +0,0 @@
import _ from 'lodash';
import React from 'react';
import Checkbox from '../forms/Checkbox';
import SettingsTab from './SettingsTab';
export default class StorageTab extends SettingsTab {
constructor() {
super(...arguments);
this.state = {};
}
render() {
return (
<div className="form">
<div className="form__section">
<div className="form__section__heading">
Directories
</div>
<div className="form__row">
<div className="form__column">
<label className="form__label">
Default Download Directory
</label>
<input className="textbox" type="text"
onChange={this.handleClientSettingCheckboxChange.bind(this, 'directoryDefault')}
value={this.getFieldValue('directoryDefault')} />
</div>
</div>
</div>
</div>
);
}
}

View File

@@ -175,6 +175,9 @@ SettingsStore.dispatcherID = AppDispatcher.register((payload) => {
case ActionTypes.CLIENT_SETTINGS_FETCH_REQUEST_SUCCESS:
SettingsStore.handleClientSettingsFetchSuccess(action.data);
break;
case ActionTypes.CLIENT_SET_THROTTLE_SUCCESS:
SettingsStore.fetchClientSettings();
break;
case ActionTypes.SETTINGS_FETCH_REQUEST_ERROR:
SettingsStore.handleSettingsFetchError(action.error);
break;

View File

@@ -93,10 +93,6 @@ class ClientRequest {
}
send() {
// TODO: Remove this.
if (!this) {
console.log('\n\n\n\n\n\n\nthis is null\n\n\n\n\n\n');
}
let handleSuccess = this.handleSuccess.bind(this);
let handleError = this.handleError.bind(this);
@@ -174,9 +170,9 @@ class ClientRequest {
});
}
// Ensure client's response gets mapped to the correct requested property.
if (options.setPropertiesArr) {
options.setPropertiesArr(requestedSettings);
// Ensure client's response gets mapped to the correct requested keys.
if (options.setRequestedKeysArr) {
options.setRequestedKeysArr(requestedSettings);
}
requestedSettings.forEach((settingsKey) => {

View File

@@ -71,14 +71,26 @@ var client = {
},
getSettings: (options, callback) => {
let properties = [];
let requestedSettingsKeys = [];
let request = new ClientRequest();
let response = {};
let outboundTransformation = {
throttleGlobalDownMax: (apiResponse) => {
return Number(apiResponse) / 1024;
},
throttleGlobalUpMax: (apiResponse) => {
return Number(apiResponse) / 1024;
},
piecesMemoryMax: (apiResponse) => {
return Number(apiResponse) / (1024 * 1024);
}
};
request.add('fetchSettings', {
options,
setPropertiesArr: (propertiesArr) => {
properties = propertiesArr;
setRequestedKeysArr: (requestedSettingsKeysArr) => {
requestedSettingsKeys = requestedSettingsKeysArr;
}
});
@@ -88,7 +100,14 @@ var client = {
}
data.forEach((datum, index) => {
response[clientSettingsMap[properties[index]]] = datum[0];
let value = datum[0];
let settingsKey = clientSettingsMap[requestedSettingsKeys[index]];
if (!!outboundTransformation[settingsKey]) {
value = outboundTransformation[settingsKey](value);
}
response[settingsKey] = value;
});
return response;
@@ -216,7 +235,36 @@ var client = {
return;
}
request.add('setSettings', {settings: payloads});
let inboundTransformation = {
throttleGlobalDownMax: (userInput) => {
return {
id: userInput.id,
data: Number(userInput.data) * 1024
};
},
throttleGlobalUpMax: (userInput) => {
return {
id: userInput.id,
data: Number(userInput.data) * 1024
};
},
piecesMemoryMax: (userInput) => {
return {
id: userInput.id,
data: Number(userInput.data) * 1024 * 1024
};
}
};
let transformedPayloads = payloads.map((payload) => {
if (!!inboundTransformation[payload.id]) {
return inboundTransformation[payload.id](payload);
}
return payload;
});
request.add('setSettings', {settings: transformedPayloads});
request.onComplete(callback);
request.send();
},

View File

@@ -35,7 +35,7 @@ const clientSettingsMap = objectUtil.reflect({
sessionUseLock: 'session.use_lock',
systemFileSplitSize: 'system.file.split_size',
systemFileSplitSuffix: 'system.file.split_suffix',
throttleDownMax: 'throttle.global_down.max_rate',
throttleGlobalDownMax: 'throttle.global_down.max_rate',
throttleGlobalUpMax: 'throttle.global_up.max_rate',
throttleMaxDownloadsDiv: 'throttle.max_downloads.div',
throttleMaxDownloadsGlobal: 'throttle.max_downloads.global',
@@ -86,7 +86,7 @@ clientSettingsMap.defaults = [
'sessionUseLock',
'systemFileSplitSize',
'systemFileSplitSuffix',
'throttleDownMax',
'throttleGlobalDownMax',
'throttleGlobalUpMax',
'throttleMaxDownloadsDiv',
'throttleMaxDownloadsGlobal',