diff --git a/webapp/components/profile_picture.jsx b/webapp/components/profile_picture.jsx
index 17a4ddc65f..26e9f30d9a 100644
--- a/webapp/components/profile_picture.jsx
+++ b/webapp/components/profile_picture.jsx
@@ -7,6 +7,11 @@ import React from 'react';
import {OverlayTrigger} from 'react-bootstrap';
export default class ProfilePicture extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.hideProfilePopover = this.hideProfilePopover.bind(this);
+ }
shouldComponentUpdate(nextProps) {
if (!Utils.areObjectsEqual(nextProps.user, this.props.user)) {
return true;
@@ -35,6 +40,10 @@ export default class ProfilePicture extends React.Component {
return false;
}
+ hideProfilePopover() {
+ this.refs.overlay.hide();
+ }
+
render() {
let statusClass = '';
if (this.props.status) {
@@ -43,6 +52,7 @@ export default class ProfilePicture extends React.Component {
if (this.props.user) {
return (
}
>
diff --git a/webapp/components/profile_popover.jsx b/webapp/components/profile_popover.jsx
index 8b431b643c..d7d9929ee5 100644
--- a/webapp/components/profile_popover.jsx
+++ b/webapp/components/profile_popover.jsx
@@ -4,14 +4,17 @@
import * as Utils from 'utils/utils.jsx';
import UserStore from 'stores/user_store.jsx';
import WebrtcStore from 'stores/webrtc_store.jsx';
+import TeamStore from 'stores/team_store.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
import * as WebrtcActions from 'actions/webrtc_actions.jsx';
+import {openDirectChannelToUser} from 'actions/channel_actions.jsx';
import Constants from 'utils/constants.jsx';
const UserStatuses = Constants.UserStatuses;
const PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES;
import {Popover, OverlayTrigger, Tooltip} from 'react-bootstrap';
import {FormattedMessage} from 'react-intl';
+import {browserHistory} from 'react-router/es6';
import React from 'react';
export default class ProfilePopover extends React.Component {
@@ -19,8 +22,10 @@ export default class ProfilePopover extends React.Component {
super(props);
this.initWebrtc = this.initWebrtc.bind(this);
+ this.handleShowDirectChannel = this.handleShowDirectChannel.bind(this);
this.state = {
- currentUserId: UserStore.getCurrentId()
+ currentUserId: UserStore.getCurrentId(),
+ loadingDMChannel: -1
};
}
shouldComponentUpdate(nextProps) {
@@ -60,6 +65,33 @@ export default class ProfilePopover extends React.Component {
return false;
}
+ handleShowDirectChannel(e) {
+ e.preventDefault();
+
+ if (!this.props.user) {
+ return;
+ }
+
+ const user = this.props.user;
+
+ if (this.state.loadingDMChannel !== -1) {
+ return;
+ }
+
+ this.setState({loadingDMChannel: user.id});
+
+ openDirectChannelToUser(
+ user,
+ (channel) => {
+ this.setState({loadingDMChannel: -1});
+ if (this.props.hide) {
+ this.props.hide();
+ }
+ browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/channels/' + channel.name);
+ }
+ );
+ }
+
initWebrtc() {
if (this.props.status !== UserStatuses.OFFLINE && !WebrtcStore.isBusy()) {
GlobalActions.emitCloseRightHandSide();
@@ -73,6 +105,7 @@ export default class ProfilePopover extends React.Component {
delete popoverProps.src;
delete popoverProps.status;
delete popoverProps.isBusy;
+ delete popoverProps.hide;
let webrtc;
const userMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
@@ -203,6 +236,28 @@ export default class ProfilePopover extends React.Component {
);
}
+ if (this.props.user.id !== UserStore.getCurrentId()) {
+ dataContent.push(
+
+ );
+ }
+
return (
}
>
diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json
index ecc25e42fe..641c8daa8e 100644
--- a/webapp/i18n/en.json
+++ b/webapp/i18n/en.json
@@ -2162,6 +2162,7 @@
"user.settings.security.title": "Security Settings",
"user.settings.security.viewHistory": "View Access History",
"user_list.notFound": "No users found",
+ "user_profile.send.dm": "Send Message",
"user_profile.webrtc.call": "Start Video Call",
"user_profile.webrtc.offline": "The user is offline",
"user_profile.webrtc.unavailable": "New call unavailable until your existing call ends",
diff --git a/webapp/sass/components/_popover.scss b/webapp/sass/components/_popover.scss
index 1bd1f2c3b6..b4839bd1f9 100644
--- a/webapp/sass/components/_popover.scss
+++ b/webapp/sass/components/_popover.scss
@@ -34,6 +34,32 @@
}
}
}
+
+ .popover-dm__content {
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ -ms-border-radius: 0;
+ -o-border-radius: 0;
+ border-radius: 0;
+ max-width: 100%;
+ overflow: hidden;
+ padding: 5px 5px 5px 0px;
+ text-overflow: ellipsis;
+ margin: 0;
+ font-size: 14px;
+ border-top: 1px solid #ebebeb;
+ border-color: rgba(221, 221, 221, 0.2);
+ margin-top: 5px;
+ margin-bottom: -5px;
+ > a {
+ > i {
+ margin-right: 5px;
+ }
+ > span {
+ text-transform: capitalize;
+ }
+ }
+ }
}
.channel-header__info {
diff --git a/webapp/utils/utils.jsx b/webapp/utils/utils.jsx
index 38d59a82cc..1ddb286903 100644
--- a/webapp/utils/utils.jsx
+++ b/webapp/utils/utils.jsx
@@ -595,6 +595,7 @@ export function applyTheme(theme) {
changeCss('.app__body .popover.left>.arrow', 'border-left-color:' + changeOpacity(theme.centerChannelColor, 0.25));
changeCss('.app__body .popover.top>.arrow', 'border-top-color:' + changeOpacity(theme.centerChannelColor, 0.25));
changeCss('.app__body .suggestion-list__content .command, .app__body .popover .popover-title', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2));
+ changeCss('.app__body .suggestion-list__content .command, .app__body .popover .popover-dm__content', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2));
changeCss('.app__body .suggestion-list__divider:before, .app__body .dropdown-menu .divider, .app__body .search-help-popover .search-autocomplete__divider:before', 'background:' + theme.centerChannelColor);
changeCss('.app__body .custom-textarea', 'color:' + theme.centerChannelColor);
changeCss('.app__body .post-image__column', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2));