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

Add storeEvents impl.

This commit is contained in:
Kegan Dougal
2015-07-02 11:03:50 +01:00
parent 023a3cf2bd
commit ea738e31ba
4 changed files with 99 additions and 11 deletions

View File

@@ -830,27 +830,38 @@ MatrixClient.prototype.roomState = function(roomId, callback) {
*/ */
MatrixClient.prototype.scrollback = function(room, limit, callback) { MatrixClient.prototype.scrollback = function(room, limit, callback) {
if (utils.isFunction(limit)) { callback = limit; limit = undefined; } if (utils.isFunction(limit)) { callback = limit; limit = undefined; }
limit = limit || 30;
if (room.oldState.paginationToken === null) { if (room.oldState.paginationToken === null) {
return q(room); // already at the start. return q(room); // already at the start.
} }
// attempt to grab more events from the store first
var numAdded = this.store.scrollback(room, limit).length;
if (numAdded === limit) {
// store contained everything we needed.
return q(room);
}
// reduce the required number of events appropriately
limit = limit - numAdded;
var path = utils.encodeUri( var path = utils.encodeUri(
"/rooms/$roomId/messages", {$roomId: room.roomId} "/rooms/$roomId/messages", {$roomId: room.roomId}
); );
limit = limit || 30;
var params = { var params = {
from: room.oldState.paginationToken, from: room.oldState.paginationToken,
limit: limit, limit: limit,
dir: 'b' dir: 'b'
}; };
var defer = q.defer(); var defer = q.defer();
var self = this;
this._http.authedRequest(callback, "GET", path, params).done(function(res) { this._http.authedRequest(callback, "GET", path, params).done(function(res) {
room.addEventsToTimeline( var matrixEvents = utils.map(res.chunk, _PojoToMatrixEventMapper);
utils.map(res.chunk, _PojoToMatrixEventMapper), true room.addEventsToTimeline(matrixEvents, true);
);
room.oldState.paginationToken = res.end; room.oldState.paginationToken = res.end;
if (res.chunk.length < limit) { if (res.chunk.length < limit) {
room.oldState.paginationToken = null; room.oldState.paginationToken = null;
} }
self.store.storeEvents(room, matrixEvents, res.end, true);
_resolve(callback, defer, room); _resolve(callback, defer, room);
}, function(err) { }, function(err) {
_reject(callback, defer, err); _reject(callback, defer, err);

View File

@@ -98,6 +98,17 @@ module.exports.MatrixInMemoryStore.prototype = {
*/ */
scrollback: function(room, limit) { scrollback: function(room, limit) {
return []; return [];
},
/**
* Store events for a room. The events have already been added to the timeline
* @param {Room} room The room to store events for.
* @param {Array<MatrixEvent>} events The events to store.
* @param {string} token The token associated with these events.
* @param {boolean} toStart True if these are paginated results.
*/
storeEvents: function(room, events, token, toStart) {
// no-op because they've already been added to the room instance.
} }
// TODO // TODO

View File

@@ -86,6 +86,16 @@ StubStore.prototype = {
*/ */
scrollback: function(room, limit) { scrollback: function(room, limit) {
return []; return [];
},
/**
* Store events for a room.
* @param {Room} room The room to store events for.
* @param {Array<MatrixEvent>} events The events to store.
* @param {string} token The token associated with these events.
* @param {boolean} toStart True if these are paginated results.
*/
storeEvents: function(room, events, token, toStart) {
} }
// TODO // TODO

View File

@@ -364,6 +364,59 @@ WebStorageStore.prototype.scrollback = function(room, limit) {
return scrollback; return scrollback;
}; };
/**
* Store events for a room. The events have already been added to the timeline.
* @param {Room} room The room to store events for.
* @param {Array<MatrixEvent>} events The events to store.
* @param {string} token The token associated with these events.
* @param {boolean} toStart True if these are paginated results. The last element
* is the 'oldest' (for parity with homeserver scrollback APIs).
*/
WebStorageStore.prototype.storeEvents = function(room, events, token, toStart) {
if (toStart) {
// add paginated events to lowest batch indexes (can go -ve)
var lowIndex = getIndexExtremity(
getTimelineIndices(this.store, room.roomId), true
);
var i, key, batch;
for (i = 0; i < events.length; i++) { // loop events to be stored
key = keyName(room.roomId, "timeline", lowIndex);
batch = this.store.getItem(key) || [];
while (batch.length < this.batchSize && i < events.length) {
batch.unshift(events[i]);
i++; // increment to insert next event into this batch
}
i--; // decrement to avoid skipping one (for loop ++s)
this.store.setItem(key, batch);
lowIndex--; // decrement index to get a new batch.
}
}
else {
// dump as live events
var liveEvents = this.store.getItem(
keyName(room.roomId, "timeline", "live")
) || [];
debuglog(
"Adding %s events to %s live list (which has %s already)",
events.length, room.roomId, liveEvents.length
);
var updateState = false;
liveEvents.concat(utils.map(events, function(me) {
// cheeky check to avoid looping twice
if (me.isState()) {
updateState = true;
}
return me.event;
}));
if (updateState) {
debuglog("Storing state for %s as new events updated state", room.roomId);
// use 0 batch size; we don't care about batching right now.
var serRoom = SerialisedRoom.fromRoom(room, 0);
this.store.setItem(keyName(serRoom.roomId, "state"), serRoom.state);
}
}
};
/** /**
* Sync the 'live' timeline, batching live events according to 'batchSize'. * Sync the 'live' timeline, batching live events according to 'batchSize'.
* @param {string} roomId The room to sync the timeline. * @param {string} roomId The room to sync the timeline.
@@ -375,7 +428,7 @@ WebStorageStore.prototype._syncTimeline = function(roomId, timelineIndices) {
var liveEvents = this.store.getItem(keyName(roomId, "timeline", "live")) || []; var liveEvents = this.store.getItem(keyName(roomId, "timeline", "live")) || [];
// get the highest numbered $INDEX batch // get the highest numbered $INDEX batch
var highestIndex = getHighestIndex(timelineIndices); var highestIndex = getIndexExtremity(timelineIndices);
var hiKey = keyName(roomId, "timeline", highestIndex); var hiKey = keyName(roomId, "timeline", highestIndex);
var hiBatch = this.store.getItem(hiKey) || []; var hiBatch = this.store.getItem(hiKey) || [];
// fill up the existing batch first. // fill up the existing batch first.
@@ -481,7 +534,7 @@ function loadRoom(store, roomId, numEvents, tokenArray) {
// add most recent numEvents // add most recent numEvents
var recentEvents = []; var recentEvents = [];
var index = getHighestIndex(getTimelineIndices(store, roomId)); var index = getIndexExtremity(getTimelineIndices(store, roomId));
var eventIndex = index; var eventIndex = index;
var i, key, batch; var i, key, batch;
while (recentEvents.length < numEvents) { while (recentEvents.length < numEvents) {
@@ -534,15 +587,18 @@ function getTimelineIndices(store, roomId) {
return keys; return keys;
} }
function getHighestIndex(timelineIndices) { function getIndexExtremity(timelineIndices, getLowest) {
var highestIndex, index; var extremity, index;
for (var i = 0; i < timelineIndices.length; i++) { for (var i = 0; i < timelineIndices.length; i++) {
index = parseInt(timelineIndices[i]); index = parseInt(timelineIndices[i]);
if (!isNaN(index) && (highestIndex === undefined || index > highestIndex)) { if (!isNaN(index) && (
highestIndex = index; extremity === undefined ||
!getLowest && index > extremity ||
getLowest && index < extremity)) {
extremity = index;
} }
} }
return highestIndex; return extremity;
} }
function keyName(roomId, key, index) { function keyName(roomId, key, index) {