forked from matrix/element-web
make presence work better on the memberlist. kludges around lack of syjs-28. is about as good as angular was now.
This commit is contained in:
parent
a5a6a35122
commit
5fe41e28d7
|
@ -131,9 +131,9 @@ module.exports = React.createClass({
|
||||||
if (this.state.hover || this.state.menu) {
|
if (this.state.hover || this.state.menu) {
|
||||||
var presence;
|
var presence;
|
||||||
// FIXME: make presence data update whenever User.presence changes...
|
// FIXME: make presence data update whenever User.presence changes...
|
||||||
var active = this.props.member.user ? (this.props.member.user.lastActiveAgo || -1) : -1;
|
var active = this.props.member.user ? ((Date.now() - (this.props.member.user.lastPresenceTs - this.props.member.user.lastActiveAgo)) || -1) : -1;
|
||||||
if (active >= 0) {
|
if (active >= 0) {
|
||||||
presence = <div className="mx_MemberTile_presence">{ this.getPrettyPresence(this.props.member.user) } for { this.getDuration(active) }</div>;
|
presence = <div className="mx_MemberTile_presence">{ this.getPrettyPresence(this.props.member.user) } { this.getDuration(active) } ago</div>;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
presence = <div className="mx_MemberTile_presence">{ this.getPrettyPresence(this.props.member.user) }</div>;
|
presence = <div className="mx_MemberTile_presence">{ this.getPrettyPresence(this.props.member.user) }</div>;
|
||||||
|
|
|
@ -35,18 +35,6 @@ module.exports = React.createClass({
|
||||||
return { editing: false };
|
return { editing: false };
|
||||||
},
|
},
|
||||||
|
|
||||||
// FIXME: combine this more nicely with the MemberInfo positioning stuff...
|
|
||||||
onMemberListScroll: function(ev) {
|
|
||||||
if (this.refs.memberListScroll) {
|
|
||||||
var memberListScroll = this.refs.memberListScroll.getDOMNode();
|
|
||||||
// offset the current MemberInfo bubble
|
|
||||||
var memberInfo = document.getElementsByClassName("mx_MemberInfo")[0];
|
|
||||||
if (memberInfo) {
|
|
||||||
memberInfo.style.top = (memberInfo.parentElement.offsetTop - memberListScroll.scrollTop) + "px";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
makeMemberTiles: function() {
|
makeMemberTiles: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
return Object.keys(self.state.memberDict).map(function(userId) {
|
return Object.keys(self.state.memberDict).map(function(userId) {
|
||||||
|
@ -97,7 +85,7 @@ module.exports = React.createClass({
|
||||||
<div className="mx_MemberList_chevron">
|
<div className="mx_MemberList_chevron">
|
||||||
<img src="img/chevron.png" width="24" height="13"/>
|
<img src="img/chevron.png" width="24" height="13"/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_MemberList_border" ref="memberListScroll" onScroll={ this.onMemberListScroll }>
|
<div className="mx_MemberList_border">
|
||||||
<h2>Members</h2>
|
<h2>Members</h2>
|
||||||
<div className="mx_MemberList_wrapper">
|
<div className="mx_MemberList_wrapper">
|
||||||
{this.makeMemberTiles()}
|
{this.makeMemberTiles()}
|
||||||
|
|
|
@ -48,6 +48,8 @@ module.exports = {
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
// Lazy-load in more than the first N members
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (!self.isMounted()) return;
|
if (!self.isMounted()) return;
|
||||||
self.setState({
|
self.setState({
|
||||||
|
@ -59,13 +61,23 @@ module.exports = {
|
||||||
// member tile and re-render it. This is more efficient than every tile
|
// member tile and re-render it. This is more efficient than every tile
|
||||||
// evar attaching their own listener.
|
// evar attaching their own listener.
|
||||||
function updateUserState(event, user) {
|
function updateUserState(event, user) {
|
||||||
|
// evil hack to track the age of this presence info.
|
||||||
|
// this should be removed once syjs-28 is resolved in the JS SDK itself.
|
||||||
|
user.lastPresenceTs = Date.now();
|
||||||
|
|
||||||
var tile = self.refs[user.userId];
|
var tile = self.refs[user.userId];
|
||||||
|
|
||||||
|
console.log("presence event " + JSON.stringify(event) + " user = " + user + " tile = " + tile);
|
||||||
|
|
||||||
if (tile) {
|
if (tile) {
|
||||||
// update the whole list to get the order right, not just this cell...
|
self._updateList(); // reorder the membership list
|
||||||
self.forceUpdate();
|
self.forceUpdate(); // FIXME: is the a more efficient way of reordering with react?
|
||||||
// tile.forceUpdate();
|
// XXX: do we even need to do this, or is it done by the main list?
|
||||||
|
tile.forceUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// FIXME: we should probably also reset 'lastActiveAgo' to zero whenever
|
||||||
|
// we see a typing notif from a user, as we don't get presence updates for those.
|
||||||
MatrixClientPeg.get().on("User.presence", updateUserState);
|
MatrixClientPeg.get().on("User.presence", updateUserState);
|
||||||
this.userPresenceFn = updateUserState;
|
this.userPresenceFn = updateUserState;
|
||||||
},
|
},
|
||||||
|
@ -136,17 +148,23 @@ module.exports = {
|
||||||
var all_members = room.currentState.members;
|
var all_members = room.currentState.members;
|
||||||
var all_user_ids = Object.keys(all_members);
|
var all_user_ids = Object.keys(all_members);
|
||||||
|
|
||||||
|
// XXX: dirty hack until SYJS-28 is fixed
|
||||||
|
all_user_ids.map(function(userId) {
|
||||||
|
if (all_members[userId].user && !all_members[userId].user.lastPresenceTs) {
|
||||||
|
all_members[userId].user.lastPresenceTs = Date.now();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
all_user_ids.sort(function(userIdA, userIdB) {
|
all_user_ids.sort(function(userIdA, userIdB) {
|
||||||
var userA = all_members[userIdA].user;
|
var userA = all_members[userIdA].user;
|
||||||
var userB = all_members[userIdB].user;
|
var userB = all_members[userIdB].user;
|
||||||
|
|
||||||
var latA = userA ? userA.lastActiveAgo || Number.MAX_VALUE : Number.MAX_VALUE;
|
var latA = userA ? (userA.lastPresenceTs - (userA.lastActiveAgo || userA.lastPresenceTs)) : 0;
|
||||||
var latB = userB ? userB.lastActiveAgo || Number.MAX_VALUE : Number.MAX_VALUE;
|
var latB = userB ? (userB.lastPresenceTs - (userB.lastActiveAgo || userB.lastPresenceTs)) : 0;
|
||||||
|
|
||||||
return latA - latB;
|
return latB - latA;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var to_display = {};
|
var to_display = {};
|
||||||
var count = 0;
|
var count = 0;
|
||||||
for (var i = 0; i < all_user_ids.length && (limit === undefined || count < limit); ++i) {
|
for (var i = 0; i < all_user_ids.length && (limit === undefined || count < limit); ++i) {
|
||||||
|
@ -154,6 +172,8 @@ module.exports = {
|
||||||
var m = all_members[user_id];
|
var m = all_members[user_id];
|
||||||
|
|
||||||
if (m.membership == 'join' || m.membership == 'invite') {
|
if (m.membership == 'join' || m.membership == 'invite') {
|
||||||
|
// XXX: this is evil, and relies on the fact that Object.keys() iterates
|
||||||
|
// over the keys of a dict in insertion order (if those keys are strings)
|
||||||
to_display[user_id] = m;
|
to_display[user_id] = m;
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue