Address review comments

Rearrange a couple of things for clarity, and add some comments.
This commit is contained in:
Richard van der Hoff
2016-01-28 12:36:12 +00:00
parent b1e2090eef
commit b42e5d5fcf
+73 -28
View File
@@ -64,6 +64,9 @@ function TimelineWindow(client, room, opts) {
this._client = client;
this._room = room;
// these will be TimelineIndex objects; they delineate the 'start' and
// 'end' of the window.
//
// _start.index is inclusive; _end.index is exclusive.
this._start = null;
this._end = null;
@@ -93,7 +96,7 @@ TimelineWindow.prototype.load = function(initialEventId, initialWindowSize) {
// make sure that our window includes the event
for (var i = 0; i < tl.getEvents().length; i++) {
if (tl.getEvents()[i].getId() == initialEventId) {
return [tl, i];
return {timeline: tl, index: i};
}
}
throw new Error("getEventTimeline result didn't include requested event");
@@ -103,11 +106,11 @@ TimelineWindow.prototype.load = function(initialEventId, initialWindowSize) {
// start with the most recent events
var tl = this._room.getLiveTimeline();
prom = q([tl, tl.getEvents().length]);
prom = q({timeline: tl, index: tl.getEvents().length});
}
prom = prom.then(function(v) {
var tl = v[0], eventIndex = v[1];
var tl = v.timeline, eventIndex = v.index;
var endIndex = Math.min(tl.getEvents().length,
eventIndex + initialWindowSize / 2);
@@ -145,8 +148,8 @@ TimelineWindow.prototype.canPaginate = function(direction) {
throw new Error("Invalid direction '" + direction + "'");
}
return tl.timeline.getNeighbouringTimeline(direction) ||
tl.timeline.getPaginationToken(direction);
return Boolean(tl.timeline.getNeighbouringTimeline(direction) ||
tl.timeline.getPaginationToken(direction));
};
/**
@@ -159,8 +162,11 @@ TimelineWindow.prototype.canPaginate = function(direction) {
* number are immediately available, then we return immediately rather than
* making an API call.
*
* @param {boolean} [makeRequest = true] whether we should make API calls to
* fetch further events if we don't have any.
* @param {boolean} [makeRequest = true] whether we should make API calls to
* fetch further events if we don't have any at all. (This has no effect if
* the room already knows about additional events in the relevant direction,
* even if there are fewer than 'size' of them, as we will just return those
* we already know about.)
*
* @return {module:client.Promise} Resolves to a boolean which is true if more events
* were successfully retrieved.
@@ -200,8 +206,9 @@ TimelineWindow.prototype.paginate = function(direction, size, makeRequest) {
debuglog("TimelineWindow: increased cap by " + count +
" (now " + this._eventCount + ")");
// remove some events from the other end, if necessary
if (this._eventCount > this._windowLimit) {
this._unpaginate(direction != EventTimeline.BACKWARDS);
var excess = this._eventCount - this._windowLimit;
if (excess > 0) {
this._unpaginate(excess, direction != EventTimeline.BACKWARDS);
}
return q(true);
}
@@ -240,15 +247,20 @@ TimelineWindow.prototype.paginate = function(direction, size, makeRequest) {
/**
* Trim the window to the windowlimit
*
* @param {number} delta number of events to remove from the timeline
* @param {boolean} startOfTimeline if events should be removed from the start
* of the timeline.
*
* @private
*/
TimelineWindow.prototype._unpaginate = function(startOfTimeline) {
TimelineWindow.prototype._unpaginate = function(delta, startOfTimeline) {
var tl = startOfTimeline ? this._start : this._end;
var delta = this._eventCount - this._windowLimit;
// sanity-check the delta
if (delta > this._eventCount || delta < 0) {
throw new Error("Attemting to unpaginate " + delta + " events, but " +
"only have " + this._eventCount + " in the timeline");
}
while (delta > 0) {
var count = startOfTimeline ? tl.advance(delta) : tl.retreat(delta);
@@ -280,10 +292,20 @@ TimelineWindow.prototype.getEvents = function() {
var result = [];
for (var timeline = this._start.timeline; timeline !== null;
timeline = timeline.getNeighbouringTimeline(EventTimeline.FORWARDS)) {
// iterate through each timeline between this._start and this._end
// (inclusive).
var timeline = this._start.timeline;
while (true) {
var events = timeline.getEvents();
// For the first timeline in the chain, we want to start at
// this._start.index. For the last timeline in the chain, we want to
// stop before this._end.index. Otherwise, we want to copy all of the
// events in the timeline.
//
// (Note that both this._start.index and this._end.index are relative
// to their respective timelines' BaseIndex).
//
var startIndex = 0, endIndex = events.length;
if (timeline === this._start.timeline) {
startIndex = this._start.index + timeline.getBaseIndex();
@@ -295,7 +317,15 @@ TimelineWindow.prototype.getEvents = function() {
for (var i = startIndex; i < endIndex; i++) {
result.push(events[i]);
}
// if we're not done, iterate to the next timeline.
if (timeline === this._end.timeline) {
break;
} else {
timeline = timeline.getNeighbouringTimeline(EventTimeline.FORWARDS);
}
}
return result;
};
@@ -320,7 +350,7 @@ function TimelineIndex(timeline, index) {
* timeline
*/
TimelineIndex.prototype.minIndex = function() {
return -this.timeline.getBaseIndex();
return this.timeline.getBaseIndex() * -1;
};
/**
@@ -338,25 +368,40 @@ TimelineIndex.prototype.maxIndex = function() {
* @return {number} number of events successfully advanced by
*/
TimelineIndex.prototype.advance = function(delta) {
// first try moving the cap
var x;
if (delta === 0) {
if (!delta) {
return 0;
} else if (delta < 0) {
x = Math.max(delta, this.minIndex() - this.index);
if (x < 0) {
this.index += x;
return x;
}
// first try moving the index in the current timeline. See if there is room
// to do so.
var cappedDelta;
if (delta < 0) {
// we want to wind the index backwards.
//
// (this.minIndex() - this.index) is a negative number whose magnitude
// is the amount of room we have to wind back the index in the current
// timeline. We cap delta to this quantity.
cappedDelta = Math.max(delta, this.minIndex() - this.index);
if (cappedDelta < 0) {
this.index += cappedDelta;
return cappedDelta;
}
} else {
x = Math.min(delta, this.maxIndex() - this.index);
if (x > 0) {
this.index += x;
return x;
// we want to wind the index forwards.
//
// (this.maxIndex() - this.index) is a (positive) number whose magnitude
// is the amount of room we have to wind forward the index in the current
// timeline. We cap delta to this quantity.
cappedDelta = Math.min(cappedDelta, this.maxIndex() - this.index);
if (cappedDelta > 0) {
this.index += cappedDelta;
return cappedDelta;
}
}
// next see if there is a neighbouring timeline to switch to
// the index is already at the start/end of the current timeline.
//
// next see if there is a neighbouring timeline to switch to.
var neighbour = this.timeline.getNeighbouringTimeline(
delta < 0 ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS);
if (neighbour) {