diff options
Diffstat (limited to 'web/react/components/user_settings/user_settings_appearance.jsx')
-rw-r--r-- | web/react/components/user_settings/user_settings_appearance.jsx | 261 |
1 files changed, 157 insertions, 104 deletions
diff --git a/web/react/components/user_settings/user_settings_appearance.jsx b/web/react/components/user_settings/user_settings_appearance.jsx index aec3b319d..7617f04d1 100644 --- a/web/react/components/user_settings/user_settings_appearance.jsx +++ b/web/react/components/user_settings/user_settings_appearance.jsx @@ -2,78 +2,119 @@ // See License.txt for license information. var UserStore = require('../../stores/user_store.jsx'); -var SettingItemMin = require('../setting_item_min.jsx'); -var SettingItemMax = require('../setting_item_max.jsx'); var Client = require('../../utils/client.jsx'); var Utils = require('../../utils/utils.jsx'); -var ThemeColors = ['#2389d7', '#008a17', '#dc4fad', '#ac193d', '#0072c6', '#d24726', '#ff8f32', '#82ba00', '#03b3b2', '#008299', '#4617b4', '#8c0095', '#004b8b', '#004b8b', '#570000', '#380000', '#585858', '#000000']; +const CustomThemeChooser = require('./custom_theme_chooser.jsx'); +const PremadeThemeChooser = require('./premade_theme_chooser.jsx'); +const AppDispatcher = require('../../dispatcher/app_dispatcher.jsx'); +const Constants = require('../../utils/constants.jsx'); +const ActionTypes = Constants.ActionTypes; export default class UserSettingsAppearance extends React.Component { constructor(props) { super(props); + this.onChange = this.onChange.bind(this); this.submitTheme = this.submitTheme.bind(this); this.updateTheme = this.updateTheme.bind(this); this.handleClose = this.handleClose.bind(this); + this.handleImportModal = this.handleImportModal.bind(this); this.state = this.getStateFromStores(); + + this.originalTheme = this.state.theme; + } + componentDidMount() { + UserStore.addChangeListener(this.onChange); + + if (this.props.activeSection === 'theme') { + $(React.findDOMNode(this.refs[this.state.theme])).addClass('active-border'); + } + $('#user_settings').on('hidden.bs.modal', this.handleClose); + } + componentDidUpdate() { + if (this.props.activeSection === 'theme') { + $('.color-btn').removeClass('active-border'); + $(React.findDOMNode(this.refs[this.state.theme])).addClass('active-border'); + } + } + componentWillUnmount() { + UserStore.removeChangeListener(this.onChange); + $('#user_settings').off('hidden.bs.modal', this.handleClose); } getStateFromStores() { - var user = UserStore.getCurrentUser(); - var theme = '#2389d7'; - if (ThemeColors != null) { - theme = ThemeColors[0]; + const user = UserStore.getCurrentUser(); + let theme = null; + + if ($.isPlainObject(user.theme_props) && !$.isEmptyObject(user.theme_props)) { + theme = user.theme_props; + } else { + theme = $.extend(true, {}, Constants.THEMES.default); } - if (user.props && user.props.theme) { - theme = user.props.theme; + + let type = 'premade'; + if (theme.type === 'custom') { + type = 'custom'; } - return {theme: theme.toLowerCase()}; + return {theme, type}; + } + onChange() { + const newState = this.getStateFromStores(); + + if (!Utils.areStatesEqual(this.state, newState)) { + this.setState(newState); + } } submitTheme(e) { e.preventDefault(); var user = UserStore.getCurrentUser(); - if (!user.props) { - user.props = {}; - } - user.props.theme = this.state.theme; + user.theme_props = this.state.theme; Client.updateUser(user, - function success() { - this.props.updateSection(''); - window.location.reload(); - }.bind(this), - function fail(err) { + (data) => { + AppDispatcher.handleServerAction({ + type: ActionTypes.RECIEVED_ME, + me: data + }); + + $('#user_settings').off('hidden.bs.modal', this.handleClose); + this.props.updateTab('general'); + $('#user_settings').modal('hide'); + }, + (err) => { var state = this.getStateFromStores(); state.serverError = err; this.setState(state); - }.bind(this) + } ); } - updateTheme(e) { - var hex = Utils.rgb2hex(e.target.style.backgroundColor); - this.setState({theme: hex.toLowerCase()}); + updateTheme(theme) { + this.setState({theme}); + Utils.applyTheme(theme); } - handleClose() { - this.setState({serverError: null}); - this.props.updateTab('general'); + updateType(type) { + this.setState({type}); } - componentDidMount() { - if (this.props.activeSection === 'theme') { - $(React.findDOMNode(this.refs[this.state.theme])).addClass('active-border'); - } - $('#user_settings').on('hidden.bs.modal', this.handleClose); - } - componentDidUpdate() { - if (this.props.activeSection === 'theme') { - $('.color-btn').removeClass('active-border'); - $(React.findDOMNode(this.refs[this.state.theme])).addClass('active-border'); - } + handleClose() { + const state = this.getStateFromStores(); + state.serverError = null; + + Utils.applyTheme(state.theme); + + this.setState(state); + + $('.ps-container.modal-body').scrollTop(0); + $('.ps-container.modal-body').perfectScrollbar('update'); + $('#user_settings').modal('hide'); } - componentWillUnmount() { - $('#user_settings').off('hidden.bs.modal', this.handleClose); - this.props.updateSection(''); + handleImportModal() { + $('#user_settings').modal('hide'); + AppDispatcher.handleViewAction({ + type: ActionTypes.TOGGLE_IMPORT_THEME_MODAL, + value: true + }); } render() { var serverError; @@ -81,67 +122,73 @@ export default class UserSettingsAppearance extends React.Component { serverError = this.state.serverError; } - var themeSection; - var self = this; - - if (ThemeColors != null) { - if (this.props.activeSection === 'theme') { - var themeButtons = []; - - for (var i = 0; i < ThemeColors.length; i++) { - themeButtons.push( - <button - key={ThemeColors[i] + 'key' + i} - ref={ThemeColors[i]} - type='button' - className='btn btn-lg color-btn' - style={{backgroundColor: ThemeColors[i]}} - onClick={this.updateTheme} - /> - ); - } - - var inputs = []; - - inputs.push( - <li - key='themeColorSetting' - className='setting-list-item' - > - <div - className='btn-group' - data-toggle='buttons-radio' - > - {themeButtons} - </div> - </li> - ); - - themeSection = ( - <SettingItemMax - title='Theme Color' - inputs={inputs} - submit={this.submitTheme} - serverError={serverError} - updateSection={function updateSection(e) { - self.props.updateSection(''); - e.preventDefault(); - }} - /> - ); - } else { - themeSection = ( - <SettingItemMin - title='Theme Color' - describe={this.state.theme} - updateSection={function updateSection() { - self.props.updateSection('theme'); - }} - /> - ); - } + const displayCustom = this.state.type === 'custom'; + + let custom; + let premade; + if (displayCustom) { + custom = ( + <CustomThemeChooser + theme={this.state.theme} + updateTheme={this.updateTheme} + /> + ); + } else { + premade = ( + <PremadeThemeChooser + theme={this.state.theme} + updateTheme={this.updateTheme} + /> + ); } + const themeUI = ( + <div className='section-max appearance-section'> + <div className='col-sm-12'> + <div className='radio'> + <label> + <input type='radio' + checked={!displayCustom} + onChange={this.updateType.bind(this, 'premade')} + > + {'Theme Colors'} + </input> + </label> + <br/> + </div> + {premade} + <div className='radio'> + <label> + <input type='radio' + checked={displayCustom} + onChange={this.updateType.bind(this, 'custom')} + > + {'Custom Theme'} + </input> + </label> + <br/> + </div> + {custom} + <hr /> + {serverError} + <a + className='btn btn-sm btn-primary' + href='#' + onClick={this.submitTheme} + > + {'Submit'} + </a> + <a + className='btn btn-sm theme' + href='#' + onClick={this.handleClose} + > + {'Cancel'} + </a> + </div> + </div> + ); + return ( <div> <div className='modal-header'> @@ -151,21 +198,28 @@ export default class UserSettingsAppearance extends React.Component { data-dismiss='modal' aria-label='Close' > - <span aria-hidden='true'>×</span> + <span aria-hidden='true'>{'×'}</span> </button> <h4 className='modal-title' ref='title' > - <i className='modal-back'></i>Appearance Settings + <i className='modal-back'></i>{'Appearance Settings'} </h4> </div> <div className='user-settings'> - <h3 className='tab-header'>Appearance Settings</h3> + <h3 className='tab-header'>{'Appearance Settings'}</h3> <div className='divider-dark first'/> - {themeSection} + {themeUI} <div className='divider-dark'/> </div> + <br/> + <a + className='theme' + onClick={this.handleImportModal} + > + {'Import from Slack'} + </a> </div> ); } @@ -176,6 +230,5 @@ UserSettingsAppearance.defaultProps = { }; UserSettingsAppearance.propTypes = { activeSection: React.PropTypes.string, - updateSection: React.PropTypes.func, updateTab: React.PropTypes.func }; |