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
Этот коммит содержится в:
коммит произвёл
Christopher Speller
родитель
dbcf8572e5
Коммит
d6fdd93679
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}
|
||||
|
||||
37
webapp/components/status_icon.jsx
Обычный файл
37
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
|
||||
};
|
||||
Ссылка в новой задаче
Block a user