1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-18 05:42:00 +03:00

Make things work again

This commit is contained in:
Kegan Dougal
2015-12-09 10:42:05 +00:00
parent 2b659656cc
commit 3543abf7bd
3 changed files with 134 additions and 31 deletions

View File

@@ -621,9 +621,10 @@ MatrixClient.prototype.joinRoom = function(roomIdOrAlias, opts, callback) {
this._http.authedRequest(undefined, "POST", path, undefined, {}).then( this._http.authedRequest(undefined, "POST", path, undefined, {}).then(
function(res) { function(res) {
var roomId = res.room_id; var roomId = res.room_id;
var room = createNewRoom(self, roomId); // XXX FIXME TODO var syncApi = new SyncApi(self);
var room = syncApi.createRoom(roomId);
if (opts.syncRoom) { if (opts.syncRoom) {
return _syncRoom(self, room); // XXX FIXME TODO return syncApi.syncRoom(room);
} }
return q(room); return q(room);
}, function(err) { }, function(err) {
@@ -2424,12 +2425,6 @@ function checkTurnServers(client) {
}); });
} }
function retryTimeMsForAttempt(attempt) {
// 2,4,8,16,32,64,128,128,128,... seconds
// max 2^7 secs = 2.1 mins
return Math.pow(2, Math.min(attempt, 7)) * 1000;
}
function _reject(callback, defer, err) { function _reject(callback, defer, err) {
if (callback) { if (callback) {
callback(err); callback(err);
@@ -2456,6 +2451,10 @@ function _PojoToMatrixEventMapper(client) {
return mapper; return mapper;
} }
MatrixClient.prototype.getEventMapper = function() {
return _PojoToMatrixEventMapper(this);
};
// Identity Server Operations // Identity Server Operations
// ========================== // ==========================
@@ -2502,8 +2501,6 @@ MatrixClient.prototype.generateClientSecret = function() {
module.exports.MatrixClient = MatrixClient; module.exports.MatrixClient = MatrixClient;
/** */ /** */
module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED; module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED;
/** */
module.exports.EventMapper = _PojoToMatrixEventMapper;
// MatrixClient Event JSDocs // MatrixClient Event JSDocs

View File

@@ -195,7 +195,7 @@ function PushProcessor(client) {
}; };
var matchingRuleForEventWithRulesets = function(ev, rulesets) { var matchingRuleForEventWithRulesets = function(ev, rulesets) {
if (!rulesets) { return null; } if (!rulesets || !rulesets.device) { return null; }
if (ev.user_id == client.credentials.userId) { return null; } if (ev.user_id == client.credentials.userId) { return null; }
var allDevNames = Object.keys(rulesets.device); var allDevNames = Object.keys(rulesets.device);

View File

@@ -8,14 +8,19 @@
* an alternative syncing API, we may want to have a proper syncing interface * an alternative syncing API, we may want to have a proper syncing interface
* for HTTP and WS at some point. * for HTTP and WS at some point.
*/ */
var q = require("q");
var StubStore = require("./store/stub"); var StubStore = require("./store/stub");
var EventMapper = require("./client").EventMapper;
var User = require("./models/user"); var User = require("./models/user");
var Room = require("./models/room"); var Room = require("./models/room");
var utils = require("./utils"); var utils = require("./utils");
var MatrixEvent = require("./models/event").MatrixEvent; var MatrixEvent = require("./models/event").MatrixEvent;
function retryTimeMsForAttempt(attempt) {
// 2,4,8,16,32,64,128,128,128,... seconds
// max 2^7 secs = 2.1 mins
return Math.pow(2, Math.min(attempt, 7)) * 1000;
}
function startSyncingRetryTimer(client, attempt, fn) { function startSyncingRetryTimer(client, attempt, fn) {
client._syncingRetry = {}; client._syncingRetry = {};
client._syncingRetry.fn = fn; client._syncingRetry.fn = fn;
@@ -79,6 +84,99 @@ function reEmit(reEmitEntity, emittableEntity, eventNames) {
}); });
} }
function _syncRoom(client, room) {
if (client._syncingRooms[room.roomId]) {
return client._syncingRooms[room.roomId];
}
var defer = q.defer();
client._syncingRooms[room.roomId] = defer.promise;
client.roomInitialSync(room.roomId, client._config.initialSyncLimit).done(
function(res) {
room.timeline = []; // blow away any previous messages.
_processRoomEvents(client, room, res.state, res.messages);
room.recalculate(client.credentials.userId);
client.store.storeRoom(room);
client.emit("Room", room);
defer.resolve(room);
client._syncingRooms[room.roomId] = undefined;
}, function(err) {
defer.reject(err);
client._syncingRooms[room.roomId] = undefined;
});
return defer.promise;
}
function _processRoomEvents(client, 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), client.getEventMapper()
);
var stateEvents = utils.map(stateEventList, client.getEventMapper());
room.oldState.setStateEvents(oldStateEvents);
room.currentState.setStateEvents(stateEvents);
_resolveInvites(client, room);
// 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 : [],
client.getEventMapper()
).reverse(), true
);
if (messageChunk) {
room.oldState.paginationToken = messageChunk.start;
}
}
function _resolveInvites(client, room) {
if (!room || !client._config.resolveInvitesToProfiles) {
return;
}
// For each invited room member we want to give them a displayname/avatar url
// if they have one (the m.room.member invites don't contain this).
room.getMembersWithMembership("invite").forEach(function(member) {
if (member._requestedProfileInfo) {
return;
}
member._requestedProfileInfo = true;
// try to get a cached copy first.
var user = client.getUser(member.userId);
var promise;
if (user) {
promise = q({
avatar_url: user.avatarUrl,
displayname: user.displayName
});
}
else {
promise = client.getProfileInfo(member.userId);
}
promise.done(function(info) {
// slightly naughty by doctoring the invite event but this means all
// the code paths remain the same between invite/join display name stuff
// which is a worthy trade-off for some minor pollution.
var inviteEvent = member.events.member;
if (inviteEvent.getContent().membership !== "invite") {
// between resolving and now they have since joined, so don't clobber
return;
}
inviteEvent.getContent().avatar_url = info.avatar_url;
inviteEvent.getContent().displayname = info.displayname;
member.setMembershipEvent(inviteEvent, room.currentState); // fire listeners
}, function(err) {
// OH WELL.
});
});
}
/** /**
* <b>Internal class - unstable.</b> * <b>Internal class - unstable.</b>
* Construct an entity which is able to sync with a homeserver. * Construct an entity which is able to sync with a homeserver.
@@ -89,15 +187,23 @@ function SyncApi(client) {
this.opts = {}; this.opts = {};
} }
SyncApi.prototype.createRoom = function(roomId) {
return createNewRoom(this.client, roomId);
};
SyncApi.prototype.syncRoom = function(room) {
return _syncRoom(this.client, room);
};
/** /**
* @param {Object} opts * @param {Object} opts
* @param {Number} opts.historyLen * @param {Number} opts.historyLen
* @param {Boolean} opts.includeArchived * @param {Boolean} opts.includeArchived
*/ */
SyncApi.prototype.sync = function(opts) { SyncApi.prototype.sync = function(opts) {
console.log("SyncApi.sync -> %s", opts); console.log("SyncApi.sync");
this.opts = opts || {}; this.opts = opts || {};
return this._sync(); return this._prepareForSync();
} }
@@ -119,7 +225,7 @@ SyncApi.prototype._prepareForSync = function(attempt) {
}, function(err) { }, function(err) {
attempt += 1; attempt += 1;
startSyncingRetryTimer(client, attempt, function() { startSyncingRetryTimer(client, attempt, function() {
prepareForSync(client, attempt); self._prepareForSync(attempt);
}); });
updateSyncState(client, "ERROR", { error: err }); updateSyncState(client, "ERROR", { error: err });
}); });
@@ -147,7 +253,7 @@ SyncApi.prototype._sync = function(attempt) {
// intercept the results and put them into our store // intercept the results and put them into our store
if (!(client.store instanceof StubStore)) { if (!(client.store instanceof StubStore)) {
utils.forEach( utils.forEach(
utils.map(data.presence, EventMapper(client)), utils.map(data.presence, client.getEventMapper()),
function(e) { function(e) {
var user = createNewUser(client, e.getContent().user_id); var user = createNewUser(client, e.getContent().user_id);
user.setPresenceEvent(e); user.setPresenceEvent(e);
@@ -157,7 +263,7 @@ SyncApi.prototype._sync = function(attempt) {
// group receipts by room ID. // group receipts by room ID.
var receiptsByRoom = {}; var receiptsByRoom = {};
data.receipts = data.receipts || []; data.receipts = data.receipts || [];
utils.forEach(data.receipts.map(EventMapper(client)), utils.forEach(data.receipts.map(client.getEventMapper()),
function(receiptEvent) { function(receiptEvent) {
if (!receiptsByRoom[receiptEvent.getRoomId()]) { if (!receiptsByRoom[receiptEvent.getRoomId()]) {
receiptsByRoom[receiptEvent.getRoomId()] = []; receiptsByRoom[receiptEvent.getRoomId()] = [];
@@ -189,7 +295,7 @@ SyncApi.prototype._sync = function(attempt) {
data.rooms[i].state.push(inviteEvent); data.rooms[i].state.push(inviteEvent);
} }
_processRoomEvents( // XXX _processRoomEvents(
client, room, data.rooms[i].state, data.rooms[i].messages client, room, data.rooms[i].state, data.rooms[i].messages
); );
@@ -200,7 +306,7 @@ SyncApi.prototype._sync = function(attempt) {
var privateUserData = data.rooms[i].account_data || []; var privateUserData = data.rooms[i].account_data || [];
var privateUserDataEvents = var privateUserDataEvents =
utils.map(privateUserData, EventMapper(client)); utils.map(privateUserData, client.getEventMapper());
for (j = 0; j < privateUserDataEvents.length; j++) { for (j = 0; j < privateUserDataEvents.length; j++) {
var event = privateUserDataEvents[j]; var event = privateUserDataEvents[j];
if (event.getType() === "m.tag") { if (event.getType() === "m.tag") {
@@ -253,7 +359,7 @@ SyncApi.prototype._sync = function(attempt) {
console.error("/initialSync error (%s attempts): %s", attempt, err); console.error("/initialSync error (%s attempts): %s", attempt, err);
attempt += 1; attempt += 1;
startSyncingRetryTimer(client, attempt, function() { startSyncingRetryTimer(client, attempt, function() {
self._sync(opts, attempt); self._sync(attempt);
}); });
updateSyncState(client, "ERROR", { error: err }); updateSyncState(client, "ERROR", { error: err });
}); });
@@ -305,13 +411,13 @@ SyncApi.prototype._pollForEvents = function(attempt) {
} }
if (client._syncState !== "SYNCING") { if (client._syncState !== "SYNCING") {
updateSyncState(self, "SYNCING"); updateSyncState(client, "SYNCING");
} }
try { try {
var events = []; var events = [];
if (data) { if (data) {
events = utils.map(data.chunk, EventMapper(self)); events = utils.map(data.chunk, client.getEventMapper());
} }
if (!(client.store instanceof StubStore)) { if (!(client.store instanceof StubStore)) {
var roomIdsWithNewInvites = {}; var roomIdsWithNewInvites = {};
@@ -337,7 +443,7 @@ SyncApi.prototype._pollForEvents = function(attempt) {
usr.setPresenceEvent(events[i]); usr.setPresenceEvent(events[i]);
} }
else { else {
usr = createNewUser(self, events[i].getContent().user_id); usr = createNewUser(client, events[i].getContent().user_id);
usr.setPresenceEvent(events[i]); usr.setPresenceEvent(events[i]);
client.store.storeUser(usr); client.store.storeUser(usr);
} }
@@ -350,7 +456,7 @@ SyncApi.prototype._pollForEvents = function(attempt) {
var room = client.store.getRoom(roomId); var room = client.store.getRoom(roomId);
var isBrandNewRoom = false; var isBrandNewRoom = false;
if (!room) { if (!room) {
room = createNewRoom(self, roomId); room = createNewRoom(client, roomId);
isBrandNewRoom = true; isBrandNewRoom = true;
} }
@@ -375,12 +481,12 @@ SyncApi.prototype._pollForEvents = function(attempt) {
if (!wasJoined && justJoined) { if (!wasJoined && justJoined) {
// we've just transitioned into a join state for this room, // we've just transitioned into a join state for this room,
// so sync state. // so sync state.
_syncRoom(self, room); // XXX _syncRoom(client, room);
} }
}); });
Object.keys(roomIdsWithNewInvites).forEach(function(inviteRoomId) { Object.keys(roomIdsWithNewInvites).forEach(function(inviteRoomId) {
_resolveInvites(self, client.store.getRoom(inviteRoomId)); // XXX _resolveInvites(client, client.store.getRoom(inviteRoomId));
}); });
} }
if (data) { if (data) {
@@ -394,7 +500,7 @@ SyncApi.prototype._pollForEvents = function(attempt) {
console.error("Event stream error:"); console.error("Event stream error:");
console.error(e); console.error(e);
} }
client._pollForEvents(); self._pollForEvents();
}, function(err) { }, function(err) {
console.error("/events error: %s", JSON.stringify(err)); console.error("/events error: %s", JSON.stringify(err));
if (discardResult) { if (discardResult) {
@@ -405,10 +511,10 @@ SyncApi.prototype._pollForEvents = function(attempt) {
} }
attempt += 1; attempt += 1;
startSyncingRetryTimer(self, attempt, function() { startSyncingRetryTimer(client, attempt, function() {
client._pollForEvents(attempt); self._pollForEvents(attempt);
}); });
updateSyncState(self, "ERROR", { error: err }); updateSyncState(client, "ERROR", { error: err });
}); });
} }