You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-08-09 10:22:46 +03:00
Synthesize implicit read receipts in recalculateRoom to make them correct when the room is first loaded.
This commit is contained in:
@@ -201,16 +201,10 @@ Room.prototype.addEventsToTimeline = function(events, toStartOfTimeline) {
|
||||
|
||||
// This is really ugly because JS has no way to express an object literal
|
||||
// where the name of a key comes from an expression
|
||||
if (events[i].sender) {
|
||||
var fakeReceipt = {content: {}};
|
||||
fakeReceipt.content[events[i].getId()] = {
|
||||
'm.read': {
|
||||
}
|
||||
};
|
||||
fakeReceipt.content[events[i].getId()]['m.read'][events[i].sender.userId] = {
|
||||
ts: events[i].getTs()
|
||||
};
|
||||
this.addReceipt(new MatrixEvent(fakeReceipt));
|
||||
if (!toStartOfTimeline && events[i].sender) {
|
||||
this.addReceipt(new MatrixEvent(this._synthesizeReceipt(
|
||||
events[i].sender.userId, events[i], "m.read"
|
||||
)));
|
||||
}
|
||||
|
||||
this.emit("Room.timeline", events[i], this, Boolean(toStartOfTimeline), false);
|
||||
@@ -347,8 +341,60 @@ Room.prototype.recalculate = function(userId) {
|
||||
if (oldName !== this.name) {
|
||||
this.emit("Room.name", this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// recalculate read receipts, adding implicit ones where necessary
|
||||
// NB. This is a duplication of logic for injecting implicit receipts,
|
||||
// it would be technically possible to only ever generate these
|
||||
// receipts in addEventsToTimeline but doing so means correctly
|
||||
// choosing whether to keep or replace the existing receipt which
|
||||
// is complex and slow. This is faster and more understandable.
|
||||
|
||||
var usersFound = {};
|
||||
for (var i = this.timeline.length - 1; i >= 0; --i) {
|
||||
// loop through the timeline backwards looking for either an
|
||||
// event sent by each user or a real receipt from them.
|
||||
// Replace the read receipt for that user with whichever
|
||||
// occurs later in the timeline (ie. first because we're going
|
||||
// backwards).
|
||||
var e = this.timeline[i];
|
||||
|
||||
var readReceiptsForEvent = this.getReceiptsForEvent(e);
|
||||
|
||||
for (var receiptIt = 0; receiptIt < readReceiptsForEvent.length; ++receiptIt) {
|
||||
var receipt = readReceiptsForEvent[receiptIt];
|
||||
if (receipt.type !== "m.read") { continue; }
|
||||
|
||||
var userId = receipt.userId;
|
||||
if (usersFound[userId]) { continue; }
|
||||
|
||||
// Then this is the receipt we keep for this user
|
||||
usersFound[userId] = 1;
|
||||
}
|
||||
|
||||
if (e.sender && usersFound[e.sender.userId] === undefined) {
|
||||
// no receipt yet for this sender, so we synthesize one.
|
||||
|
||||
this.addReceipt(this._synthesizeReceipt(e.sender.userId, e, "m.read"));
|
||||
|
||||
usersFound[e.sender.userId] = 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Room.prototype._synthesizeReceipt = function(userId, event, receiptType) {
|
||||
// This is really ugly because JS has no way to express an object literal
|
||||
// where the name of a key comes from an expression
|
||||
var fakeReceipt = {content: {}};
|
||||
fakeReceipt.content[event.getId()] = {};
|
||||
fakeReceipt.content[event.getId()][receiptType] = {};
|
||||
fakeReceipt.content[event.getId()][receiptType][userId] = {
|
||||
ts: event
|
||||
};
|
||||
return new MatrixEvent(fakeReceipt);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of user IDs who have <b>read up to</b> the given event.
|
||||
|
Reference in New Issue
Block a user