mirror of
https://github.com/element-hq/element-web
synced 2024-11-28 12:28:50 +03:00
Factor out common code between MemberTile and UserTile into EntityTile. Use EntityTile.
This commit is contained in:
parent
fd99b260f4
commit
71009d81b6
5 changed files with 149 additions and 157 deletions
|
@ -60,6 +60,7 @@ module.exports.components['views.messages.MVideoBody'] = require('./components/v
|
|||
module.exports.components['views.messages.TextualBody'] = require('./components/views/messages/TextualBody');
|
||||
module.exports.components['views.messages.TextualEvent'] = require('./components/views/messages/TextualEvent');
|
||||
module.exports.components['views.messages.UnknownBody'] = require('./components/views/messages/UnknownBody');
|
||||
module.exports.components['views.rooms.EntityTile'] = require('./components/views/rooms/EntityTile');
|
||||
module.exports.components['views.rooms.EventTile'] = require('./components/views/rooms/EventTile');
|
||||
module.exports.components['views.rooms.MemberInfo'] = require('./components/views/rooms/MemberInfo');
|
||||
module.exports.components['views.rooms.MemberList'] = require('./components/views/rooms/MemberList');
|
||||
|
|
118
src/components/views/rooms/EntityTile.js
Normal file
118
src/components/views/rooms/EntityTile.js
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
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');
|
||||
|
||||
|
||||
var PRESENCE_CLASS = {
|
||||
"offline": "mx_MemberTile_offline",
|
||||
"online": "mx_MemberTile_online",
|
||||
"unavailable": "mx_MemberTile_unavailable"
|
||||
};
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'EntityTile',
|
||||
|
||||
propTypes: {
|
||||
name: React.PropTypes.string,
|
||||
title: React.PropTypes.string,
|
||||
avatarJsx: React.PropTypes.any, // <BaseAvatar />
|
||||
presenceState: React.PropTypes.string,
|
||||
presenceActiveAgo: React.PropTypes.number,
|
||||
showInviteButton: React.PropTypes.bool,
|
||||
shouldComponentUpdate: React.PropTypes.func,
|
||||
onClick: React.PropTypes.func
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
shouldComponentUpdate: function(nextProps, nextState) { return false; },
|
||||
onClick: function() {},
|
||||
presenceState: "offline",
|
||||
presenceActiveAgo: -1,
|
||||
showInviteButton: false,
|
||||
};
|
||||
},
|
||||
|
||||
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() {
|
||||
var presenceClass = PRESENCE_CLASS[this.props.presenceState];
|
||||
var mainClassName = "mx_MemberTile ";
|
||||
mainClassName += presenceClass;
|
||||
if (this.state.hover) {
|
||||
mainClassName += " mx_MemberTile_hover";
|
||||
}
|
||||
|
||||
var nameEl;
|
||||
if (this.state.hover) {
|
||||
var PresenceLabel = sdk.getComponent("rooms.PresenceLabel");
|
||||
nameEl = (
|
||||
<div className="mx_MemberTile_details">
|
||||
<img className="mx_MemberTile_chevron" src="img/member_chevron.png" width="8" height="12"/>
|
||||
<div className="mx_MemberTile_userId">{ this.props.name }</div>
|
||||
<PresenceLabel activeAgo={this.props.presenceActiveAgo}
|
||||
presenceState={this.props.presenceState} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else {
|
||||
nameEl = (
|
||||
<div className="mx_MemberTile_name">
|
||||
{ this.props.name }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
|
||||
var av = this.props.avatarJsx || <BaseAvatar name={name} width={36} height={36} />;
|
||||
|
||||
return (
|
||||
<div className={mainClassName} title={ this.props.title }
|
||||
onClick={ this.props.onClick } onMouseEnter={ this.mouseEnter }
|
||||
onMouseLeave={ this.mouseLeave }>
|
||||
<div className="mx_MemberTile_avatar">
|
||||
{av}
|
||||
</div>
|
||||
{ nameEl }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
|
@ -28,8 +28,7 @@ module.exports = React.createClass({
|
|||
|
||||
propTypes: {
|
||||
member: React.PropTypes.any, // RoomMember
|
||||
onFinished: React.PropTypes.func,
|
||||
customDisplayName: React.PropTypes.string // for 3pid invites
|
||||
customDisplayName: React.PropTypes.string, // for 3pid invites
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
|
@ -37,13 +36,12 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
shouldComponentUpdate: function(nextProps, nextState) {
|
||||
if (this.state.hover !== nextState.hover) return true;
|
||||
if (!this.props.member) { return false; } // e.g. 3pid members
|
||||
if (
|
||||
this.member_last_modified_time === undefined ||
|
||||
this.member_last_modified_time < nextProps.member.getLastModifiedTime()
|
||||
) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
nextProps.member.user &&
|
||||
|
@ -55,14 +53,6 @@ module.exports = React.createClass({
|
|||
return false;
|
||||
},
|
||||
|
||||
mouseEnter: function(e) {
|
||||
this.setState({ 'hover': true });
|
||||
},
|
||||
|
||||
mouseLeave: function(e) {
|
||||
this.setState({ 'hover': false });
|
||||
},
|
||||
|
||||
onClick: function(e) {
|
||||
if (!this.props.member) { return; } // e.g. 3pid members
|
||||
|
||||
|
@ -91,13 +81,21 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
var EntityTile = sdk.getComponent('rooms.EntityTile');
|
||||
|
||||
var member = this.props.member;
|
||||
var isMyUser = false;
|
||||
var name = this._getDisplayName();
|
||||
var active = -1;
|
||||
var presenceClass = "mx_MemberTile_offline";
|
||||
var presenceState = (member && member.user) ? member.user.presence : null;
|
||||
|
||||
var av;
|
||||
if (member) {
|
||||
av = (
|
||||
<MemberAvatar member={member} width={36} height={36} />
|
||||
);
|
||||
|
||||
if (member.user) {
|
||||
this.user_last_modified_time = member.user.getLastModifiedTime();
|
||||
|
||||
|
@ -105,75 +103,20 @@ module.exports = React.createClass({
|
|||
active = (
|
||||
(Date.now() - (member.user.lastPresenceTs - member.user.lastActiveAgo)) || -1
|
||||
);
|
||||
|
||||
if (member.user.presence === "online") {
|
||||
presenceClass = "mx_MemberTile_online";
|
||||
}
|
||||
else if (member.user.presence === "unavailable") {
|
||||
presenceClass = "mx_MemberTile_unavailable";
|
||||
}
|
||||
}
|
||||
this.member_last_modified_time = member.getLastModifiedTime();
|
||||
isMyUser = MatrixClientPeg.get().credentials.userId == member.userId;
|
||||
|
||||
// if (this.props.member && this.props.member.powerLevelNorm > 0) {
|
||||
// var img = "img/p/p" + Math.floor(20 * this.props.member.powerLevelNorm / 100) + ".png";
|
||||
// power = <img src={ img } className="mx_MemberTile_power" width="44" height="44" alt=""/>;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
var mainClassName = "mx_MemberTile ";
|
||||
mainClassName += presenceClass;
|
||||
if (this.state.hover) {
|
||||
mainClassName += " mx_MemberTile_hover";
|
||||
}
|
||||
|
||||
var nameEl;
|
||||
if (this.state.hover) {
|
||||
var presenceState = (member && member.user) ? member.user.presence : null;
|
||||
var PresenceLabel = sdk.getComponent("rooms.PresenceLabel");
|
||||
nameEl = (
|
||||
<div className="mx_MemberTile_details">
|
||||
<img className="mx_MemberTile_chevron" src="img/member_chevron.png" width="8" height="12"/>
|
||||
<div className="mx_MemberTile_userId">{ name }</div>
|
||||
<PresenceLabel activeAgo={active}
|
||||
presenceState={presenceState} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else {
|
||||
nameEl = (
|
||||
<div className="mx_MemberTile_name">
|
||||
{ name }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
|
||||
var av;
|
||||
if (member) {
|
||||
av = (
|
||||
<MemberAvatar member={member} width={36} height={36} />
|
||||
);
|
||||
}
|
||||
else {
|
||||
av = (
|
||||
<BaseAvatar name={name} width={36} height={36} />
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className={mainClassName} title={ this.getPowerLabel() }
|
||||
onClick={ this.onClick } onMouseEnter={ this.mouseEnter }
|
||||
onMouseLeave={ this.mouseLeave }>
|
||||
<div className="mx_MemberTile_avatar">
|
||||
{av}
|
||||
</div>
|
||||
{ nameEl }
|
||||
</div>
|
||||
<EntityTile {...this.props} presenceActiveAgo={active} presenceState={presenceState}
|
||||
avatarJsx={av} title={this.getPowerLabel()} onClick={this.onClick}
|
||||
shouldComponentUpdate={this.shouldComponentUpdate.bind(this)}
|
||||
name={name} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -28,6 +28,7 @@ var SearchableEntityList = React.createClass({
|
|||
emptyQueryShowsAll: React.PropTypes.bool,
|
||||
onSubmit: React.PropTypes.func, // fn(inputText)
|
||||
entities: React.PropTypes.array,
|
||||
onEntityClick: React.PropTypes.func
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
|
@ -35,7 +36,8 @@ var SearchableEntityList = React.createClass({
|
|||
searchPlaceholderText: "Search",
|
||||
entities: [],
|
||||
emptyQueryShowsAll: false,
|
||||
onSubmit: function() {}
|
||||
onSubmit: function() {},
|
||||
onEntityClick: function() {}
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -77,8 +79,8 @@ var SearchableEntityList = React.createClass({
|
|||
placeholder={this.props.searchPlaceholderText} />
|
||||
</form>
|
||||
<div className="mx_SearchableEntityList_list">
|
||||
{this.state.results.map(function(entity) {
|
||||
return entity.getJsx();
|
||||
{this.state.results.map((entity) => {
|
||||
return entity.getJsx(this.props.onEntityClick);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -28,101 +28,29 @@ module.exports = React.createClass({
|
|||
displayName: 'UserTile',
|
||||
|
||||
propTypes: {
|
||||
user: React.PropTypes.any.isRequired, // User
|
||||
onInviteClick: React.PropTypes.func, //onInviteClick(User)
|
||||
showInvite: React.PropTypes.bool,
|
||||
onClick: React.PropTypes.func
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {};
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
onClick: function() {},
|
||||
onInviteClick: function() {},
|
||||
showInvite: false
|
||||
};
|
||||
},
|
||||
|
||||
shouldComponentUpdate: function(nextProps, nextState) {
|
||||
if (this.state.hover !== nextState.hover) return true;
|
||||
return false;
|
||||
},
|
||||
|
||||
mouseEnter: function(e) {
|
||||
this.setState({ 'hover': true });
|
||||
},
|
||||
|
||||
mouseLeave: function(e) {
|
||||
this.setState({ 'hover': false });
|
||||
user: React.PropTypes.any.isRequired // User
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var EntityTile = sdk.getComponent("rooms.EntityTile");
|
||||
var user = this.props.user;
|
||||
var name = user.displayName || user.userId;
|
||||
var isMyUser = MatrixClientPeg.get().credentials.userId == user.userId;
|
||||
var active = -1;
|
||||
var presenceClass = "mx_MemberTile_offline";
|
||||
|
||||
this.user_last_modified_time = user.getLastModifiedTime();
|
||||
|
||||
// FIXME: make presence data update whenever User.presence changes...
|
||||
active = (
|
||||
(Date.now() - (user.lastPresenceTs - user.lastActiveAgo)) || -1
|
||||
);
|
||||
|
||||
if (user.presence === "online") {
|
||||
presenceClass = "mx_MemberTile_online";
|
||||
}
|
||||
else if (user.presence === "unavailable") {
|
||||
presenceClass = "mx_MemberTile_unavailable";
|
||||
}
|
||||
|
||||
|
||||
var mainClassName = "mx_MemberTile ";
|
||||
mainClassName += presenceClass;
|
||||
if (this.state.hover) {
|
||||
mainClassName += " mx_MemberTile_hover";
|
||||
}
|
||||
|
||||
var nameEl;
|
||||
if (this.state.hover) {
|
||||
var PresenceLabel = sdk.getComponent("rooms.PresenceLabel");
|
||||
nameEl = (
|
||||
<div className="mx_MemberTile_details">
|
||||
<img className="mx_MemberTile_chevron" src="img/member_chevron.png" width="8" height="12"/>
|
||||
<div className="mx_MemberTile_userId">{ name }</div>
|
||||
<PresenceLabel activeAgo={active}
|
||||
presenceState={user.presence} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else {
|
||||
nameEl = (
|
||||
<div className="mx_MemberTile_name">
|
||||
{ name }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
|
||||
if (this.props.showInvite) {
|
||||
// TODO
|
||||
}
|
||||
var avatarJsx = (
|
||||
<BaseAvatar width={36} height={36} name={name} idName={user.userId}
|
||||
url={ Avatar.avatarUrlForUser(user, 36, 36, "crop") } />
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={mainClassName} title={ user.userId }
|
||||
onClick={ this.props.onClick } onMouseEnter={ this.mouseEnter }
|
||||
onMouseLeave={ this.mouseLeave }>
|
||||
<div className="mx_MemberTile_avatar">
|
||||
<BaseAvatar width={36} height={36} name={name} idName={user.userId}
|
||||
url={ Avatar.avatarUrlForUser(user, 36, 36, "crop") } />
|
||||
</div>
|
||||
{ nameEl }
|
||||
</div>
|
||||
<EntityTile {...this.props} presenceState={user.presence} presenceActiveAgo={active}
|
||||
name={name} title={user.userId} avatarJsx={avatarJsx} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue