diff options
-rw-r--r-- | model/utils.go | 2 | ||||
-rw-r--r-- | web/react/components/channel_invite_modal.jsx | 178 | ||||
-rw-r--r-- | web/react/components/file_upload.jsx | 2 | ||||
-rw-r--r-- | web/react/components/setting_item_max.jsx | 2 | ||||
-rw-r--r-- | web/react/stores/browser_store.jsx | 2 |
5 files changed, 104 insertions, 82 deletions
diff --git a/model/utils.go b/model/utils.go index c7f991da2..a8257467b 100644 --- a/model/utils.go +++ b/model/utils.go @@ -18,7 +18,7 @@ import ( const ( // Also change web/react/stores/browser_store.jsx BROWSER_STORE_VERSION - ETAG_ROOT_VERSION = "11" + ETAG_ROOT_VERSION = "12" ) type StringMap map[string]string diff --git a/web/react/components/channel_invite_modal.jsx b/web/react/components/channel_invite_modal.jsx index 1b8fe4199..d90522e8c 100644 --- a/web/react/components/channel_invite_modal.jsx +++ b/web/react/components/channel_invite_modal.jsx @@ -4,131 +4,153 @@ var UserStore = require('../stores/user_store.jsx'); var ChannelStore = require('../stores/channel_store.jsx'); var MemberList = require('./member_list.jsx'); +var LoadingScreen = require('./loading_screen.jsx'); var utils = require('../utils/utils.jsx'); var client = require('../utils/client.jsx'); var AsyncClient = require('../utils/async_client.jsx'); -function getStateFromStores() { - var users = UserStore.getActiveOnlyProfiles(); - var memberIds = ChannelStore.getCurrentExtraInfo().members.map(function(user) { return user.id; }); - var nonmembers = []; - for (var id in users) { - if (memberIds.indexOf(id) == -1) { - nonmembers.push(users[id]); - } - } +export default class ChannelInviteModal extends React.Component { + constructor() { + super(); - nonmembers.sort(function(a,b) { - return a.username.localeCompare(b.username); - }); + this.componentDidMount = this.componentDidMount.bind(this); + this.componentWillUnmount = this.componentWillUnmount.bind(this); + this.onShow = this.onShow.bind(this); + this.onHide = this.onHide.bind(this); + this.onListenerChange = this.onListenerChange.bind(this); + this.handleInvite = this.handleInvite.bind(this); - var channel_name = ChannelStore.getCurrent() ? ChannelStore.getCurrent().display_name : ""; + this.isShown = false; + this.state = this.getStateFromStores(); + } + getStateFromStores() { + function getId(user) { + return user.id; + } + var users = UserStore.getActiveOnlyProfiles(); + var memberIds = ChannelStore.getCurrentExtraInfo().members.map(getId); - return { - nonmembers: nonmembers, - memberIds: memberIds, - channel_name: channel_name - }; -} + var loading = $.isEmptyObject(users); -module.exports = React.createClass({ - displayName: "ChannelInviteModal", + var nonmembers = []; + for (var id in users) { + if (memberIds.indexOf(id) === -1) { + nonmembers.push(users[id]); + } + } - isShown: false, - getInitialState: function() { - return {}; - }, + nonmembers.sort(function sortByUsername(a, b) { + return a.username.localeCompare(b.username); + }); - componentDidMount: function() { - $(React.findDOMNode(this)) - .on('hidden.bs.modal', this._onHide) - .on('show.bs.modal', this._onShow); - }, + var channelName = ''; + if (ChannelStore.getCurrent()) { + channelName = ChannelStore.getCurrent().display_name; + } - _onShow: function() { - ChannelStore.addExtraInfoChangeListener(this._onChange); - ChannelStore.addChangeListener(this._onChange); - this.isShown = true; - this._onChange(); - }, + return { + nonmembers: nonmembers, + memberIds: memberIds, + channelName: channelName, + loading: loading + }; + } + componentDidMount() { + $(React.findDOMNode(this)).on('hidden.bs.modal', this.onHide); + $(React.findDOMNode(this)).on('show.bs.modal', this.onShow); - _onHide: function() { - ChannelStore.removeExtraInfoChangeListener(this._onChange); - ChannelStore.removeChangeListener(this._onChange); + ChannelStore.addExtraInfoChangeListener(this.onListenerChange); + ChannelStore.addChangeListener(this.onListenerChange); + UserStore.addChangeListener(this.onListenerChange); + } + componentWillUnmount() { + ChannelStore.removeExtraInfoChangeListener(this.onListenerChange); + ChannelStore.removeChangeListener(this.onListenerChange); + UserStore.removeChangeListener(this.onListenerChange); + } + onShow() { + this.isShown = true; + this.onListenerChange(); + } + onHide() { this.isShown = false; - }, - - _onChange: function() { - this.setState(getStateFromStores()); - }, - - handleInvite: function(user_id) { + } + onListenerChange() { + var newState = this.getStateFromStores(); + if (!utils.areStatesEqual(this.state, newState) && this.isShown) { + this.setState(newState); + } + } + handleInvite(userId) { // Make sure the user isn't already a member of the channel - if (this.state.memberIds.indexOf(user_id) > -1) { + if (this.state.memberIds.indexOf(userId) > -1) { return; } var data = {}; - data.user_id = user_id; + data.user_id = userId; client.addChannelMember(ChannelStore.getCurrentId(), data, - function() { + function sucess() { var nonmembers = this.state.nonmembers; var memberIds = this.state.memberIds; for (var i = 0; i < nonmembers.length; i++) { - if (user_id === nonmembers[i].id) { + if (userId === nonmembers[i].id) { nonmembers[i].invited = true; - memberIds.push(user_id); + memberIds.push(userId); break; } } - this.setState({ invite_error: null, memberIds: memberIds, nonmembers: nonmembers }); + this.setState({inviteError: null, memberIds: memberIds, nonmembers: nonmembers}); AsyncClient.getChannelExtraInfo(true); }.bind(this), - function(err) { - this.setState({ invite_error: err.message }); + function error(err) { + this.setState({inviteError: err.message}); }.bind(this) ); - }, - - shouldComponentUpdate: function(nextProps, nextState) { - return this.isShown && !utils.areStatesEqual(this.state, nextState); - }, - - render: function() { - var invite_error = this.state.invite_error ? <label className='has-error control-label'>{this.state.invite_error}</label> : null; + } + render() { + var inviteError = null; + if (this.state.inviteError) { + inviteError = (<label className='has-error control-label'>{this.state.inviteError}</label>); + } var currentMember = ChannelStore.getCurrentMember(); var isAdmin = false; if (currentMember) { - isAdmin = currentMember.roles.indexOf("admin") > -1 || UserStore.getCurrentUser().roles.indexOf("admin") > -1; + isAdmin = currentMember.roles.indexOf('admin') > -1 || UserStore.getCurrentUser().roles.indexOf('admin') > -1; + } + + var content; + if (this.state.loading) { + content = (<LoadingScreen />); + } else { + content = (<MemberList memberList={this.state.nonmembers} isAdmin={isAdmin} handleInvite={this.handleInvite} />); } return ( - <div className="modal fade" id="channel_invite" tabIndex="-1" role="dialog" aria-hidden="true"> - <div className="modal-dialog" role="document"> - <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.channel_name}</h4> + <div className='modal fade' id='channel_invite' tabIndex='-1' role='dialog' aria-hidden='true'> + <div className='modal-dialog' role='document'> + <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> </div> - <div className="modal-body"> - { invite_error } - <MemberList - memberList={this.state.nonmembers} - isAdmin={isAdmin} - handleInvite={this.handleInvite} /> + <div className='modal-body'> + {inviteError} + {content} </div> - <div className="modal-footer"> - <button type="button" className="btn btn-default" data-dismiss="modal">Close</button> + <div className='modal-footer'> + <button type='button' className='btn btn-default' data-dismiss='modal'>Close</button> </div> </div> </div> </div> ); } -}); +} +ChannelInviteModal.displayName = 'ChannelInviteModal'; diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index 7497ec330..e77982559 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -219,7 +219,7 @@ module.exports = React.createClass({ continue; } - var channelId = this.props.channelId || ChannelStore.getCurrentId(); + var channelId = self.props.channelId || ChannelStore.getCurrentId(); // generate a unique id that can be used by other components to refer back to this file upload var clientId = utils.generateId(); diff --git a/web/react/components/setting_item_max.jsx b/web/react/components/setting_item_max.jsx index d3d386534..fd95b8b32 100644 --- a/web/react/components/setting_item_max.jsx +++ b/web/react/components/setting_item_max.jsx @@ -3,7 +3,7 @@ module.exports = React.createClass({ render: function() { - var clientError = this.props.clientError ? <div className='form-group'><label className='col-sm-12 has-error'>{ this.props.clientError }</label></div> : null; + var clientError = this.props.client_error ? <div className='form-group'><label className='col-sm-12 has-error'>{ this.props.client_error }</label></div> : null; var server_error = this.props.server_error ? <div className='form-group'><label className='col-sm-12 has-error'>{ this.props.server_error }</label></div> : null; var inputs = this.props.inputs; diff --git a/web/react/stores/browser_store.jsx b/web/react/stores/browser_store.jsx index 436b8d76d..b1f51e5f4 100644 --- a/web/react/stores/browser_store.jsx +++ b/web/react/stores/browser_store.jsx @@ -10,7 +10,7 @@ function getPrefix() { } // Also change model/utils.go ETAG_ROOT_VERSION -var BROWSER_STORE_VERSION = '.4'; +var BROWSER_STORE_VERSION = '.5'; module.exports = { initialized: false, |