From 80a235adf91fd753e4e47b619ca112d13f17654e Mon Sep 17 00:00:00 2001 From: Kegan Dougal <kegan@matrix.org> Date: Mon, 30 Nov 2015 15:13:28 +0000 Subject: [PATCH] Move and merge MemberList --- package.json | 1 + .../views/rooms}/MemberList.js | 105 ++++++++++++++++-- 2 files changed, 99 insertions(+), 7 deletions(-) rename src/{controllers/organisms => components/views/rooms}/MemberList.js (68%) diff --git a/package.json b/package.json index 0b5a18168f..fda905f94e 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "q": "^1.4.1", "react": "^0.14.2", "react-dom": "^0.14.2", + "react-gemini-scrollbar": "^2.0.1", "sanitize-html": "^1.11.1", "velocity-animate": "^1.2.3" }, diff --git a/src/controllers/organisms/MemberList.js b/src/components/views/rooms/MemberList.js similarity index 68% rename from src/controllers/organisms/MemberList.js rename to src/components/views/rooms/MemberList.js index 3e9736cf8e..8ca24f8992 100644 --- a/src/controllers/organisms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -13,14 +13,17 @@ 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. */ - -var MatrixClientPeg = require("../../MatrixClientPeg"); -var Modal = require("../../Modal"); -var sdk = require('../../index'); +var React = require('react'); +var classNames = require('classnames'); +var MatrixClientPeg = require("../../../MatrixClientPeg"); +var Modal = require("../../../Modal"); +var sdk = require('../../../index'); +var GeminiScrollbar = require('react-gemini-scrollbar'); var INITIAL_LOAD_NUM_MEMBERS = 50; -module.exports = { +module.exports = React.createClass({ + displayName: 'MemberList', getInitialState: function() { if (!this.props.roomId) return { members: [] }; var cli = MatrixClientPeg.get(); @@ -195,6 +198,94 @@ module.exports = { } } return to_display; - } -}; + }, + + + + memberSort: function(userIdA, userIdB) { + var userA = this.memberDict[userIdA].user; + var userB = this.memberDict[userIdB].user; + + var presenceMap = { + online: 3, + unavailable: 2, + offline: 1 + }; + + var presenceOrdA = userA ? presenceMap[userA.presence] : 0; + var presenceOrdB = userB ? presenceMap[userB.presence] : 0; + + if (presenceOrdA != presenceOrdB) { + 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; + }, + + makeMemberTiles: function(membership) { + var MemberTile = sdk.getComponent("rooms.MemberTile"); + + var self = this; + return self.state.members.filter(function(userId) { + var m = self.memberDict[userId]; + return m.membership == membership; + }).map(function(userId) { + var m = self.memberDict[userId]; + return ( + <MemberTile key={userId} member={m} ref={userId} /> + ); + }); + }, + + onPopulateInvite: function(e) { + this.onInvite(this.refs.invite.value); + e.preventDefault(); + }, + + inviteTile: function() { + if (this.state.inviting) { + var Loader = sdk.getComponent("elements.Spinner"); + return ( + <Loader /> + ); + } else { + return ( + <form onSubmit={this.onPopulateInvite}> + <input className="mx_MemberList_invite" ref="invite" placeholder="Invite another user"/> + </form> + ); + } + }, + + render: function() { + var invitedSection = null; + var invitedMemberTiles = this.makeMemberTiles('invite'); + if (invitedMemberTiles.length > 0) { + invitedSection = ( + <div className="mx_MemberList_invited"> + <h2>Invited</h2> + <div className="mx_MemberList_wrapper"> + {invitedMemberTiles} + </div> + </div> + ); + } + return ( + <div className="mx_MemberList"> + <GeminiScrollbar autoshow={true} className="mx_MemberList_border"> + {this.inviteTile()} + <div> + <div className="mx_MemberList_wrapper"> + {this.makeMemberTiles('join')} + </div> + </div> + {invitedSection} + </GeminiScrollbar> + </div> + ); + } +});