forked from mystiq/hydrogen-web
aggregate relations when seeing event target during back-pagination
This commit is contained in:
parent
9099a76f45
commit
ce5409dc26
3 changed files with 46 additions and 6 deletions
|
@ -119,13 +119,14 @@ export class GapWriter {
|
|||
eventStorageEntry.displayName = member.displayName;
|
||||
eventStorageEntry.avatarUrl = member.avatarUrl;
|
||||
}
|
||||
txn.timelineEvents.insert(eventStorageEntry);
|
||||
const eventEntry = new EventEntry(eventStorageEntry, this._fragmentIdComparer);
|
||||
directionalAppend(entries, eventEntry, direction);
|
||||
const updatedRelationTargetEntries = await this._relationWriter.writeRelation(eventEntry, txn, log);
|
||||
// this will modify eventStorageEntry if it is a relation target
|
||||
const updatedRelationTargetEntries = await this._relationWriter.writeGapRelation(eventStorageEntry, direction, txn, log);
|
||||
if (updatedRelationTargetEntries) {
|
||||
updatedEntries.push(...updatedRelationTargetEntries);
|
||||
}
|
||||
txn.timelineEvents.insert(eventStorageEntry);
|
||||
const eventEntry = new EventEntry(eventStorageEntry, this._fragmentIdComparer);
|
||||
directionalAppend(entries, eventEntry, direction);
|
||||
}
|
||||
return {entries, updatedEntries};
|
||||
}
|
||||
|
|
|
@ -44,10 +44,36 @@ export class RelationWriter {
|
|||
}
|
||||
}
|
||||
}
|
||||
// TODO: check if sourceEntry is in timelineRelations as a target, and if so reaggregate it
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} storageEntry the event object, as it will be stored in storage.
|
||||
* Will be modified (but not written to storage) in case this event is
|
||||
* a relation target for which we've previously received relations.
|
||||
* @param {Direction} direction of the gap fill
|
||||
* */
|
||||
async writeGapRelation(storageEntry, direction, txn, log) {
|
||||
const sourceEntry = new EventEntry(storageEntry, this._fragmentIdComparer);
|
||||
const result = await this.writeRelation(sourceEntry, txn, log);
|
||||
// when back-paginating, it can also happen that we've received relations
|
||||
// for this event before, which now upon receiving the target need to be aggregated.
|
||||
if (direction.isBackward) {
|
||||
const relations = await txn.timelineRelations.getAllForTarget(this._roomId, sourceEntry.id);
|
||||
if (relations.length) {
|
||||
for (const r of relations) {
|
||||
const relationStorageEntry = await txn.timelineEvents.getByEventId(this._roomId, r.sourceEventId);
|
||||
if (relationStorageEntry) {
|
||||
const relationEntry = new EventEntry(relationStorageEntry, this._fragmentIdComparer);
|
||||
await this._applyRelation(relationEntry, storageEntry, txn, log);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {EventEntry} sourceEntry
|
||||
* @param {Object} targetStorageEntry event entry as stored in the timelineEvents store
|
||||
|
|
|
@ -59,4 +59,17 @@ export class TimelineRelationStore {
|
|||
const keys = await this._store.selectAll(range);
|
||||
return keys.map(decodeKey);
|
||||
}
|
||||
|
||||
async getAllForTarget(roomId, targetId) {
|
||||
// exclude both keys as they are theoretical min and max,
|
||||
// but we should't have a match for just the room id, or room id with max
|
||||
const range = this._store.IDBKeyRange.bound(
|
||||
encodeKey(roomId, targetId, MIN_UNICODE, MIN_UNICODE),
|
||||
encodeKey(roomId, targetId, MAX_UNICODE, MAX_UNICODE),
|
||||
true,
|
||||
true
|
||||
);
|
||||
const keys = await this._store.selectAll(range);
|
||||
return keys.map(decodeKey);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue