1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-18 05:42:00 +03:00

Merge pull request #41 from matrix-org/implicit_read_receipts

Implicit read receipts
This commit is contained in:
David Baker
2015-11-05 14:42:48 +00:00
3 changed files with 55 additions and 6 deletions

View File

@@ -954,6 +954,9 @@ function _sendEvent(client, room, event, callback) {
// the fake event we made above. If we don't find it, we're still
// waiting on the real event and so should assign the fake event
// with the real event_id for matching later.
// FIXME: This manipulation of the room should probably be done
// inside the room class, not by the client.
var matchingEvent = utils.findElement(room.timeline, function(ev) {
return ev.getId() === eventId;
}, true);
@@ -966,13 +969,13 @@ function _sendEvent(client, room, event, callback) {
matchingEvent.event.content = event.event.content;
matchingEvent.event.type = event.event.type;
}
utils.removeElement(room.timeline, function(ev) {
return ev.getId() === event.getId();
}, true);
room.removeEvents([event.getId()]);
}
else {
room.removeEvents([event.getId()]);
event.event.event_id = res.event_id;
event.status = null;
room.addEventsToTimeline([event]);
}
}

View File

@@ -194,7 +194,26 @@ Room.prototype.addEventsToTimeline = function(events, toStartOfTimeline) {
else {
this.timeline.push(events[i]);
}
this.emit("Room.timeline", events[i], this, Boolean(toStartOfTimeline));
// synthesize and inject implicit read receipts
// Done after adding the event because otherwise the app would get a read receipt
// pointing to an event that wasn't yet in the timeline
// 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));
}
this.emit("Room.timeline", events[i], this, Boolean(toStartOfTimeline), false);
}
};
@@ -260,6 +279,29 @@ Room.prototype.addEvents = function(events, duplicateStrategy) {
}
};
/**
* Removes events from this room.
* @param {String} event_ids A list of event_ids to remove.
*/
Room.prototype.removeEvents = function(event_ids) {
// avoids defining a function in the loop, which is a lint error
function removeEventWithId(timeline, id) {
// NB. we supply reverse to search from the end,
// on the assumption that recents events are much
// more likley to be removed than older ones.
return utils.removeElement(timeline, function(e) {
return e.getId() == id;
}, true);
}
for (var i = 0; i < event_ids.length; ++i) {
var removed = removeEventWithId(this.timeline, event_ids[i]);
if (removed) {
this.emit("Room.timeline", removed, this, undefined, true);
}
}
};
/**
* Recalculate various aspects of the room, including the room name and
* room summary. Call this any time the room's current state is modified.
@@ -513,6 +555,7 @@ module.exports = Room;
* @param {MatrixEvent} event The matrix event which caused this event to fire.
* @param {Room} room The room whose Room.timeline was updated.
* @param {boolean} toStartOfTimeline True if this event was added to the start
* @param {boolean} removed True if this event has just been removed from the timeline
* (beginning; oldest) of the timeline e.g. due to pagination.
* @example
* matrixClient.on("Room.timeline", function(event, room, toStartOfTimeline){

View File

@@ -152,19 +152,22 @@ module.exports.findElement = function(array, fn, reverse) {
*/
module.exports.removeElement = function(array, fn, reverse) {
var i;
var removed;
if (reverse) {
for (i = array.length - 1; i >= 0; i--) {
if (fn(array[i], i, array)) {
removed = array[i];
array.splice(i, 1);
return true;
return removed;
}
}
}
else {
for (i = 0; i < array.length; i++) {
if (fn(array[i], i, array)) {
removed = array[i];
array.splice(i, 1);
return true;
return removed;
}
}
}