diff options
author | Kevyn Bruyere <6eme.hokage@gmail.com> | 2016-06-15 14:30:32 +0200 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2016-06-15 06:30:32 -0600 |
commit | d6fdd936797890565dff4e6951a6792b7e09831c (patch) | |
tree | ca188cd891cb4930bae303f1d5f92250c75deba3 /webapp/components | |
parent | dbcf8572e5af1c0c244850627437d97616098740 (diff) | |
download | chat-d6fdd936797890565dff4e6951a6792b7e09831c.tar.gz chat-d6fdd936797890565dff4e6951a6792b7e09831c.tar.bz2 chat-d6fdd936797890565dff4e6951a6792b7e09831c.zip |
PLT-946 Add status icon to the left of the username in DM channel (#3258)
Add a StatusIcon component to be able to display a status icon from anywhere
Diffstat (limited to 'webapp/components')
-rw-r--r-- | webapp/components/channel_header.jsx | 22 | ||||
-rw-r--r-- | webapp/components/navbar.jsx | 20 | ||||
-rw-r--r-- | webapp/components/sidebar.jsx | 24 | ||||
-rw-r--r-- | webapp/components/status_icon.jsx | 37 |
4 files changed, 80 insertions, 23 deletions
diff --git a/webapp/components/channel_header.jsx b/webapp/components/channel_header.jsx index 34ac53705..181d37ca2 100644 --- a/webapp/components/channel_header.jsx +++ b/webapp/components/channel_header.jsx @@ -15,6 +15,7 @@ import ChannelNotificationsModal from './channel_notifications_modal.jsx'; import DeleteChannelModal from './delete_channel_modal.jsx'; import RenameChannelModal from './rename_channel_modal.jsx'; import ToggleModalButton from './toggle_modal_button.jsx'; +import StatusIcon from './status_icon.jsx'; import ChannelStore from 'stores/channel_store.jsx'; import UserStore from 'stores/user_store.jsx'; @@ -82,6 +83,7 @@ export default class ChannelHeader extends React.Component { SearchStore.addSearchChangeListener(this.onListenerChange); PreferenceStore.addChangeListener(this.onListenerChange); UserStore.addChangeListener(this.onListenerChange); + UserStore.addStatusesChangeListener(this.onListenerChange); $('.sidebar--left .dropdown-menu').perfectScrollbar(); document.addEventListener('keydown', this.openRecentMentions); } @@ -91,6 +93,7 @@ export default class ChannelHeader extends React.Component { SearchStore.removeSearchChangeListener(this.onListenerChange); PreferenceStore.removeChangeListener(this.onListenerChange); UserStore.removeChangeListener(this.onListenerChange); + UserStore.removeStatusesChangeListener(this.onListenerChange); document.removeEventListener('keydown', this.openRecentMentions); } onListenerChange() { @@ -157,6 +160,21 @@ export default class ChannelHeader extends React.Component { showRenameChannelModal: false }); } + + getTeammateStatus() { + const channel = this.state.channel; + + // get status for direct message channels + if (channel.type === 'D') { + const currentUserId = this.state.currentUser.id; + const teammate = this.state.users.find((user) => user.id !== currentUserId); + if (teammate) { + return UserStore.getStatus(teammate.id); + } + } + return null; + } + render() { if (!this.validState()) { return null; @@ -173,7 +191,7 @@ export default class ChannelHeader extends React.Component { ); const popoverContent = ( <Popover - id='hader-popover' + id='header-popover' bStyle='info' bSize='large' placement='bottom' @@ -459,7 +477,7 @@ export default class ChannelHeader extends React.Component { data-toggle='dropdown' aria-expanded='true' > - <strong className='heading'>{channelTitle} </strong> + <strong className='heading'><StatusIcon status={this.getTeammateStatus()}/>{channelTitle} </strong> <span className='glyphicon glyphicon-chevron-down header-dropdown__icon'/> </a> <ul diff --git a/webapp/components/navbar.jsx b/webapp/components/navbar.jsx index cfda38670..32682bc78 100644 --- a/webapp/components/navbar.jsx +++ b/webapp/components/navbar.jsx @@ -13,6 +13,7 @@ import ChannelNotificationsModal from './channel_notifications_modal.jsx'; import DeleteChannelModal from './delete_channel_modal.jsx'; import RenameChannelModal from './rename_channel_modal.jsx'; import ToggleModalButton from './toggle_modal_button.jsx'; +import StatusIcon from './status_icon.jsx'; import UserStore from 'stores/user_store.jsx'; import ChannelStore from 'stores/channel_store.jsx'; @@ -77,12 +78,14 @@ export default class Navbar extends React.Component { componentDidMount() { ChannelStore.addChangeListener(this.onChange); ChannelStore.addExtraInfoChangeListener(this.onChange); + UserStore.addStatusesChangeListener(this.onChange); $('.inner-wrap').click(this.hideSidebars); document.addEventListener('keydown', this.showChannelSwitchModal); } componentWillUnmount() { ChannelStore.removeChangeListener(this.onChange); ChannelStore.removeExtraInfoChangeListener(this.onChange); + UserStore.removeStatusesChangeListener(this.onChange); document.removeEventListener('keydown', this.showChannelSwitchModal); } handleSubmit(e) { @@ -352,7 +355,7 @@ export default class Navbar extends React.Component { data-toggle='dropdown' aria-expanded='true' > - <span className='heading'>{channelTitle} </span> + <span className='heading'><StatusIcon status={this.getTeammateStatus()}/>{channelTitle} </span> <span className='glyphicon glyphicon-chevron-down header-dropdown__icon'></span> </a> <ul @@ -446,6 +449,21 @@ export default class Navbar extends React.Component { return buttons; } + + getTeammateStatus() { + const channel = this.state.channel; + + // get status for direct message channels + if (channel.type === 'D') { + const currentUserId = this.state.currentUser.id; + const teammate = this.state.users.find((user) => user.id !== currentUserId); + if (teammate) { + return UserStore.getStatus(teammate.id); + } + } + return null; + } + render() { if (!this.isStateValid()) { return null; diff --git a/webapp/components/sidebar.jsx b/webapp/components/sidebar.jsx index 1c02c9d98..f6c2a1a5a 100644 --- a/webapp/components/sidebar.jsx +++ b/webapp/components/sidebar.jsx @@ -8,6 +8,7 @@ import MoreDirectChannels from './more_direct_channels.jsx'; import SidebarHeader from './sidebar_header.jsx'; import UnreadChannelIndicator from './unread_channel_indicator.jsx'; import TutorialTip from './tutorial/tutorial_tip.jsx'; +import StatusIcon from './status_icon.jsx'; import ChannelStore from 'stores/channel_store.jsx'; import UserStore from 'stores/user_store.jsx'; @@ -503,30 +504,14 @@ export default class Sidebar extends React.Component { rowClass += ' has-badge'; } - // set up status icon for direct message channels - var status = null; - if (channel.type === 'D') { - var statusIcon = ''; - if (channel.status === 'online') { - statusIcon = Constants.ONLINE_ICON_SVG; - } else if (channel.status === 'away') { - statusIcon = Constants.AWAY_ICON_SVG; - } else { - statusIcon = Constants.OFFLINE_ICON_SVG; - } - status = ( - <span - className='status' - dangerouslySetInnerHTML={{__html: statusIcon}} - /> - ); - } - var icon = null; if (channel.type === 'O') { icon = <div className='status'><i className='fa fa-globe'></i></div>; } else if (channel.type === 'P') { icon = <div className='status'><i className='fa fa-lock'></i></div>; + } else { + // set up status icon for direct message channels (status is null for other channel types) + icon = <StatusIcon status={channel.status}/>; } let closeButton = null; @@ -581,7 +566,6 @@ export default class Sidebar extends React.Component { className={rowClass} > {icon} - {status} {channel.display_name} {badge} {closeButton} diff --git a/webapp/components/status_icon.jsx b/webapp/components/status_icon.jsx new file mode 100644 index 000000000..a4242fb60 --- /dev/null +++ b/webapp/components/status_icon.jsx @@ -0,0 +1,37 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import Constants from 'utils/constants.jsx'; + +import React from 'react'; + +export default class StatusIcon extends React.Component { + render() { + const status = this.props.status; + + if (!status) { + return null; + } + + let statusIcon = ''; + if (status === 'online') { + statusIcon = Constants.ONLINE_ICON_SVG; + } else if (status === 'away') { + statusIcon = Constants.AWAY_ICON_SVG; + } else { + statusIcon = Constants.OFFLINE_ICON_SVG; + } + + return ( + <span + className='status' + dangerouslySetInnerHTML={{__html: statusIcon}} + /> + ); + } + +} + +StatusIcon.propTypes = { + status: React.PropTypes.string.isRequired +};
\ No newline at end of file |