summaryrefslogtreecommitdiffstats
path: root/webapp
diff options
context:
space:
mode:
authorCorey Hulen <corey@hulen.com>2016-05-04 06:31:42 -0700
committerChristopher Speller <crspeller@gmail.com>2016-05-04 09:31:42 -0400
commit6611229cd7bd3cdfc0082c0a581145aaac0ab322 (patch)
treedb6670a8c2716179bfe6e07b82588d83d3afb6bd /webapp
parent6b06f49e8910ed44f619adad15ab268758312852 (diff)
downloadchat-6611229cd7bd3cdfc0082c0a581145aaac0ab322.tar.gz
chat-6611229cd7bd3cdfc0082c0a581145aaac0ab322.tar.bz2
chat-6611229cd7bd3cdfc0082c0a581145aaac0ab322.zip
PLT-2707 Adding option to show DM list from all of server (#2871)
* PLT-2707 Adding option to show DM list from all of server * Fixing loc
Diffstat (limited to 'webapp')
-rw-r--r--webapp/action_creators/global_actions.jsx9
-rw-r--r--webapp/client/client.jsx11
-rw-r--r--webapp/components/admin_console/team_settings.jsx40
-rw-r--r--webapp/components/create_team/components/team_url.jsx2
-rw-r--r--webapp/components/filtered_user_list.jsx90
-rw-r--r--webapp/components/more_direct_channels.jsx79
-rw-r--r--webapp/components/sidebar.jsx35
-rw-r--r--webapp/i18n/en.json9
-rw-r--r--webapp/i18n/es.json2
-rw-r--r--webapp/i18n/fr.json2
-rw-r--r--webapp/i18n/ja.json2
-rw-r--r--webapp/i18n/pt.json2
-rw-r--r--webapp/sass/components/_modal.scss15
-rw-r--r--webapp/stores/user_store.jsx41
-rw-r--r--webapp/tests/client_user.test.jsx14
-rw-r--r--webapp/utils/async_client.jsx22
-rw-r--r--webapp/utils/constants.jsx1
-rw-r--r--webapp/utils/utils.jsx7
18 files changed, 323 insertions, 60 deletions
diff --git a/webapp/action_creators/global_actions.jsx b/webapp/action_creators/global_actions.jsx
index 335c20219..ae7352e5d 100644
--- a/webapp/action_creators/global_actions.jsx
+++ b/webapp/action_creators/global_actions.jsx
@@ -157,6 +157,11 @@ export function emitPostFocusEvent(postId) {
);
}
+export function emitProfilesForDmList() {
+ AsyncClient.getProfilesForDirectMessageList();
+ AsyncClient.getTeamMembers(TeamStore.getCurrentId());
+}
+
export function emitCloseRightHandSide() {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_SEARCH,
@@ -335,6 +340,10 @@ export function emitClearSuggestions(suggestionId) {
}
export function emitPreferenceChangedEvent(preference) {
+ if (preference.category === Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW) {
+ AsyncClient.getDirectProfiles();
+ }
+
AppDispatcher.handleServerAction({
type: Constants.ActionTypes.RECEIVED_PREFERENCE,
preference
diff --git a/webapp/client/client.jsx b/webapp/client/client.jsx
index 69f573eff..73cc6120f 100644
--- a/webapp/client/client.jsx
+++ b/webapp/client/client.jsx
@@ -862,13 +862,22 @@ export default class Client {
getProfilesForTeam = (teamId, success, error) => {
request.
- get(`${this.getUsersRoute()}/profiles/${teamId}?skip_direct=true`).
+ get(`${this.getUsersRoute()}/profiles/${teamId}`).
set(this.defaultHeaders).
type('application/json').
accept('application/json').
end(this.handleResponse.bind(this, 'getProfilesForTeam', success, error));
}
+ getProfilesForDirectMessageList = (success, error) => {
+ request.
+ get(`${this.getUsersRoute()}/profiles_for_dm_list/${this.getTeamId()}`).
+ set(this.defaultHeaders).
+ type('application/json').
+ accept('application/json').
+ end(this.handleResponse.bind(this, 'getProfilesForDirectMessageList', success, error));
+ }
+
getStatuses = (ids, success, error) => {
request.
post(`${this.getUsersRoute()}/status`).
diff --git a/webapp/components/admin_console/team_settings.jsx b/webapp/components/admin_console/team_settings.jsx
index bbb7ec3c4..e7bfcd74a 100644
--- a/webapp/components/admin_console/team_settings.jsx
+++ b/webapp/components/admin_console/team_settings.jsx
@@ -24,6 +24,14 @@ const holders = defineMessages({
saving: {
id: 'admin.team.saving',
defaultMessage: 'Saving Config...'
+ },
+ restrictDirectMessageAny: {
+ id: 'admin.team.restrict_direct_message_any',
+ defaultMessage: 'Any user on the Mattermost server'
+ },
+ restrictDirectMessageTeam: {
+ id: 'admin.team.restrict_direct_message_team',
+ defaultMessage: 'Any member of the team'
}
});
@@ -48,6 +56,7 @@ class TeamSettings extends React.Component {
saveNeeded: false,
brandImageExists: false,
enableCustomBrand: this.props.config.TeamSettings.EnableCustomBrand,
+ restrictDirectMessage: this.props.config.TeamSettings.RestrictDirectMessage,
serverError: null
};
}
@@ -104,6 +113,7 @@ class TeamSettings extends React.Component {
config.TeamSettings.EnableUserCreation = this.refs.EnableUserCreation.checked;
config.TeamSettings.EnableOpenServer = this.refs.EnableOpenServer.checked;
config.TeamSettings.RestrictTeamNames = this.refs.RestrictTeamNames.checked;
+ config.TeamSettings.RestrictDirectMessage = this.refs.RestrictDirectMessage.value.trim();
if (this.refs.EnableCustomBrand) {
config.TeamSettings.EnableCustomBrand = this.refs.EnableCustomBrand.checked;
@@ -660,6 +670,36 @@ class TeamSettings extends React.Component {
</div>
</div>
+ <div className='form-group'>
+ <label
+ className='control-label col-sm-4'
+ htmlFor='restrictDirectMessage'
+ >
+ <FormattedMessage
+ id='admin.team.restrictDirectMessage'
+ defaultMessage='Enable users to open Direct Message channels with:'
+ />
+ </label>
+ <div className='col-sm-8'>
+ <select
+ className='form-control'
+ id='restrictDirectMessage'
+ ref='RestrictDirectMessage'
+ defaultValue={this.props.config.TeamSettings.RestrictDirectMessage}
+ onChange={this.handleChange.bind(this, 'restrictDirectMessage')}
+ >
+ <option value='any'>{formatMessage(holders.restrictDirectMessageAny)}</option>
+ <option value='team'>{formatMessage(holders.restrictDirectMessageTeam)}</option>
+ </select>
+ <p className='help-text'>
+ <FormattedHTMLMessage
+ id='admin.team.restrictDirectMessageDesc'
+ defaultMessage='"Any user on the Mattermost server" enables users to open a Direct Message channel with any user on the server, even if they are not on any teams together. "Any member of the team" limits the ability to open Direct Message channels to only users who are in the same team.'
+ />
+ </p>
+ </div>
+ </div>
+
{brand}
<div className='form-group'>
diff --git a/webapp/components/create_team/components/team_url.jsx b/webapp/components/create_team/components/team_url.jsx
index 1a20066b5..34e696938 100644
--- a/webapp/components/create_team/components/team_url.jsx
+++ b/webapp/components/create_team/components/team_url.jsx
@@ -5,6 +5,7 @@ import $ from 'jquery';
import ReactDOM from 'react-dom';
import * as Utils from 'utils/utils.jsx';
import Client from 'utils/web_client.jsx';
+import * as AsyncClient from 'utils/async_client.jsx';
import TeamStore from 'stores/team_store.jsx';
import UserStore from 'stores/user_store.jsx';
import Constants from 'utils/constants.jsx';
@@ -99,6 +100,7 @@ class TeamUrl extends React.Component {
(team) => {
Client.track('signup', 'signup_team_08_complete');
$('#sign-up-button').button('reset');
+ AsyncClient.getDirectProfiles();
TeamStore.saveTeam(team);
TeamStore.appendTeamMember({team_id: team.id, user_id: UserStore.getCurrentId(), roles: 'admin'});
TeamStore.emitChange();
diff --git a/webapp/components/filtered_user_list.jsx b/webapp/components/filtered_user_list.jsx
index e12faa298..83747c03d 100644
--- a/webapp/components/filtered_user_list.jsx
+++ b/webapp/components/filtered_user_list.jsx
@@ -15,6 +15,14 @@ const holders = defineMessages({
search: {
id: 'filtered_user_list.search',
defaultMessage: 'Search members'
+ },
+ anyTeam: {
+ id: 'filtered_user_list.any_team',
+ defaultMessage: 'All Users'
+ },
+ teamOnly: {
+ id: 'filtered_user_list.team_only',
+ defaultMessage: 'Members of this Team'
}
});
@@ -25,9 +33,13 @@ class FilteredUserList extends React.Component {
super(props);
this.handleFilterChange = this.handleFilterChange.bind(this);
+ this.handleListChange = this.handleListChange.bind(this);
+ this.filterUsers = this.filterUsers.bind(this);
this.state = {
- filter: ''
+ filter: '',
+ users: this.filterUsers(props.teamMembers, props.users),
+ selected: 'team'
};
}
@@ -37,18 +49,49 @@ class FilteredUserList extends React.Component {
}
}
+ filterUsers(teamMembers, users) {
+ if (!teamMembers || teamMembers.length === 0) {
+ return users;
+ }
+
+ var filteredUsers = users.filter((user) => {
+ for (const index in teamMembers) {
+ if (teamMembers.hasOwnProperty(index) && teamMembers[index].user_id === user.id) {
+ return true;
+ }
+ }
+
+ return false;
+ });
+
+ return filteredUsers;
+ }
+
handleFilterChange(e) {
this.setState({
filter: e.target.value
});
}
+ handleListChange(e) {
+ var users = this.props.users;
+
+ if (e.target.value === 'team') {
+ users = this.filterUsers(this.props.teamMembers, this.props.users);
+ }
+
+ this.setState({
+ selected: e.target.value,
+ users
+ });
+ }
+
render() {
const {formatMessage} = this.props.intl;
- let users = this.props.users;
+ let users = this.state.users;
- if (this.state.filter) {
+ if (this.state.filter && this.state.filter.length > 0) {
const filter = this.state.filter.toLowerCase();
users = users.filter((user) => {
@@ -60,7 +103,7 @@ class FilteredUserList extends React.Component {
}
let count;
- if (users.length === this.props.users.length) {
+ if (users.length === this.state.users.length) {
count = (
<FormattedMessage
id='filtered_user_list.count'
@@ -77,12 +120,42 @@ class FilteredUserList extends React.Component {
defaultMessage='{count} {count, plural, =0 {0 members} one {member} other {members}} of {total} Total'
values={{
count: users.length,
- total: this.props.users.length
+ total: this.state.users.length
}}
/>
);
}
+ let teamToggle;
+
+ let teamMembers = this.props.teamMembers;
+ if (this.props.showTeamToggle) {
+ teamMembers = [];
+
+ teamToggle = (
+ <div className='col-sm-6'>
+ <select
+ className='form-control member-select'
+ id='restrictList'
+ ref='restrictList'
+ defaultValue='team'
+ onChange={this.handleListChange}
+ >
+ <option value='any'>{formatMessage(holders.anyTeam)}</option>
+ <option value='team'>{formatMessage(holders.teamOnly)}</option>
+ </select>
+ <span
+ className='member-show'
+ >
+ <FormattedMessage
+ id='filtered_user_list.show'
+ defaultMessage='Show'
+ />
+ </span>
+ </div>
+ );
+ }
+
return (
<div
className='filtered-user-list'
@@ -100,6 +173,7 @@ class FilteredUserList extends React.Component {
<div className='col-sm-6'>
<span className='member-count'>{count}</span>
</div>
+ {teamToggle}
</div>
<div
ref='userList'
@@ -107,7 +181,7 @@ class FilteredUserList extends React.Component {
>
<UserList
users={users}
- teamMembers={this.props.teamMembers}
+ teamMembers={teamMembers}
actions={this.props.actions}
actionProps={this.props.actionProps}
/>
@@ -121,7 +195,8 @@ FilteredUserList.defaultProps = {
users: [],
teamMembers: [],
actions: [],
- actionProps: {}
+ actionProps: {},
+ showTeamToggle: false
};
FilteredUserList.propTypes = {
@@ -130,6 +205,7 @@ FilteredUserList.propTypes = {
teamMembers: React.PropTypes.arrayOf(React.PropTypes.object),
actions: React.PropTypes.arrayOf(React.PropTypes.func),
actionProps: React.PropTypes.object,
+ showTeamToggle: React.PropTypes.bool,
style: React.PropTypes.object
};
diff --git a/webapp/components/more_direct_channels.jsx b/webapp/components/more_direct_channels.jsx
index a7fb2b6cd..761ce0c37 100644
--- a/webapp/components/more_direct_channels.jsx
+++ b/webapp/components/more_direct_channels.jsx
@@ -4,11 +4,14 @@
import {Modal} from 'react-bootstrap';
import FilteredUserList from './filtered_user_list.jsx';
import UserStore from 'stores/user_store.jsx';
+import TeamStore from 'stores/team_store.jsx';
import * as Utils from 'utils/utils.jsx';
+import * as GlobalActions from 'action_creators/global_actions.jsx';
import {FormattedMessage} from 'react-intl';
import {browserHistory} from 'react-router';
import SpinnerButton from 'components/spinner_button.jsx';
+import LoadingScreen from 'components/loading_screen.jsx';
import React from 'react';
@@ -17,38 +20,27 @@ export default class MoreDirectChannels extends React.Component {
super(props);
this.handleHide = this.handleHide.bind(this);
+ this.handleOnEnter = this.handleOnEnter.bind(this);
this.handleShowDirectChannel = this.handleShowDirectChannel.bind(this);
this.handleUserChange = this.handleUserChange.bind(this);
+ this.onTeamChange = this.onTeamChange.bind(this);
this.createJoinDirectChannelButton = this.createJoinDirectChannelButton.bind(this);
this.state = {
- users: this.getUsersFromStore(),
+ users: null,
+ teamMembers: null,
loadingDMChannel: -1
};
}
- getUsersFromStore() {
- const currentId = UserStore.getCurrentId();
- const profiles = UserStore.getActiveOnlyProfiles();
- const users = [];
-
- for (const id in profiles) {
- if (id !== currentId) {
- users.push(profiles[id]);
- }
- }
-
- users.sort((a, b) => a.username.localeCompare(b.username));
-
- return users;
- }
-
componentDidMount() {
- UserStore.addChangeListener(this.handleUserChange);
+ UserStore.addDmListChangeListener(this.handleUserChange);
+ TeamStore.addChangeListener(this.onTeamChange);
}
componentWillUnmount() {
- UserStore.removeChangeListener(this.handleUserChange);
+ UserStore.removeDmListChangeListener(this.handleUserChange);
+ TeamStore.removeChangeListener(this.onTeamChange);
}
shouldComponentUpdate(nextProps, nextState) {
@@ -77,6 +69,17 @@ export default class MoreDirectChannels extends React.Component {
}
}
+ handleOnEnter() {
+ this.setState({
+ users: null,
+ teamMembers: null
+ });
+ }
+
+ handleOnEntered() {
+ GlobalActions.emitProfilesForDmList();
+ }
+
handleShowDirectChannel(teammate, e) {
e.preventDefault();
@@ -99,7 +102,15 @@ export default class MoreDirectChannels extends React.Component {
}
handleUserChange() {
- this.setState({users: this.getUsersFromStore()});
+ this.setState({
+ users: UserStore.getProfilesForDmList()
+ });
+ }
+
+ onTeamChange() {
+ this.setState({
+ teamMembers: TeamStore.getMembersForTeam()
+ });
}
createJoinDirectChannelButton({user}) {
@@ -123,11 +134,33 @@ export default class MoreDirectChannels extends React.Component {
maxHeight = Utils.windowHeight() - 300;
}
+ var body = null;
+ if (this.state.users == null || this.state.teamMembers == null) {
+ body = (<LoadingScreen/>);
+ } else {
+ var showTeamToggle = false;
+ if (global.window.mm_config.RestrictDirectMessage === 'any') {
+ showTeamToggle = true;
+ }
+
+ body = (
+ <FilteredUserList
+ style={{maxHeight}}
+ users={this.state.users}
+ teamMembers={this.state.teamMembers}
+ actions={[this.createJoinDirectChannelButton]}
+ showTeamToggle={showTeamToggle}
+ />
+ );
+ }
+
return (
<Modal
dialogClassName='more-modal more-direct-channels'
show={this.props.show}
onHide={this.handleHide}
+ onEnter={this.handleOnEnter}
+ onEntered={this.handleOnEntered}
>
<Modal.Header closeButton={true}>
<Modal.Title>
@@ -138,11 +171,7 @@ export default class MoreDirectChannels extends React.Component {
</Modal.Title>
</Modal.Header>
<Modal.Body>
- <FilteredUserList
- style={{maxHeight}}
- users={this.state.users}
- actions={[this.createJoinDirectChannelButton]}
- />
+ {body}
</Modal.Body>
<Modal.Footer>
<button
diff --git a/webapp/components/sidebar.jsx b/webapp/components/sidebar.jsx
index 4ab8b6b40..4ce89d37c 100644
--- a/webapp/components/sidebar.jsx
+++ b/webapp/components/sidebar.jsx
@@ -124,8 +124,6 @@ export default class Sidebar extends React.Component {
directChannels.sort(this.sortChannelsByDisplayName);
- const hiddenDirectChannelCount = UserStore.getActiveOnlyProfileList(true).length - directChannels.length;
-
const tutorialStep = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), 999);
return {
@@ -134,7 +132,6 @@ export default class Sidebar extends React.Component {
publicChannels,
privateChannels,
directChannels,
- hiddenDirectChannelCount,
unreadCounts: JSON.parse(JSON.stringify(ChannelStore.getUnreadCounts())),
showTutorialTip: tutorialStep === TutorialSteps.CHANNEL_POPOVER,
currentTeam: TeamStore.getCurrent(),
@@ -527,25 +524,19 @@ export default class Sidebar extends React.Component {
}
head.appendChild(link);
- var directMessageMore = null;
- if (this.state.hiddenDirectChannelCount > 0) {
- directMessageMore = (
- <li key='more'>
- <a
- href='#'
- onClick={this.showMoreDirectChannelsModal}
- >
- <FormattedMessage
- id='sidebar.more'
- defaultMessage='More ({count})'
- values={{
- count: this.state.hiddenDirectChannelCount
- }}
- />
- </a>
- </li>
- );
- }
+ var directMessageMore = (
+ <li key='more'>
+ <a
+ href='#'
+ onClick={this.showMoreDirectChannelsModal}
+ >
+ <FormattedMessage
+ id='sidebar.more'
+ defaultMessage='More'
+ />
+ </a>
+ </li>
+ );
let showChannelModal = false;
if (this.state.newChannelModalType !== '') {
diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json
index fbbf66fbd..da2acba3d 100644
--- a/webapp/i18n/en.json
+++ b/webapp/i18n/en.json
@@ -542,6 +542,10 @@
"admin.team.userCreationTitle": "Enable User Creation: ",
"admin.team_analytics.activeUsers": "Active Users With Posts",
"admin.team_analytics.totalPosts": "Total Posts",
+ "admin.team.restrictDirectMessage": "Enable users to open Direct Message channels with:",
+ "admin.team.restrictDirectMessageDesc": "'Any user on the Mattermost server' enables users to open a Direct Message channel with any user on the server, even if they are not on any teams together. 'Any member of the team' limits the ability to open Direct Message channels to only users who are in the same team.",
+ "admin.team.restrict_direct_message_any": "Any user on the Mattermost server",
+ "admin.team.restrict_direct_message_team": "Any member of the team",
"admin.userList.title": "Users for {team}",
"admin.userList.title2": "Users for {team} ({count})",
"admin.user_item.authServiceEmail": ", <strong>Sign-in Method:</strong> Email",
@@ -859,6 +863,9 @@
"file_upload.pasted": "Image Pasted at ",
"filtered_user_list.count": "{count} {count, plural, =0 {0 members} one {member} other {members}}",
"filtered_user_list.countTotal": "{count} {count, plural, =0 {0 members} one {member} other {members}} of {total} Total",
+ "filtered_user_list.show": "Show",
+ "filtered_user_list.any_team": "All Users",
+ "filtered_user_list.team_only": "Members of this Team",
"filtered_user_list.member": "Member",
"filtered_user_list.search": "Search members",
"find_team.email": "Email",
@@ -1120,7 +1127,7 @@
"sidebar.createChannel": "Create new channel",
"sidebar.createGroup": "Create new group",
"sidebar.direct": "Direct Messages",
- "sidebar.more": "More ({count})",
+ "sidebar.more": "More",
"sidebar.moreElips": "More...",
"sidebar.pg": "Private Groups",
"sidebar.removeList": "Remove from list",
diff --git a/webapp/i18n/es.json b/webapp/i18n/es.json
index 34e4360b5..b6189916e 100644
--- a/webapp/i18n/es.json
+++ b/webapp/i18n/es.json
@@ -1118,7 +1118,7 @@
"sidebar.createChannel": "Crear un nuevo canal",
"sidebar.createGroup": "Crear un nuevo grupo",
"sidebar.direct": "Mensajes Directos",
- "sidebar.more": "Más ({count})",
+ "sidebar.more": "Más",
"sidebar.moreElips": "Más...",
"sidebar.pg": "Grupos Privados",
"sidebar.removeList": "Remover de la lista",
diff --git a/webapp/i18n/fr.json b/webapp/i18n/fr.json
index c92dff181..31f646d84 100644
--- a/webapp/i18n/fr.json
+++ b/webapp/i18n/fr.json
@@ -976,7 +976,7 @@
"sidebar.createChannel": "Créer un nouveau canal",
"sidebar.createGroup": "Créer un nouveau groupe",
"sidebar.direct": "Messages privés",
- "sidebar.more": "Plus ({count})",
+ "sidebar.more": "Plus",
"sidebar.moreElips": "Plus...",
"sidebar.pg": "Groupes privés",
"sidebar.removeList": "Retirer de la liste",
diff --git a/webapp/i18n/ja.json b/webapp/i18n/ja.json
index 88e10498e..f6bc8cc7d 100644
--- a/webapp/i18n/ja.json
+++ b/webapp/i18n/ja.json
@@ -1078,7 +1078,7 @@
"sidebar.createChannel": "新しいチャンネルを作成する",
"sidebar.createGroup": "新しいグループを作成する",
"sidebar.direct": "ダイレクトメッセージ",
- "sidebar.more": "もっと表示する({count})",
+ "sidebar.more": "もっと表示する",
"sidebar.moreElips": "もっと…",
"sidebar.pg": "非公開グループ",
"sidebar.removeList": "一覧から削除する",
diff --git a/webapp/i18n/pt.json b/webapp/i18n/pt.json
index d10487c79..501727f98 100644
--- a/webapp/i18n/pt.json
+++ b/webapp/i18n/pt.json
@@ -1120,7 +1120,7 @@
"sidebar.createChannel": "Criar novo canal",
"sidebar.createGroup": "Criar um novo grupo",
"sidebar.direct": "Mensagens Diretas",
- "sidebar.more": "Mais ({count})",
+ "sidebar.more": "Mais",
"sidebar.moreElips": "Mais...",
"sidebar.pg": "Grupos Privados",
"sidebar.removeList": "Remover da lista",
diff --git a/webapp/sass/components/_modal.scss b/webapp/sass/components/_modal.scss
index f66a08804..90afe1b11 100644
--- a/webapp/sass/components/_modal.scss
+++ b/webapp/sass/components/_modal.scss
@@ -436,6 +436,21 @@
margin-top: 5px;
}
+ .member-show {
+ @include opacity(.8);
+ float: right;
+ margin-top: 12px;
+ margin-right: 3px;
+ }
+
+ .member-select {
+ @include opacity(.8);
+ float: right;
+ width: auto;
+ margin-top: 5px;
+ margin-right: 5px;
+ }
+
.more-purpose {
@include opacity(.7);
}
diff --git a/webapp/stores/user_store.jsx b/webapp/stores/user_store.jsx
index 8d685aea3..5a27d15ea 100644
--- a/webapp/stores/user_store.jsx
+++ b/webapp/stores/user_store.jsx
@@ -7,6 +7,7 @@ import EventEmitter from 'events';
import Constants from 'utils/constants.jsx';
const ActionTypes = Constants.ActionTypes;
+const CHANGE_EVENT_DM_LIST = 'change_dm_list';
const CHANGE_EVENT = 'change';
const CHANGE_EVENT_SESSIONS = 'change_sessions';
const CHANGE_EVENT_AUDITS = 'change_audits';
@@ -19,6 +20,7 @@ class UserStoreClass extends EventEmitter {
}
clear() {
+ this.profiles_for_dm_list = {};
this.profiles = {};
this.direct_profiles = {};
this.statuses = {};
@@ -40,6 +42,18 @@ class UserStoreClass extends EventEmitter {
this.removeListener(CHANGE_EVENT, callback);
}
+ emitDmListChange() {
+ this.emit(CHANGE_EVENT_DM_LIST);
+ }
+
+ addDmListChangeListener(callback) {
+ this.on(CHANGE_EVENT_DM_LIST, callback);
+ }
+
+ removeDmListChangeListener(callback) {
+ this.removeListener(CHANGE_EVENT_DM_LIST, callback);
+ }
+
emitSessionsChange() {
this.emit(CHANGE_EVENT_SESSIONS);
}
@@ -190,6 +204,29 @@ class UserStoreClass extends EventEmitter {
}
}
+ getProfilesForDmList() {
+ const currentId = this.getCurrentId();
+ const profiles = [];
+
+ for (const id in this.profiles_for_dm_list) {
+ if (this.profiles_for_dm_list.hasOwnProperty(id) && id !== currentId) {
+ var profile = this.profiles_for_dm_list[id];
+
+ if (profile.delete_at === 0) {
+ profiles.push(profile);
+ }
+ }
+ }
+
+ profiles.sort((a, b) => a.username.localeCompare(b.username));
+
+ return profiles;
+ }
+
+ saveProfilesForDmList(profiles) {
+ this.profiles_for_dm_list = profiles;
+ }
+
setSessions(sessions) {
this.sessions = sessions;
}
@@ -278,6 +315,10 @@ UserStore.dispatchToken = AppDispatcher.register((payload) => {
var action = payload.action;
switch (action.type) {
+ case ActionTypes.RECEIVED_PROFILES_FOR_DM_LIST:
+ UserStore.saveProfilesForDmList(action.profiles);
+ UserStore.emitDmListChange();
+ break;
case ActionTypes.RECEIVED_PROFILES:
UserStore.saveProfiles(action.profiles);
UserStore.emitChange();
diff --git a/webapp/tests/client_user.test.jsx b/webapp/tests/client_user.test.jsx
index 7835a38bf..610308fa3 100644
--- a/webapp/tests/client_user.test.jsx
+++ b/webapp/tests/client_user.test.jsx
@@ -480,6 +480,20 @@ describe('Client.User', function() {
});
});
+ it('getProfilesForDirectMessageList', function(done) {
+ TestHelper.initBasic(() => {
+ TestHelper.basicClient().getProfilesForDirectMessageList(
+ function(data) {
+ assert.equal(Object.keys(data).length > 0, true);
+ done();
+ },
+ function(err) {
+ done(new Error(err.message));
+ }
+ );
+ });
+ });
+
it('getStatuses', function(done) {
TestHelper.initBasic(() => {
var ids = [];
diff --git a/webapp/utils/async_client.jsx b/webapp/utils/async_client.jsx
index 189b159e8..0dede3bc9 100644
--- a/webapp/utils/async_client.jsx
+++ b/webapp/utils/async_client.jsx
@@ -224,6 +224,28 @@ export function getTeamMembers(teamId) {
);
}
+export function getProfilesForDirectMessageList() {
+ if (isCallInProgress('getProfilesForDirectMessageList')) {
+ return;
+ }
+
+ callTracker.getProfilesForDirectMessageList = utils.getTimestamp();
+ Client.getProfilesForDirectMessageList(
+ (data) => {
+ callTracker.getProfilesForDirectMessageList = 0;
+
+ AppDispatcher.handleServerAction({
+ type: ActionTypes.RECEIVED_PROFILES_FOR_DM_LIST,
+ profiles: data
+ });
+ },
+ (err) => {
+ callTracker.getProfilesForDirectMessageList = 0;
+ dispatchError(err, 'getProfilesForDirectMessageList');
+ }
+ );
+}
+
export function getProfiles() {
if (isCallInProgress('getProfiles')) {
return;
diff --git a/webapp/utils/constants.jsx b/webapp/utils/constants.jsx
index 88bf56706..3ae99d7fa 100644
--- a/webapp/utils/constants.jsx
+++ b/webapp/utils/constants.jsx
@@ -60,6 +60,7 @@ export default {
RECEIVED_MENTION_DATA: null,
RECEIVED_ADD_MENTION: null,
+ RECEIVED_PROFILES_FOR_DM_LIST: null,
RECEIVED_PROFILES: null,
RECEIVED_DIRECT_PROFILES: null,
RECEIVED_ME: null,
diff --git a/webapp/utils/utils.jsx b/webapp/utils/utils.jsx
index 8917c97e4..e34fa403f 100644
--- a/webapp/utils/utils.jsx
+++ b/webapp/utils/utils.jsx
@@ -1247,6 +1247,13 @@ export function openDirectChannelToUser(user, successCb, errorCb) {
'true'
);
+ // if the user in another team and isn't already in the direct message
+ // list then we should add him so his name shows up correctly.
+ var profileUser = UserStore.getProfile(user.id);
+ if (!profileUser) {
+ UserStore.getDirectProfiles()[user.id] = user;
+ }
+
const channelName = this.getDirectChannelName(UserStore.getCurrentId(), user.id);
let channel = ChannelStore.getByName(channelName);