You've already forked matrix-js-sdk
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:
@@ -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
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
146
lib/sync.js
146
lib/sync.js
@@ -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 });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user