diff --git a/src/TabComplete.js b/src/TabComplete.js
index 8886e21af9..3005411e13 100644
--- a/src/TabComplete.js
+++ b/src/TabComplete.js
@@ -24,10 +24,10 @@ const KEY_WINDOWS = 91;
//
// Capturing group containing the start
// of line or a whitespace char
-// \_______________ __________Capturing group of 1 or more non-whitespace chars
+// \_______________ __________Capturing group of 0 or more non-whitespace chars
// _|__ _|_ followed by the end of line
// / \/ \
-const MATCH_REGEX = /(^|\s)(\S+)$/;
+const MATCH_REGEX = /(^|\s)(\S*)$/;
class TabComplete {
diff --git a/src/TabCompleteEntries.js b/src/TabCompleteEntries.js
index 9aef7736a8..a23050063f 100644
--- a/src/TabCompleteEntries.js
+++ b/src/TabCompleteEntries.js
@@ -127,15 +127,9 @@ MemberEntry.fromMemberList = function(members) {
return 0; // don't care
}
else { // both User objects exist
- if (userA.lastActiveAgo < userB.lastActiveAgo) {
- return -1; // a comes first
- }
- else if (userA.lastActiveAgo > userB.lastActiveAgo) {
- return 1; // b comes first
- }
- else {
- return 0; // same last active ago
- }
+ var lastActiveAgoA = userA.lastActiveAgo || Number.MAX_SAFE_INTEGER;
+ var lastActiveAgoB = userB.lastActiveAgo || Number.MAX_SAFE_INTEGER;
+ return lastActiveAgoA - lastActiveAgoB;
}
}).map(function(m) {
return new MemberEntry(m);
diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js
index dcb16f7231..65dd9534d7 100644
--- a/src/components/structures/RoomView.js
+++ b/src/components/structures/RoomView.js
@@ -455,11 +455,16 @@ module.exports = React.createClass({
},
_updateTabCompleteList: new rate_limited_func(function() {
+ var cli = MatrixClientPeg.get();
+
if (!this.state.room || !this.tabComplete) {
return;
}
+ var members = this.state.room.getJoinedMembers().filter(function(member) {
+ if (member.userId !== cli.credentials.userId) return true;
+ });
this.tabComplete.setCompletionList(
- MemberEntry.fromMemberList(this.state.room.getJoinedMembers()).concat(
+ MemberEntry.fromMemberList(members).concat(
CommandEntry.fromCommands(SlashCommands.getCommandList())
)
);
diff --git a/src/components/views/rooms/EntityTile.js b/src/components/views/rooms/EntityTile.js
index ec586431be..47e3fd3350 100644
--- a/src/components/views/rooms/EntityTile.js
+++ b/src/components/views/rooms/EntityTile.js
@@ -38,6 +38,7 @@ module.exports = React.createClass({
className: React.PropTypes.string,
presenceState: React.PropTypes.string,
presenceActiveAgo: React.PropTypes.number,
+ presenceCurrentlyActive: React.PropTypes.bool,
showInviteButton: React.PropTypes.bool,
shouldComponentUpdate: React.PropTypes.func,
onClick: React.PropTypes.func,
@@ -88,6 +89,7 @@ module.exports = React.createClass({
{ this.props.name }
);
diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js
index cc2983290b..dadc0407c1 100644
--- a/src/components/views/rooms/MemberList.js
+++ b/src/components/views/rooms/MemberList.js
@@ -317,10 +317,10 @@ module.exports = React.createClass({
return presenceOrdB - presenceOrdA;
}
- var latA = userA ? (userA.lastPresenceTs - (userA.lastActiveAgo || userA.lastPresenceTs)) : 0;
- var latB = userB ? (userB.lastPresenceTs - (userB.lastActiveAgo || userB.lastPresenceTs)) : 0;
-
- return latB - latA;
+ var lastActiveTsA = userA && userA.lastActiveAgo ? userA.lastPresenceTs - userA.lastActiveAgo : 0;
+ var lastActiveTsB = userB && userB.lastActiveAgo ? userB.lastPresenceTs - userB.lastActiveAgo : 0;
+
+ return lastActiveTsB - lastActiveTsA;
},
onSearchQueryChanged: function(input) {
diff --git a/src/components/views/rooms/MemberTile.js b/src/components/views/rooms/MemberTile.js
index 01750b9676..b19a215668 100644
--- a/src/components/views/rooms/MemberTile.js
+++ b/src/components/views/rooms/MemberTile.js
@@ -84,14 +84,14 @@ module.exports = React.createClass({
this.user_last_modified_time = member.user.getLastModifiedTime();
// FIXME: make presence data update whenever User.presence changes...
- active = (
- (Date.now() - (member.user.lastPresenceTs - member.user.lastActiveAgo)) || -1
- );
+ active = member.user.lastActiveAgo ?
+ (Date.now() - (member.user.lastPresenceTs - member.user.lastActiveAgo)) : -1;
}
this.member_last_modified_time = member.getLastModifiedTime();
return (
);
diff --git a/src/components/views/rooms/PresenceLabel.js b/src/components/views/rooms/PresenceLabel.js
index 4ecad5b3df..ac0410c1f7 100644
--- a/src/components/views/rooms/PresenceLabel.js
+++ b/src/components/views/rooms/PresenceLabel.js
@@ -25,7 +25,15 @@ module.exports = React.createClass({
displayName: 'PresenceLabel',
propTypes: {
+ // number of milliseconds ago this user was last active.
+ // zero = unknown
activeAgo: React.PropTypes.number,
+
+ // if true, activeAgo is an approximation and "Now" should
+ // be shown instead
+ currentlyActive: React.PropTypes.bool,
+
+ // offline, online, etc
presenceState: React.PropTypes.string
},
@@ -67,9 +75,10 @@ module.exports = React.createClass({
render: function() {
if (this.props.activeAgo >= 0) {
+ var ago = this.props.currentlyActive ? "now" : (this.getDuration(this.props.activeAgo) + " ago");
return (
- { this.getPrettyPresence(this.props.presenceState) } { this.getDuration(this.props.activeAgo) } ago
+ { this.getPrettyPresence(this.props.presenceState) } { ago }
);
}
diff --git a/src/components/views/rooms/UserTile.js b/src/components/views/rooms/UserTile.js
index 6597796764..9608247d5e 100644
--- a/src/components/views/rooms/UserTile.js
+++ b/src/components/views/rooms/UserTile.js
@@ -38,9 +38,8 @@ module.exports = React.createClass({
var active = -1;
// FIXME: make presence data update whenever User.presence changes...
- active = (
- (Date.now() - (user.lastPresenceTs - user.lastActiveAgo)) || -1
- );
+ active = user.lastActiveAgo ?
+ (Date.now() - (user.lastPresenceTs - user.lastActiveAgo)) : -1;
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
var avatarJsx = (
@@ -50,6 +49,7 @@ module.exports = React.createClass({
return (
);
}