mirror of
https://github.com/zoriya/flood.git
synced 2026-06-05 19:54:18 +00:00
Handle default settings better
This commit is contained in:
@@ -89,17 +89,9 @@ $modal--body--foreground: desaturate(lighten($foreground, 20%), 10%);
|
|||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
height: 16px;
|
height: 16px;
|
||||||
margin: 0 $spacing-unit * 1/3;
|
margin: 0 $spacing-unit * 1/3 0 0;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,10 @@ $notification--foreground: #8fa2b2;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& + .notification {
|
||||||
|
margin-top: $spacing-unit * 2/5;
|
||||||
|
}
|
||||||
|
|
||||||
&__content {
|
&__content {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const SettingsActions = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
saveSettings: (settings) => {
|
saveSettings: (settings, options = {}) => {
|
||||||
return axios.patch('/client/settings', settings)
|
return axios.patch('/client/settings', settings)
|
||||||
.then((json = {}) => {
|
.then((json = {}) => {
|
||||||
return json.data;
|
return json.data;
|
||||||
@@ -32,11 +32,12 @@ const SettingsActions = {
|
|||||||
.then((data) => {
|
.then((data) => {
|
||||||
AppDispatcher.dispatchServerAction({
|
AppDispatcher.dispatchServerAction({
|
||||||
type: ActionTypes.SETTINGS_SAVE_REQUEST_SUCCESS,
|
type: ActionTypes.SETTINGS_SAVE_REQUEST_SUCCESS,
|
||||||
data
|
data,
|
||||||
|
options
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.trace(error);
|
||||||
AppDispatcher.dispatchServerAction({
|
AppDispatcher.dispatchServerAction({
|
||||||
type: ActionTypes.SETTINGS_SAVE_REQUEST_ERROR,
|
type: ActionTypes.SETTINGS_SAVE_REQUEST_ERROR,
|
||||||
error
|
error
|
||||||
|
|||||||
@@ -27,34 +27,10 @@ const UIActions = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
dismissModal: () => {
|
dismissModal: () => {
|
||||||
// TODO: Remove this try..catch.
|
AppDispatcher.dispatchUIAction({
|
||||||
try {
|
type: ActionTypes.UI_DISPLAY_MODAL,
|
||||||
AppDispatcher.dispatchUIAction({
|
data: null
|
||||||
type: ActionTypes.UI_DISPLAY_MODAL,
|
});
|
||||||
data: null
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
fetchSortProps: () => {
|
|
||||||
return axios.get('/ui/sort-props')
|
|
||||||
.then((json = {}) => {
|
|
||||||
return json.data;
|
|
||||||
})
|
|
||||||
.then((data) => {
|
|
||||||
AppDispatcher.dispatchServerAction({
|
|
||||||
type: ActionTypes.UI_SORT_PROPS_REQUEST_SUCCESS,
|
|
||||||
data
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
AppDispatcher.dispatchServerAction({
|
|
||||||
type: ActionTypes.UI_SORT_PROPS_REQUEST_ERROR,
|
|
||||||
error
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleDetailsClick: (data) => {
|
handleDetailsClick: (data) => {
|
||||||
@@ -93,12 +69,6 @@ const UIActions = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setTorrentsSort: (data) => {
|
setTorrentsSort: (data) => {
|
||||||
axios
|
|
||||||
.post('/ui/sort-props', data)
|
|
||||||
.catch(() => {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
AppDispatcher.dispatchUIAction({
|
AppDispatcher.dispatchUIAction({
|
||||||
type: ActionTypes.UI_SET_TORRENT_SORT,
|
type: ActionTypes.UI_SET_TORRENT_SORT,
|
||||||
data
|
data
|
||||||
|
|||||||
@@ -2,14 +2,16 @@ import classnames from 'classnames';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import EventTypes from '../../constants/EventTypes';
|
import EventTypes from '../../constants/EventTypes';
|
||||||
|
import LoadingIndicatorDots from '../icons/LoadingIndicatorDots';
|
||||||
import Modal from './Modal';
|
import Modal from './Modal';
|
||||||
import SettingsSpeedLimit from './SettingsSpeedLimit';
|
import SettingsSpeedLimit from './SettingsSpeedLimit';
|
||||||
import SettingsStore from '../../stores/SettingsStore';
|
import SettingsStore from '../../stores/SettingsStore';
|
||||||
|
|
||||||
const METHODS_TO_BIND = [
|
const METHODS_TO_BIND = [
|
||||||
'handleSettingsChange',
|
|
||||||
'handleSaveSettingsClick',
|
'handleSaveSettingsClick',
|
||||||
'handleSettingsFetchRequestSuccess'
|
'handleSaveSettingsError',
|
||||||
|
'handleSettingsChange',
|
||||||
|
'handleSettingsStoreChange'
|
||||||
];
|
];
|
||||||
|
|
||||||
export default class SettingsModal extends React.Component {
|
export default class SettingsModal extends React.Component {
|
||||||
@@ -17,12 +19,8 @@ export default class SettingsModal extends React.Component {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
settings: {
|
isSavingSettings: false,
|
||||||
speedLimits: {
|
settings: SettingsStore.getSettings()
|
||||||
download: null,
|
|
||||||
upload: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
METHODS_TO_BIND.forEach((method) => {
|
METHODS_TO_BIND.forEach((method) => {
|
||||||
@@ -31,21 +29,25 @@ export default class SettingsModal extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
SettingsStore.listen(EventTypes.SETTINGS_FETCH_REQUEST_SUCCESS, this.handleSettingsFetchRequestSuccess);
|
SettingsStore.listen(EventTypes.SETTINGS_CHANGE,
|
||||||
|
this.handleSettingsStoreChange);
|
||||||
|
SettingsStore.listen(EventTypes.SETTINGS_SAVE_REQUEST_ERROR,
|
||||||
|
this.handleSaveSettingsError);
|
||||||
SettingsStore.fetchSettings('speedLimits');
|
SettingsStore.fetchSettings('speedLimits');
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
SettingsStore.unlisten(EventTypes.SETTINGS_FETCH_REQUEST_SUCCESS, this.handleSettingsFetchRequestSuccess);
|
SettingsStore.unlisten(EventTypes.SETTINGS_CHANGE,
|
||||||
|
this.handleSettingsStoreChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
getActions() {
|
getActions() {
|
||||||
let icon = null;
|
let icon = null;
|
||||||
let primaryButtonText = 'Add Torrent';
|
let primaryButtonText = 'Save Settings';
|
||||||
|
|
||||||
if (this.state.isAddingTorrents) {
|
if (this.state.isSavingSettings) {
|
||||||
icon = <LoadingIndicatorDots viewBox="0 0 32 32" />;
|
icon = <LoadingIndicatorDots viewBox="0 0 32 32" />;
|
||||||
primaryButtonText = 'Adding...';
|
primaryButtonText = 'Saving...';
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@@ -57,7 +59,13 @@ export default class SettingsModal extends React.Component {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
clickHandler: this.handleSaveSettingsClick,
|
clickHandler: this.handleSaveSettingsClick,
|
||||||
content: 'Save Settings',
|
content: (
|
||||||
|
<span>
|
||||||
|
{icon}
|
||||||
|
{primaryButtonText}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
supplementalClassName: icon != null ? 'has-icon' : '',
|
||||||
triggerDismiss: false,
|
triggerDismiss: false,
|
||||||
type: 'primary'
|
type: 'primary'
|
||||||
}
|
}
|
||||||
@@ -65,6 +73,8 @@ export default class SettingsModal extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleSaveSettingsClick() {
|
handleSaveSettingsClick() {
|
||||||
|
this.setState({isSavingSettings: true});
|
||||||
|
|
||||||
let settingsToSave = Object.keys(this.state.settings).map((settingsKey) => {
|
let settingsToSave = Object.keys(this.state.settings).map((settingsKey) => {
|
||||||
return {
|
return {
|
||||||
id: settingsKey,
|
id: settingsKey,
|
||||||
@@ -72,14 +82,18 @@ export default class SettingsModal extends React.Component {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
SettingsStore.saveSettings(settingsToSave);
|
SettingsStore.saveSettings(settingsToSave, {dismissModal: true, notify: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSaveSettingsError() {
|
||||||
|
this.setState({isSavingSettings: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSettingsFetchRequestError(error) {
|
handleSettingsFetchRequestError(error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSettingsFetchRequestSuccess() {
|
handleSettingsStoreChange() {
|
||||||
this.setState({
|
this.setState({
|
||||||
settings: SettingsStore.getSettings()
|
settings: SettingsStore.getSettings()
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export default class SettingsSpeedLimit extends React.Component {
|
|||||||
getDownloadValue() {
|
getDownloadValue() {
|
||||||
let displayedValue = this.state.downloadValue;
|
let displayedValue = this.state.downloadValue;
|
||||||
|
|
||||||
if (displayedValue == null) {
|
if (displayedValue == null && this.props.settings.speedLimits != null) {
|
||||||
displayedValue = this.processSpeedsForDisplay(this.props.settings.speedLimits.download);
|
displayedValue = this.processSpeedsForDisplay(this.props.settings.speedLimits.download);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ export default class SettingsSpeedLimit extends React.Component {
|
|||||||
getUploadValue() {
|
getUploadValue() {
|
||||||
let displayedValue = this.state.uploadValue;
|
let displayedValue = this.state.uploadValue;
|
||||||
|
|
||||||
if (displayedValue == null) {
|
if (displayedValue == null && this.props.settings.speedLimits != null) {
|
||||||
displayedValue = this.processSpeedsForDisplay(this.props.settings.speedLimits.upload);
|
displayedValue = this.processSpeedsForDisplay(this.props.settings.speedLimits.upload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export default class Notification extends React.Component {
|
|||||||
icon = <CircleExclamationIcon />;
|
icon = <CircleExclamationIcon />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.count !== 1) {
|
if (!!this.props.accumulation && this.props.count !== 1) {
|
||||||
countText = (
|
countText = (
|
||||||
<span className="notification__count">
|
<span className="notification__count">
|
||||||
{this.props.count}
|
{this.props.count}
|
||||||
|
|||||||
@@ -10,14 +10,13 @@ import SettingsStore from '../../stores/SettingsStore';
|
|||||||
import TransferDataStore from '../../stores/TransferDataStore';
|
import TransferDataStore from '../../stores/TransferDataStore';
|
||||||
|
|
||||||
const METHODS_TO_BIND = ['handleSettingsFetchRequestSuccess', 'onTransferDataRequestSuccess'];
|
const METHODS_TO_BIND = ['handleSettingsFetchRequestSuccess', 'onTransferDataRequestSuccess'];
|
||||||
const DEFAULT_SPEEDS = [1024, 10240, 102400, 512000, 1048576, 2097152, 5242880, 10485760, 0];
|
|
||||||
|
|
||||||
class SpeedLimitDropdown extends React.Component {
|
class SpeedLimitDropdown extends React.Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
speedLimits: {},
|
speedLimits: SettingsStore.getSettings('speedLimits'),
|
||||||
throttle: null
|
throttle: null
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -27,27 +26,23 @@ class SpeedLimitDropdown extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
SettingsStore.listen(EventTypes.SETTINGS_FETCH_REQUEST_SUCCESS, this.handleSettingsFetchRequestSuccess);
|
SettingsStore.listen(EventTypes.SETTINGS_CHANGE,
|
||||||
|
this.handleSettingsFetchRequestSuccess);
|
||||||
|
TransferDataStore.listen(EventTypes.CLIENT_TRANSFER_DATA_REQUEST_SUCCESS,
|
||||||
|
this.onTransferDataRequestSuccess);
|
||||||
SettingsStore.fetchSettings('speedLimits');
|
SettingsStore.fetchSettings('speedLimits');
|
||||||
TransferDataStore.listen(
|
|
||||||
EventTypes.CLIENT_TRANSFER_DATA_REQUEST_SUCCESS,
|
|
||||||
this.onTransferDataRequestSuccess
|
|
||||||
);
|
|
||||||
TransferDataStore.fetchTransferData();
|
TransferDataStore.fetchTransferData();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
SettingsStore.unlisten(EventTypes.SETTINGS_FETCH_REQUEST_SUCCESS, this.handleSettingsFetchRequestSuccess);
|
SettingsStore.unlisten(EventTypes.SETTINGS_CHANGE,
|
||||||
TransferDataStore.unlisten(
|
this.handleSettingsFetchRequestSuccess);
|
||||||
EventTypes.CLIENT_TRANSFER_DATA_REQUEST_SUCCESS,
|
TransferDataStore.unlisten(EventTypes.CLIENT_TRANSFER_DATA_REQUEST_SUCCESS,
|
||||||
this.onTransferDataRequestSuccess
|
this.onTransferDataRequestSuccess);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onTransferDataRequestSuccess() {
|
onTransferDataRequestSuccess() {
|
||||||
this.setState({
|
this.setState({throttle: TransferDataStore.getThrottles({latest: true})});
|
||||||
throttle: TransferDataStore.getThrottles({latest: true})
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getDropdownHeader() {
|
getDropdownHeader() {
|
||||||
@@ -82,7 +77,7 @@ class SpeedLimitDropdown extends React.Component {
|
|||||||
|
|
||||||
let insertCurrentThrottle = true;
|
let insertCurrentThrottle = true;
|
||||||
let currentThrottle = this.state.throttle;
|
let currentThrottle = this.state.throttle;
|
||||||
let speeds = this.state.speedLimits[property] || DEFAULT_SPEEDS;
|
let speeds = this.state.speedLimits[property];
|
||||||
|
|
||||||
let items = speeds.map((bytes) => {
|
let items = speeds.map((bytes) => {
|
||||||
let selected = false;
|
let selected = false;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import Add from '../icons/Add';
|
|||||||
import EventTypes from '../../constants/EventTypes';
|
import EventTypes from '../../constants/EventTypes';
|
||||||
import PauseIcon from '../icons/PauseIcon';
|
import PauseIcon from '../icons/PauseIcon';
|
||||||
import Remove from '../icons/Remove';
|
import Remove from '../icons/Remove';
|
||||||
|
import SettingsStore from '../../stores/SettingsStore';
|
||||||
import SortDropdown from './SortDropdown';
|
import SortDropdown from './SortDropdown';
|
||||||
import StartIcon from '../icons/StartIcon';
|
import StartIcon from '../icons/StartIcon';
|
||||||
import StopIcon from '../icons/StopIcon';
|
import StopIcon from '../icons/StopIcon';
|
||||||
@@ -28,7 +29,7 @@ export default class ActionBar extends React.Component {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
sortBy: TorrentFilterStore.getTorrentsSort()
|
sortBy: SettingsStore.getSettings('sortTorrents')
|
||||||
};
|
};
|
||||||
|
|
||||||
METHODS_TO_BIND.forEach((method) => {
|
METHODS_TO_BIND.forEach((method) => {
|
||||||
@@ -37,12 +38,13 @@ export default class ActionBar extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
TorrentFilterStore.fetchSortProps();
|
this.onSortChange();
|
||||||
TorrentFilterStore.listen(EventTypes.UI_TORRENTS_SORT_CHANGE, this.onSortChange);
|
SettingsStore.listen(EventTypes.SETTINGS_CHANGE, this.onSortChange);
|
||||||
|
SettingsStore.fetchSettings('sortTorrents');
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_SORT_CHANGE, this.onSortChange);
|
SettingsStore.unlisten(EventTypes.SETTINGS_CHANGE, this.onSortChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAddTorrents() {
|
handleAddTorrents() {
|
||||||
@@ -97,6 +99,7 @@ export default class ActionBar extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleSortChange(sortBy) {
|
handleSortChange(sortBy) {
|
||||||
|
SettingsStore.saveSettings({id: 'sortTorrents', data: sortBy});
|
||||||
UIActions.setTorrentsSort(sortBy);
|
UIActions.setTorrentsSort(sortBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,9 +112,9 @@ export default class ActionBar extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onSortChange() {
|
onSortChange() {
|
||||||
this.setState({
|
let sortBy = SettingsStore.getSettings('sortTorrents');
|
||||||
sortBy: TorrentFilterStore.getTorrentsSort()
|
TorrentFilterStore.setTorrentsSort(sortBy);
|
||||||
});
|
this.setState({sortBy});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import CSSTransitionGroup from 'react-addons-css-transition-group';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Dropdown from '../forms/Dropdown';
|
import Dropdown from '../forms/Dropdown';
|
||||||
import UIActions from '../../actions/UIActions';
|
|
||||||
|
|
||||||
const METHODS_TO_BIND = [
|
const METHODS_TO_BIND = [
|
||||||
'getDropdownHeader',
|
'getDropdownHeader',
|
||||||
@@ -105,6 +104,10 @@ export default class SortDropdown extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
if (this.props.selectedItem == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
handleItemSelect={this.handleItemSelect}
|
handleItemSelect={this.handleItemSelect}
|
||||||
|
|||||||
@@ -17,8 +17,11 @@ const EventTypes = {
|
|||||||
CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS: 'CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS',
|
CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS: 'CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS',
|
||||||
CLIENT_TRANSFER_HISTORY_REQUEST_ERROR: 'CLIENT_TRANSFER_HISTORY_REQUEST_ERROR',
|
CLIENT_TRANSFER_HISTORY_REQUEST_ERROR: 'CLIENT_TRANSFER_HISTORY_REQUEST_ERROR',
|
||||||
NOTIFICATIONS_CHANGE: 'NOTIFICATIONS_CHANGE',
|
NOTIFICATIONS_CHANGE: 'NOTIFICATIONS_CHANGE',
|
||||||
SETTINGS_FETCH_REQUEST_SUCCESS: 'SETTINGS_FETCH_REQUEST_SUCCESS',
|
SETTINGS_CHANGE: 'SETTINGS_CHANGE',
|
||||||
|
SETTINGS_SAVE_REQUEST_ERROR: 'SETTINGS_SAVE_REQUEST_ERROR',
|
||||||
|
SETTINGS_SAVE_REQUEST_SUCCESS: 'SETTINGS_SAVE_REQUEST_SUCCESS',
|
||||||
SETTINGS_FETCH_REQUEST_ERROR: 'SETTINGS_FETCH_REQUEST_ERROR',
|
SETTINGS_FETCH_REQUEST_ERROR: 'SETTINGS_FETCH_REQUEST_ERROR',
|
||||||
|
SETTINGS_FETCH_REQUEST_SUCCESS: 'SETTINGS_FETCH_REQUEST_SUCCESS',
|
||||||
UI_CONTEXT_MENU_CHANGE: 'UI_CONTEXT_MENU_CHANGE',
|
UI_CONTEXT_MENU_CHANGE: 'UI_CONTEXT_MENU_CHANGE',
|
||||||
UI_DEPENDENCIES_LOADED: 'UI_DEPENDENCIES_LOADED',
|
UI_DEPENDENCIES_LOADED: 'UI_DEPENDENCIES_LOADED',
|
||||||
UI_MODAL_CHANGE: 'UI_MODAL_CHANGE',
|
UI_MODAL_CHANGE: 'UI_MODAL_CHANGE',
|
||||||
|
|||||||
@@ -2,11 +2,27 @@ import ActionTypes from '../constants/ActionTypes';
|
|||||||
import AppDispatcher from '../dispatcher/AppDispatcher';
|
import AppDispatcher from '../dispatcher/AppDispatcher';
|
||||||
import BaseStore from './BaseStore';
|
import BaseStore from './BaseStore';
|
||||||
import EventTypes from '../constants/EventTypes';
|
import EventTypes from '../constants/EventTypes';
|
||||||
|
import NotificationStore from './NotificationStore';
|
||||||
import SettingsActions from '../actions/SettingsActions';
|
import SettingsActions from '../actions/SettingsActions';
|
||||||
|
import UIStore from './UIStore';
|
||||||
|
|
||||||
class SettingsStoreClass extends BaseStore {
|
class SettingsStoreClass extends BaseStore {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
// Default settings are overridden by settings stored in database.
|
||||||
|
this.settings = {
|
||||||
|
sortTorrents: {
|
||||||
|
direction: 'desc',
|
||||||
|
displayName: 'Date Added',
|
||||||
|
property: 'sortBy',
|
||||||
|
value: 'added'
|
||||||
|
},
|
||||||
|
speedLimits: {
|
||||||
|
download: [1024, 10240, 102400, 512000, 1048576, 2097152, 5242880, 10485760, 0],
|
||||||
|
upload: [1024, 10240, 102400, 512000, 1048576, 2097152, 5242880, 10485760, 0]
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchSettings(property) {
|
fetchSettings(property) {
|
||||||
@@ -21,18 +37,44 @@ class SettingsStoreClass extends BaseStore {
|
|||||||
return this.settings;
|
return this.settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSettingsFetchSuccess(settings) {
|
|
||||||
this.settings = settings;
|
|
||||||
this.emit(EventTypes.SETTINGS_FETCH_REQUEST_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSettingsFetchError(error) {
|
handleSettingsFetchError(error) {
|
||||||
this.emit(EventTypes.SETTINGS_FETCH_REQUEST_ERROR);
|
this.emit(EventTypes.SETTINGS_FETCH_REQUEST_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
saveSettings(settings) {
|
handleSettingsFetchSuccess(settings) {
|
||||||
|
Object.keys(settings).forEach((property) => {
|
||||||
|
this.settings[property] = settings[property];
|
||||||
|
});
|
||||||
|
|
||||||
|
this.emit(EventTypes.SETTINGS_CHANGE);
|
||||||
|
this.emit(EventTypes.SETTINGS_FETCH_REQUEST_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSettingsSaveRequestError() {
|
||||||
|
this.emit(EventTypes.SETTINGS_SAVE_REQUEST_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSettingsSaveRequestSuccess(data, options = {}) {
|
||||||
|
this.emit(EventTypes.SETTINGS_SAVE_REQUEST_SUCCESS);
|
||||||
|
|
||||||
|
if (options.notify) {
|
||||||
|
NotificationStore.add({
|
||||||
|
adverb: 'Successfully',
|
||||||
|
action: 'saved',
|
||||||
|
subject: 'settings',
|
||||||
|
id: 'save-torrents-success'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.dismissModal) {
|
||||||
|
UIStore.dismissModal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
saveSettings(settings, options) {
|
||||||
this.settings[settings.id] = settings.data;
|
this.settings[settings.id] = settings.data;
|
||||||
SettingsActions.saveSettings(settings);
|
SettingsActions.saveSettings(settings, options);
|
||||||
|
this.emit(EventTypes.SETTINGS_CHANGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,6 +90,12 @@ SettingsStore.dispatcherID = AppDispatcher.register((payload) => {
|
|||||||
case ActionTypes.SETTINGS_FETCH_REQUEST_ERROR:
|
case ActionTypes.SETTINGS_FETCH_REQUEST_ERROR:
|
||||||
SettingsStore.handleSettingsFetchError(action.error);
|
SettingsStore.handleSettingsFetchError(action.error);
|
||||||
break;
|
break;
|
||||||
|
case ActionTypes.SETTINGS_SAVE_REQUEST_ERROR:
|
||||||
|
SettingsStore.handleSettingsSaveRequestError(action.error);
|
||||||
|
break;
|
||||||
|
case ActionTypes.SETTINGS_SAVE_REQUEST_SUCCESS:
|
||||||
|
SettingsStore.handleSettingsSaveRequestSuccess(action.data, action.options);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import ActionTypes from '../constants/ActionTypes';
|
|||||||
import AppDispatcher from '../dispatcher/AppDispatcher';
|
import AppDispatcher from '../dispatcher/AppDispatcher';
|
||||||
import BaseStore from './BaseStore';
|
import BaseStore from './BaseStore';
|
||||||
import EventTypes from '../constants/EventTypes';
|
import EventTypes from '../constants/EventTypes';
|
||||||
|
import SettingsStore from './SettingsStore';
|
||||||
import TorrentActions from '../actions/TorrentActions';
|
import TorrentActions from '../actions/TorrentActions';
|
||||||
import UIActions from '../actions/UIActions';
|
import UIActions from '../actions/UIActions';
|
||||||
|
|
||||||
@@ -12,16 +13,7 @@ class TorrentFilterStoreClass extends BaseStore {
|
|||||||
this.searchFilter = null;
|
this.searchFilter = null;
|
||||||
this.statusFilter = 'all';
|
this.statusFilter = 'all';
|
||||||
this.trackerFilter = 'all';
|
this.trackerFilter = 'all';
|
||||||
this.sortTorrentsBy = {
|
this.sortTorrentsBy = SettingsStore.getSettings('sortTorrents');
|
||||||
direction: 'desc',
|
|
||||||
displayName: 'Date Added',
|
|
||||||
property: 'sortBy',
|
|
||||||
value: 'added'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchSortProps() {
|
|
||||||
UIActions.fetchSortProps();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchTorrentStatusCount() {
|
fetchTorrentStatusCount() {
|
||||||
|
|||||||
@@ -104,7 +104,10 @@ class TorrentStoreClass extends BaseStore {
|
|||||||
handleAddTorrentSuccess(response) {
|
handleAddTorrentSuccess(response) {
|
||||||
this.emit(EventTypes.CLIENT_ADD_TORRENT_SUCCESS);
|
this.emit(EventTypes.CLIENT_ADD_TORRENT_SUCCESS);
|
||||||
|
|
||||||
SettingsStore.saveSettings({id: 'torrentDestination', data: response.destination});
|
SettingsStore.saveSettings({
|
||||||
|
id: 'torrentDestination',
|
||||||
|
data: response.destination
|
||||||
|
});
|
||||||
|
|
||||||
NotificationStore.add({
|
NotificationStore.add({
|
||||||
adverb: 'Successfully',
|
adverb: 'Successfully',
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ class UIStoreClass extends BaseStore {
|
|||||||
this.torrentDetailsHash = null;
|
this.torrentDetailsHash = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dismissModal() {
|
||||||
|
this.setActiveModal(null);
|
||||||
|
}
|
||||||
|
|
||||||
getActiveContextMenu() {
|
getActiveContextMenu() {
|
||||||
return this.activeContextMenu;
|
return this.activeContextMenu;
|
||||||
}
|
}
|
||||||
@@ -93,9 +97,9 @@ UIStore.dispatcherID = AppDispatcher.register((payload) => {
|
|||||||
case ActionTypes.UI_DISPLAY_MODAL:
|
case ActionTypes.UI_DISPLAY_MODAL:
|
||||||
UIStore.setActiveModal(action.data);
|
UIStore.setActiveModal(action.data);
|
||||||
break;
|
break;
|
||||||
case ActionTypes.CLIENT_MOVE_TORRENTS_SUCCESS:
|
|
||||||
case ActionTypes.CLIENT_ADD_TORRENT_SUCCESS:
|
case ActionTypes.CLIENT_ADD_TORRENT_SUCCESS:
|
||||||
UIStore.setActiveModal(null);
|
case ActionTypes.CLIENT_MOVE_TORRENTS_SUCCESS:
|
||||||
|
UIStore.dismissModal();
|
||||||
break;
|
break;
|
||||||
case ActionTypes.UI_DISPLAY_CONTEXT_MENU:
|
case ActionTypes.UI_DISPLAY_CONTEXT_MENU:
|
||||||
UIStore.setActiveContextMenu(action.data);
|
UIStore.setActiveContextMenu(action.data);
|
||||||
|
|||||||
+2
-4
@@ -9,8 +9,7 @@ var logger = require('morgan');
|
|||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
var clientRoutes = require('./routes/client');
|
var clientRoutes = require('./routes/client');
|
||||||
var uiRoutes = require('./routes/ui');
|
var mainRoutes = require('./routes/index');
|
||||||
var routes = require('./routes/index');
|
|
||||||
|
|
||||||
var app = express();
|
var app = express();
|
||||||
|
|
||||||
@@ -36,9 +35,8 @@ app.use((req, res, next) => {
|
|||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use('/', routes);
|
app.use('/', mainRoutes);
|
||||||
app.use('/client', clientRoutes);
|
app.use('/client', clientRoutes);
|
||||||
app.use('/ui', uiRoutes);
|
|
||||||
|
|
||||||
// catch 404 and forward to error handler
|
// catch 404 and forward to error handler
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
let Datastore = require('nedb');
|
|
||||||
|
|
||||||
let config = require('../../config');
|
|
||||||
|
|
||||||
let uiDB = new Datastore({
|
|
||||||
autoload: true,
|
|
||||||
filename: `${config.dbPath}uiSettings.db`
|
|
||||||
});
|
|
||||||
|
|
||||||
uiDB.persistence.setAutocompactionInterval(config.dbCleanInterval);
|
|
||||||
|
|
||||||
let getDbResponseHandler = (callback) => {
|
|
||||||
return (error, docs) => {
|
|
||||||
if (error) {
|
|
||||||
callback(null, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(docs)) {
|
|
||||||
callback(docs[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(docs);
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
let uiSettings = {
|
|
||||||
get: (type, callback) => {
|
|
||||||
uiDB.find({type}, getDbResponseHandler(callback));
|
|
||||||
},
|
|
||||||
|
|
||||||
set: (payload, callback) => {
|
|
||||||
let newLocationData = Object.assign({}, {type: payload.type}, {data: payload.data});
|
|
||||||
uiDB.update({type: payload.type, data: payload.data}, getDbResponseHandler(callback));
|
|
||||||
},
|
|
||||||
|
|
||||||
getLatestTorrentLocation: (callback) => {
|
|
||||||
try {
|
|
||||||
uiDB.find({type: 'location'}, getDbResponseHandler(callback));
|
|
||||||
} catch (e) { console.log(e); }
|
|
||||||
},
|
|
||||||
|
|
||||||
getSortProps: (callback) => {
|
|
||||||
uiDB.find({type: 'sort'}, getDbResponseHandler(callback));
|
|
||||||
},
|
|
||||||
|
|
||||||
setLatestTorrentLocation: (data, callback) => {
|
|
||||||
let newLocationData = Object.assign({}, {type: 'location'}, {path: data.destination});
|
|
||||||
uiDB.update({type: 'location'}, newLocationData, {upsert: true}, getDbResponseHandler(callback));
|
|
||||||
},
|
|
||||||
|
|
||||||
setSortProps: (sortProps, callback) => {
|
|
||||||
let newSortPropData = Object.assign({}, {type: 'sort'}, sortProps);
|
|
||||||
uiDB.update({type: 'sort'}, newSortPropData, {upsert: true}, getDbResponseHandler(callback));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = uiSettings;
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
let express = require('express');
|
|
||||||
let router = express.Router();
|
|
||||||
let xmlrpc = require('xmlrpc');
|
|
||||||
|
|
||||||
let ajaxUtil = require('../util/ajaxUtil');
|
|
||||||
let client = require('../models/client');
|
|
||||||
let history = require('../models/history');
|
|
||||||
let uiSettings = require('../models/uiSettings');
|
|
||||||
|
|
||||||
router.get('/settings', (req, res, next) => {
|
|
||||||
uiSettings.get(req.body.type, ajaxUtil.getResponseFn(res));
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/settings', (req, res, next) => {
|
|
||||||
uiSettings.set(req.body, ajaxUtil.getResponseFn(res));
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/sort-props', (req, res, next) => {
|
|
||||||
uiSettings.setSortProps(req.body, ajaxUtil.getResponseFn(res));
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/sort-props', (req, res, next) => {
|
|
||||||
uiSettings.getSortProps(ajaxUtil.getResponseFn(res));
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/torrent-location', (req, res, next) => {
|
|
||||||
uiSettings.getLatestTorrentLocation(ajaxUtil.getResponseFn(res));
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/torrent-location', (req, res, next) => {
|
|
||||||
uiSettings.setLatestTorrentLocation(req.body, ajaxUtil.getResponseFn(res));
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
Reference in New Issue
Block a user