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.displayName = member.displayName;
|
||||||
eventStorageEntry.avatarUrl = member.avatarUrl;
|
eventStorageEntry.avatarUrl = member.avatarUrl;
|
||||||
}
|
}
|
||||||
txn.timelineEvents.insert(eventStorageEntry);
|
// this will modify eventStorageEntry if it is a relation target
|
||||||
const eventEntry = new EventEntry(eventStorageEntry, this._fragmentIdComparer);
|
const updatedRelationTargetEntries = await this._relationWriter.writeGapRelation(eventStorageEntry, direction, txn, log);
|
||||||
directionalAppend(entries, eventEntry, direction);
|
|
||||||
const updatedRelationTargetEntries = await this._relationWriter.writeRelation(eventEntry, txn, log);
|
|
||||||
if (updatedRelationTargetEntries) {
|
if (updatedRelationTargetEntries) {
|
||||||
updatedEntries.push(...updatedRelationTargetEntries);
|
updatedEntries.push(...updatedRelationTargetEntries);
|
||||||
}
|
}
|
||||||
|
txn.timelineEvents.insert(eventStorageEntry);
|
||||||
|
const eventEntry = new EventEntry(eventStorageEntry, this._fragmentIdComparer);
|
||||||
|
directionalAppend(entries, eventEntry, direction);
|
||||||
}
|
}
|
||||||
return {entries, updatedEntries};
|
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;
|
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 {EventEntry} sourceEntry
|
||||||
* @param {Object} targetStorageEntry event entry as stored in the timelineEvents store
|
* @param {Object} targetStorageEntry event entry as stored in the timelineEvents store
|
||||||
|
@ -224,4 +250,4 @@ const _REDACT_KEEP_CONTENT_MAP = {
|
||||||
},
|
},
|
||||||
'm.room.aliases': {'aliases': 1},
|
'm.room.aliases': {'aliases': 1},
|
||||||
};
|
};
|
||||||
// end of matrix-js-sdk code
|
// end of matrix-js-sdk code
|
||||||
|
|
|
@ -59,4 +59,17 @@ export class TimelineRelationStore {
|
||||||
const keys = await this._store.selectAll(range);
|
const keys = await this._store.selectAll(range);
|
||||||
return keys.map(decodeKey);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue