Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 3ab0757

Browse files
authored
Fix edge case with sent indicator being drawn when it shouldn't be (#11320)
* Fix edge case with sent indicator being drawn when it shouldn't be * Comment
1 parent 22f83e7 commit 3ab0757

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

src/components/structures/MessagePanel.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
633633

634634
const userId = MatrixClientPeg.safeGet().getSafeUserId();
635635

636-
let foundLastSuccessfulWeSent = false;
636+
let foundLastSuccessfulEvent = false;
637637
let lastShownNonLocalEchoIndex = -1;
638638
// Find the indices of the last successful event we sent and the last non-local-echo events shown
639639
for (let i = events.length - 1; i >= 0; i--) {
@@ -646,16 +646,21 @@ export default class MessagePanel extends React.Component<IProps, IState> {
646646
lastShownEvent = event;
647647
}
648648

649-
if (!foundLastSuccessfulWeSent && this.isSentState(event) && isEligibleForSpecialReceipt(event, userId)) {
650-
events[i].lastSuccessfulWeSent = true;
651-
foundLastSuccessfulWeSent = true;
649+
if (!foundLastSuccessfulEvent && this.isSentState(event) && isEligibleForSpecialReceipt(event)) {
650+
foundLastSuccessfulEvent = true;
651+
// If we are not sender of this last successful event eligible for special receipt then we stop here
652+
// As we do not want to render our sent receipt if there are more receipts below it and events sent
653+
// by other users get a synthetic read receipt for their sent events.
654+
if (event.getSender() === userId) {
655+
events[i].lastSuccessfulWeSent = true;
656+
}
652657
}
653658

654659
if (lastShownNonLocalEchoIndex < 0 && !event.status) {
655660
lastShownNonLocalEchoIndex = i;
656661
}
657662

658-
if (lastShownNonLocalEchoIndex >= 0 && foundLastSuccessfulWeSent) {
663+
if (lastShownNonLocalEchoIndex >= 0 && foundLastSuccessfulEvent) {
659664
break;
660665
}
661666
}

src/components/views/rooms/EventTile.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,7 @@ interface IState {
251251
* This could be a 'sending' or 'sent' receipt, for example.
252252
* @returns {boolean}
253253
*/
254-
export function isEligibleForSpecialReceipt(event: MatrixEvent, myUserId: string): boolean {
255-
// Check to see if the event was sent by us. If it wasn't, it won't qualify for special read receipts.
256-
if (event.getSender() !== myUserId) return false;
257-
254+
export function isEligibleForSpecialReceipt(event: MatrixEvent): boolean {
258255
// Determine if the type is relevant to the user.
259256
// This notably excludes state events and pretty much anything that can't be sent by the composer as a message.
260257
// For those we rely on local echo giving the impression of things changing, and expect them to be quick.
@@ -332,7 +329,9 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
332329
// Quickly check to see if the event was sent by us. If it wasn't, it won't qualify for
333330
// special read receipts.
334331
const myUserId = MatrixClientPeg.safeGet().getSafeUserId();
335-
return isEligibleForSpecialReceipt(this.props.mxEvent, myUserId);
332+
// Check to see if the event was sent by us. If it wasn't, it won't qualify for special read receipts.
333+
if (this.props.mxEvent.getSender() !== myUserId) return false;
334+
return isEligibleForSpecialReceipt(this.props.mxEvent);
336335
}
337336

338337
private get shouldShowSentReceipt(): boolean {

test/components/structures/MessagePanel-test.tsx

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { EventEmitter } from "events";
2020
import { MatrixEvent, Room, RoomMember } from "matrix-js-sdk/src/matrix";
2121
import { render } from "@testing-library/react";
2222
import { Thread } from "matrix-js-sdk/src/models/thread";
23+
import { ReceiptType } from "matrix-js-sdk/src/@types/read_receipts";
2324

2425
import MessagePanel, { shouldFormContinuation } from "../../../src/components/structures/MessagePanel";
2526
import SettingsStore from "../../../src/settings/SettingsStore";
@@ -757,12 +758,44 @@ describe("MessagePanel", function () {
757758
];
758759
const { container } = render(getComponent({ events, showReadReceipts: true }));
759760

760-
// just check we have the right number of tiles for now
761761
const tiles = container.getElementsByClassName("mx_EventTile");
762762
expect(tiles.length).toEqual(2);
763763
expect(tiles[0].querySelector(".mx_EventTile_receiptSent")).toBeTruthy();
764764
expect(tiles[1].querySelector(".mx_EventTile_receiptSent")).toBeFalsy();
765765
});
766+
767+
it("should set lastSuccessful=false on non-last event if last event has a receipt from someone else", () => {
768+
client.getRoom.mockImplementation((id) => (id === room.roomId ? room : null));
769+
const events = [
770+
TestUtilsMatrix.mkMessage({
771+
event: true,
772+
room: room.roomId,
773+
user: client.getSafeUserId(),
774+
ts: 1000,
775+
}),
776+
TestUtilsMatrix.mkMessage({
777+
event: true,
778+
room: room.roomId,
779+
user: "@other:user",
780+
ts: 1001,
781+
}),
782+
];
783+
room.addReceiptToStructure(
784+
events[1].getId()!,
785+
ReceiptType.Read,
786+
"@other:user",
787+
{
788+
ts: 1001,
789+
},
790+
true,
791+
);
792+
const { container } = render(getComponent({ events, showReadReceipts: true }));
793+
794+
const tiles = container.getElementsByClassName("mx_EventTile");
795+
expect(tiles.length).toEqual(2);
796+
expect(tiles[0].querySelector(".mx_EventTile_receiptSent")).toBeFalsy();
797+
expect(tiles[1].querySelector(".mx_EventTile_receiptSent")).toBeFalsy();
798+
});
766799
});
767800

768801
describe("shouldFormContinuation", () => {

0 commit comments

Comments
 (0)