diff --git a/src/component-index.js b/src/component-index.js index a0c2433dc3..b4452c7902 100644 --- a/src/component-index.js +++ b/src/component-index.js @@ -68,6 +68,7 @@ module.exports.components['views.room_settings.AliasSettings'] = require('./comp module.exports.components['views.room_settings.ColorSettings'] = require('./components/views/room_settings/ColorSettings'); module.exports.components['views.rooms.EntityTile'] = require('./components/views/rooms/EntityTile'); module.exports.components['views.rooms.EventTile'] = require('./components/views/rooms/EventTile'); +module.exports.components['views.rooms.InviteMemberList'] = require('./components/views/rooms/InviteMemberList'); module.exports.components['views.rooms.MemberInfo'] = require('./components/views/rooms/MemberInfo'); module.exports.components['views.rooms.MemberList'] = require('./components/views/rooms/MemberList'); module.exports.components['views.rooms.MemberTile'] = require('./components/views/rooms/MemberTile'); diff --git a/src/components/views/rooms/InviteMemberList.js b/src/components/views/rooms/InviteMemberList.js new file mode 100644 index 0000000000..a15ffa1ae8 --- /dev/null +++ b/src/components/views/rooms/InviteMemberList.js @@ -0,0 +1,97 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 React = require('react'); +var sdk = require("../../../index"); +var Entities = require("../../../Entities"); +var MatrixClientPeg = require("../../../MatrixClientPeg"); + +const INITIAL_SEARCH_RESULTS_COUNT = 10; + +module.exports = React.createClass({ + displayName: 'InviteMemberList', + + propTypes: { + roomId: React.PropTypes.string.isRequired, + onInvite: React.PropTypes.func.isRequired, // fn(inputText) + onSearchQueryChanged: React.PropTypes.func // fn(inputText) + }, + + getDefaultProps: function() { + return { + onSearchQueryChanged: function() {} + }; + }, + + getInitialState: function() { + return {}; + }, + + componentWillMount: function() { + this._room = MatrixClientPeg.get().getRoom(this.props.roomId); + this._emailEntity = null; + // Load the complete user list for inviting new users + // TODO: Keep this list bleeding-edge up-to-date. Practically speaking, + // it will do for now not being updated as random new users join different + // rooms as this list will be reloaded every room swap. + this._userList = MatrixClientPeg.get().getUsers().filter((u) => { + return !this._room.hasMembershipState(u.userId, "join"); + }); + console.log("%s users", this._userList.length); + }, + + onSearchQueryChanged: function(input) { + var EntityTile = sdk.getComponent("rooms.EntityTile"); + var BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); + + var label = input; + // if (input[0] === "@") { + // label = input; + // } + // else { + // label = "Email: " + input; + // } + + this._emailEntity = new Entities.newEntity( + } + className="mx_EntityTile_invitePlaceholder" + presenceState="online" onClick={this.props.onInvite} name={label} />, + function(query) { + return true; // always show this + } + ); + + this.props.onSearchQueryChanged(input); + }, + + render: function() { + var SearchableEntityList = sdk.getComponent("rooms.SearchableEntityList"); + var entities = Entities.fromUsers(this._userList || [], true, this.props.onInvite); + + // Add an "Email: foo@bar.com" tile as the first tile + if (this._emailEntity) { + entities.unshift(this._emailEntity); + } + + return ( + + ); + } +}); diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index adfc4c66c2..3cddee8632 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -24,7 +24,6 @@ var sdk = require('../../../index'); var GeminiScrollbar = require('react-gemini-scrollbar'); var rate_limited_func = require('../../../ratelimitedfunc'); -var INITIAL_SEARCH_RESULTS_COUNT = 10; var INITIAL_LOAD_NUM_MEMBERS = 30; var SHARE_HISTORY_WARNING = "Newly invited users will see the history of this room. "+ "If you'd prefer invited users not to see messages that were sent before they joined, "+ @@ -78,12 +77,9 @@ module.exports = React.createClass({ setTimeout(function() { if (!self.isMounted()) return; // lazy load to prevent it blocking the first render - self._loadUserList(); - self.setState({ members: self.roomMembers() }); - }, 50); // Attach a SINGLE listener for global presence changes then locate the @@ -105,24 +101,6 @@ module.exports = React.createClass({ MatrixClientPeg.get().on("User.presence", updateUserState); this.userPresenceFn = updateUserState; }, - // Remember to set 'key' on a MemberList to the ID of the room it's for - /*componentWillReceiveProps: function(newProps) { - },*/ - - _loadUserList: function() { - var room = MatrixClientPeg.get().getRoom(this.props.roomId); - if (!room) { - return; // we'll do it later - } - - // Load the complete user list for inviting new users - // TODO: Keep this list bleeding-edge up-to-date. Practically speaking, - // it will do for now not being updated as random new users join different - // rooms as this list will be reloaded every room swap. - this.userList = MatrixClientPeg.get().getUsers().filter(function(u) { - return !room.hasMembershipState(u.userId, "join"); - }); - }, onRoom: function(room) { if (room.roomId !== this.props.roomId) { @@ -132,7 +110,6 @@ module.exports = React.createClass({ // we need to wait till the room is fully populated with state // before refreshing the member list else we get a stale list. this._updateList(); - this._loadUserList(); }, onRoomStateMember: function(ev, state, member) { @@ -335,27 +312,6 @@ module.exports = React.createClass({ }, onSearchQueryChanged: function(input) { - var EntityTile = sdk.getComponent("rooms.EntityTile"); - var BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); - - var label = input; - // if (input[0] === "@") { - // label = input; - // } - // else { - // label = "Email: " + input; - // } - - this._emailEntity = new Entities.newEntity( - } - className="mx_EntityTile_invitePlaceholder" - presenceState="online" onClick={this.onInvite.bind(this, input)} name={label} />, - function(query) { - return true; // always show this - } - ); - this.setState({ searchQuery: input }); @@ -406,32 +362,9 @@ module.exports = React.createClass({ return memberList; }, - inviteTile: function() { - if (this.state.inviting) { - var Loader = sdk.getComponent("elements.Spinner"); - return ( - - ); - } else { - var SearchableEntityList = sdk.getComponent("rooms.SearchableEntityList"); - var entities = Entities.fromUsers(this.userList || [], true, this.onInvite); - - // Add an "Email: foo@bar.com" tile as the first tile - if (this._emailEntity) { - entities.unshift(this._emailEntity); - } - - return ( - - ); - } - }, - render: function() { + var InviteMemberList = sdk.getComponent("rooms.InviteMemberList"); + var invitedSection = null; var invitedMemberTiles = this.makeMemberTiles('invite', this.state.searchQuery); if (invitedMemberTiles.length > 0) { @@ -444,10 +377,27 @@ module.exports = React.createClass({ ); } + + var inviteMemberListSection; + if (this.state.inviting) { + var Loader = sdk.getComponent("elements.Spinner"); + inviteMemberListSection = ( + + ); + } + else { + inviteMemberListSection = ( + + ); + } + + var TruncatedList = sdk.getComponent("elements.TruncatedList"); return (
- {this.inviteTile()} + {inviteMemberListSection}