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 ( ); }