diff --git a/src/Entities.js b/src/Entities.js
new file mode 100644
index 0000000000..ee0d3e9d1b
--- /dev/null
+++ b/src/Entities.js
@@ -0,0 +1,91 @@
+/*
+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');
+
+/*
+ * Converts various data models to Entity objects.
+ *
+ * Entity objects provide an interface for UI components to use to display
+ * members in a data-agnostic way. This means they don't need to care if the
+ * underlying data model is a RoomMember, User or 3PID data structure, it just
+ * cares about rendering.
+ */
+
+class Entity {
+ constructor(model) {
+ this.model = model;
+ }
+
+ getJsx() {
+ return null;
+ }
+
+ matches(queryString) {
+ return false;
+ }
+}
+
+class MemberEntity extends Entity {
+ getJsx() {
+ var MemberTile = sdk.getComponent("rooms.MemberTile");
+ return (
+
+ );
+ }
+
+ matches(queryString) {
+ return this.model.name.toLowerCase().indexOf(queryString.toLowerCase()) === 0;
+ }
+}
+
+class UserEntity extends Entity {
+
+ getJsx() {
+ var UserTile = sdk.getComponent("rooms.UserTile");
+ return (
+
+ );
+ }
+
+ matches(queryString) {
+ return this.model.displayName.toLowerCase().indexOf(queryString.toLowerCase()) === 0;
+ }
+}
+
+
+module.exports = {
+ /**
+ * @param {RoomMember[]} members
+ * @return {Entity[]}
+ */
+ fromRoomMembers: function(members) {
+ return members.map(function(m) {
+ return new MemberEntity(m);
+ });
+ },
+
+ /**
+ * @param {User[]} users
+ * @return {Entity[]}
+ */
+ fromUsers: function(users) {
+ return users.map(function(u) {
+ return new UserEntity(u);
+ })
+ }
+};
diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js
index c768144cdc..f5fc5b9f82 100644
--- a/src/components/views/rooms/MemberList.js
+++ b/src/components/views/rooms/MemberList.js
@@ -18,6 +18,7 @@ var classNames = require('classnames');
var Matrix = require("matrix-js-sdk");
var MatrixClientPeg = require("../../../MatrixClientPeg");
var Modal = require("../../../Modal");
+var Entities = require("../../../Entities");
var sdk = require('../../../index');
var GeminiScrollbar = require('react-gemini-scrollbar');
@@ -280,7 +281,7 @@ module.exports = React.createClass({
diff --git a/src/components/views/rooms/SearchableEntityList.js b/src/components/views/rooms/SearchableEntityList.js
index ec8b6540f0..b8df4f6610 100644
--- a/src/components/views/rooms/SearchableEntityList.js
+++ b/src/components/views/rooms/SearchableEntityList.js
@@ -14,10 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
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');
// A list capable of displaying entities which conform to the SearchableEntity
@@ -88,39 +86,4 @@ var SearchableEntityList = React.createClass({
}
});
-SearchableEntityList.fromRoomMembers = function(members) {
- var MemberTile = sdk.getComponent("rooms.MemberTile");
- return members.map(function(m) {
- return {
- matches: function(query) {
- return m.name.toLowerCase().indexOf(query.toLowerCase()) === 0;
- },
-
- getJsx: function() {
- return (
-
- );
- }
- };
- });
-};
-
-SearchableEntityList.fromUsers = function(users) { /*
- var UserTile = sdk.getComponent("rooms.UserTile");
- return users.map(function(u) {
- return {
- matches: function(query) {
- return u.displayName.toLowerCase().indexOf(query.toLowerCase()) === 0;
- },
-
- getJsx: function() {
- return (
-
- );
- }
- };
- }); */
-};
-
-
module.exports = SearchableEntityList;