FilePanel: Implement pagination requesting using the EventIndex.
This commit is contained in:
parent
7fb3645e94
commit
49c1dbe421
3 changed files with 119 additions and 12 deletions
|
@ -71,6 +71,20 @@ const FilePanel = createReactClass({
|
||||||
return timelineSet;
|
return timelineSet;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onPaginationRequest(timelineWindow, direction, limit) {
|
||||||
|
const client = MatrixClientPeg.get();
|
||||||
|
const eventIndex = EventIndexPeg.get();
|
||||||
|
const roomId = this.props.roomId;
|
||||||
|
|
||||||
|
const room = client.getRoom(roomId);
|
||||||
|
|
||||||
|
if (client.isRoomEncrypted(roomId) && eventIndex !== null) {
|
||||||
|
return eventIndex.paginateTimelineWindow(room, timelineWindow, direction, limit);
|
||||||
|
} else {
|
||||||
|
return timelineWindow.paginate(direction, limit);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async updateTimelineSet(roomId: string) {
|
async updateTimelineSet(roomId: string) {
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
const room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
|
@ -85,7 +99,8 @@ const FilePanel = createReactClass({
|
||||||
timelineSet = await this.fetchFileEventsServer(room)
|
timelineSet = await this.fetchFileEventsServer(room)
|
||||||
|
|
||||||
if (client.isRoomEncrypted(roomId) && eventIndex !== null) {
|
if (client.isRoomEncrypted(roomId) && eventIndex !== null) {
|
||||||
await eventIndex.populateFileTimeline(room, timelineSet);
|
const timeline = timelineSet.getLiveTimeline();
|
||||||
|
await eventIndex.populateFileTimeline(timelineSet, timeline, room, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({ timelineSet: timelineSet });
|
this.setState({ timelineSet: timelineSet });
|
||||||
|
@ -128,6 +143,7 @@ const FilePanel = createReactClass({
|
||||||
manageReadMarkers={false}
|
manageReadMarkers={false}
|
||||||
timelineSet={this.state.timelineSet}
|
timelineSet={this.state.timelineSet}
|
||||||
showUrlPreview = {false}
|
showUrlPreview = {false}
|
||||||
|
onPaginationRequest={this.onPaginationRequest}
|
||||||
tileShape="file_grid"
|
tileShape="file_grid"
|
||||||
resizeNotifier={this.props.resizeNotifier}
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
empty={_t('There are no visible files in this room')}
|
empty={_t('There are no visible files in this room')}
|
||||||
|
|
|
@ -94,6 +94,10 @@ const TimelinePanel = createReactClass({
|
||||||
// callback which is called when the read-up-to mark is updated.
|
// callback which is called when the read-up-to mark is updated.
|
||||||
onReadMarkerUpdated: PropTypes.func,
|
onReadMarkerUpdated: PropTypes.func,
|
||||||
|
|
||||||
|
// callback which is called when we wish to paginate the timeline
|
||||||
|
// window.
|
||||||
|
onPaginationRequest: PropTypes.func,
|
||||||
|
|
||||||
// maximum number of events to show in a timeline
|
// maximum number of events to show in a timeline
|
||||||
timelineCap: PropTypes.number,
|
timelineCap: PropTypes.number,
|
||||||
|
|
||||||
|
@ -338,6 +342,14 @@ const TimelinePanel = createReactClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onPaginationRequest(timelineWindow, direction, size) {
|
||||||
|
if (this.props.onPaginationRequest) {
|
||||||
|
return this.props.onPaginationRequest(timelineWindow, direction, size);
|
||||||
|
} else {
|
||||||
|
return timelineWindow.paginate(direction, size);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// set off a pagination request.
|
// set off a pagination request.
|
||||||
onMessageListFillRequest: function(backwards) {
|
onMessageListFillRequest: function(backwards) {
|
||||||
if (!this._shouldPaginate()) return Promise.resolve(false);
|
if (!this._shouldPaginate()) return Promise.resolve(false);
|
||||||
|
@ -360,7 +372,7 @@ const TimelinePanel = createReactClass({
|
||||||
debuglog("TimelinePanel: Initiating paginate; backwards:"+backwards);
|
debuglog("TimelinePanel: Initiating paginate; backwards:"+backwards);
|
||||||
this.setState({[paginatingKey]: true});
|
this.setState({[paginatingKey]: true});
|
||||||
|
|
||||||
return this._timelineWindow.paginate(dir, PAGINATE_SIZE).then((r) => {
|
return this.onPaginationRequest(this._timelineWindow, dir, PAGINATE_SIZE).then((r) => {
|
||||||
if (this.unmounted) { return; }
|
if (this.unmounted) { return; }
|
||||||
|
|
||||||
debuglog("TimelinePanel: paginate complete backwards:"+backwards+"; success:"+r);
|
debuglog("TimelinePanel: paginate complete backwards:"+backwards+"; success:"+r);
|
||||||
|
|
|
@ -418,17 +418,29 @@ export default class EventIndex {
|
||||||
return indexManager.searchEventIndex(searchArgs);
|
return indexManager.searchEventIndex(searchArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
async populateFileTimeline(room, timelineSet) {
|
async loadFileEvents(room, limit = 10, fromEvent = null, direction = EventTimeline.BACKWARDS) {
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
const indexManager = PlatformPeg.get().getEventIndexingManager();
|
const indexManager = PlatformPeg.get().getEventIndexingManager();
|
||||||
|
|
||||||
|
let loadArgs = {
|
||||||
|
roomId: room.roomId,
|
||||||
|
limit: limit
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fromEvent) {
|
||||||
|
loadArgs.fromEvent = fromEvent;
|
||||||
|
loadArgs.direction = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
let events
|
||||||
|
|
||||||
// Get our events from the event index.
|
// Get our events from the event index.
|
||||||
const events = await indexManager.loadFileEvents(
|
try {
|
||||||
{
|
events = await indexManager.loadFileEvents(loadArgs);
|
||||||
roomId: room.roomId,
|
} catch (e) {
|
||||||
limit: 10
|
console.log("EventIndex: Error getting file events", e);
|
||||||
}
|
return []
|
||||||
);
|
}
|
||||||
|
|
||||||
let eventMapper = client.getEventMapper();
|
let eventMapper = client.getEventMapper();
|
||||||
|
|
||||||
|
@ -468,15 +480,82 @@ export default class EventIndex {
|
||||||
return matrixEvent;
|
return matrixEvent;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return matrixEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
async populateFileTimeline(timelineSet, timeline, room, limit = 10,
|
||||||
|
fromEvent = null, direction = EventTimeline.BACKWARDS) {
|
||||||
|
let matrixEvents = await this.loadFileEvents(room, limit, fromEvent, direction);
|
||||||
|
|
||||||
// Add the events to the live timeline of the file panel.
|
// Add the events to the live timeline of the file panel.
|
||||||
matrixEvents.forEach(e => {
|
matrixEvents.forEach(e => {
|
||||||
if (!timelineSet.eventIdToTimeline(e.getId())) {
|
if (!timelineSet.eventIdToTimeline(e.getId())) {
|
||||||
const liveTimeline = timelineSet.getLiveTimeline();
|
timelineSet.addEventToTimeline(e, timeline,
|
||||||
timelineSet.addEventToTimeline(e, liveTimeline, true)
|
direction == EventTimeline.BACKWARDS)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set the pagination token to the oldest event that we retrieved.
|
// Set the pagination token to the oldest event that we retrieved.
|
||||||
timelineSet.getLiveTimeline().setPaginationToken("", EventTimeline.BACKWARDS);
|
if (matrixEvents.length > 0) {
|
||||||
|
timeline.setPaginationToken(matrixEvents[matrixEvents.length - 1].getId(),
|
||||||
|
EventTimeline.BACKWARDS);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
timeline.setPaginationToken("", EventTimeline.BACKWARDS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paginateTimelineWindow(room, timelineWindow, direction, limit) {
|
||||||
|
let tl;
|
||||||
|
|
||||||
|
// TODO this is from the js-sdk, this should probably be exposed to
|
||||||
|
// us through the js-sdk.
|
||||||
|
const moveWindowCap = (titmelineWindow, timeline, direction, limit) => {
|
||||||
|
var count = (direction == EventTimeline.BACKWARDS) ?
|
||||||
|
timeline.retreat(limit) : timeline.advance(limit);
|
||||||
|
|
||||||
|
if (count) {
|
||||||
|
timelineWindow._eventCount += count;
|
||||||
|
var excess = timelineWindow._eventCount - timelineWindow._windowLimit;
|
||||||
|
|
||||||
|
if (excess > 0) {
|
||||||
|
timelineWindow.unpaginate(3, direction != EventTimeline.BACKWARDS);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO these private fields should be somehow exposed in the js-sdk.
|
||||||
|
if (direction == EventTimeline.BACKWARDS) tl = timelineWindow._start;
|
||||||
|
else if (direction == EventTimeline.FORWARDS) tl = timelineWindow._end;
|
||||||
|
|
||||||
|
if (!tl) return Promise.resolve(false);
|
||||||
|
if (tl.pendingPaginate) return tl.pendingPaginate;
|
||||||
|
|
||||||
|
if (moveWindowCap(timelineWindow, tl, direction, limit)) {
|
||||||
|
return Promise.resolve(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const paginationMethod = async (timelineWindow, timeline, room, direction, limit) => {
|
||||||
|
const timelineSet = timelineWindow._timelineSet;
|
||||||
|
const token = timeline.timeline.getPaginationToken(direction);
|
||||||
|
|
||||||
|
const ret = await this.populateFileTimeline(timelineSet, timeline.timeline,
|
||||||
|
room, limit, token, direction);
|
||||||
|
|
||||||
|
moveWindowCap(timelineWindow, timeline, direction, limit)
|
||||||
|
timeline.pendingPaginate = null;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
const paginationPromise = paginationMethod(timelineWindow, tl, room,
|
||||||
|
direction, limit);
|
||||||
|
tl.pendingPaginate = paginationPromise;
|
||||||
|
|
||||||
|
return paginationPromise;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue