diff options
author | Joram Wilander <jwawilander@gmail.com> | 2017-03-02 17:48:56 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-02 17:48:56 -0500 |
commit | 3a91d4e5e419a43ff19a0736ce697f8d611d36e3 (patch) | |
tree | e57ad85d49f8768a575f27c89d338a4ccaeda521 /webapp/components/sidebar.jsx | |
parent | 8c5cee9521656bcffb371aad9dae4bea8fc70e29 (diff) | |
download | chat-3a91d4e5e419a43ff19a0736ce697f8d611d36e3.tar.gz chat-3a91d4e5e419a43ff19a0736ce697f8d611d36e3.tar.bz2 chat-3a91d4e5e419a43ff19a0736ce697f8d611d36e3.zip |
PLT-3077 Add group messaging (#5489)
* Implement server changes for group messaging
* Majority of client-side implementation
* Some server updates
* Added new React multiselect component
* Fix style issues
* Add custom renderer for options
* Fix model test
* Update ENTER functionality for multiselect control
* Remove buttons from multiselect UI control
* Updating group messaging UI (#5524)
* Move filter controls up a component level
* Scroll with arrow keys
* Updating mobile layout for multiselect (#5534)
* Fix race condition when backspacing quickly
* Hidden or new GMs show up for regular messages
* Add overriding of number remaining text
* Add UI filtering for team if config setting set
* Add icon to channel switcher and class prop to status icon
* Minor updates per feedback
* Improving group messaging UI (#5563)
* UX changes per feedback
* Update email for group messages
* UI fixes for group messaging (#5587)
* Fix missing localization string
* Add maximum users message when adding members to GM
* Fix input clearing on Android
* Updating group messaging UI (#5603)
* Updating UI for group messaging (#5604)
Diffstat (limited to 'webapp/components/sidebar.jsx')
-rw-r--r-- | webapp/components/sidebar.jsx | 77 |
1 files changed, 46 insertions, 31 deletions
diff --git a/webapp/components/sidebar.jsx b/webapp/components/sidebar.jsx index c4c5f0517..ce584d477 100644 --- a/webapp/components/sidebar.jsx +++ b/webapp/components/sidebar.jsx @@ -15,6 +15,7 @@ import ChannelStore from 'stores/channel_store.jsx'; import UserStore from 'stores/user_store.jsx'; import TeamStore from 'stores/team_store.jsx'; import PreferenceStore from 'stores/preference_store.jsx'; +import ModalStore from 'stores/modal_store.jsx'; import * as AsyncClient from 'utils/async_client.jsx'; import * as Utils from 'utils/utils.jsx'; @@ -22,7 +23,7 @@ import * as ChannelUtils from 'utils/channel_utils.jsx'; import * as ChannelActions from 'actions/channel_actions.jsx'; import {trackEvent} from 'actions/diagnostics_actions.jsx'; -import Constants from 'utils/constants.jsx'; +import {ActionTypes, Constants} from 'utils/constants.jsx'; import {FormattedMessage, FormattedHTMLMessage} from 'react-intl'; @@ -49,6 +50,8 @@ export default class Sidebar extends React.Component { this.getStateFromStores = this.getStateFromStores.bind(this); this.onChange = this.onChange.bind(this); + this.onModalChange = this.onModalChange.bind(this); + this.onInChannelChange = this.onInChannelChange.bind(this); this.onScroll = this.onScroll.bind(this); this.updateUnreadIndicators = this.updateUnreadIndicators.bind(this); this.handleLeaveDirectChannel = this.handleLeaveDirectChannel.bind(this); @@ -77,6 +80,7 @@ export default class Sidebar extends React.Component { state.showDirectChannelsModal = false; state.showMoreChannelsModal = false; state.loadingDMChannel = -1; + state.inChannelChange = false; this.state = state; } @@ -96,7 +100,7 @@ export default class Sidebar extends React.Component { Object.keys(unreadCounts).forEach((chId) => { const channel = ChannelStore.get(chId); - if (channel && (channel.type === 'D' || channel.team_id === this.state.currentTeam.id)) { + if (channel && (channel.type === Constants.DM_CHANNEL || channel.type === Constants.GM_CHANNEL || channel.team_id === this.state.currentTeam.id)) { msgs += unreadCounts[chId].msgs; mentions += unreadCounts[chId].mentions; } @@ -128,13 +132,19 @@ export default class Sidebar extends React.Component { }; } + onInChannelChange() { + this.setState({inChannelChange: !this.state.inChannelChange}); + } + componentDidMount() { ChannelStore.addChangeListener(this.onChange); UserStore.addChangeListener(this.onChange); UserStore.addInTeamChangeListener(this.onChange); + UserStore.addInChannelChangeListener(this.onInChannelChange); UserStore.addStatusesChangeListener(this.onChange); TeamStore.addChangeListener(this.onChange); PreferenceStore.addChangeListener(this.onChange); + ModalStore.addModalListener(ActionTypes.TOGGLE_DM_MODAL, this.onModalChange); this.updateTitle(); this.updateUnreadIndicators(); @@ -179,13 +189,19 @@ export default class Sidebar extends React.Component { ChannelStore.removeChangeListener(this.onChange); UserStore.removeChangeListener(this.onChange); UserStore.removeInTeamChangeListener(this.onChange); + UserStore.removeInChannelChangeListener(this.onChange); UserStore.removeStatusesChangeListener(this.onChange); TeamStore.removeChangeListener(this.onChange); PreferenceStore.removeChangeListener(this.onChange); + ModalStore.removeModalListener(ActionTypes.TOGGLE_DM_MODAL, this.onModalChange); document.removeEventListener('keydown', this.navigateChannelShortcut); document.removeEventListener('keydown', this.navigateUnreadChannelShortcut); } + onModalChange(value, args) { + this.showMoreDirectChannelsModal(args.startingUsers); + } + onChange() { if (this.state.currentTeam.id !== TeamStore.getCurrentId()) { ChannelStore.clear(); @@ -203,11 +219,13 @@ export default class Sidebar extends React.Component { } let currentChannelName = channel.display_name; - if (channel.type === 'D') { + if (channel.type === Constants.DM_CHANNEL) { const teammate = Utils.getDirectTeammate(channel.id); if (teammate != null) { currentChannelName = teammate.username; } + } else if (channel.type === Constants.GM_CHANNEL) { + currentChannelName = ChannelUtils.buildGroupChannelName(channel.id); } const unread = this.getTotalUnreadCount(); @@ -331,7 +349,7 @@ export default class Sidebar extends React.Component { } getDisplayedChannels() { - return this.state.favoriteChannels.concat(this.state.publicChannels).concat(this.state.privateChannels).concat(this.state.directChannels).concat(this.state.directNonTeamChannels); + return this.state.favoriteChannels.concat(this.state.publicChannels).concat(this.state.privateChannels).concat(this.state.directAndGroupChannels).concat(this.state.directNonTeamChannels); } handleLeaveDirectChannel(e, channel) { @@ -340,9 +358,19 @@ export default class Sidebar extends React.Component { if (!this.isLeaving.get(channel.id)) { this.isLeaving.set(channel.id, true); + let id; + let category; + if (channel.type === Constants.DM_CHANNEL) { + id = channel.teammate_id; + category = Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW; + } else { + id = channel.id; + category = Constants.Preferences.CATEGORY_GROUP_CHANNEL_SHOW; + } + AsyncClient.savePreference( - Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, - channel.teammate_id, + category, + id, 'false', () => { this.isLeaving.set(channel.id, false); @@ -382,13 +410,13 @@ export default class Sidebar extends React.Component { this.setState({newChannelModalType: ''}); } - showMoreDirectChannelsModal() { + showMoreDirectChannelsModal(startingUsers) { trackEvent('ui', 'ui_channels_more_direct'); - this.setState({showDirectChannelsModal: true}); + this.setState({showDirectChannelsModal: true, startingUsers}); } hideMoreDirectChannelsModal() { - this.setState({showDirectChannelsModal: false}); + this.setState({showDirectChannelsModal: false, startingUsers: null}); } openLeftSidebar() { @@ -509,11 +537,16 @@ export default class Sidebar extends React.Component { rowClass += ' has-badge'; } + let displayName = channel.display_name; + var icon = null; if (channel.type === Constants.OPEN_CHANNEL) { icon = <div className='status'><i className='fa fa-globe'/></div>; } else if (channel.type === Constants.PRIVATE_CHANNEL) { icon = <div className='status'><i className='fa fa-lock'/></div>; + } else if (channel.type === Constants.GM_CHANNEL) { + displayName = ChannelUtils.buildGroupChannelName(channel.id); + icon = <div className='status status--group'>{UserStore.getProfileListInChannel(channel.id, true).length}</div>; } else { // set up status icon for direct message channels (status is null for other channel types) icon = ( @@ -576,7 +609,7 @@ export default class Sidebar extends React.Component { onClick={this.trackChannelSelectedEvent} > {icon} - {channel.display_name} + {displayName} {badge} {closeButton} </Link> @@ -615,27 +648,10 @@ export default class Sidebar extends React.Component { const privateChannelItems = this.state.privateChannels.map(this.createChannelElement); - const directMessageItems = this.state.directChannels.map((channel, index, arr) => { + const directMessageItems = this.state.directAndGroupChannels.map((channel, index, arr) => { return this.createChannelElement(channel, index, arr, this.handleLeaveDirectChannel); }); - const directMessageNonTeamItems = this.state.directNonTeamChannels.map((channel, index, arr) => { - return this.createChannelElement(channel, index, arr, this.handleLeaveDirectChannel); - }); - - let directDivider; - if (directMessageNonTeamItems.length !== 0) { - directDivider = - (<div className='sidebar__divider'> - <div className='sidebar__divider__text'> - <FormattedMessage - id='sidebar.otherMembers' - defaultMessage='Outside this team' - /> - </div> - </div>); - } - // update the favicon to show if there are any notifications if (this.lastBadgesActive !== this.badgesActive) { var link = document.createElement('link'); @@ -659,7 +675,7 @@ export default class Sidebar extends React.Component { <li key='more'> <a href='#' - onClick={this.showMoreDirectChannelsModal} + onClick={() => this.showMoreDirectChannelsModal()} > <FormattedMessage id='sidebar.moreElips' @@ -753,6 +769,7 @@ export default class Sidebar extends React.Component { moreDirectChannelsModal = ( <MoreDirectChannels onModalDismissed={this.hideMoreDirectChannelsModal} + startingUsers={this.state.startingUsers} /> ); } @@ -866,8 +883,6 @@ export default class Sidebar extends React.Component { </h4> </li> {directMessageItems} - {directDivider} - {directMessageNonTeamItems} {directMessageMore} </ul> </div> |