forked from matrix/element-web
Limit number of read avatars, lay them out as per the design & order them.
This commit is contained in:
parent
450036a6ed
commit
c9823d07fd
|
@ -49,7 +49,6 @@ limitations under the License.
|
||||||
.mx_EventTile .mx_MessageTimestamp {
|
.mx_EventTile .mx_MessageTimestamp {
|
||||||
color: #acacac;
|
color: #acacac;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
float: right;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile_line {
|
.mx_EventTile_line {
|
||||||
|
@ -91,10 +90,16 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_EventTile_msgOption {
|
.mx_EventTile_msgOption {
|
||||||
float: right;
|
float: right;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MessageTimestamp {
|
.mx_MessageTimestamp {
|
||||||
|
display: block;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile_last .mx_MessageTimestamp {
|
.mx_EventTile_last .mx_MessageTimestamp {
|
||||||
|
@ -106,10 +111,10 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile_editButton {
|
.mx_EventTile_editButton {
|
||||||
position: absolute;
|
display: block;
|
||||||
right: 1px;
|
|
||||||
top: 15px;
|
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile:hover .mx_EventTile_editButton {
|
.mx_EventTile:hover .mx_EventTile_editButton {
|
||||||
|
@ -125,10 +130,15 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile_readAvatars {
|
.mx_EventTile_readAvatars {
|
||||||
float: right;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile_readAvatars .mx_MemberAvatar {
|
.mx_EventTile_readAvatars .mx_MemberAvatar {
|
||||||
margin-left: 1px;
|
margin-left: 1px;
|
||||||
margin-right: 1px;
|
margin-right: 1px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_EventTile_readAvatarRemainder {
|
||||||
|
color: #acacac;
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@ var eventTileTypes = {
|
||||||
'm.room.topic' : 'molecules.EventAsTextTile',
|
'm.room.topic' : 'molecules.EventAsTextTile',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var MAX_READ_AVATARS = 5;
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'EventTile',
|
displayName: 'EventTile',
|
||||||
mixins: [EventTileController],
|
mixins: [EventTileController],
|
||||||
|
@ -80,15 +82,30 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
if (!room) return [];
|
if (!room) return [];
|
||||||
|
|
||||||
var userIds = room.getUsersReadUpTo(this.props.mxEvent);
|
// get list of read receipts, sorted most recent first
|
||||||
|
var receipts = room.getReceiptsForEvent(this.props.mxEvent).filter(function(r) {
|
||||||
|
return r.type === "m.read";
|
||||||
|
}).sort(function(r1, r2) {
|
||||||
|
return r2.data.ts - r1.data.ts;
|
||||||
|
});
|
||||||
|
|
||||||
var MemberAvatar = sdk.getComponent('atoms.MemberAvatar');
|
var MemberAvatar = sdk.getComponent('atoms.MemberAvatar');
|
||||||
|
|
||||||
for (var i = 0; i < userIds.length; ++i) {
|
for (var i = 0; i < receipts.length; ++i) {
|
||||||
var member = room.getMember(userIds[i]);
|
var member = room.getMember(receipts[i].userId);
|
||||||
avatars.push(
|
// add to the start so the most recent is on the end (ie. ends up rightmost)
|
||||||
|
avatars.unshift(
|
||||||
<MemberAvatar key={member.userId} member={member} width={14} height={14} resizeMethod="crop" />
|
<MemberAvatar key={member.userId} member={member} width={14} height={14} resizeMethod="crop" />
|
||||||
);
|
);
|
||||||
|
if (i + 1 >= MAX_READ_AVATARS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var remainder = receipts.length - MAX_READ_AVATARS;
|
||||||
|
if (remainder > 0) {
|
||||||
|
avatars.unshift(
|
||||||
|
<span className="mx_EventTile_readAvatarRemainder">+{ remainder }</span>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <span className="mx_EventTile_readAvatars">{ avatars }</span>;
|
return <span className="mx_EventTile_readAvatars">{ avatars }</span>;
|
||||||
|
@ -151,12 +168,14 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className={classes}>
|
<div className={classes}>
|
||||||
|
<div className="mx_EventTile_msgOption">
|
||||||
|
{ editButton }
|
||||||
|
{ timestamp }
|
||||||
|
{ readAvatars }
|
||||||
|
</div>
|
||||||
{ avatar }
|
{ avatar }
|
||||||
{ sender }
|
{ sender }
|
||||||
<div className="mx_EventTile_line">
|
<div className="mx_EventTile_line">
|
||||||
{ timestamp }
|
|
||||||
{ editButton }
|
|
||||||
{ readAvatars }
|
|
||||||
<EventTileType mxEvent={this.props.mxEvent} searchTerm={this.props.searchTerm} />
|
<EventTileType mxEvent={this.props.mxEvent} searchTerm={this.props.searchTerm} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue