2016-01-18 18:19:49 +03:00
|
|
|
/*
|
|
|
|
Copyright 2015, 2016 OpenMarket Ltd
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var React = require('react');
|
|
|
|
|
|
|
|
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
|
|
|
var sdk = require('../../../index');
|
2017-01-25 01:41:52 +03:00
|
|
|
import AccessibleButton from '../elements/AccessibleButton';
|
2016-01-18 18:19:49 +03:00
|
|
|
|
|
|
|
|
|
|
|
var PRESENCE_CLASS = {
|
2016-01-18 19:47:31 +03:00
|
|
|
"offline": "mx_EntityTile_offline",
|
|
|
|
"online": "mx_EntityTile_online",
|
|
|
|
"unavailable": "mx_EntityTile_unavailable"
|
2016-01-18 18:19:49 +03:00
|
|
|
};
|
|
|
|
|
2016-07-14 19:41:07 +03:00
|
|
|
|
2016-07-14 20:18:44 +03:00
|
|
|
function presenceClassForMember(presenceState, lastActiveAgo) {
|
2016-07-14 19:41:07 +03:00
|
|
|
// offline is split into two categories depending on whether we have
|
|
|
|
// a last_active_ago for them.
|
2016-07-14 20:18:44 +03:00
|
|
|
if (presenceState == 'offline') {
|
|
|
|
if (lastActiveAgo) {
|
2016-07-14 19:41:07 +03:00
|
|
|
return PRESENCE_CLASS['offline'] + '_beenactive';
|
|
|
|
} else {
|
|
|
|
return PRESENCE_CLASS['offline'] + '_neveractive';
|
|
|
|
}
|
2016-07-14 20:18:44 +03:00
|
|
|
} else if (presenceState) {
|
|
|
|
return PRESENCE_CLASS[presenceState];
|
2016-07-14 19:41:07 +03:00
|
|
|
} else {
|
2016-07-14 20:13:54 +03:00
|
|
|
return PRESENCE_CLASS['offline'] + '_neveractive';
|
2016-07-14 19:41:07 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-18 18:19:49 +03:00
|
|
|
module.exports = React.createClass({
|
|
|
|
displayName: 'EntityTile',
|
|
|
|
|
|
|
|
propTypes: {
|
|
|
|
name: React.PropTypes.string,
|
|
|
|
title: React.PropTypes.string,
|
|
|
|
avatarJsx: React.PropTypes.any, // <BaseAvatar />
|
2016-01-21 20:39:12 +03:00
|
|
|
className: React.PropTypes.string,
|
2016-01-18 18:19:49 +03:00
|
|
|
presenceState: React.PropTypes.string,
|
2016-04-18 03:35:40 +03:00
|
|
|
presenceLastActiveAgo: React.PropTypes.number,
|
|
|
|
presenceLastTs: React.PropTypes.number,
|
2016-03-17 03:07:30 +03:00
|
|
|
presenceCurrentlyActive: React.PropTypes.bool,
|
2016-01-18 18:19:49 +03:00
|
|
|
showInviteButton: React.PropTypes.bool,
|
|
|
|
shouldComponentUpdate: React.PropTypes.func,
|
2016-01-21 14:41:28 +03:00
|
|
|
onClick: React.PropTypes.func,
|
|
|
|
suppressOnHover: React.PropTypes.bool
|
2016-01-18 18:19:49 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
getDefaultProps: function() {
|
|
|
|
return {
|
2016-01-21 18:57:59 +03:00
|
|
|
shouldComponentUpdate: function(nextProps, nextState) { return true; },
|
2016-01-18 18:19:49 +03:00
|
|
|
onClick: function() {},
|
|
|
|
presenceState: "offline",
|
2016-04-18 03:35:40 +03:00
|
|
|
presenceLastActiveAgo: 0,
|
|
|
|
presenceLastTs: 0,
|
2016-01-18 18:19:49 +03:00
|
|
|
showInviteButton: false,
|
2016-01-21 14:41:28 +03:00
|
|
|
suppressOnHover: false
|
2016-01-18 18:19:49 +03:00
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
getInitialState: function() {
|
|
|
|
return {
|
|
|
|
hover: false
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
shouldComponentUpdate: function(nextProps, nextState) {
|
|
|
|
if (this.state.hover !== nextState.hover) return true;
|
|
|
|
return this.props.shouldComponentUpdate(nextProps, nextState);
|
|
|
|
},
|
|
|
|
|
|
|
|
mouseEnter: function(e) {
|
|
|
|
this.setState({ 'hover': true });
|
|
|
|
},
|
|
|
|
|
|
|
|
mouseLeave: function(e) {
|
|
|
|
this.setState({ 'hover': false });
|
|
|
|
},
|
|
|
|
|
|
|
|
render: function() {
|
2016-07-14 20:13:15 +03:00
|
|
|
const presenceClass = presenceClassForMember(
|
2016-07-14 19:41:07 +03:00
|
|
|
this.props.presenceState, this.props.presenceLastActiveAgo
|
|
|
|
);
|
|
|
|
|
2016-01-18 19:47:31 +03:00
|
|
|
var mainClassName = "mx_EntityTile ";
|
2016-01-21 20:39:12 +03:00
|
|
|
mainClassName += presenceClass + (this.props.className ? (" " + this.props.className) : "");
|
2016-01-18 18:19:49 +03:00
|
|
|
var nameEl;
|
2016-08-09 22:01:51 +03:00
|
|
|
const {name} = this.props;
|
2016-01-21 14:41:28 +03:00
|
|
|
|
2016-08-11 05:25:12 +03:00
|
|
|
const EmojiText = sdk.getComponent('elements.EmojiText');
|
2016-01-21 14:41:28 +03:00
|
|
|
if (this.state.hover && !this.props.suppressOnHover) {
|
2016-04-18 03:35:40 +03:00
|
|
|
var activeAgo = this.props.presenceLastActiveAgo ?
|
|
|
|
(Date.now() - (this.props.presenceLastTs - this.props.presenceLastActiveAgo)) : -1;
|
|
|
|
|
2016-01-21 14:41:28 +03:00
|
|
|
mainClassName += " mx_EntityTile_hover";
|
2016-01-18 18:19:49 +03:00
|
|
|
var PresenceLabel = sdk.getComponent("rooms.PresenceLabel");
|
|
|
|
nameEl = (
|
2016-01-18 19:47:31 +03:00
|
|
|
<div className="mx_EntityTile_details">
|
|
|
|
<img className="mx_EntityTile_chevron" src="img/member_chevron.png" width="8" height="12"/>
|
2016-08-09 22:01:51 +03:00
|
|
|
<EmojiText element="div" className="mx_EntityTile_name_hover">{name}</EmojiText>
|
2016-04-18 03:35:40 +03:00
|
|
|
<PresenceLabel activeAgo={ activeAgo }
|
2016-03-17 01:44:54 +03:00
|
|
|
currentlyActive={this.props.presenceCurrentlyActive}
|
2016-01-18 18:19:49 +03:00
|
|
|
presenceState={this.props.presenceState} />
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nameEl = (
|
2016-08-09 22:01:51 +03:00
|
|
|
<EmojiText element="div" className="mx_EntityTile_name">{name}</EmojiText>
|
2016-01-18 18:19:49 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-01-18 19:47:31 +03:00
|
|
|
var inviteButton;
|
|
|
|
if (this.props.showInviteButton) {
|
|
|
|
inviteButton = (
|
|
|
|
<div className="mx_EntityTile_invite">
|
2016-01-18 20:21:28 +03:00
|
|
|
<img src="img/plus.svg" width="16" height="16" />
|
2016-01-18 19:47:31 +03:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-01-18 20:37:17 +03:00
|
|
|
var power;
|
|
|
|
var powerLevel = this.props.powerLevel;
|
|
|
|
if (powerLevel >= 50 && powerLevel < 99) {
|
|
|
|
power = <img src="img/mod.svg" className="mx_EntityTile_power" width="16" height="17" alt="Mod"/>;
|
|
|
|
}
|
|
|
|
if (powerLevel >= 99) {
|
|
|
|
power = <img src="img/admin.svg" className="mx_EntityTile_power" width="16" height="17" alt="Admin"/>;
|
|
|
|
}
|
|
|
|
|
2016-01-18 19:47:31 +03:00
|
|
|
|
2016-01-18 18:19:49 +03:00
|
|
|
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
|
|
|
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
|
|
|
|
2016-01-20 17:14:04 +03:00
|
|
|
var av = this.props.avatarJsx || <BaseAvatar name={this.props.name} width={36} height={36} />;
|
2016-01-18 18:19:49 +03:00
|
|
|
|
|
|
|
return (
|
2017-01-13 19:25:26 +03:00
|
|
|
<AccessibleButton className={mainClassName} title={ this.props.title }
|
2016-01-18 18:19:49 +03:00
|
|
|
onClick={ this.props.onClick } onMouseEnter={ this.mouseEnter }
|
|
|
|
onMouseLeave={ this.mouseLeave }>
|
2016-01-18 19:47:31 +03:00
|
|
|
<div className="mx_EntityTile_avatar">
|
2016-01-20 18:52:34 +03:00
|
|
|
{ av }
|
|
|
|
{ power }
|
2016-01-18 18:19:49 +03:00
|
|
|
</div>
|
|
|
|
{ nameEl }
|
2016-01-18 19:47:31 +03:00
|
|
|
{ inviteButton }
|
2017-01-13 19:25:26 +03:00
|
|
|
</AccessibleButton>
|
2016-01-18 18:19:49 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|