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
Impl syncing of left rooms. Factor out getting or creating filters.
This commit is contained in:
@@ -2117,8 +2117,30 @@ MatrixClient.prototype.search = function(opts, callback) {
|
|||||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
*/
|
*/
|
||||||
MatrixClient.prototype.syncLeftRooms = function() {
|
MatrixClient.prototype.syncLeftRooms = function() {
|
||||||
|
// Guard against multiple calls whilst ongoing and multiple calls post success
|
||||||
|
if (this._syncedLeftRooms) {
|
||||||
|
console.log("Already synced left rooms");
|
||||||
|
return q([]); // don't call syncRooms again if it succeeded.
|
||||||
|
}
|
||||||
|
if (this._syncLeftRoomsPromise) {
|
||||||
|
console.log("Returning ongoing request promise");
|
||||||
|
return this._syncLeftRoomsPromise; // return the ongoing request
|
||||||
|
}
|
||||||
|
console.log("Making sync left rooms request");
|
||||||
|
var self = this;
|
||||||
var syncApi = new SyncApi(this);
|
var syncApi = new SyncApi(this);
|
||||||
return syncApi.syncLeftRooms();
|
this._syncLeftRoomsPromise = syncApi.syncLeftRooms();
|
||||||
|
|
||||||
|
// cleanup locks
|
||||||
|
this._syncLeftRoomsPromise.then(function(res) {
|
||||||
|
console.log("Marking success of sync left room request");
|
||||||
|
self._syncedLeftRooms = true; // flip the bit on success
|
||||||
|
}).finally(function() {
|
||||||
|
console.log("Cleaning up request state");
|
||||||
|
self._syncLeftRoomsPromise = null; // cleanup ongoing request state
|
||||||
|
});
|
||||||
|
|
||||||
|
return this._syncLeftRoomsPromise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
111
lib/sync.js
111
lib/sync.js
@@ -21,12 +21,14 @@ var Filter = require("./filter");
|
|||||||
// to determine the max time we're willing to wait.
|
// to determine the max time we're willing to wait.
|
||||||
var BUFFER_PERIOD_MS = 20 * 1000;
|
var BUFFER_PERIOD_MS = 20 * 1000;
|
||||||
|
|
||||||
function getFilterName(userId) {
|
function getFilterName(userId, suffix) {
|
||||||
// scope this on the user ID because people may login on many accounts
|
// scope this on the user ID because people may login on many accounts
|
||||||
// and they all need to be stored!
|
// and they all need to be stored!
|
||||||
return "FILTER_SYNC_" + userId;
|
return "FILTER_SYNC_" + userId + (suffix ? "_" + suffix : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <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.
|
||||||
@@ -79,8 +81,63 @@ SyncApi.prototype.createRoom = function(roomId) {
|
|||||||
* @return {Promise} Resolved when they've been added to the store.
|
* @return {Promise} Resolved when they've been added to the store.
|
||||||
*/
|
*/
|
||||||
SyncApi.prototype.syncLeftRooms = function() {
|
SyncApi.prototype.syncLeftRooms = function() {
|
||||||
// TODO
|
var client = this.client;
|
||||||
return null;
|
var self = this;
|
||||||
|
|
||||||
|
// grab a filter with limit=0 and include_leave=true
|
||||||
|
var filter = new Filter(this.client.credentials.userId);
|
||||||
|
filter.setTimelineLimit(1);
|
||||||
|
filter.setIncludeLeaveRooms(true);
|
||||||
|
|
||||||
|
var localTimeoutMs = this.opts.pollTimeout + BUFFER_PERIOD_MS;
|
||||||
|
var qps = {
|
||||||
|
timeout: 1 // don't want to block since this is a single isolated req
|
||||||
|
};
|
||||||
|
|
||||||
|
return this._getOrCreateFilter(
|
||||||
|
getFilterName(client.credentials.userId, "LEFT_ROOMS"), filter
|
||||||
|
).then(function(filterId) {
|
||||||
|
qps.filter = filterId;
|
||||||
|
return client._http.authedRequestWithPrefix(
|
||||||
|
undefined, "GET", "/sync", qps, undefined, httpApi.PREFIX_V2_ALPHA,
|
||||||
|
localTimeoutMs
|
||||||
|
);
|
||||||
|
}).then(function(data) {
|
||||||
|
var leaveRooms = [];
|
||||||
|
if (data.rooms && data.rooms.leave) {
|
||||||
|
leaveRooms = self._mapSyncResponseToRoomArray(data.rooms.leave);
|
||||||
|
}
|
||||||
|
var rooms = [];
|
||||||
|
leaveRooms.forEach(function(leaveObj) {
|
||||||
|
var room = leaveObj.room;
|
||||||
|
rooms.push(room);
|
||||||
|
if (!leaveObj.isBrandNewRoom) {
|
||||||
|
// the intention behind syncLeftRooms is to add in rooms which were
|
||||||
|
// *omitted* from the initial /sync. Rooms the user were joined to
|
||||||
|
// but then left whilst the app is running will appear in this list
|
||||||
|
// and we do not want to bother with them since they will have the
|
||||||
|
// current state already (and may get dupe messages if we add
|
||||||
|
// yet more timeline events!), so skip them.
|
||||||
|
// NB: When we persist rooms to localStorage this will be more
|
||||||
|
// complicated...
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
leaveObj.timeline = leaveObj.timeline || {};
|
||||||
|
var timelineEvents = self._mapSyncEventsFormat(leaveObj.timeline, room);
|
||||||
|
var stateEvents = self._mapSyncEventsFormat(leaveObj.state, room);
|
||||||
|
var paginationToken = (
|
||||||
|
leaveObj.timeline.limited ? leaveObj.timeline.prev_batch : null
|
||||||
|
);
|
||||||
|
self._processRoomEvents(
|
||||||
|
room, stateEvents, timelineEvents, paginationToken
|
||||||
|
);
|
||||||
|
room.recalculate(client.credentials.userId);
|
||||||
|
client.store.storeRoom(room);
|
||||||
|
client.emit("Room", room);
|
||||||
|
});
|
||||||
|
client._syncedLeftRooms = true;
|
||||||
|
return rooms;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,27 +169,14 @@ SyncApi.prototype.sync = function() {
|
|||||||
attempt = attempt || 0;
|
attempt = attempt || 0;
|
||||||
attempt += 1;
|
attempt += 1;
|
||||||
|
|
||||||
|
|
||||||
// Get or create filter
|
|
||||||
var filterId = client.store.getFilterIdByName(
|
|
||||||
getFilterName(client.credentials.userId)
|
|
||||||
);
|
|
||||||
if (filterId) {
|
|
||||||
// super, just use that.
|
|
||||||
console.log("Using existing filter ID %s", filterId);
|
|
||||||
self._sync({ filterId: filterId });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a filter
|
|
||||||
var filter = new Filter(client.credentials.userId);
|
var filter = new Filter(client.credentials.userId);
|
||||||
filter.setTimelineLimit(self.opts.initialSyncLimit);
|
filter.setTimelineLimit(self.opts.initialSyncLimit);
|
||||||
client.createFilter(filter.getDefinition()).done(function(filter) {
|
|
||||||
client.store.setFilterIdByName(
|
self._getOrCreateFilter(
|
||||||
getFilterName(client.credentials.userId), filter.filterId
|
getFilterName(client.credentials.userId), filter
|
||||||
);
|
).done(function(filterId) {
|
||||||
console.log("Created filter ", filter.filterId);
|
console.log("Using existing filter ID %s", filterId);
|
||||||
self._sync({ filterId: filter.filterId }); // Now start the /sync loop
|
self._sync({ filterId: filterId });
|
||||||
}, retryHandler(attempt, getFilter));
|
}, retryHandler(attempt, getFilter));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,6 +392,27 @@ SyncApi.prototype._sync = function(syncOptions, attempt) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} filterName
|
||||||
|
* @param {Filter} filter
|
||||||
|
* @return {Promise<String>} Filter ID
|
||||||
|
*/
|
||||||
|
SyncApi.prototype._getOrCreateFilter = function(filterName, filter) {
|
||||||
|
var client = this.client;
|
||||||
|
var filterId = client.store.getFilterIdByName(filterName);
|
||||||
|
if (filterId) {
|
||||||
|
// super, just use that.
|
||||||
|
console.log("Using existing filter ID %s", filterId);
|
||||||
|
return q(filterId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a filter
|
||||||
|
return client.createFilter(filter.getDefinition()).then(function(createdFilter) {
|
||||||
|
client.store.setFilterIdByName(filterName, createdFilter.filterId);
|
||||||
|
return createdFilter.filterId;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
* @return {Object[]}
|
* @return {Object[]}
|
||||||
|
Reference in New Issue
Block a user