1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-07-31 15:24:23 +03:00

Sync room state when joining via client.joinRoom

Does not currently sync state when another device joins.
Update node example app to refresh room list.
This commit is contained in:
Kegan Dougal
2015-06-22 17:50:49 +01:00
parent ad70b3d434
commit bc0e2ad504
4 changed files with 126 additions and 44 deletions

View File

@ -28,7 +28,9 @@ rl.on('line', function(line) {
viewingRoom = roomList[roomIndex];
if (viewingRoom.getMember(myUserId).membership === "invite") {
// join the room first
matrixClient.joinRoom(viewingRoom.roomId).done(function() {
matrixClient.joinRoom(viewingRoom.roomId).done(function(room) {
roomList = matrixClient.getRooms();
viewingRoom = room;
printMessages();
}, function(err) {
console.log("Error: %s", err);
@ -69,6 +71,13 @@ matrixClient.on("syncComplete", function() {
printHelp();
});
matrixClient.on("Room", function() {
roomList = matrixClient.getRooms();
if (!viewingRoom) {
printRoomList();
}
});
// print incoming messages.
matrixClient.on("Room.timeline", function(event, room, toStartOfTimeline) {
if (toStartOfTimeline) {

View File

@ -121,12 +121,26 @@ MatrixClient.prototype.createRoom = function(options, callback) {
* Join a room.
* @param {string} roomIdOrAlias The room ID or room alias to join.
* @param {module:client.callback} callback Optional.
* @return {module:client.Promise} Resolves: <code>{room_id: {string}}</code>
* @return {module:client.Promise} Resolves: Room object.
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
MatrixClient.prototype.joinRoom = function(roomIdOrAlias, callback) {
var path = utils.encodeUri("/join/$roomid", { $roomid: roomIdOrAlias});
return this._http.authedRequest(callback, "POST", path, undefined, {});
var defer = q.defer();
var self = this;
this._http.authedRequest(undefined, "POST", path, undefined, {}).then(
function(res) {
var roomId = res.room_id;
var room = createNewRoom(self, roomId);
return _syncRoom(self, room);
}, function(err) {
_reject(callback, defer, err);
}).done(function(room) {
_resolve(callback, defer, room);
}, function(err) {
_reject(callback, defer, err);
});
return defer.promise;
};
/**
@ -915,10 +929,6 @@ MatrixClient.prototype.isLoggedIn = function() {
};
// Higher level APIs
// =================
@ -959,10 +969,8 @@ MatrixClient.prototype.startClient = function(historyLen) {
var i, j;
// intercept the results and put them into our store
if (self.store) {
var eventMapper = function(event) {
return new MatrixEvent(event);
};
utils.forEach(utils.map(data.presence, eventMapper), function(e) {
utils.forEach(utils.map(data.presence, _PojoToMatrixEventMapper),
function(e) {
var user = createNewUser(self, e.getContent().user_id);
user.setPresenceEvent(e);
self.store.storeUser(user);
@ -986,27 +994,8 @@ MatrixClient.prototype.startClient = function(historyLen) {
});
}
// "old" and "current" state are the same initially; they
// start diverging if the user paginates.
// We must deep copy otherwise membership changes in old state
// will leak through to current state!
var oldStateEvents = utils.map(
utils.deepCopy(data.rooms[i].state), eventMapper
);
var stateEvents = utils.map(data.rooms[i].state, eventMapper);
room.oldState.setStateEvents(oldStateEvents);
room.currentState.setStateEvents(stateEvents);
// add events to the timeline *after* setting the state
// events so messages use the right display names. Initial sync
// returns messages in chronological order, so we need to reverse
// it to get most recent -> oldest. We need it in that order in
// order to diverge old/current state correctly.
room.addEventsToTimeline(
utils.map(
data.rooms[i].messages ? data.rooms[i].messages.chunk : [],
eventMapper
).reverse(), true
_processRoomEvents(
room, data.rooms[i].state, data.rooms[i].messages
);
// cache the name/summary/etc prior to storage since we don't
@ -1087,23 +1076,38 @@ function _pollForEvents(client) {
}
// add events to room
var roomIds = utils.keys(roomIdToEvents);
for (i = 0; i < roomIds.length; i++) {
var room = self.store.getRoom(roomIds[i]);
var shouldStoreRoom = false;
utils.forEach(roomIds, function(roomId) {
var room = self.store.getRoom(roomId);
var isBrandNewRoom = false;
if (!room) {
room = createNewRoom(self, roomIds[i]);
shouldStoreRoom = true;
room = createNewRoom(self, roomId);
isBrandNewRoom = true;
}
room.addEvents(roomIdToEvents[roomIds[i]], "replace");
//var wasJoined = room.hasMembershipState(
// self.credentials.userId, "join"
//);
room.addEvents(roomIdToEvents[roomId], "replace");
room.recalculate(self.credentials.userId);
if (shouldStoreRoom) {
// store the Room for things like invite events so developers
// can update the UI
if (isBrandNewRoom) {
self.store.storeRoom(room);
// TODO: Should be doing roomInitialSync here to pull in
// all state before emitting this(!)
self.emit("Room", room);
}
}
/* TODO invite->join trigger roominitialsync
var justJoined = room.hasMembershipState(
self.credentials.userId, "join"
);
if (!wasJoined && justJoined) {
// we've just transitioned into a join state for this room,
// so sync state.
_syncRoom(self, room);
} */
});
}
if (data) {
self.fromToken = data.end;
@ -1122,6 +1126,45 @@ function _pollForEvents(client) {
});
}
function _syncRoom(client, room) {
var defer = q.defer();
client.roomInitialSync(room.roomId, 8).done(function(res) {
_processRoomEvents(room, res.state, res.messages);
room.recalculate(client.credentials.userId);
client.store.storeRoom(room);
client.emit("Room", room);
defer.resolve(room);
}, function(err) {
defer.reject(err);
});
return defer.promise;
}
function _processRoomEvents(room, stateEventList, messageChunk) {
// "old" and "current" state are the same initially; they
// start diverging if the user paginates.
// We must deep copy otherwise membership changes in old state
// will leak through to current state!
var oldStateEvents = utils.map(
utils.deepCopy(stateEventList), _PojoToMatrixEventMapper
);
var stateEvents = utils.map(stateEventList, _PojoToMatrixEventMapper);
room.oldState.setStateEvents(oldStateEvents);
room.currentState.setStateEvents(stateEvents);
// add events to the timeline *after* setting the state
// events so messages use the right display names. Initial sync
// returns messages in chronological order, so we need to reverse
// it to get most recent -> oldest. We need it in that order in
// order to diverge old/current state correctly.
room.addEventsToTimeline(
utils.map(
messageChunk ? messageChunk.chunk : [],
_PojoToMatrixEventMapper
).reverse(), true
);
}
/**
* High level helper method to stop the client from polling and allow a
* clean shutdown.
@ -1178,6 +1221,24 @@ function createNewRoom(client, roomId) {
return room;
}
function _reject(callback, defer, err) {
if (callback) {
callback(err);
}
defer.reject(err);
}
function _resolve(callback, defer, res) {
if (callback) {
callback(null, res);
}
defer.resolve(res);
}
function _PojoToMatrixEventMapper(plainOldJsObject) {
return new MatrixEvent(plainOldJsObject);
}
/** */
module.exports.MatrixClient = MatrixClient;
@ -1215,7 +1276,8 @@ module.exports.MatrixClient = MatrixClient;
*/
/**
* Fires whenever a new Room is added. <strong>This event is experimental and
* Fires whenever a new Room is added. This will fire when you are invited to a
* room, as well as when you join a room. <strong>This event is experimental and
* may change.</strong>
* @event module:client~MatrixClient#"Room"
* @param {Room} room The newly created, fully populated room.

View File

@ -55,6 +55,18 @@ utils.inherits(Room, EventEmitter);
});
};
/**
* Check if the given user_id has the given membership state.
* @param {string} userId The user ID to check.
* @param {string} membership The membership e.g. <code>'join'</code>
* @return {boolean} True if this user_id has the given membership state.
*/
Room.prototype.hasMembershipState = function(userId, membership) {
return utils.filter(this.currentState.getMembers(), function(m) {
return m.membership === membership && m.userId === userId;
}).length > 0;
};
/**
* Add some events to this room's timeline. Will fire "Room.timeline" for
* each event added.

View File

@ -4,7 +4,6 @@
* of requests.
* @module scheduler
*/
var EventStatus = require("./models/event").EventStatus;
var utils = require("./utils");
var q = require("q");