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--background: #242b36;
$textbox--foreground: #5e728c; $textbox--foreground: #5e728c;

View File

@@ -4,7 +4,7 @@ $modal--heading--background: #303845;
$modal--heading--foreground: #a3bad4; $modal--heading--foreground: #a3bad4;
$modal--heading--border: #1a232c; $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--duration: 0.5s;
$modal--transition--scale: 0.85; $modal--transition--scale: 0.85;
@@ -379,13 +379,13 @@ $modal--tabs--in-body--background: #2a323e;
&__heading { &__heading {
color: $modal--heading--foreground; color: $modal--heading--foreground;
font-size: 0.9em; font-size: 0.925em;
font-weight: 500; font-weight: 500;
} }
&__sub-heading { &__sub-heading {
color: $modal--sub-heading--foreground; 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 EventTypes from '../../constants/EventTypes';
import LoadingIndicatorDots from '../icons/LoadingIndicatorDots'; import LoadingIndicatorDots from '../icons/LoadingIndicatorDots';
import Modal from './Modal'; import Modal from './Modal';
import ResourcesTab from '../settings/ResourcesTab';
import SettingsStore from '../../stores/SettingsStore'; import SettingsStore from '../../stores/SettingsStore';
import StorageTab from '../settings/StorageTab';
const METHODS_TO_BIND = [ const METHODS_TO_BIND = [
'handleClientSettingsChange', 'handleClientSettingsChange',
@@ -177,13 +177,13 @@ export default class SettingsModal extends React.Component {
}, },
label: 'Connectivity' label: 'Connectivity'
}, },
storage: { resources: {
content: StorageTab, content: ResourcesTab,
props: { props: {
onClientSettingsChange: this.handleClientSettingsChange, onClientSettingsChange: this.handleClientSettingsChange,
settings: this.state.clientSettings 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">
<div className="form__section"> <div className="form__section">
<p className="form__section__heading"> <p className="form__section__heading">
Speed Limit Dropdown Presets Transfer Rate Throttles
</p>
<p className="form__section__sub-heading">
Enter a comma-separated list of speeds in kB. 0 represents unlimited.
</p> </p>
<div className="form__row"> <div className="form__row">
<div className="form__column"> <div className="form__column">
<label className="form__label"> <label className="form__label">
Download Presets Dropdown Presets: Download
</label> </label>
<input className="textbox" type="text" <input className="textbox" type="text"
onChange={this.handleDownloadTextChange} onChange={this.handleDownloadTextChange}
value={downloadValue} /> value={downloadValue} />
</div> </div>
</div>
<div className="form__row">
<div className="form__column"> <div className="form__column">
<label className="form__label"> <label className="form__label">
Upload Presets Dropdown Presets: Upload
</label> </label>
<input className="textbox" type="text" <input className="textbox" type="text"
onChange={this.handleUploadTextChange} onChange={this.handleUploadTextChange}
value={uploadValue} /> value={uploadValue} />
</div> </div>
</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>
<div className="form__section"> <div className="form__section">
<div className="form__section__heading"> <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: case ActionTypes.CLIENT_SETTINGS_FETCH_REQUEST_SUCCESS:
SettingsStore.handleClientSettingsFetchSuccess(action.data); SettingsStore.handleClientSettingsFetchSuccess(action.data);
break; break;
case ActionTypes.CLIENT_SET_THROTTLE_SUCCESS:
SettingsStore.fetchClientSettings();
break;
case ActionTypes.SETTINGS_FETCH_REQUEST_ERROR: case ActionTypes.SETTINGS_FETCH_REQUEST_ERROR:
SettingsStore.handleSettingsFetchError(action.error); SettingsStore.handleSettingsFetchError(action.error);
break; break;

View File

@@ -93,10 +93,6 @@ class ClientRequest {
} }
send() { 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 handleSuccess = this.handleSuccess.bind(this);
let handleError = this.handleError.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. // Ensure client's response gets mapped to the correct requested keys.
if (options.setPropertiesArr) { if (options.setRequestedKeysArr) {
options.setPropertiesArr(requestedSettings); options.setRequestedKeysArr(requestedSettings);
} }
requestedSettings.forEach((settingsKey) => { requestedSettings.forEach((settingsKey) => {

View File

@@ -71,14 +71,26 @@ var client = {
}, },
getSettings: (options, callback) => { getSettings: (options, callback) => {
let properties = []; let requestedSettingsKeys = [];
let request = new ClientRequest(); let request = new ClientRequest();
let response = {}; 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', { request.add('fetchSettings', {
options, options,
setPropertiesArr: (propertiesArr) => { setRequestedKeysArr: (requestedSettingsKeysArr) => {
properties = propertiesArr; requestedSettingsKeys = requestedSettingsKeysArr;
} }
}); });
@@ -88,7 +100,14 @@ var client = {
} }
data.forEach((datum, index) => { 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; return response;
@@ -216,7 +235,36 @@ var client = {
return; 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.onComplete(callback);
request.send(); request.send();
}, },

View File

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