diff options
Diffstat (limited to 'webapp/components/member_list_channel')
-rw-r--r-- | webapp/components/member_list_channel/index.js | 24 | ||||
-rw-r--r-- | webapp/components/member_list_channel/member_list_channel.jsx | 171 |
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()} + /> + ); + } +} |