summaryrefslogtreecommitdiffstats
path: root/webapp/components/member_list_channel
diff options
context:
space:
mode:
authorJoram Wilander <jwawilander@gmail.com>2017-04-28 13:16:03 -0400
committerChristopher Speller <crspeller@gmail.com>2017-04-28 13:16:03 -0400
commit96906482cecb0df21c8e1a40a2ba00c13c0182a7 (patch)
tree3bb35ca9fe2a3beb212b5350116f7bb488d7a119 /webapp/components/member_list_channel
parent302ec17beed9128101ef61d69b45d3ee29e16f1e (diff)
downloadchat-96906482cecb0df21c8e1a40a2ba00c13c0182a7.tar.gz
chat-96906482cecb0df21c8e1a40a2ba00c13c0182a7.tar.bz2
chat-96906482cecb0df21c8e1a40a2ba00c13c0182a7.zip
PLT-6214 Move channel store and actions over to redux (#6235)
* Move channel store and actions over to redux * Fix style errors * Fix unit test * Various fixes * More fixes * Revert config changes
Diffstat (limited to 'webapp/components/member_list_channel')
-rw-r--r--webapp/components/member_list_channel/index.js24
-rw-r--r--webapp/components/member_list_channel/member_list_channel.jsx171
2 files changed, 195 insertions, 0 deletions
diff --git a/webapp/components/member_list_channel/index.js b/webapp/components/member_list_channel/index.js
new file mode 100644
index 000000000..c0f70709e
--- /dev/null
+++ b/webapp/components/member_list_channel/index.js
@@ -0,0 +1,24 @@
+// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import {connect} from 'react-redux';
+import {bindActionCreators} from 'redux';
+import {getChannelStats} from 'mattermost-redux/actions/channels';
+
+import MemberListChannel from './member_list_channel.jsx';
+
+function mapStateToProps(state, ownProps) {
+ return {
+ ...ownProps
+ };
+}
+
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ getChannelStats
+ }, dispatch)
+ };
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(MemberListChannel);
diff --git a/webapp/components/member_list_channel/member_list_channel.jsx b/webapp/components/member_list_channel/member_list_channel.jsx
new file mode 100644
index 000000000..af2304433
--- /dev/null
+++ b/webapp/components/member_list_channel/member_list_channel.jsx
@@ -0,0 +1,171 @@
+// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import ChannelMembersDropdown from 'components/channel_members_dropdown';
+import SearchableUserList from 'components/searchable_user_list/searchable_user_list_container.jsx';
+
+import ChannelStore from 'stores/channel_store.jsx';
+import UserStore from 'stores/user_store.jsx';
+import TeamStore from 'stores/team_store.jsx';
+
+import {searchUsers, loadProfilesAndTeamMembersAndChannelMembers, loadTeamMembersAndChannelMembersForProfilesList} from 'actions/user_actions.jsx';
+
+import Constants from 'utils/constants.jsx';
+
+import * as UserAgent from 'utils/user_agent.jsx';
+
+import React from 'react';
+
+import store from 'stores/redux_store.jsx';
+import {searchProfilesInCurrentChannel} from 'mattermost-redux/selectors/entities/users';
+
+const USERS_PER_PAGE = 50;
+
+export default class MemberListChannel extends React.Component {
+ static propTypes = {
+ channel: React.PropTypes.object.isRequired,
+ actions: React.PropTypes.shape({
+ getChannelStats: React.PropTypes.func.isRequired
+ }).isRequired
+ }
+
+ constructor(props) {
+ super(props);
+
+ this.onChange = this.onChange.bind(this);
+ this.onStatsChange = this.onStatsChange.bind(this);
+ this.search = this.search.bind(this);
+ this.loadComplete = this.loadComplete.bind(this);
+
+ this.searchTimeoutId = 0;
+ this.term = '';
+
+ const stats = ChannelStore.getCurrentStats();
+
+ this.state = {
+ users: UserStore.getProfileListInChannel(),
+ teamMembers: Object.assign({}, TeamStore.getMembersInTeam()),
+ channelMembers: Object.assign({}, ChannelStore.getMembersInChannel()),
+ total: stats.member_count,
+ loading: true
+ };
+ }
+
+ componentDidMount() {
+ UserStore.addInTeamChangeListener(this.onChange);
+ UserStore.addStatusesChangeListener(this.onChange);
+ TeamStore.addChangeListener(this.onChange);
+ ChannelStore.addChangeListener(this.onChange);
+ ChannelStore.addStatsChangeListener(this.onStatsChange);
+
+ loadProfilesAndTeamMembersAndChannelMembers(0, Constants.PROFILE_CHUNK_SIZE, TeamStore.getCurrentId(), ChannelStore.getCurrentId(), this.loadComplete);
+ this.props.actions.getChannelStats(ChannelStore.getCurrentId());
+ }
+
+ componentWillUnmount() {
+ UserStore.removeInTeamChangeListener(this.onChange);
+ UserStore.removeStatusesChangeListener(this.onChange);
+ TeamStore.removeChangeListener(this.onChange);
+ ChannelStore.removeChangeListener(this.onChange);
+ ChannelStore.removeStatsChangeListener(this.onStatsChange);
+ }
+
+ loadComplete() {
+ this.setState({loading: false});
+ }
+
+ onChange() {
+ let users;
+ if (this.term) {
+ users = searchProfilesInCurrentChannel(store.getState(), this.term);
+ } else {
+ users = UserStore.getProfileListInChannel();
+ }
+
+ this.setState({
+ users,
+ teamMembers: Object.assign({}, TeamStore.getMembersInTeam()),
+ channelMembers: Object.assign({}, ChannelStore.getMembersInChannel())
+ });
+ }
+
+ onStatsChange() {
+ const stats = ChannelStore.getCurrentStats();
+ this.setState({total: stats.member_count});
+ }
+
+ nextPage(page) {
+ loadProfilesAndTeamMembersAndChannelMembers(page + 1, USERS_PER_PAGE);
+ }
+
+ search(term) {
+ clearTimeout(this.searchTimeoutId);
+ this.term = term;
+
+ if (term === '') {
+ this.setState({loading: false});
+ this.searchTimeoutId = '';
+ this.onChange();
+ return;
+ }
+
+ const searchTimeoutId = setTimeout(
+ () => {
+ searchUsers(term, TeamStore.getCurrentId(), {},
+ (users) => {
+ if (searchTimeoutId !== this.searchTimeoutId) {
+ return;
+ }
+
+ this.setState({loading: true});
+
+ loadTeamMembersAndChannelMembersForProfilesList(users, TeamStore.getCurrentId(), ChannelStore.getCurrentId(), this.loadComplete);
+ }
+ );
+ },
+ Constants.SEARCH_TIMEOUT_MILLISECONDS
+ );
+
+ this.searchTimeoutId = searchTimeoutId;
+ }
+
+ render() {
+ const teamMembers = this.state.teamMembers;
+ const channelMembers = this.state.channelMembers;
+ const users = this.state.users;
+ const actionUserProps = {};
+
+ let usersToDisplay;
+ if (this.state.loading) {
+ usersToDisplay = null;
+ } else {
+ usersToDisplay = [];
+
+ for (let i = 0; i < users.length; i++) {
+ const user = users[i];
+
+ if (teamMembers[user.id] && channelMembers[user.id]) {
+ usersToDisplay.push(user);
+ actionUserProps[user.id] = {
+ channel: this.props.channel,
+ teamMember: teamMembers[user.id],
+ channelMember: channelMembers[user.id]
+ };
+ }
+ }
+ }
+
+ return (
+ <SearchableUserList
+ users={usersToDisplay}
+ usersPerPage={USERS_PER_PAGE}
+ total={this.state.total}
+ nextPage={this.nextPage}
+ search={this.search}
+ actions={[ChannelMembersDropdown]}
+ actionUserProps={actionUserProps}
+ focusOnMount={!UserAgent.isMobile()}
+ />
+ );
+ }
+}