You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-12-23 22:42:10 +03:00
Fix a bug which made the timelines get confused about local messages
Make sure that the timeline index is kept consistent when the id of an event changes when we receive the remote echo of a message we sent.
This commit is contained in:
@@ -575,13 +575,23 @@ Room.prototype._addLiveEvents = function(events) {
|
||||
// Exists due to client.js:815 (MatrixClient.sendEvent)
|
||||
// We should make txnId a first class citizen.
|
||||
if (events[i]._txnId) {
|
||||
// this is the outgoing copy of the event (ie, the local echo).
|
||||
this._txnToEvent[events[i]._txnId] = events[i];
|
||||
}
|
||||
else if (events[i].getUnsigned().transaction_id) {
|
||||
// remote echo of an event we sent earlier
|
||||
var existingEvent = this._txnToEvent[events[i].getUnsigned().transaction_id];
|
||||
if (existingEvent) {
|
||||
// no longer pending
|
||||
delete this._txnToEvent[events[i].getUnsigned().transaction_id];
|
||||
|
||||
// update the timeline map, because the event id has changed
|
||||
var existingTimeline = this._eventIdToTimeline[existingEvent.getId()];
|
||||
if (existingTimeline) {
|
||||
delete this._eventIdToTimeline[existingEvent.getId()];
|
||||
this._eventIdToTimeline[events[i].getId()] = existingTimeline;
|
||||
}
|
||||
|
||||
// replace the event source
|
||||
existingEvent.event = events[i].event;
|
||||
continue;
|
||||
|
||||
@@ -564,6 +564,85 @@ describe("MatrixClient event timelines", function() {
|
||||
|
||||
httpBackend.flush().catch(utils.failTest);
|
||||
});
|
||||
});
|
||||
|
||||
describe("event timeline for sent events", function() {
|
||||
var TXN_ID = "txn1";
|
||||
var event = utils.mkMessage({
|
||||
room: roomId, user: userId, msg: "a body",
|
||||
});
|
||||
event.unsigned = {transaction_id: TXN_ID};
|
||||
|
||||
beforeEach(function() {
|
||||
// set up handlers for both the message send, and the
|
||||
// /sync
|
||||
httpBackend.when("PUT", "/send/m.room.message/"+TXN_ID).respond(200, {
|
||||
event_id: event.event_id,
|
||||
});
|
||||
httpBackend.when("GET", "/sync").respond(200, {
|
||||
next_batch: "s_5_4",
|
||||
rooms: {
|
||||
join: {
|
||||
"!foo:bar": {
|
||||
timeline: {
|
||||
events: [
|
||||
event
|
||||
],
|
||||
prev_batch: "f_1_1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should work when /send returns before /sync", function(done) {
|
||||
var room = client.getRoom(roomId);
|
||||
|
||||
client.sendTextMessage(roomId, "a body", TXN_ID).then(function(res) {
|
||||
expect(res.event_id).toEqual(event.event_id);
|
||||
return client.getEventTimeline(room, event.event_id);
|
||||
}).then(function(tl) {
|
||||
expect(tl.getEvents().length).toEqual(2); // the initial sync contained an event
|
||||
expect(tl.getEvents()[1].getContent().body).toEqual("a body");
|
||||
|
||||
// now let the sync complete, and check it again
|
||||
return httpBackend.flush("/sync", 1);
|
||||
}).then(function() {
|
||||
return client.getEventTimeline(room, event.event_id);
|
||||
}).then(function(tl) {
|
||||
expect(tl.getEvents().length).toEqual(2);
|
||||
expect(tl.getEvents()[1].event).toEqual(event);
|
||||
}).catch(utils.failTest).done(done);
|
||||
|
||||
httpBackend.flush("/send/m.room.message/" + TXN_ID, 1).catch(utils.failTest);
|
||||
});
|
||||
|
||||
it("should work when /send returns after /sync", function(done) {
|
||||
var room = client.getRoom(roomId);
|
||||
|
||||
// initiate the send, and set up checks to be done when it completes
|
||||
// - but note that it won't complete until after the /sync does, below.
|
||||
client.sendTextMessage(roomId, "a body", TXN_ID).then(function(res) {
|
||||
console.log("sendTextMessage completed");
|
||||
expect(res.event_id).toEqual(event.event_id);
|
||||
return client.getEventTimeline(room, event.event_id);
|
||||
}).then(function(tl) {
|
||||
console.log("getEventTimeline completed (2)");
|
||||
expect(tl.getEvents().length).toEqual(2);
|
||||
expect(tl.getEvents()[1].getContent().body).toEqual("a body");
|
||||
}).catch(utils.failTest).done(done);
|
||||
|
||||
httpBackend.flush("/sync", 1).then(function() {
|
||||
return client.getEventTimeline(room, event.event_id);
|
||||
}).then(function(tl) {
|
||||
console.log("getEventTimeline completed (1)");
|
||||
expect(tl.getEvents().length).toEqual(2);
|
||||
expect(tl.getEvents()[1].event).toEqual(event);
|
||||
|
||||
// now let the send complete.
|
||||
return httpBackend.flush("/send/m.room.message/" + TXN_ID, 1);
|
||||
}).catch(utils.failTest);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user