diff options
Diffstat (limited to 'webapp')
-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 | ||||
-rw-r--r-- | webapp/sass/components/_status-icon.scss | 33 | ||||
-rw-r--r-- | webapp/sass/layout/_headers.scss | 2 | ||||
-rw-r--r-- | webapp/sass/layout/_sidebar-left.scss | 34 | ||||
-rw-r--r-- | webapp/sass/responsive/_mobile.scss | 2 | ||||
-rw-r--r-- | webapp/utils/utils.jsx | 8 |
9 files changed, 126 insertions, 56 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 diff --git a/webapp/sass/components/_status-icon.scss b/webapp/sass/components/_status-icon.scss new file mode 100644 index 000000000..32ce07164 --- /dev/null +++ b/webapp/sass/components/_status-icon.scss @@ -0,0 +1,33 @@ +@charset 'UTF-8'; + +.status { + display: inline-block; + margin-right: 6px; + position: relative; + top: 1px; + width: 12px; + + svg { + max-height: 14px; + } + + i, + path, + ellipse { + @include opacity(.5); + + &.online--icon, + &.away--icon { + @include opacity(1); + } + } + + .fa-lock { + margin-left: 1px; + } + + .fa-globe { + position: relative; + top: -1px; + } +}
\ No newline at end of file diff --git a/webapp/sass/layout/_headers.scss b/webapp/sass/layout/_headers.scss index d0ccfbe23..2382a39e4 100644 --- a/webapp/sass/layout/_headers.scss +++ b/webapp/sass/layout/_headers.scss @@ -144,6 +144,8 @@ white-space: normal; } } + + @import "../components/status-icon"; } .channel-intro { diff --git a/webapp/sass/layout/_sidebar-left.scss b/webapp/sass/layout/_sidebar-left.scss index 6b8658d25..d4d01c865 100644 --- a/webapp/sass/layout/_sidebar-left.scss +++ b/webapp/sass/layout/_sidebar-left.scss @@ -60,38 +60,6 @@ top: 5px; } - .status { - display: inline-block; - margin-right: 6px; - position: relative; - top: 1px; - width: 12px; - - svg { - max-height: 14px; - } - - i, - path, - ellipse { - @include opacity(.5); - - &.online--icon, - &.away--icon { - @include opacity(1); - } - } - - .fa-lock { - margin-left: 1px; - } - - .fa-globe { - position: relative; - top: -1px; - } - } - .nav-pills__container { -webkit-overflow-scrolling: touch; height: calc(100% - 80px); @@ -234,6 +202,8 @@ color: #666666; } } + + @import "../components/status-icon"; } .channel-loading-gif { diff --git a/webapp/sass/responsive/_mobile.scss b/webapp/sass/responsive/_mobile.scss index cb1191fe3..6308829ec 100644 --- a/webapp/sass/responsive/_mobile.scss +++ b/webapp/sass/responsive/_mobile.scss @@ -590,6 +590,8 @@ .navbar-brand { white-space: nowrap; + + @import "../components/status-icon"; } } } diff --git a/webapp/utils/utils.jsx b/webapp/utils/utils.jsx index 96eedaf75..d2fd2efbf 100644 --- a/webapp/utils/utils.jsx +++ b/webapp/utils/utils.jsx @@ -521,7 +521,7 @@ export function applyTheme(theme) { changeCss('@media(max-width: 768px){.app__body .modal .settings-modal .settings-table .nav>li>a', 'color:' + theme.sidebarText, 1); changeCss('.app__body .sidebar--left .nav-pills__container li>h4, .app__body .sidebar--left .add-channel-btn', 'color:' + changeOpacity(theme.sidebarText, 0.6), 1); changeCss('.app__body .sidebar--left .add-channel-btn:hover, .app__body .sidebar--left .add-channel-btn:focus', 'color:' + theme.sidebarText, 1); - changeCss('.app__body .sidebar--left .status .offline--icon, .app__body .sidebar--left .status .offline--icon', 'fill:' + theme.sidebarText, 1); + changeCss('.app__body .sidebar--left .status .offline--icon', 'fill:' + theme.sidebarText, 1); changeCss('@media(max-width: 768px){.app__body .modal .settings-modal .settings-table .nav>li>a', 'border-color:' + changeOpacity(theme.sidebarText, 0.2), 2); } @@ -566,10 +566,14 @@ export function applyTheme(theme) { if (theme.onlineIndicator) { changeCss('.app__body .sidebar--left .status .online--icon', 'fill:' + theme.onlineIndicator, 1); + changeCss('.app__body .channel-header__info .status .online--icon', 'fill:' + theme.onlineIndicator, 1); + changeCss('.app__body .navbar .status .online--icon', 'fill:' + theme.onlineIndicator, 1); } if (theme.awayIndicator) { changeCss('.app__body .sidebar--left .status .away--icon', 'fill:' + theme.awayIndicator, 1); + changeCss('.app__body .channel-header__info .status .away--icon', 'fill:' + theme.awayIndicator, 1); + changeCss('.app__body .navbar .status .away--icon', 'fill:' + theme.awayIndicator, 1); } if (theme.mentionBj) { @@ -659,6 +663,8 @@ export function applyTheme(theme) { changeCss('.app__body .post.post--comment .post__body', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1); changeCss('@media(min-width: 768px){.app__body .post.post--compact.same--root.post--comment .post__content', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1); changeCss('.app__body .post.post--comment.current--user .post__body', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1); + changeCss('.app__body .channel-header__info .status .offline--icon', 'fill:' + theme.centerChannelColor, 1); + changeCss('.app__body .navbar .status .offline--icon', 'fill:' + theme.centerChannelColor, 1); } if (theme.newMessageSeparator) { |