You've already forked matrix-js-sdk
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:
@ -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) {
|
||||
|
146
lib/client.js
146
lib/client.js
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -4,7 +4,6 @@
|
||||
* of requests.
|
||||
* @module scheduler
|
||||
*/
|
||||
var EventStatus = require("./models/event").EventStatus;
|
||||
var utils = require("./utils");
|
||||
var q = require("q");
|
||||
|
||||
|
Reference in New Issue
Block a user