From 899701d4b4b37df60cd7c2d8afc2782727adb2f9 Mon Sep 17 00:00:00 2001 From: John Furrow Date: Sat, 9 Jul 2016 00:12:18 -0700 Subject: [PATCH 1/4] Style dropdowns in SettingsModal --- client/sass/base/_form-elements.scss | 33 +++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/client/sass/base/_form-elements.scss b/client/sass/base/_form-elements.scss index c4234f8a..5526e768 100644 --- a/client/sass/base/_form-elements.scss +++ b/client/sass/base/_form-elements.scss @@ -1,5 +1,7 @@ $form--label--foreground: desaturate(lighten(#5c7087, 3%), 3%); +$form--element--border-radius: 4px; + $textbox--background: #242b36; $textbox--foreground: #5e728c; $textbox--placeholder: #424d5e; @@ -76,7 +78,7 @@ $interacative-list--item--icon--fill--hover: rgba(lighten($interacative-list--it .textbox { background: $textbox--background; - border-radius: 4px; + border-radius: $form--element--border-radius; border: 1px solid $textbox--border; color: $textbox--foreground; display: block; @@ -119,7 +121,7 @@ $interacative-list--item--icon--fill--hover: rgba(lighten($interacative-list--it .button { background: transparent; border: none; - border-radius: 4px; + border-radius: $form--element--border-radius; cursor: pointer; font-weight: 500; padding: 8px 22px; @@ -253,7 +255,7 @@ $interacative-list--item--icon--fill--hover: rgba(lighten($interacative-list--it .interactive-list { @extend .textbox; @extend .textbox.is-fulfilled; - border-radius: 4px; + border-radius: $form--element--border-radius; color: $interacative-list--item--foreground; padding: $spacing-unit * 1/2; @@ -384,6 +386,31 @@ $interacative-list--item--icon--fill--hover: rgba(lighten($interacative-list--it justify-content: center; padding-top: $spacing-unit * 3/5; } + + & > .dropdown { + + & > .dropdown { + + &__trigger { + + .dropdown { + + &__button { + @extend .button--deemphasize; + border-radius: $form--element--border-radius; + transition: background 0.25s, color 0.25s; + } + } + } + } + } + + .dropdown { + + &__button { + padding-top: 7px; + } + } } &__actions { From 044aa80d99dc9a25020c00aa02679fe0d7a6b1ef Mon Sep 17 00:00:00 2001 From: John Furrow Date: Sat, 9 Jul 2016 00:13:03 -0700 Subject: [PATCH 2/4] Listen for locale changes and re-render accordingly --- client/scripts/app.js | 70 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/client/scripts/app.js b/client/scripts/app.js index d1babe25..6602764d 100644 --- a/client/scripts/app.js +++ b/client/scripts/app.js @@ -5,32 +5,74 @@ import ReactDOM from 'react-dom'; import * as i18n from './i18n'; import Application from './components/Layout/Application'; +import EventTypes from './constants/EventTypes'; import Login from './views/Login'; import Register from './views/Register'; import SettingsStore from './stores/SettingsStore'; import TorrentList from './views/TorrentList'; +import UIStore from './stores/UIStore'; + +let appRoutes = ( + + + + + + + + + +); + +const METHODS_TO_BIND = ['handleSettingsChange']; class FloodApp extends React.Component { + constructor() { + super(); + + this.state = { + locale: SettingsStore.getFloodSettings('language') + }; + + METHODS_TO_BIND.forEach((method) => { + this[method] = this[method].bind(this); + }); + } + + componentWillMount() { + UIStore.registerDependency('flood-settings'); + } + + componentDidMount() { + SettingsStore.listen(EventTypes.SETTINGS_CHANGE, + this.handleSettingsChange); + } + + componentWillUnmount() { + SettingsStore.unlisten(EventTypes.SETTINGS_CHANGE, + this.handleSettingsChange); + } + + handleSettingsChange() { + if (SettingsStore.getFloodSettings('language') !== this.state.language) { + this.setState({locale: SettingsStore.getFloodSettings('language')}); + } + + UIStore.satisfyDependency('flood-settings'); + } + render() { + let {locale} = this.state; + return ( - - - - - - - - - + + {appRoutes} + ); } } -let locale = SettingsStore.getFloodSettings('language'); - ReactDOM.render( - - - , + , document.getElementById('app') ); From 09dd2f5361b696e2c6e6a79c51d274910c23f904 Mon Sep 17 00:00:00 2001 From: John Furrow Date: Sat, 9 Jul 2016 00:14:15 -0700 Subject: [PATCH 3/4] Load settings from databse only if defined --- client/scripts/stores/SettingsStore.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/scripts/stores/SettingsStore.js b/client/scripts/stores/SettingsStore.js index 62dbb059..fd82792d 100644 --- a/client/scripts/stores/SettingsStore.js +++ b/client/scripts/stores/SettingsStore.js @@ -93,7 +93,9 @@ class SettingsStoreClass extends BaseStore { this.fetchStatus.floodSettingsFetched = true; Object.keys(settings).forEach((property) => { - this.floodSettings[property] = settings[property]; + if (settings[property] != null) { + this.floodSettings[property] = settings[property]; + } }); this.emit(EventTypes.SETTINGS_FETCH_REQUEST_SUCCESS); From 88f969635f241e439c462606eaa13329251a1b87 Mon Sep 17 00:00:00 2001 From: John Furrow Date: Sat, 9 Jul 2016 00:14:58 -0700 Subject: [PATCH 4/4] Add UI settings --- .../components/Modals/SettingsModal/UITab.js | 93 +++++++++++++++++++ .../components/Modals/SettingsModal/index.js | 11 +++ client/scripts/constants/Languages.js | 12 +++ 3 files changed, 116 insertions(+) create mode 100644 client/scripts/components/Modals/SettingsModal/UITab.js create mode 100644 client/scripts/constants/Languages.js diff --git a/client/scripts/components/Modals/SettingsModal/UITab.js b/client/scripts/components/Modals/SettingsModal/UITab.js new file mode 100644 index 00000000..3d81a15c --- /dev/null +++ b/client/scripts/components/Modals/SettingsModal/UITab.js @@ -0,0 +1,93 @@ +import _ from 'lodash'; +import {formatMessage, FormattedMessage, injectIntl} from 'react-intl'; +import React from 'react'; + +import AuthStore from '../../../stores/AuthStore'; +import Checkbox from '../../General/FormElements/Checkbox'; +import Close from '../../Icons/Close'; +import Dropdown from '../../General/FormElements/Dropdown'; +import EventTypes from '../../../constants/EventTypes'; +import Languages from '../../../constants/Languages'; +import SettingsStore from '../../../stores/SettingsStore'; +import SettingsTab from './SettingsTab'; + +const METHODS_TO_BIND = [ + 'handleItemSelect' +]; + +class UITab extends SettingsTab { + constructor() { + super(...arguments); + + this.state = { + selectedLanguage: SettingsStore.getFloodSettings('language') + }; + + METHODS_TO_BIND.forEach((method) => { + this[method] = this[method].bind(this); + }); + } + + getDropdownHeader() { + return ( + + + + + + ); + } + + getDropdownMenu() { + let items = Object.keys(Languages).map((language) => { + return { + displayName: this.props.intl.formatMessage( + Languages[language] + ), + selected: this.state.selectedLanguage === language, + language + }; + }); + + // Dropdown expects an array of arrays. + return [items]; + } + + handleItemSelect(item) { + let {language} = item; + + this.setState({selectedLanguage: language}); + this.props.onSettingsChange({language}); + } + + render() { + return ( +
+
+
+ +
+
+
+ + +
+
+
+
+ ); + } +} + +export default injectIntl(UITab); diff --git a/client/scripts/components/Modals/SettingsModal/index.js b/client/scripts/components/Modals/SettingsModal/index.js index 45f9325f..3c206006 100644 --- a/client/scripts/components/Modals/SettingsModal/index.js +++ b/client/scripts/components/Modals/SettingsModal/index.js @@ -11,6 +11,7 @@ import LoadingIndicatorDots from '../../Icons/LoadingIndicatorDots'; import Modal from '../Modal'; import ResourcesTab from './ResourcesTab'; import SettingsStore from '../../../stores/SettingsStore'; +import UITab from './UITab'; const METHODS_TO_BIND = [ 'handleClientSettingsChange', @@ -213,6 +214,16 @@ class SettingsModal extends React.Component { id: 'settings.tabs.authentication', defaultMessage: 'Authentication' }) + }, + ui: { + content: UITab, + label: this.props.intl.formatMessage({ + id: 'settings.tabs.userinterface', + defaultMessage: 'User Interface' + }), + props: { + onSettingsChange: this.handleFloodSettingsChange + } } }; diff --git a/client/scripts/constants/Languages.js b/client/scripts/constants/Languages.js new file mode 100644 index 00000000..fe27fa5b --- /dev/null +++ b/client/scripts/constants/Languages.js @@ -0,0 +1,12 @@ +const Languages = { + en: { + defaultMessage: 'English', + id: 'locale.language.en' + }, + nl: { + defaultMessage: 'Nederlands', + id: 'locale.language.nl' + } +}; + +export default Languages;