diff --git a/src/Lifecycle.js b/src/Lifecycle.js
index 53adea6196..62fbe5f929 100644
--- a/src/Lifecycle.js
+++ b/src/Lifecycle.js
@@ -22,6 +22,7 @@ import Notifier from './Notifier'
import UserActivity from './UserActivity';
import Presence from './Presence';
import dis from './dispatcher';
+import DMRoomMap from './utils/DMRoomMap';
/**
* Called at startup, to attempt to build a logged-in Matrix session. It tries
@@ -317,6 +318,7 @@ export function startMatrixClient() {
Notifier.start();
UserActivity.start();
Presence.start();
+ DMRoomMap.makeShared().start();
MatrixClientPeg.start();
}
@@ -354,6 +356,7 @@ export function stopMatrixClient() {
Notifier.stop();
UserActivity.stop();
Presence.stop();
+ DMRoomMap.shared().stop();
var cli = MatrixClientPeg.get();
if (cli) {
cli.stopClient();
diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js
index 9efb7164bb..1f0338a4de 100644
--- a/src/components/views/rooms/RoomTile.js
+++ b/src/components/views/rooms/RoomTile.js
@@ -70,8 +70,7 @@ module.exports = React.createClass({
},
_isDirectMessageRoom: function(roomId) {
- const dmRoomMap = new DMRoomMap(MatrixClientPeg.get());
- var dmRooms = dmRoomMap.getUserIdForRoomId(roomId);
+ var dmRooms = DMRoomMap.shared().getUserIdForRoomId(roomId);
if (dmRooms) {
return true;
} else {
@@ -277,11 +276,9 @@ module.exports = React.createClass({
var RoomAvatar = sdk.getComponent('avatars.RoomAvatar');
var directMessageIndicator;
- // Temporarily turning off the LGM badges as isDirectMessageRoom is horribly unperformant
- // - see https://github.com/vector-im/vector-web/issues/2343
- // if (this._isDirectMessageRoom(this.props.room.roomId)) {
- // directMessageIndicator = ;
- // }
+ if (this._isDirectMessageRoom(this.props.room.roomId)) {
+ directMessageIndicator = ;
+ }
// These props are injected by React DnD,
// as defined by your `collect` function above:
diff --git a/src/utils/DMRoomMap.js b/src/utils/DMRoomMap.js
index 78ace8fb11..d6242719ba 100644
--- a/src/utils/DMRoomMap.js
+++ b/src/utils/DMRoomMap.js
@@ -14,16 +14,25 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
+import MatrixClientPeg from '../MatrixClientPeg';
+
/**
* Class that takes a Matrix Client and flips the m.direct map
* so the operation of mapping a room ID to which user it's a DM
* with can be performed efficiently.
+ *
+ * With 'start', this can also keep itself up to date over time.
*/
export default class DMRoomMap {
constructor(matrixClient) {
this.matrixClient = matrixClient;
this.roomToUser = null;
+ // XXX: Force-bind the event handler method because it
+ // doesn't call it with our object as the 'this'
+ // (use a static property arrow function for this when we can)
+ this._onAccountData = this._onAccountData.bind(this);
+
const mDirectEvent = matrixClient.getAccountData('m.direct');
if (!mDirectEvent) {
this.userToRooms = {};
@@ -32,6 +41,40 @@ export default class DMRoomMap {
}
}
+ /**
+ * Makes and returns a new shared instance that can then be accessed
+ * with shared(). This returned instance is not automatically started.
+ */
+ static makeShared() {
+ DMRoomMap._sharedInstance = new DMRoomMap(MatrixClientPeg.get());
+ return DMRoomMap._sharedInstance;
+ }
+
+ /**
+ * Returns a shared instance of the class
+ * that uses the singleton matrix client
+ * The shared instance must be started before use.
+ */
+ static shared() {
+ return DMRoomMap._sharedInstance;
+ }
+
+ start() {
+ this._populateRoomToUser();
+ this.matrixClient.on("accountData", this._onAccountData);
+ }
+
+ stop() {
+ this.matrixClient.removeListener("accountData", this._onAccountData);
+ }
+
+ _onAccountData(ev) {
+ if (ev.getType() == 'm.direct') {
+ this.userToRooms = this.matrixClient.getAccountData('m.direct').getContent();
+ this._populateRoomToUser();
+ }
+ }
+
getDMRoomsForUserId(userId) {
// Here, we return the empty list if there are no rooms,
// since the number of conversations you have with this user is zero.