diff options
Diffstat (limited to 'web/react/components')
-rw-r--r-- | web/react/components/channel_header.jsx | 2 | ||||
-rw-r--r-- | web/react/components/channel_info_modal.jsx | 2 | ||||
-rw-r--r-- | web/react/components/channel_invite_modal.jsx | 2 | ||||
-rw-r--r-- | web/react/components/channel_members.jsx | 2 | ||||
-rw-r--r-- | web/react/components/channel_notifications.jsx | 302 | ||||
-rw-r--r-- | web/react/components/edit_channel_modal.jsx | 2 | ||||
-rw-r--r-- | web/react/components/find_team.jsx | 4 | ||||
-rw-r--r-- | web/react/components/more_channels.jsx | 112 | ||||
-rw-r--r-- | web/react/components/navbar.jsx | 3 | ||||
-rw-r--r-- | web/react/components/post_list.jsx | 13 | ||||
-rw-r--r-- | web/react/components/removed_from_channel_modal.jsx | 20 | ||||
-rw-r--r-- | web/react/components/setting_item_max.jsx | 2 | ||||
-rw-r--r-- | web/react/components/setting_upload.jsx | 2 | ||||
-rw-r--r-- | web/react/components/team_import_tab.jsx | 4 | ||||
-rw-r--r-- | web/react/components/user_settings_notifications.jsx | 406 | ||||
-rw-r--r-- | web/react/components/user_settings_security.jsx | 10 | ||||
-rw-r--r-- | web/react/components/view_image.jsx | 32 |
17 files changed, 649 insertions, 271 deletions
diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx index 90a776791..0254d0e82 100644 --- a/web/react/components/channel_header.jsx +++ b/web/react/components/channel_header.jsx @@ -105,7 +105,7 @@ module.exports = React.createClass({ if (!utils.areStatesEqual(newState, this.state)) { this.setState(newState); } - $('.channel-header__info .description').popover({placement: 'bottom', trigger: 'hover', html: true, delay: {show: 500, hide: 500}}); + $('.channel-header__info .description').popover({placement: 'bottom', trigger: 'hover click', html: true, delay: {show: 500, hide: 500}}); }, onSocketChange: function(msg) { if (msg.action === 'new_user') { diff --git a/web/react/components/channel_info_modal.jsx b/web/react/components/channel_info_modal.jsx index 18addb52f..6d999870a 100644 --- a/web/react/components/channel_info_modal.jsx +++ b/web/react/components/channel_info_modal.jsx @@ -32,7 +32,7 @@ module.exports = React.createClass({ <div className="modal-content"> <div className="modal-header"> <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> - <h4 className="modal-title" id="myModalLabel">{channel.display_name}</h4> + <h4 className="modal-title" id="myModalLabel"><span className="name">{channel.display_name}</span></h4> </div> <div className="modal-body"> <div className="row form-group"> diff --git a/web/react/components/channel_invite_modal.jsx b/web/react/components/channel_invite_modal.jsx index d90522e8c..e446167ec 100644 --- a/web/react/components/channel_invite_modal.jsx +++ b/web/react/components/channel_invite_modal.jsx @@ -138,7 +138,7 @@ export default class ChannelInviteModal extends React.Component { <div className='modal-content'> <div className='modal-header'> <button type='button' className='close' data-dismiss='modal' aria-label='Close'><span aria-hidden='true'>×</span></button> - <h4 className='modal-title'>Add New Members to {this.state.channelName}</h4> + <h4 className='modal-title'>Add New Members to <span className='name'>{this.state.channel_name}</span></h4> </div> <div className='modal-body'> {inviteError} diff --git a/web/react/components/channel_members.jsx b/web/react/components/channel_members.jsx index cfb8ed41c..db4bec400 100644 --- a/web/react/components/channel_members.jsx +++ b/web/react/components/channel_members.jsx @@ -126,7 +126,7 @@ module.exports = React.createClass({ <div className="modal-content"> <div className="modal-header"> <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> - <h4 className="modal-title">{this.state.channel_name + " Members"}</h4> + <h4 className="modal-title"><span className="name">{this.state.channel_name}</span> Members</h4> <a className="btn btn-md btn-primary" data-toggle="modal" data-target="#channel_invite"><i className="glyphicon glyphicon-envelope"/> Add New Members</a> </div> <div ref="modalBody" className="modal-body"> diff --git a/web/react/components/channel_notifications.jsx b/web/react/components/channel_notifications.jsx index 38bc91682..884bad9d2 100644 --- a/web/react/components/channel_notifications.jsx +++ b/web/react/components/channel_notifications.jsx @@ -9,159 +9,230 @@ var client = require('../utils/client.jsx'); var UserStore = require('../stores/user_store.jsx'); var ChannelStore = require('../stores/channel_store.jsx'); -module.exports = React.createClass({ - componentDidMount: function() { - ChannelStore.addChangeListener(this._onChange); +export default class ChannelNotifications extends React.Component { + constructor(props) { + super(props); + this.onListenerChange = this.onListenerChange.bind(this); + this.updateSection = this.updateSection.bind(this); + this.handleUpdate = this.handleUpdate.bind(this); + this.handleRadioClick = this.handleRadioClick.bind(this); + this.handleQuietToggle = this.handleQuietToggle.bind(this); + this.state = {notifyLevel: '', title: '', channelId: '', activeSection: ''}; + } + componentDidMount() { + ChannelStore.addChangeListener(this.onListenerChange); var self = this; - $(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) { + $(this.refs.modal.getDOMNode()).on('show.bs.modal', function showModal(e) { var button = e.relatedTarget; - var channel_id = button.getAttribute('data-channelid'); + var channelId = button.getAttribute('data-channelid'); - var notifyLevel = ChannelStore.getMember(channel_id).notify_level; + var notifyLevel = ChannelStore.getMember(channelId).notify_level; var quietMode = false; - if (notifyLevel === "quiet") quietMode = true; - self.setState({ notify_level: notifyLevel, quiet_mode: quietMode, title: button.getAttribute('data-title'), channel_id: channel_id }); + + if (notifyLevel === 'quiet') { + quietMode = true; + } + + self.setState({notifyLevel: notifyLevel, quietMode: quietMode, title: button.getAttribute('data-title'), channelId: channelId}); }); - }, - componentWillUnmount: function() { - ChannelStore.removeChangeListener(this._onChange); - }, - _onChange: function() { - if (!this.state.channel_id) return; - var notifyLevel = ChannelStore.getMember(this.state.channel_id).notify_level; + } + componentWillUnmount() { + ChannelStore.removeChangeListener(this.onListenerChange); + } + onListenerChange() { + if (!this.state.channelId) { + return; + } + + var notifyLevel = ChannelStore.getMember(this.state.channelId).notify_level; var quietMode = false; - if (notifyLevel === "quiet") quietMode = true; + if (notifyLevel === 'quiet') { + quietMode = true; + } var newState = this.state; - newState.notify_level = notifyLevel; - newState.quiet_mode = quietMode; + newState.notifyLevel = notifyLevel; + newState.quietMode = quietMode; if (!utils.areStatesEqual(this.state, newState)) { this.setState(newState); } - }, - updateSection: function(section) { - this.setState({ activeSection: section }); - }, - getInitialState: function() { - return { notify_level: "", title: "", channel_id: "", activeSection: "" }; - }, - handleUpdate: function() { - var channel_id = this.state.channel_id; - var notify_level = this.state.quiet_mode ? "quiet" : this.state.notify_level; + } + updateSection(section) { + this.setState({activeSection: section}); + } + handleUpdate() { + var channelId = this.state.channelId; + var notifyLevel = this.state.notifyLevel; + if (this.state.quietMode) { + notifyLevel = 'quiet'; + } var data = {}; - data["channel_id"] = channel_id; - data["user_id"] = UserStore.getCurrentId(); - data["notify_level"] = notify_level; + data.channel_id = channelId; + data.user_id = UserStore.getCurrentId(); + data.notify_level = notifyLevel; - if (!data["notify_level"] || data["notify_level"].length === 0) return; + if (!data.notify_level || data.notify_level.length === 0) { + return; + } client.updateNotifyLevel(data, - function(data) { - var member = ChannelStore.getMember(channel_id); - member.notify_level = notify_level; + function success() { + var member = ChannelStore.getMember(channelId); + member.notify_level = notifyLevel; ChannelStore.setChannelMember(member); - this.updateSection(""); + this.updateSection(''); }.bind(this), - function(err) { - this.setState({ server_error: err.message }); + function error(err) { + this.setState({serverError: err.message}); }.bind(this) ); - }, - handleRadioClick: function(notifyLevel) { - this.setState({ notify_level: notifyLevel, quiet_mode: false }); + } + handleRadioClick(notifyLevel) { + this.setState({notifyLevel: notifyLevel, quietMode: false}); this.refs.modal.getDOMNode().focus(); - }, - handleQuietToggle: function(quietMode) { - this.setState({ notify_level: "none", quiet_mode: quietMode }); + } + handleQuietToggle(quietMode) { + this.setState({notifyLevel: 'none', quietMode: quietMode}); this.refs.modal.getDOMNode().focus(); - }, - render: function() { - var server_error = this.state.server_error ? <div className='form-group has-error'><label className='control-label'>{ this.state.server_error }</label></div> : null; + } + render() { + var serverError = null; + if (this.state.serverError) { + serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>; + } var self = this; + var describe = ''; + var inputs = []; + + var handleUpdateSection; var desktopSection; if (this.state.activeSection === 'desktop') { var notifyActive = [false, false, false]; - if (this.state.notify_level === "mention") { + if (this.state.notifyLevel === 'mention') { notifyActive[1] = true; - } else if (this.state.notify_level === "all") { + } else if (this.state.notifyLevel === 'all') { notifyActive[0] = true; } else { notifyActive[2] = true; } - var inputs = []; - inputs.push( <div> - <div className="radio"> + <div className='radio'> <label> - <input type="radio" checked={notifyActive[0]} onClick={function(){self.handleRadioClick("all")}}>For all activity</input> + <input + type='radio' + checked={notifyActive[0]} + onChange={self.handleRadioClick.bind(this, 'all')} + > + For all activity + </input> </label> <br/> </div> - <div className="radio"> + <div className='radio'> <label> - <input type="radio" checked={notifyActive[1]} onClick={function(){self.handleRadioClick("mention")}}>Only for mentions</input> + <input + type='radio' + checked={notifyActive[1]} + onChange={self.handleRadioClick.bind(this, 'mention')} + > + Only for mentions + </input> </label> <br/> </div> - <div className="radio"> + <div className='radio'> <label> - <input type="radio" checked={notifyActive[2]} onClick={function(){self.handleRadioClick("none")}}>Never</input> + <input + type='radio' + checked={notifyActive[2]} + onChange={self.handleRadioClick.bind(this, 'none')} + > + Never + </input> </label> </div> </div> ); + handleUpdateSection = function updateSection(e) { + self.updateSection(''); + self.onListenerChange(); + e.preventDefault(); + }; + desktopSection = ( <SettingItemMax - title="Send desktop notifications" + title='Send desktop notifications' inputs={inputs} submit={this.handleUpdate} - server_error={server_error} - updateSection={function(e){self.updateSection("");self._onChange();e.preventDefault();}} + server_error={serverError} + updateSection={handleUpdateSection} /> ); } else { - var describe = ""; - if (this.state.notify_level === "mention") { - describe = "Only for mentions"; - } else if (this.state.notify_level === "all") { - describe = "For all activity"; + if (this.state.notifyLevel === 'mention') { + describe = 'Only for mentions'; + } else if (this.state.notifyLevel === 'all') { + describe = 'For all activity'; } else { - describe = "Never"; + describe = 'Never'; } + handleUpdateSection = function updateSection(e) { + self.updateSection('desktop'); + e.preventDefault(); + }; + desktopSection = ( <SettingItemMin - title="Send desktop notifications" + title='Send desktop notifications' describe={describe} - updateSection={function(e){self.updateSection("desktop");e.preventDefault();}} + updateSection={handleUpdateSection} /> ); } var quietSection; if (this.state.activeSection === 'quiet') { - var quietActive = ["",""]; - if (this.state.quiet_mode) { - quietActive[0] = "active"; + var quietActive = [false, false]; + if (this.state.quietMode) { + quietActive[0] = true; } else { - quietActive[1] = "active"; + quietActive[1] = true; } - var inputs = []; - inputs.push( <div> - <div className="btn-group" data-toggle="buttons-radio"> - <button className={"btn btn-default "+quietActive[0]} onClick={function(){self.handleQuietToggle(true)}}>On</button> - <button className={"btn btn-default "+quietActive[1]} onClick={function(){self.handleQuietToggle(false)}}>Off</button> + <div className='radio'> + <label> + <input + type='radio' + checked={quietActive[0]} + onChange={self.handleQuietToggle.bind(this, true)} + > + On + </input> + </label> + <br/> + </div> + <div className='radio'> + <label> + <input + type='radio' + checked={quietActive[1]} + onChange={self.handleQuietToggle.bind(this, false)} + > + Off + </input> + </label> + <br/> </div> </div> ); @@ -173,62 +244,85 @@ module.exports = React.createClass({ </div> ); + handleUpdateSection = function updateSection(e) { + self.updateSection(''); + self.onListenerChange(); + e.preventDefault(); + }; + quietSection = ( <SettingItemMax - title="Quiet mode" + title='Quiet mode' inputs={inputs} submit={this.handleUpdate} - server_error={server_error} - updateSection={function(e){self.updateSection("");self._onChange();e.preventDefault();}} + server_error={serverError} + updateSection={handleUpdateSection} /> ); } else { - var describe = ""; - if (this.state.quiet_mode) { - describe = "On"; + if (this.state.quietMode) { + describe = 'On'; } else { - describe = "Off"; + describe = 'Off'; } + handleUpdateSection = function updateSection(e) { + self.updateSection('quiet'); + e.preventDefault(); + }; + quietSection = ( <SettingItemMin - title="Quiet mode" + title='Quiet mode' describe={describe} - updateSection={function(e){self.updateSection("quiet");e.preventDefault();}} + updateSection={handleUpdateSection} /> ); } - var self = this; return ( - <div className="modal fade" id="channel_notifications" ref="modal" tabIndex="-1" role="dialog" aria-hidden="true"> - <div className="modal-dialog settings-modal"> - <div className="modal-content"> - <div className="modal-header"> - <button type="button" className="close" data-dismiss="modal"> - <span aria-hidden="true">×</span> - <span className="sr-only">Close</span> + <div + className='modal fade' + id='channel_notifications' + ref='modal' + tabIndex='-1' + role='dialog' + aria-hidden='true' + > + <div className='modal-dialog settings-modal'> + <div className='modal-content'> + <div className='modal-header'> + <button + type='button' + className='close' + data-dismiss='modal' + > + <span aria-hidden='true'>×</span> + <span className='sr-only'>Close</span> </button> - <h4 className="modal-title">{"Notification Preferences for " + this.state.title}</h4> + <h4 className='modal-title'>Notification Preferences for <span className='name'>{this.state.title}</span></h4> </div> - <div className="modal-body"> - <div className="settings-table"> - <div className="settings-content"> - <div ref="wrapper" className="user-settings"> + <div className='modal-body'> + <div className='settings-table'> + <div className='settings-content'> + <div + ref='wrapper' + className='user-settings' + > <br/> - <div className="divider-dark first"/> + <div className='divider-dark first'/> {desktopSection} - <div className="divider-light"/> + <div className='divider-light'/> {quietSection} - <div className="divider-dark"/> + <div className='divider-dark'/> </div> </div> </div> - { server_error } + {serverError} </div> </div> </div> </div> ); } -}); +} diff --git a/web/react/components/edit_channel_modal.jsx b/web/react/components/edit_channel_modal.jsx index dcff5b89d..1a633b193 100644 --- a/web/react/components/edit_channel_modal.jsx +++ b/web/react/components/edit_channel_modal.jsx @@ -56,7 +56,7 @@ module.exports = React.createClass({ <div className="modal-content"> <div className="modal-header"> <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> - <h4 className="modal-title" ref="title">Edit {this.state.title} Description</h4> + <h4 className="modal-title" ref="title">Edit Description for {this.state.title}</h4> </div> <div className="modal-body"> <textarea className="form-control no-resize" rows="6" ref="channelDesc" maxLength="1024" value={this.state.description} onChange={this.handleUserInput}></textarea> diff --git a/web/react/components/find_team.jsx b/web/react/components/find_team.jsx index 91a842ffc..d896a1f12 100644 --- a/web/react/components/find_team.jsx +++ b/web/react/components/find_team.jsx @@ -47,7 +47,7 @@ module.exports = React.createClass({ return ( <div> <h4>{"Find Your " + utils.toTitleCase(strings.Team)}</h4> - <p>{"An email was sent with links to any " + strings.TeamPlural}</p> + <p>{"An email was sent with links to any " + strings.TeamPlural + " to which you are a member."}</p> </div> ); } @@ -56,7 +56,7 @@ module.exports = React.createClass({ <div> <h4>Find Your Team</h4> <form onSubmit={this.handleSubmit}> - <p>{"We'll send you an email with links to your " + strings.TeamPlural + "."}</p> + <p>{"Get an email with links to any " + strings.TeamPlural + " to which you are a member."}</p> <div className="form-group"> <label className='control-label'>Email</label> <div className={ email_error ? "form-group has-error" : "form-group" }> diff --git a/web/react/components/more_channels.jsx b/web/react/components/more_channels.jsx index 5261ed6a7..2b2c8b68d 100644 --- a/web/react/components/more_channels.jsx +++ b/web/react/components/more_channels.jsx @@ -14,11 +14,21 @@ function getStateFromStores() { }; } -module.exports = React.createClass({ - displayName: 'MoreChannelsModal', +export default class MoreChannels extends React.Component { + constructor(props) { + super(props); - componentDidMount: function() { - ChannelStore.addMoreChangeListener(this._onChange); + this.onListenerChange = this.onListenerChange.bind(this); + this.handleJoin = this.handleJoin.bind(this); + this.handleNewChannel = this.handleNewChannel.bind(this); + + var initState = getStateFromStores(); + initState.channelType = ''; + initState.joiningChannel = -1; + this.state = initState; + } + componentDidMount() { + ChannelStore.addMoreChangeListener(this.onListenerChange); $(this.refs.modal.getDOMNode()).on('shown.bs.modal', function shown() { asyncClient.getMoreChannels(true); }); @@ -28,43 +38,42 @@ module.exports = React.createClass({ var button = e.relatedTarget; self.setState({channelType: $(button).attr('data-channeltype')}); }); - }, - componentWillUnmount: function() { - ChannelStore.removeMoreChangeListener(this._onChange); - }, - _onChange: function() { + } + componentWillUnmount() { + ChannelStore.removeMoreChangeListener(this.onListenerChange); + } + onListenerChange() { var newState = getStateFromStores(); if (!utils.areStatesEqual(newState.channels, this.state.channels)) { this.setState(newState); } - }, - getInitialState: function() { - var initState = getStateFromStores(); - initState.channelType = ''; - return initState; - }, - handleJoin: function(id) { - client.joinChannel(id, - function() { + } + handleJoin(channel, channelIndex) { + this.setState({joiningChannel: channelIndex}); + client.joinChannel(channel.id, + function joinSuccess() { $(this.refs.modal.getDOMNode()).modal('hide'); - asyncClient.getChannel(id); + asyncClient.getChannel(channel.id); + utils.switchChannel(channel); + this.setState({joiningChannel: -1}); }.bind(this), - function(err) { + function joinFail(err) { + this.setState({joiningChannel: -1}); this.state.serverError = err.message; this.setState(this.state); }.bind(this) ); - }, - handleNewChannel: function() { + } + handleNewChannel() { $(this.refs.modal.getDOMNode()).modal('hide'); - }, - render: function() { + } + render() { var serverError; if (this.state.serverError) { serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>; } - var outter = this; + var self = this; var moreChannels; if (this.state.channels != null) { @@ -74,14 +83,29 @@ module.exports = React.createClass({ moreChannels = ( <table className='more-channel-table table'> <tbody> - {channels.map(function cMap(channel) { + {channels.map(function cMap(channel, index) { + var joinButton; + if (self.state.joiningChannel === index) { + joinButton = (<img + className='join-channel-loading-gif' + src='/static/images/load.gif' + />); + } else { + joinButton = (<button + onClick={self.handleJoin.bind(self, channel, index)} + className='btn btn-primary'>Join + </button>); + } + return ( <tr key={channel.id}> <td> <p className='more-channel-name'>{channel.display_name}</p> <p className='more-channel-description'>{channel.description}</p> </td> - <td className='td--action'><button onClick={outter.handleJoin.bind(outter, channel.id)} className='btn btn-primary'>Join</button></td> + <td className='td--action'> + {joinButton} + </td> </tr> ); })} @@ -102,23 +126,47 @@ module.exports = React.createClass({ } return ( - <div className='modal fade' id='more_channels' ref='modal' tabIndex='-1' role='dialog' aria-hidden='true'> + <div + className='modal fade' + id='more_channels' + ref='modal' + tabIndex='-1' + role='dialog' + aria-hidden='true' + > <div className='modal-dialog'> <div className='modal-content'> <div className='modal-header'> - <button type='button' className='close' data-dismiss='modal'> + <button + type='button' + className='close' + data-dismiss='modal' + > <span aria-hidden='true'>×</span> <span className='sr-only'>Close</span> </button> <h4 className='modal-title'>More Channels</h4> - <button data-toggle='modal' data-target='#new_channel' data-channeltype={this.state.channelType} type='button' className='btn btn-primary channel-create-btn' onClick={this.handleNewChannel}>Create New Channel</button> + <button + data-toggle='modal' + data-target='#new_channel' + data-channeltype={this.state.channelType} + type='button' + className='btn btn-primary channel-create-btn' + onClick={this.handleNewChannel}>Create New Channel + </button> </div> <div className='modal-body'> {moreChannels} {serverError} </div> <div className='modal-footer'> - <button type='button' className='btn btn-default' data-dismiss='modal'>Close</button> + <button + type='button' + className='btn btn-default' + data-dismiss='modal' + > + Close + </button> </div> </div> </div> @@ -126,4 +174,4 @@ module.exports = React.createClass({ ); } -}); +} diff --git a/web/react/components/navbar.jsx b/web/react/components/navbar.jsx index 3e0a66e92..06c373e5d 100644 --- a/web/react/components/navbar.jsx +++ b/web/react/components/navbar.jsx @@ -152,6 +152,8 @@ module.exports = React.createClass({ var channelMenuDropdown = null; if (channel) { + var viewInfoOption = <li role='presentation'><a role='menuitem' data-toggle='modal' data-target='#channel_info' data-channelid={channel.id} href='#'>View Info</a></li> + var addMembersOption = null; if (!isDirect && !ChannelStore.isDefault(channel)) { addMembersOption = <li role='presentation'><a role='menuitem' data-toggle='modal' data-target='#channel_invite' href='#'>Add Members</a></li>; @@ -192,6 +194,7 @@ module.exports = React.createClass({ <span className='glyphicon glyphicon-chevron-down header-dropdown__icon'></span> </a> <ul className='dropdown-menu' role='menu' aria-labelledby='channel_header_dropdown'> + {viewInfoOption} {addMembersOption} {manageMembersOption} {setChannelDescriptionOption} diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index 8b60f0251..7748f5c2a 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -75,6 +75,7 @@ module.exports = React.createClass({ utils.changeCss('.mention-link', 'color: ' + user.props.theme + ';'); utils.changeCss('@media(max-width: 768px){.search-bar__container', 'background: ' + user.props.theme + ';}'); utils.changeCss('.search-item-container:hover', 'background: ' + utils.changeOpacity(user.props.theme, 0.05) + ';'); + utils.changeCss('.nav-pills__unread-indicator', 'background: ' + utils.changeOpacity(user.props.theme, 0.05) + ';'); } if (user.props.theme !== '#000000' && user.props.theme !== '#585858') { @@ -377,8 +378,8 @@ module.exports = React.createClass({ <strong><UserProfile userId={teammate.id} /></strong> </div> <p className='channel-intro-text'> - {'This is the start of your private message history with ' + teammateName + '.'}<br/> - {'Private messages and files shared here are not shown to people outside this area.'} + This is the start of your private message history with <strong>{teammateName}</strong>.<br/> + Private messages and files shared here are not shown to people outside this area. </p> <a className='intro-links' href='#' style={userStyle} data-toggle='modal' data-target='#edit_channel' data-desc={channel.description} data-title={channel.display_name} data-channelid={channel.id}><i className='fa fa-pencil'></i>Set a description</a> </div> @@ -416,9 +417,9 @@ module.exports = React.createClass({ <div className='channel-intro'> <h4 className='channel-intro__title'>Beginning of {uiName}</h4> <p className='channel-intro__content'> - Welcome to {uiName}! + Welcome to <strong>{uiName}</strong>! <br/><br/> - {'This is the first channel ' + strings.Team + 'mates see when they'} + This is the first channel {strings.Team}mates see when they <br/> sign up - use it for posting updates everyone needs to know. <br/><br/> @@ -434,7 +435,7 @@ module.exports = React.createClass({ <div className='channel-intro'> <h4 className='channel-intro__title'>Beginning of {uiName}</h4> <p className='channel-intro__content'> - {'This is the start of ' + uiName + ', a channel for non-work-related conversations.'} + This is the start of <strong>{uiName}</strong>, a channel for non-work-related conversations. <br/> </p> <a className='intro-links' href='#' style={userStyle} data-toggle='modal' data-target='#edit_channel' data-desc={channel.description} data-title={uiName} data-channelid={channel.id}><i className='fa fa-pencil'></i>Set a description</a> @@ -453,7 +454,7 @@ module.exports = React.createClass({ var createMessage; if (creatorName !== '') { - createMessage = 'This is the start of the ' + uiName + ' ' + uiType + ', created by ' + creatorName + ' on ' + utils.displayDate(channel.create_at) + '.'; + createMessage = (<span>This is the start of the <strong>{uiName}</strong> {uiType}, created by <strong>{creatorName}</strong> on <strong>{utils.displayDate(channel.create_at)}</strong></span>); } else { createMessage = 'This is the start of the ' + uiName + ' ' + uiType + ', created on ' + utils.displayDate(channel.create_at) + '.'; } diff --git a/web/react/components/removed_from_channel_modal.jsx b/web/react/components/removed_from_channel_modal.jsx index a8889a92a..4a49e1c98 100644 --- a/web/react/components/removed_from_channel_modal.jsx +++ b/web/react/components/removed_from_channel_modal.jsx @@ -20,7 +20,7 @@ module.exports = React.createClass({ var townSquare = ChannelStore.getByName("town-square"); utils.switchChannel(townSquare); - this.setState({channelName: "", remover: ""}) + this.setState({channelName: "", remover: ""}); }, componentDidMount: function() { $(this.getDOMNode()).on('show.bs.modal',this.handleShow); @@ -40,18 +40,18 @@ module.exports = React.createClass({ if (currentUser != null) { return ( - <div className="modal fade" ref="modal" id="removed_from_channel" tabIndex="-1" role="dialog" aria-hidden="true"> - <div className="modal-dialog"> - <div className="modal-content"> - <div className="modal-header"> - <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> - <h4 className="modal-title">Removed from {channelName}</h4> + <div className='modal fade' ref='modal' id='removed_from_channel' tabIndex='-1' role='dialog' aria-hidden='true'> + <div className='modal-dialog'> + <div className='modal-content'> + <div className='modal-header'> + <button type='button' className='close' data-dismiss='modal' aria-label='Close'><span aria-hidden='true'>×</span></button> + <h4 className='modal-title'>Removed from <span className='name'>{channelName}</span></h4> </div> - <div className="modal-body"> + <div className='modal-body'> <p>{remover} removed you from {channelName}</p> </div> - <div className="modal-footer"> - <button type="button" className="btn btn-primary" data-dismiss="modal">Okay</button> + <div className='modal-footer'> + <button type='button' className='btn btn-primary' data-dismiss='modal'>Okay</button> </div> </div> </div> diff --git a/web/react/components/setting_item_max.jsx b/web/react/components/setting_item_max.jsx index fd95b8b32..1599041b0 100644 --- a/web/react/components/setting_item_max.jsx +++ b/web/react/components/setting_item_max.jsx @@ -20,7 +20,7 @@ module.exports = React.createClass({ <hr /> { server_error } { clientError } - { this.props.submit ? <a className="btn btn-sm btn-primary" onClick={this.props.submit}>Submit</a> : "" } + { this.props.submit ? <a className="btn btn-sm btn-primary" href="#" onClick={this.props.submit}>Submit</a> : "" } <a className="btn btn-sm theme" href="#" onClick={this.props.updateSection}>Cancel</a> </li> </ul> diff --git a/web/react/components/setting_upload.jsx b/web/react/components/setting_upload.jsx index 870710850..83b6d85fc 100644 --- a/web/react/components/setting_upload.jsx +++ b/web/react/components/setting_upload.jsx @@ -67,7 +67,7 @@ module.exports = React.createClass({ <li className='setting-list-item'> {serverError} {clientError} - <span className='btn btn-sm btn-primary btn-file sel-btn'>SelectFile<input ref='uploadinput' accept={this.props.fileTypesAccepted} type='file' onChange={this.onFileSelect}/></span> + <span className='btn btn-sm btn-primary btn-file sel-btn'>Select File<input ref='uploadinput' accept={this.props.fileTypesAccepted} type='file' onChange={this.onFileSelect}/></span> <a className={'btn btn-sm btn-primary'} onClick={this.doSubmit}>Import</a> <a className='btn btn-sm theme' href='#' onClick={this.doCancel}>Cancel</a> </li> diff --git a/web/react/components/team_import_tab.jsx b/web/react/components/team_import_tab.jsx index 131add999..ae7f875cb 100644 --- a/web/react/components/team_import_tab.jsx +++ b/web/react/components/team_import_tab.jsx @@ -39,12 +39,12 @@ module.exports = React.createClass({ break; case 'done': messageSection = ( - <p>Import sucessfull: <a href={this.state.link} download='MattermostImportSummery.txt'>View Summery</a></p> + <p>Import sucessfull: <a href={this.state.link} download='MattermostImportSummary.txt'>View Summary</a></p> ); break; case 'fail': messageSection = ( - <p>Import failure: <a href={this.state.link} download='MattermostImportSummery.txt'>View Summery</a></p> + <p>Import failure: <a href={this.state.link} download='MattermostImportSummary.txt'>View Summary</a></p> ); break; } diff --git a/web/react/components/user_settings_notifications.jsx b/web/react/components/user_settings_notifications.jsx index 33ae01eaa..6637bbcb5 100644 --- a/web/react/components/user_settings_notifications.jsx +++ b/web/react/components/user_settings_notifications.jsx @@ -67,16 +67,28 @@ function getNotificationsStateFromStores() { return {notifyLevel: desktop, enableEmail: email, soundNeeded: soundNeeded, enableSound: sound, usernameKey: usernameKey, mentionKey: mentionKey, customKeys: customKeys, customKeysChecked: customKeys.length > 0, firstNameKey: firstNameKey, allKey: allKey, channelKey: channelKey}; } -module.exports = React.createClass({ - displayName: 'NotificationsTab', - propTypes: { - user: React.PropTypes.object, - updateSection: React.PropTypes.func, - updateTab: React.PropTypes.func, - activeSection: React.PropTypes.string, - activeTab: React.PropTypes.string - }, - handleSubmit: function() { +export default class NotificationsTab extends React.Component { + constructor(props) { + super(props); + + this.handleSubmit = this.handleSubmit.bind(this); + this.handleClose = this.handleClose.bind(this); + this.updateSection = this.updateSection.bind(this); + this.onListenerChange = this.onListenerChange.bind(this); + this.handleNotifyRadio = this.handleNotifyRadio.bind(this); + this.handleEmailRadio = this.handleEmailRadio.bind(this); + this.handleSoundRadio = this.handleSoundRadio.bind(this); + this.updateUsernameKey = this.updateUsernameKey.bind(this); + this.updateMentionKey = this.updateMentionKey.bind(this); + this.updateFirstNameKey = this.updateFirstNameKey.bind(this); + this.updateAllKey = this.updateAllKey.bind(this); + this.updateChannelKey = this.updateChannelKey.bind(this); + this.updateCustomMentionKeys = this.updateCustomMentionKeys.bind(this); + this.onCustomChange = this.onCustomChange.bind(this); + + this.state = getNotificationsStateFromStores(); + } + handleSubmit() { var data = {}; data.user_id = this.props.user.id; data.email = this.state.enableEmail; @@ -110,66 +122,63 @@ module.exports = React.createClass({ this.setState({serverError: err.message}); }.bind(this) ); - }, - handleClose: function() { - $(this.getDOMNode()).find('.form-control').each(function clearField() { + } + handleClose() { + $(React.findDOMNode(this)).find('.form-control').each(function clearField() { this.value = ''; }); this.setState(assign({}, getNotificationsStateFromStores(), {serverError: null})); this.props.updateTab('general'); - }, - updateSection: function(section) { + } + updateSection(section) { this.setState(this.getInitialState()); this.props.updateSection(section); - }, - componentDidMount: function() { + } + componentDidMount() { UserStore.addChangeListener(this.onListenerChange); $('#user_settings').on('hidden.bs.modal', this.handleClose); - }, - componentWillUnmount: function() { + } + componentWillUnmount() { UserStore.removeChangeListener(this.onListenerChange); $('#user_settings').off('hidden.bs.modal', this.handleClose); this.props.updateSection(''); - }, - onListenerChange: function() { + } + onListenerChange() { var newState = getNotificationsStateFromStores(); if (!utils.areStatesEqual(newState, this.state)) { this.setState(newState); } - }, - getInitialState: function() { - return getNotificationsStateFromStores(); - }, - handleNotifyRadio: function(notifyLevel) { + } + handleNotifyRadio(notifyLevel) { this.setState({notifyLevel: notifyLevel}); this.refs.wrapper.getDOMNode().focus(); - }, - handleEmailRadio: function(enableEmail) { + } + handleEmailRadio(enableEmail) { this.setState({enableEmail: enableEmail}); this.refs.wrapper.getDOMNode().focus(); - }, - handleSoundRadio: function(enableSound) { + } + handleSoundRadio(enableSound) { this.setState({enableSound: enableSound}); this.refs.wrapper.getDOMNode().focus(); - }, - updateUsernameKey: function(val) { + } + updateUsernameKey(val) { this.setState({usernameKey: val}); - }, - updateMentionKey: function(val) { + } + updateMentionKey(val) { this.setState({mentionKey: val}); - }, - updateFirstNameKey: function(val) { + } + updateFirstNameKey(val) { this.setState({firstNameKey: val}); - }, - updateAllKey: function(val) { + } + updateAllKey(val) { this.setState({allKey: val}); - }, - updateChannelKey: function(val) { + } + updateChannelKey(val) { this.setState({channelKey: val}); - }, - updateCustomMentionKeys: function() { + } + updateCustomMentionKeys() { var checked = this.refs.customcheck.getDOMNode().checked; if (checked) { @@ -180,12 +189,12 @@ module.exports = React.createClass({ } else { this.setState({customKeys: '', customKeysChecked: false}); } - }, - onCustomChange: function() { + } + onCustomChange() { this.refs.customcheck.getDOMNode().checked = true; this.updateCustomMentionKeys(); - }, - render: function() { + } + render() { var serverError = null; if (this.state.serverError) { serverError = this.state.serverError; @@ -196,6 +205,7 @@ module.exports = React.createClass({ var user = this.props.user; var desktopSection; + var handleUpdateDesktopSection; if (this.props.activeSection === 'desktop') { var notifyActive = [false, false, false]; if (this.state.notifyLevel === 'mention') { @@ -206,41 +216,63 @@ module.exports = React.createClass({ notifyActive[0] = true; } - var inputs = []; + let inputs = []; inputs.push( <div> <div className='radio'> <label> - <input type='radio' checked={notifyActive[0]} onClick={function(){self.handleNotifyRadio('all')}}>For all activity</input> + <input type='radio' + checked={notifyActive[0]} + onChange={self.handleNotifyRadio.bind(this, 'all')} + > + For all activity + </input> </label> <br/> </div> <div className='radio'> <label> - <input type='radio' checked={notifyActive[1]} onClick={function(){self.handleNotifyRadio('mention')}}>Only for mentions and private messages</input> + <input + type='radio' + checked={notifyActive[1]} + onChange={self.handleNotifyRadio.bind(this, 'mention')} + > + Only for mentions and private messages + </input> </label> <br/> </div> <div className='radio'> <label> - <input type='radio' checked={notifyActive[2]} onClick={function(){self.handleNotifyRadio('none')}}>Never</input> + <input + type='radio' + checked={notifyActive[2]} + onChange={self.handleNotifyRadio.bind(this, 'none')} + > + Never + </input> </label> </div> </div> ); + handleUpdateDesktopSection = function updateDesktopSection(e) { + self.props.updateSection(''); + e.preventDefault(); + }; + desktopSection = ( <SettingItemMax title='Send desktop notifications' inputs={inputs} submit={this.handleSubmit} server_error={serverError} - updateSection={function(e){self.updateSection('');e.preventDefault();}} + updateSection={handleUpdateDesktopSection} /> ); } else { - var describe = ''; + let describe = ''; if (this.state.notifyLevel === 'mention') { describe = 'Only for mentions and private messages'; } else if (this.state.notifyLevel === 'none') { @@ -249,162 +281,278 @@ module.exports = React.createClass({ describe = 'For all activity'; } + handleUpdateDesktopSection = function updateDesktopSection() { + self.props.updateSection('desktop'); + }; + desktopSection = ( <SettingItemMin title='Send desktop notifications' describe={describe} - updateSection={function(){self.updateSection('desktop');}} + updateSection={handleUpdateDesktopSection} /> ); } var soundSection; + var handleUpdateSoundSection; if (this.props.activeSection === 'sound' && this.state.soundNeeded) { - var soundActive = ['', '']; + var soundActive = [false, false]; if (this.state.enableSound === 'false') { - soundActive[1] = 'active'; + soundActive[1] = true; } else { - soundActive[0] = 'active'; + soundActive[0] = true; } - var inputs = []; + let inputs = []; inputs.push( <div> - <div className='btn-group' data-toggle='buttons-radio'> - <button className={'btn btn-default '+soundActive[0]} onClick={function(){self.handleSoundRadio('true')}}>On</button> - <button className={'btn btn-default '+soundActive[1]} onClick={function(){self.handleSoundRadio('false')}}>Off</button> + <div className='radio'> + <label> + <input + type='radio' + checked={soundActive[0]} + onChange={self.handleSoundRadio.bind(this, 'true')} + > + On + </input> + </label> + <br/> </div> - </div> + <div className='radio'> + <label> + <input + type='radio' + checked={soundActive[1]} + onChange={self.handleSoundRadio.bind(this, 'false')} + > + Off + </input> + </label> + <br/> + </div> + </div> ); + handleUpdateSoundSection = function updateSoundSection(e) { + self.props.updateSection(''); + e.preventDefault(); + }; + soundSection = ( <SettingItemMax title='Desktop notification sounds' inputs={inputs} submit={this.handleSubmit} server_error={serverError} - updateSection={function(e){self.updateSection('');e.preventDefault();}} + updateSection={handleUpdateSoundSection} /> ); } else { - var describe = ''; + let describe = ''; if (!this.state.soundNeeded) { - describe = 'Please configure notification sounds in your browser settings' + describe = 'Please configure notification sounds in your browser settings'; } else if (this.state.enableSound === 'false') { describe = 'Off'; } else { describe = 'On'; } + handleUpdateSoundSection = function updateSoundSection() { + self.props.updateSection('sound'); + }; + soundSection = ( <SettingItemMin title='Desktop notification sounds' describe={describe} - updateSection={function(){self.updateSection('sound');}} + updateSection={handleUpdateSoundSection} disableOpen = {!this.state.soundNeeded} /> ); } var emailSection; + var handleUpdateEmailSection; if (this.props.activeSection === 'email') { - var emailActive = ['','']; + var emailActive = [false, false]; if (this.state.enableEmail === 'false') { - emailActive[1] = 'active'; + emailActive[1] = true; } else { - emailActive[0] = 'active'; + emailActive[0] = true; } - var inputs = []; + let inputs = []; inputs.push( <div> - <div className='btn-group' data-toggle='buttons-radio'> - <button className={'btn btn-default '+emailActive[0]} onClick={function(){self.handleEmailRadio('true')}}>On</button> - <button className={'btn btn-default '+emailActive[1]} onClick={function(){self.handleEmailRadio('false')}}>Off</button> + <div className='radio'> + <label> + <input + type='radio' + checked={emailActive[0]} + onChange={self.handleEmailRadio.bind(this, 'true')} + > + On + </input> + </label> + <br/> + </div> + <div className='radio'> + <label> + <input + type='radio' + checked={emailActive[1]} + onChange={self.handleEmailRadio.bind(this, 'false')} + > + Off + </input> + </label> + <br/> </div> <div><br/>{'Email notifications are sent for mentions and private messages after you have been away from ' + config.SiteName + ' for 5 minutes.'}</div> </div> ); + handleUpdateEmailSection = function updateEmailSection(e) { + self.props.updateSection(''); + e.preventDefault(); + }; + emailSection = ( <SettingItemMax title='Email notifications' inputs={inputs} submit={this.handleSubmit} server_error={serverError} - updateSection={function(e){self.updateSection('');e.preventDefault();}} + updateSection={handleUpdateEmailSection} /> ); } else { - var describe = ''; + let describe = ''; if (this.state.enableEmail === 'false') { describe = 'Off'; } else { describe = 'On'; } + handleUpdateEmailSection = function updateEmailSection() { + self.props.updateSection('email'); + }; + emailSection = ( <SettingItemMin title='Email notifications' describe={describe} - updateSection={function(){self.updateSection('email');}} + updateSection={handleUpdateEmailSection} /> ); } var keysSection; + var handleUpdateKeysSection; if (this.props.activeSection === 'keys') { - var inputs = []; + let inputs = []; + + let handleUpdateFirstNameKey; + let handleUpdateUsernameKey; + let handleUpdateMentionKey; + let handleUpdateAllKey; + let handleUpdateChannelKey; if (user.first_name) { + handleUpdateFirstNameKey = function handleFirstNameKeyChange(e) { + self.updateFirstNameKey(e.target.checked); + }; inputs.push( <div> <div className='checkbox'> <label> - <input type='checkbox' checked={this.state.firstNameKey} onChange={function(e){self.updateFirstNameKey(e.target.checked);}}>{'Your case sensitive first name "' + user.first_name + '"'}</input> + <input + type='checkbox' + checked={this.state.firstNameKey} + onChange={handleUpdateFirstNameKey} + > + {'Your case sensitive first name "' + user.first_name + '"'} + </input> </label> </div> </div> ); } + handleUpdateUsernameKey = function handleUsernameKeyChange(e) { + self.updateUsernameKey(e.target.checked); + }; inputs.push( <div> <div className='checkbox'> <label> - <input type='checkbox' checked={this.state.usernameKey} onChange={function(e){self.updateUsernameKey(e.target.checked);}}>{'Your non-case sensitive username "' + user.username + '"'}</input> + <input + type='checkbox' + checked={this.state.usernameKey} + onChange={handleUpdateUsernameKey} + > + {'Your non-case sensitive username "' + user.username + '"'} + </input> </label> </div> </div> ); + handleUpdateMentionKey = function handleMentionKeyChange(e) { + self.updateMentionKey(e.target.checked); + }; inputs.push( <div> <div className='checkbox'> <label> - <input type='checkbox' checked={this.state.mentionKey} onChange={function(e){self.updateMentionKey(e.target.checked);}}>{'Your username mentioned "@' + user.username + '"'}</input> + <input + type='checkbox' + checked={this.state.mentionKey} + onChange={handleUpdateMentionKey} + > + {'Your username mentioned "@' + user.username + '"'} + </input> </label> </div> </div> ); + handleUpdateAllKey = function handleAllKeyChange(e) { + self.updateAllKey(e.target.checked); + }; inputs.push( <div> <div className='checkbox'> <label> - <input type='checkbox' checked={this.state.allKey} onChange={function(e){self.updateAllKey(e.target.checked);}}>{'Team-wide mentions "@all"'}</input> + <input + type='checkbox' + checked={this.state.allKey} + onChange={handleUpdateAllKey} + > + {'Team-wide mentions "@all"'} + </input> </label> </div> </div> ); + handleUpdateChannelKey = function handleChannelKeyChange(e) { + self.updateChannelKey(e.target.checked); + }; inputs.push( <div> <div className='checkbox'> <label> - <input type='checkbox' checked={this.state.channelKey} onChange={function(e){self.updateChannelKey(e.target.checked);}}>{'Channel-wide mentions "@channel"'}</input> + <input + type='checkbox' + checked={this.state.channelKey} + onChange={handleUpdateChannelKey} + > + {'Channel-wide mentions "@channel"'} + </input> </label> </div> </div> @@ -414,32 +562,61 @@ module.exports = React.createClass({ <div> <div className='checkbox'> <label> - <input ref='customcheck' type='checkbox' checked={this.state.customKeysChecked} onChange={this.updateCustomMentionKeys}>{'Other non-case sensitive words, separated by commas:'}</input> + <input + ref='customcheck' + type='checkbox' + checked={this.state.customKeysChecked} + onChange={this.updateCustomMentionKeys} + > + {'Other non-case sensitive words, separated by commas:'} + </input> </label> </div> - <input ref='custommentions' className='form-control mentions-input' type='text' defaultValue={this.state.customKeys} onChange={this.onCustomChange} /> + <input + ref='custommentions' + className='form-control mentions-input' + type='text' + defaultValue={this.state.customKeys} + onChange={this.onCustomChange} + /> </div> ); + handleUpdateKeysSection = function updateKeysSection(e) { + self.props.updateSection(''); + e.preventDefault(); + }; keysSection = ( <SettingItemMax title='Words that trigger mentions' inputs={inputs} submit={this.handleSubmit} server_error={serverError} - updateSection={function(e){self.updateSection('');e.preventDefault();}} + updateSection={handleUpdateKeysSection} /> ); } else { - var keys = []; - if (this.state.firstNameKey) keys.push(user.first_name); - if (this.state.usernameKey) keys.push(user.username); - if (this.state.mentionKey) keys.push('@'+user.username); - if (this.state.allKey) keys.push('@all'); - if (this.state.channelKey) keys.push('@channel'); - if (this.state.customKeys.length > 0) keys = keys.concat(this.state.customKeys.split(',')); - - var describe = ''; + let keys = []; + if (this.state.firstNameKey) { + keys.push(user.first_name); + } + if (this.state.usernameKey) { + keys.push(user.username); + } + if (this.state.mentionKey) { + keys.push('@' + user.username); + } + if (this.state.allKey) { + keys.push('@all'); + } + if (this.state.channelKey) { + keys.push('@channel'); + } + if (this.state.customKeys.length > 0) { + keys = keys.concat(this.state.customKeys.split(',')); + } + + let describe = ''; for (var i = 0; i < keys.length; i++) { describe += '"' + keys[i] + '", '; } @@ -450,11 +627,15 @@ module.exports = React.createClass({ describe = 'No words configured'; } + handleUpdateKeysSection = function updateKeysSection() { + self.props.updateSection('keys'); + }; + keysSection = ( <SettingItemMin title='Words that trigger mentions' describe={describe} - updateSection={function(){self.updateSection('keys');}} + updateSection={handleUpdateKeysSection} /> ); } @@ -462,10 +643,26 @@ module.exports = React.createClass({ return ( <div> <div className='modal-header'> - <button type='button' className='close' data-dismiss='modal' aria-label='Close'><span aria-hidden='true'>×</span></button> - <h4 className='modal-title' ref='title'><i className='modal-back'></i>Notifications</h4> + <button + type='button' + className='close' + data-dismiss='modal' + aria-label='Close' + > + <span aria-hidden='true'>×</span> + </button> + <h4 + className='modal-title' + ref='title' + > + <i className='modal-back'></i> + Notifications + </h4> </div> - <div ref='wrapper' className='user-settings'> + <div + ref='wrapper' + className='user-settings' + > <h3 className='tab-header'>Notifications</h3> <div className='divider-dark first'/> {desktopSection} @@ -481,4 +678,17 @@ module.exports = React.createClass({ ); } -}); +} + +NotificationsTab.defaultProps = { + user: null, + activeSection: '', + activeTab: '' +}; +NotificationsTab.propTypes = { + user: React.PropTypes.object, + updateSection: React.PropTypes.func, + updateTab: React.PropTypes.func, + activeSection: React.PropTypes.string, + activeTab: React.PropTypes.string +}; diff --git a/web/react/components/user_settings_security.jsx b/web/react/components/user_settings_security.jsx index 568d3fe99..39d707d90 100644 --- a/web/react/components/user_settings_security.jsx +++ b/web/react/components/user_settings_security.jsx @@ -62,11 +62,9 @@ module.exports = React.createClass({ this.setState({confirmPassword: e.target.value}); }, handleHistoryOpen: function() { - this.setState({willReturn: true}); $("#user_settings").modal('hide'); }, handleDevicesOpen: function() { - this.setState({willReturn: true}); $("#user_settings").modal('hide'); }, handleClose: function() { @@ -75,11 +73,7 @@ module.exports = React.createClass({ }); this.setState({currentPassword: '', newPassword: '', confirmPassword: '', serverError: null, passwordError: null}); - if (!this.state.willReturn) { - this.props.updateTab('general'); - } else { - this.setState({willReturn: false}); - } + this.props.updateTab('general'); }, componentDidMount: function() { $('#user_settings').on('hidden.bs.modal', this.handleClose); @@ -89,7 +83,7 @@ module.exports = React.createClass({ this.props.updateSection(''); }, getInitialState: function() { - return {currentPassword: '', newPassword: '', confirmPassword: '', willReturn: false}; + return {currentPassword: '', newPassword: '', confirmPassword: ''}; }, render: function() { var serverError = this.state.serverError ? this.state.serverError : null; diff --git a/web/react/components/view_image.jsx b/web/react/components/view_image.jsx index 2b7f64030..6077c4ebc 100644 --- a/web/react/components/view_image.jsx +++ b/web/react/components/view_image.jsx @@ -109,6 +109,26 @@ module.exports = React.createClass({ } ); + if (this.refs.previewArrowLeft) { + $(this.refs.previewArrowLeft.getDOMNode()).hover( + function onModalHover() { + $(self.refs.imageFooter.getDOMNode()).addClass('footer--show'); + }, function offModalHover() { + $(self.refs.imageFooter.getDOMNode()).removeClass('footer--show'); + } + ); + } + + if (this.refs.previewArrowRight) { + $(this.refs.previewArrowRight.getDOMNode()).hover( + function onModalHover() { + $(self.refs.imageFooter.getDOMNode()).addClass('footer--show'); + }, function offModalHover() { + $(self.refs.imageFooter.getDOMNode()).removeClass('footer--show'); + } + ); + } + $(window).on('keyup', this.handleKeyPress); // keep track of whether or not this component is mounted so we can safely set the state asynchronously @@ -252,13 +272,21 @@ module.exports = React.createClass({ var rightArrow = ''; if (this.props.filenames.length > 1) { leftArrow = ( - <a className='modal-prev-bar' href='#' onClick={this.handlePrev}> + <a + ref='previewArrowLeft' + className='modal-prev-bar' + href='#' + onClick={this.handlePrev}> <i className='image-control image-prev'/> </a> ); rightArrow = ( - <a className='modal-next-bar' href='#' onClick={this.handleNext}> + <a + ref='previewArrowRight' + className='modal-next-bar' + href='#' + onClick={this.handleNext}> <i className='image-control image-next'/> </a> ); |