summaryrefslogtreecommitdiffstats
path: root/webapp/components/channel_invite_modal.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/components/channel_invite_modal.jsx')
-rw-r--r--webapp/components/channel_invite_modal.jsx166
1 files changed, 77 insertions, 89 deletions
diff --git a/webapp/components/channel_invite_modal.jsx b/webapp/components/channel_invite_modal.jsx
index c7c1906a5..99a4b9313 100644
--- a/webapp/components/channel_invite_modal.jsx
+++ b/webapp/components/channel_invite_modal.jsx
@@ -1,124 +1,85 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import $ from 'jquery';
import ChannelInviteButton from './channel_invite_button.jsx';
-import FilteredUserList from './filtered_user_list.jsx';
+import SearchableUserList from './searchable_user_list.jsx';
import LoadingScreen from './loading_screen.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import UserStore from 'stores/user_store.jsx';
+import TeamStore from 'stores/team_store.jsx';
+
+import {searchUsers} from 'actions/user_actions.jsx';
import * as Utils from 'utils/utils.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
-import {FormattedMessage} from 'react-intl';
-
+import React from 'react';
import {Modal} from 'react-bootstrap';
+import {FormattedMessage} from 'react-intl';
-import React from 'react';
+const USERS_PER_PAGE = 50;
export default class ChannelInviteModal extends React.Component {
constructor(props) {
super(props);
- this.onListenerChange = this.onListenerChange.bind(this);
- this.getStateFromStores = this.getStateFromStores.bind(this);
+ this.onChange = this.onChange.bind(this);
this.handleInviteError = this.handleInviteError.bind(this);
+ this.nextPage = this.nextPage.bind(this);
+ this.search = this.search.bind(this);
- this.state = this.getStateFromStores();
- }
- shouldComponentUpdate(nextProps, nextState) {
- if (!this.props.show && !nextProps.show) {
- return false;
- }
-
- if (!Utils.areObjectsEqual(this.props, nextProps)) {
- return true;
- }
-
- if (!Utils.areObjectsEqual(this.state, nextState)) {
- return true;
- }
-
- return false;
- }
- getStateFromStores() {
- const users = UserStore.getActiveOnlyProfiles();
-
- if ($.isEmptyObject(users)) {
- return {
- loading: true
- };
- }
-
- // make sure we have all members of this channel before rendering
- const extraInfo = ChannelStore.getCurrentExtraInfo();
- if (extraInfo.member_count !== extraInfo.members.length) {
- AsyncClient.getChannelExtraInfo(this.props.channel.id, -1);
-
- return {
- loading: true
- };
- }
-
- const currentUser = UserStore.getCurrentUser();
- if (!currentUser) {
- return {
- loading: true
- };
- }
-
- const currentMember = ChannelStore.getCurrentMember();
- if (!currentMember) {
- return {
- loading: true
- };
- }
+ this.term = '';
- const memberIds = extraInfo.members.map((user) => user.id);
+ const channelStats = ChannelStore.getStats(props.channel.id);
+ const teamStats = TeamStore.getCurrentStats();
- var nonmembers = [];
- for (var id in users) {
- if (memberIds.indexOf(id) === -1) {
- nonmembers.push(users[id]);
- }
- }
-
- nonmembers.sort((a, b) => {
- return a.username.localeCompare(b.username);
- });
-
- return {
- nonmembers,
- loading: false,
- currentUser,
- currentMember
+ this.state = {
+ users: [],
+ total: teamStats.member_count - channelStats.member_count,
+ search: false
};
}
+
componentWillReceiveProps(nextProps) {
if (!this.props.show && nextProps.show) {
- ChannelStore.addExtraInfoChangeListener(this.onListenerChange);
- ChannelStore.addChangeListener(this.onListenerChange);
- UserStore.addChangeListener(this.onListenerChange);
- this.onListenerChange();
+ TeamStore.addStatsChangeListener(this.onChange);
+ ChannelStore.addStatsChangeListener(this.onChange);
+ UserStore.addNotInChannelChangeListener(this.onChange);
+ UserStore.addStatusesChangeListener(this.onChange);
+
+ this.onChange();
+ AsyncClient.getProfilesNotInChannel(this.props.channel.id, 0);
+ AsyncClient.getTeamStats(TeamStore.getCurrentId());
} else if (this.props.show && !nextProps.show) {
- ChannelStore.removeExtraInfoChangeListener(this.onListenerChange);
- ChannelStore.removeChangeListener(this.onListenerChange);
- UserStore.removeChangeListener(this.onListenerChange);
+ TeamStore.removeStatsChangeListener(this.onChange);
+ ChannelStore.removeStatsChangeListener(this.onChange);
+ UserStore.removeNotInChannelChangeListener(this.onChange);
+ UserStore.removeStatusesChangeListener(this.onChange);
}
}
+
componentWillUnmount() {
- ChannelStore.removeExtraInfoChangeListener(this.onListenerChange);
- ChannelStore.removeChangeListener(this.onListenerChange);
- UserStore.removeChangeListener(this.onListenerChange);
+ ChannelStore.removeStatsChangeListener(this.onChange);
+ ChannelStore.removeChangeListener(this.onChange);
+ UserStore.removeNotInChannelChangeListener(this.onChange);
}
- onListenerChange() {
- var newState = this.getStateFromStores();
- if (!Utils.areObjectsEqual(this.state, newState)) {
- this.setState(newState);
+
+ onChange() {
+ if (this.state.search) {
+ this.search(this.term);
+ return;
}
+
+ const channelStats = ChannelStore.getStats(this.props.channel.id);
+ const teamStats = TeamStore.getCurrentStats();
+
+ this.setState({
+ users: UserStore.getProfileListNotInChannel(this.props.channel.id),
+ total: teamStats.member_count - channelStats.member_count
+ });
}
+
handleInviteError(err) {
if (err) {
this.setState({
@@ -130,6 +91,29 @@ export default class ChannelInviteModal extends React.Component {
});
}
}
+
+ nextPage(page) {
+ AsyncClient.getProfilesNotInChannel(this.props.channel.id, (page + 1) * USERS_PER_PAGE, USERS_PER_PAGE);
+ }
+
+ search(term) {
+ this.term = term;
+
+ if (term === '') {
+ this.setState({users: UserStore.getProfileListNotInChannel(), search: false});
+ return;
+ }
+
+ searchUsers(
+ term,
+ TeamStore.getCurrentId(),
+ {not_in_channel: this.props.channel.id},
+ (users) => {
+ this.setState({search: true, users});
+ }
+ );
+ }
+
render() {
var inviteError = null;
if (this.state.inviteError) {
@@ -145,9 +129,13 @@ export default class ChannelInviteModal extends React.Component {
maxHeight = Utils.windowHeight() - 300;
}
content = (
- <FilteredUserList
+ <SearchableUserList
style={{maxHeight}}
- users={this.state.nonmembers}
+ users={this.state.users}
+ usersPerPage={USERS_PER_PAGE}
+ total={this.state.total}
+ nextPage={this.nextPage}
+ search={this.search}
actions={[ChannelInviteButton]}
actionProps={{
channel: this.props.channel,