Skip to content

Commit dcf3e53

Browse files
authored
Don't allow pin or edit of messages with a send status (#31158)
* Don't allow pin or edit of messages with a send status * lint and improve comments.
1 parent 18a5565 commit dcf3e53

File tree

4 files changed

+35
-3
lines changed

4 files changed

+35
-3
lines changed

src/utils/EventUtils.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ export function canEditContent(matrixClient: MatrixClient, mxEvent: MatrixEvent)
7070

7171
if (
7272
!isCancellable ||
73-
mxEvent.status === EventStatus.CANCELLED ||
73+
// Editing local echos is not supported(results in send a message that references the local ID).
74+
// We need to ensure the event is not local, and therefore has no send status.
75+
mxEvent.status !== null ||
7476
mxEvent.isRedacted() ||
7577
mxEvent.isRelation(RelationType.Replace) ||
7678
mxEvent.getSender() !== matrixClient.getUserId()

src/utils/PinningUtils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ export default class PinningUtils {
8181
const room = matrixClient.getRoom(mxEvent.getRoomId());
8282
if (!room) return false;
8383

84+
// Should have a non-local event id
85+
if (mxEvent.status !== null) return false;
86+
8487
return PinningUtils.userHasPinOrUnpinPermission(matrixClient, room) && PinningUtils.isPinnable(mxEvent);
8588
}
8689

@@ -94,6 +97,9 @@ export default class PinningUtils {
9497
const room = matrixClient.getRoom(mxEvent.getRoomId());
9598
if (!room) return false;
9699

100+
// Should have a non-local event id
101+
if (mxEvent.status !== null) return false;
102+
97103
return PinningUtils.userHasPinOrUnpinPermission(matrixClient, room) && PinningUtils.isUnpinnable(mxEvent);
98104
}
99105

@@ -123,6 +129,9 @@ export default class PinningUtils {
123129
const eventId = mxEvent.getId();
124130
if (!eventId) return;
125131

132+
// Should have a non-local event id
133+
if (mxEvent.status !== null) return;
134+
126135
// Get the current pinned events of the room
127136
const pinnedIds: Array<string> =
128137
room

test/unit-tests/components/views/context_menus/MessageContextMenu-test.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,8 @@ function createMenu(
748748
// @ts-ignore illegally set private prop
749749
room.currentState.beacons = beacons;
750750

751-
mxEvent.setStatus(EventStatus.SENT);
751+
// The base case is that we have received the remote echo and have an eventId. No sending status.
752+
mxEvent.setStatus(null);
752753

753754
client.getUserId = jest.fn().mockReturnValue("@user:example.com");
754755
client.getRoom = jest.fn().mockReturnValue(room);

test/unit-tests/components/views/messages/MessageActionBar-test.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ describe("<MessageActionBar />", () => {
125125

126126
beforeEach(() => {
127127
jest.clearAllMocks();
128-
alicesMessageEvent.setStatus(EventStatus.SENT);
128+
// The base case is that we have received the remote echo and have an eventId. No sending status.
129+
alicesMessageEvent.setStatus(null);
129130
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
130131
jest.spyOn(SettingsStore, "setValue").mockResolvedValue(undefined);
131132
});
@@ -376,6 +377,25 @@ describe("<MessageActionBar />", () => {
376377
expect(queryByLabelText("Delete")).toBeTruthy();
377378
});
378379

380+
it("only shows retry and delete buttons when event could not be sent", () => {
381+
// Enable pin and other features
382+
jest.spyOn(SettingsStore, "getValue").mockReturnValue(true);
383+
384+
alicesMessageEvent.setStatus(EventStatus.NOT_SENT);
385+
const { queryByLabelText } = getComponent({ mxEvent: alicesMessageEvent });
386+
387+
// Should show retry and cancel buttons
388+
expect(queryByLabelText("Retry")).toBeTruthy();
389+
expect(queryByLabelText("Delete")).toBeTruthy();
390+
391+
// Should NOT show edit, pin, react, reply buttons
392+
expect(queryByLabelText("Edit")).toBeFalsy();
393+
expect(queryByLabelText("Pin")).toBeFalsy();
394+
expect(queryByLabelText("React")).toBeFalsy();
395+
expect(queryByLabelText("Reply")).toBeFalsy();
396+
expect(queryByLabelText("Reply in thread")).toBeFalsy();
397+
});
398+
379399
it.todo("unsends event on cancel click");
380400
it.todo("retrys event on retry click");
381401
});

0 commit comments

Comments
 (0)