From 044eaf7eb598ca4609c740f51ab1863f40881c32 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 6 Nov 2024 14:55:21 +0000 Subject: [PATCH 01/44] Update calls to addEventToTimeline and addLiveEvents for new signature Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/FilePanel.tsx | 6 ++- src/indexing/EventIndex.ts | 6 ++- src/utils/dm/createDmLocalRoom.ts | 2 +- test/test-utils/call.ts | 50 +++++++++++-------- test/test-utils/threads.ts | 2 +- test/unit-tests/Notifier-test.ts | 3 +- test/unit-tests/RoomNotifs-test.ts | 10 ++-- test/unit-tests/Unread-test.ts | 14 +++--- .../components/structures/RoomView-test.tsx | 24 +++++---- .../structures/ThreadPanel-test.tsx | 12 ++--- .../structures/TimelinePanel-test.tsx | 35 ++++++++----- .../RoomGeneralContextMenu-test.tsx | 2 +- .../views/dialogs/InviteDialog-test.tsx | 23 +++++---- .../components/views/elements/Pill-test.tsx | 2 +- .../views/elements/RoomTopic-test.tsx | 2 +- .../UnreadNotificationBadge-test.tsx | 2 +- .../views/rooms/RoomHeader-test.tsx | 2 +- .../views/settings/Notifications-test.tsx | 2 +- .../notifications/Notifications2-test.tsx | 2 +- .../events/EventTileFactory-test.ts | 2 +- test/unit-tests/models/Call-test.ts | 2 +- .../unit-tests/stores/MemberListStore-test.ts | 1 + test/unit-tests/stores/RoomViewStore-test.ts | 2 +- .../room-list/MessagePreviewStore-test.ts | 2 +- .../algorithms/RecentAlgorithm-test.ts | 18 +++---- .../previews/ReactionEventPreview-test.ts | 4 +- test/unit-tests/useTopic-test.tsx | 4 +- .../utils/exportUtils/HTMLExport-test.ts | 27 +++++----- test/unit-tests/utils/notifications-test.ts | 6 +-- .../components/VoiceBroadcastBody-test.tsx | 6 +-- .../models/VoiceBroadcastPlayback-test.tsx | 14 +++--- .../utils/hasRoomLiveVoiceBroadcast-test.ts | 2 +- .../utils/isRelatedToVoiceBroadcast-test.ts | 4 +- .../utils/retrieveStartedInfoEvent-test.ts | 2 +- 34 files changed, 166 insertions(+), 131 deletions(-) diff --git a/src/components/structures/FilePanel.tsx b/src/components/structures/FilePanel.tsx index 74a91d8cbc..07a20315f5 100644 --- a/src/components/structures/FilePanel.tsx +++ b/src/components/structures/FilePanel.tsx @@ -104,7 +104,11 @@ class FilePanel extends React.Component { } if (!this.state.timelineSet.eventIdToTimeline(ev.getId()!)) { - this.state.timelineSet.addEventToTimeline(ev, timeline, false); + this.state.timelineSet.addEventToTimeline(ev, timeline, { + fromCache: false, + addToState: false, + toStartOfTimeline: false, + }); } } diff --git a/src/indexing/EventIndex.ts b/src/indexing/EventIndex.ts index ec3935cd68..0b1a29e9a4 100644 --- a/src/indexing/EventIndex.ts +++ b/src/indexing/EventIndex.ts @@ -820,7 +820,11 @@ export default class EventIndex extends EventEmitter { // Add the events to the timeline of the file panel. matrixEvents.forEach((e) => { if (!timelineSet.eventIdToTimeline(e.getId()!)) { - timelineSet.addEventToTimeline(e, timeline, direction == EventTimeline.BACKWARDS); + timelineSet.addEventToTimeline(e, timeline, { + toStartOfTimeline: direction == EventTimeline.BACKWARDS, + fromCache: false, + addToState: false, + }); } }); diff --git a/src/utils/dm/createDmLocalRoom.ts b/src/utils/dm/createDmLocalRoom.ts index 6d6cf0712b..0a3d312368 100644 --- a/src/utils/dm/createDmLocalRoom.ts +++ b/src/utils/dm/createDmLocalRoom.ts @@ -109,7 +109,7 @@ export async function createDmLocalRoom(client: MatrixClient, targets: Member[]) localRoom.targets = targets; localRoom.updateMyMembership(KnownMembership.Join); - localRoom.addLiveEvents(events); + localRoom.addLiveEvents(events, { addToState: true }); localRoom.currentState.setStateEvents(events); localRoom.name = localRoom.getDefaultRoomName(client.getUserId()!); client.store.storeRoom(localRoom); diff --git a/test/test-utils/call.ts b/test/test-utils/call.ts index 0262e5537f..df87fcaa55 100644 --- a/test/test-utils/call.ts +++ b/test/test-utils/call.ts @@ -44,17 +44,20 @@ export class MockedCall extends Call { } public static create(room: Room, id: string) { - room.addLiveEvents([ - mkEvent({ - event: true, - type: this.EVENT_TYPE, - room: room.roomId, - user: "@alice:example.org", - content: { "m.type": "m.video", "m.intent": "m.prompt" }, - skey: id, - ts: Date.now(), - }), - ]); + room.addLiveEvents( + [ + mkEvent({ + event: true, + type: this.EVENT_TYPE, + room: room.roomId, + user: "@alice:example.org", + content: { "m.type": "m.video", "m.intent": "m.prompt" }, + skey: id, + ts: Date.now(), + }), + ], + { addToState: true }, + ); // @ts-ignore deliberately calling a private method // Let CallStore know that a call might now exist CallStore.instance.updateRoom(room); @@ -81,17 +84,20 @@ export class MockedCall extends Call { public destroy() { // Terminate the call for good measure - this.room.addLiveEvents([ - mkEvent({ - event: true, - type: MockedCall.EVENT_TYPE, - room: this.room.roomId, - user: "@alice:example.org", - content: { ...this.event.getContent(), "m.terminated": "Call ended" }, - skey: this.widget.id, - ts: Date.now(), - }), - ]); + this.room.addLiveEvents( + [ + mkEvent({ + event: true, + type: MockedCall.EVENT_TYPE, + room: this.room.roomId, + user: "@alice:example.org", + content: { ...this.event.getContent(), "m.terminated": "Call ended" }, + skey: this.widget.id, + ts: Date.now(), + }), + ], + { addToState: true }, + ); super.destroy(); } diff --git a/test/test-utils/threads.ts b/test/test-utils/threads.ts index d2459653e5..83313b1b8d 100644 --- a/test/test-utils/threads.ts +++ b/test/test-utils/threads.ts @@ -157,6 +157,6 @@ export const populateThread = async ({ // that it is already loaded, and send the events again to the room // so they are added to the thread timeline. ret.thread.initialEventsFetched = true; - await room.addLiveEvents(ret.events); + await room.addLiveEvents(ret.events, { addToState: false }); return ret; }; diff --git a/test/unit-tests/Notifier-test.ts b/test/unit-tests/Notifier-test.ts index 7bfde2afb3..2833659792 100644 --- a/test/unit-tests/Notifier-test.ts +++ b/test/unit-tests/Notifier-test.ts @@ -624,8 +624,7 @@ describe("Notifier", () => { content: { body: "this is a thread root" }, }), testRoom.threadsTimelineSets[0]!.getLiveTimeline(), - false, - false, + { toStartOfTimeline: false, fromCache: false, addToState: true }, ); expect(fn).not.toHaveBeenCalled(); diff --git a/test/unit-tests/RoomNotifs-test.ts b/test/unit-tests/RoomNotifs-test.ts index 51416ab7fd..65089eba94 100644 --- a/test/unit-tests/RoomNotifs-test.ts +++ b/test/unit-tests/RoomNotifs-test.ts @@ -147,7 +147,7 @@ describe("RoomNotifs test", () => { const itShouldCountPredecessorHighlightWhenThereIsAPredecessorInTheCreateEvent = (): void => { it("and there is a predecessor in the create event, it should count predecessor highlight", () => { - room.addLiveEvents([mkCreateEvent(OLD_ROOM_ID)]); + room.addLiveEvents([mkCreateEvent(OLD_ROOM_ID)], { addToState: true }); expect(getUnreadNotificationCount(room, NotificationCountType.Total, false)).toBe(8); expect(getUnreadNotificationCount(room, NotificationCountType.Highlight, false)).toBe(7); @@ -157,7 +157,7 @@ describe("RoomNotifs test", () => { const itShouldCountPredecessorHighlightWhenThereIsAPredecessorEvent = (): void => { it("and there is a predecessor event, it should count predecessor highlight", () => { client.getVisibleRooms(); - room.addLiveEvents([mkCreateEvent(OLD_ROOM_ID)]); + room.addLiveEvents([mkCreateEvent(OLD_ROOM_ID)], { addToState: true }); upsertRoomStateEvents(room, [mkPredecessorEvent(OLD_ROOM_ID)]); expect(getUnreadNotificationCount(room, NotificationCountType.Total, false)).toBe(8); @@ -185,7 +185,7 @@ describe("RoomNotifs test", () => { itShouldCountPredecessorHighlightWhenThereIsAPredecessorEvent(); it("and there is only a predecessor event, it should not count predecessor highlight", () => { - room.addLiveEvents([mkCreateEvent()]); + room.addLiveEvents([mkCreateEvent()], { addToState: true }); upsertRoomStateEvents(room, [mkPredecessorEvent(OLD_ROOM_ID)]); expect(getUnreadNotificationCount(room, NotificationCountType.Total, false)).toBe(2); @@ -204,7 +204,7 @@ describe("RoomNotifs test", () => { itShouldCountPredecessorHighlightWhenThereIsAPredecessorEvent(); it("and there is only a predecessor event, it should count predecessor highlight", () => { - room.addLiveEvents([mkCreateEvent()]); + room.addLiveEvents([mkCreateEvent()], { addToState: true }); upsertRoomStateEvents(room, [mkPredecessorEvent(OLD_ROOM_ID)]); expect(getUnreadNotificationCount(room, NotificationCountType.Total, false)).toBe(8); @@ -212,7 +212,7 @@ describe("RoomNotifs test", () => { }); it("and there is an unknown room in the predecessor event, it should not count predecessor highlight", () => { - room.addLiveEvents([mkCreateEvent()]); + room.addLiveEvents([mkCreateEvent()], { addToState: true }); upsertRoomStateEvents(room, [mkPredecessorEvent("!unknon:example.com")]); expect(getUnreadNotificationCount(room, NotificationCountType.Total, false)).toBe(2); diff --git a/test/unit-tests/Unread-test.ts b/test/unit-tests/Unread-test.ts index 8719da06ef..15d3dab8f5 100644 --- a/test/unit-tests/Unread-test.ts +++ b/test/unit-tests/Unread-test.ts @@ -138,7 +138,7 @@ describe("Unread", () => { room: roomId, content: {}, }); - room.addLiveEvents([event]); + room.addLiveEvents([event], { addToState: true }); // Don't care about the code path of hidden events. mocked(haveRendererForEvent).mockClear().mockReturnValue(true); @@ -157,7 +157,7 @@ describe("Unread", () => { content: {}, }); // Only for timeline events. - room.addLiveEvents([event]); + room.addLiveEvents([event], { addToState: true }); expect(doesRoomHaveUnreadMessages(room, false)).toBe(false); }); @@ -201,7 +201,7 @@ describe("Unread", () => { content: {}, }); // Only for timeline events. - room.addLiveEvents([event2]); + room.addLiveEvents([event2], { addToState: true }); expect(doesRoomHaveUnreadMessages(room, false)).toBe(true); }); @@ -403,7 +403,7 @@ describe("Unread", () => { redactedEvent.makeRedacted(redactedEvent, room); console.log("Event Id", redactedEvent.getId()); // Only for timeline events. - room.addLiveEvents([redactedEvent]); + room.addLiveEvents([redactedEvent], { addToState: true }); expect(doesRoomHaveUnreadMessages(room, true)).toBe(true); expect(logger.warn).toHaveBeenCalledWith( @@ -448,7 +448,7 @@ describe("Unread", () => { room: roomId, content: {}, }); - room.addLiveEvents([event]); + room.addLiveEvents([event], { addToState: true }); }); it("an unthreaded receipt for the event makes the room read", () => { @@ -502,7 +502,7 @@ describe("Unread", () => { ts: 100, currentUserId: myId, }); - room.addLiveEvents(events); + room.addLiveEvents(events, { addToState: true }); threadEvent = events[1]; }); @@ -555,7 +555,7 @@ describe("Unread", () => { room: roomId, content: {}, }); - room.addLiveEvents([event]); + room.addLiveEvents([event], { addToState: true }); // It still returns false expect(doesRoomHaveUnreadThreads(room)).toBe(false); diff --git a/test/unit-tests/components/structures/RoomView-test.tsx b/test/unit-tests/components/structures/RoomView-test.tsx index b6a0f28637..dfc663dc23 100644 --- a/test/unit-tests/components/structures/RoomView-test.tsx +++ b/test/unit-tests/components/structures/RoomView-test.tsx @@ -249,15 +249,19 @@ describe("RoomView", () => { cli.isRoomEncrypted.mockReturnValue(true); // and fake an encryption event into the room to prompt it to re-check - room.addLiveEvents([ - new MatrixEvent({ - type: "m.room.encryption", - sender: cli.getUserId()!, - content: {}, - event_id: "someid", - room_id: room.roomId, - }), - ]); + room.addLiveEvents( + [ + new MatrixEvent({ + type: "m.room.encryption", + sender: cli.getUserId()!, + content: {}, + event_id: "someid", + room_id: room.roomId, + state_key: "", + }), + ], + { addToState: true }, + ); // URL previews should now be disabled expect(roomViewInstance.state.showUrlPreview).toBe(false); @@ -440,7 +444,7 @@ describe("RoomView", () => { skey: id, ts, }); - room.addLiveEvents([widgetEvent]); + room.addLiveEvents([widgetEvent], { addToState: true }); room.currentState.setStateEvents([widgetEvent]); cli.emit(RoomStateEvent.Events, widgetEvent, room.currentState, null); await flushPromises(); diff --git a/test/unit-tests/components/structures/ThreadPanel-test.tsx b/test/unit-tests/components/structures/ThreadPanel-test.tsx index 1b4d59d9af..ddb6058759 100644 --- a/test/unit-tests/components/structures/ThreadPanel-test.tsx +++ b/test/unit-tests/components/structures/ThreadPanel-test.tsx @@ -209,11 +209,11 @@ describe("ThreadPanel", () => { return event ? Promise.resolve(event) : Promise.reject(); }); const [allThreads, myThreads] = room.threadsTimelineSets; - allThreads!.addLiveEvent(otherThread.rootEvent); - allThreads!.addLiveEvent(mixedThread.rootEvent); - allThreads!.addLiveEvent(ownThread.rootEvent); - myThreads!.addLiveEvent(mixedThread.rootEvent); - myThreads!.addLiveEvent(ownThread.rootEvent); + allThreads!.addLiveEvent(otherThread.rootEvent, { addToState: true }); + allThreads!.addLiveEvent(mixedThread.rootEvent, { addToState: true }); + allThreads!.addLiveEvent(ownThread.rootEvent, { addToState: true }); + myThreads!.addLiveEvent(mixedThread.rootEvent, { addToState: true }); + myThreads!.addLiveEvent(ownThread.rootEvent, { addToState: true }); let events: EventData[] = []; const renderResult = render(); @@ -259,7 +259,7 @@ describe("ThreadPanel", () => { return event ? Promise.resolve(event) : Promise.reject(); }); const [allThreads] = room.threadsTimelineSets; - allThreads!.addLiveEvent(otherThread.rootEvent); + allThreads!.addLiveEvent(otherThread.rootEvent, { addToState: true }); let events: EventData[] = []; const renderResult = render(); diff --git a/test/unit-tests/components/structures/TimelinePanel-test.tsx b/test/unit-tests/components/structures/TimelinePanel-test.tsx index 4a66351779..8f52c1bf25 100644 --- a/test/unit-tests/components/structures/TimelinePanel-test.tsx +++ b/test/unit-tests/components/structures/TimelinePanel-test.tsx @@ -66,7 +66,7 @@ const mkTimeline = (room: Room, events: MatrixEvent[]): [EventTimeline, EventTim getPendingEvents: () => [] as MatrixEvent[], } as unknown as EventTimelineSet; const timeline = new EventTimeline(timelineSet); - events.forEach((event) => timeline.addEvent(event, { toStartOfTimeline: false })); + events.forEach((event) => timeline.addEvent(event, { toStartOfTimeline: false, addToState: true })); return [timeline, timelineSet]; }; @@ -150,9 +150,11 @@ const setupPagination = ( mocked(client).paginateEventTimeline.mockImplementation(async (tl, { backwards }) => { if (tl === timeline) { if (backwards) { - forEachRight(previousPage ?? [], (event) => tl.addEvent(event, { toStartOfTimeline: true })); + forEachRight(previousPage ?? [], (event) => + tl.addEvent(event, { toStartOfTimeline: true, addToState: true }), + ); } else { - (nextPage ?? []).forEach((event) => tl.addEvent(event, { toStartOfTimeline: false })); + (nextPage ?? []).forEach((event) => tl.addEvent(event, { toStartOfTimeline: false, addToState: true })); } // Prevent any further pagination attempts in this direction tl.setPaginationToken(null, backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS); @@ -256,7 +258,7 @@ describe("TimelinePanel", () => { describe("and reading the timeline", () => { beforeEach(async () => { await renderTimelinePanel(); - timelineSet.addLiveEvent(ev1, {}); + timelineSet.addLiveEvent(ev1, { addToState: true }); await flushPromises(); // @ts-ignore @@ -285,11 +287,11 @@ describe("TimelinePanel", () => { }); it("and forgetting the read markers, should send the stored marker again", async () => { - timelineSet.addLiveEvent(ev2, {}); + timelineSet.addLiveEvent(ev2, { addToState: true }); // Add the event to the room as well as the timeline, so we can find it when we // call findEventById in getEventReadUpTo. This is odd because in our test // setup, timelineSet is not actually the timelineSet of the room. - await room.addLiveEvents([ev2], {}); + await room.addLiveEvents([ev2], { addToState: true }); room.addEphemeralEvents([newReceipt(ev2.getId()!, userId, 222, 200)]); await timelinePanel.forgetReadMarker(); expect(client.setRoomReadMarkers).toHaveBeenCalledWith(roomId, ev2.getId()); @@ -315,7 +317,7 @@ describe("TimelinePanel", () => { it("should send a fully read marker and a private receipt", async () => { await renderTimelinePanel(); - timelineSet.addLiveEvent(ev1, {}); + timelineSet.addLiveEvent(ev1, { addToState: true }); await flushPromises(); // @ts-ignore @@ -361,7 +363,7 @@ describe("TimelinePanel", () => { it("should send receipts but no fully_read when reading the thread timeline", async () => { await renderTimelinePanel(); - timelineSet.addLiveEvent(threadEv1, {}); + timelineSet.addLiveEvent(threadEv1, { addToState: true }); await flushPromises(); // @ts-ignore @@ -871,7 +873,9 @@ describe("TimelinePanel", () => { // @ts-ignore thread.fetchEditsWhereNeeded = () => Promise.resolve(); await thread.addEvent(reply1, false, true); - await allThreads.getLiveTimeline().addEvent(thread.rootEvent!, { toStartOfTimeline: true }); + await allThreads + .getLiveTimeline() + .addEvent(thread.rootEvent!, { toStartOfTimeline: true, addToState: true }); const replyToEvent = jest.spyOn(thread, "replyToEvent", "get"); const dom = render( @@ -907,7 +911,9 @@ describe("TimelinePanel", () => { // @ts-ignore realThread.fetchEditsWhereNeeded = () => Promise.resolve(); await realThread.addEvent(reply1, true); - await allThreads.getLiveTimeline().addEvent(realThread.rootEvent!, { toStartOfTimeline: true }); + await allThreads + .getLiveTimeline() + .addEvent(realThread.rootEvent!, { toStartOfTimeline: true, addToState: true }); const replyToEvent = jest.spyOn(realThread, "replyToEvent", "get"); // @ts-ignore @@ -968,7 +974,9 @@ describe("TimelinePanel", () => { events.push(rootEvent); - events.forEach((event) => timelineSet.getLiveTimeline().addEvent(event, { toStartOfTimeline: true })); + events.forEach((event) => + timelineSet.getLiveTimeline().addEvent(event, { toStartOfTimeline: true, addToState: true }), + ); const roomMembership = mkMembership({ mship: KnownMembership.Join, @@ -988,7 +996,10 @@ describe("TimelinePanel", () => { jest.spyOn(roomState, "getMember").mockReturnValue(member); jest.spyOn(timelineSet.getLiveTimeline(), "getState").mockReturnValue(roomState); - timelineSet.addEventToTimeline(roomMembership, timelineSet.getLiveTimeline(), { toStartOfTimeline: false }); + timelineSet.addEventToTimeline(roomMembership, timelineSet.getLiveTimeline(), { + toStartOfTimeline: false, + addToState: true, + }); for (const event of events) { jest.spyOn(event, "isDecryptionFailure").mockReturnValue(true); diff --git a/test/unit-tests/components/views/context_menus/RoomGeneralContextMenu-test.tsx b/test/unit-tests/components/views/context_menus/RoomGeneralContextMenu-test.tsx index 10de3996e6..97517ff9d6 100644 --- a/test/unit-tests/components/views/context_menus/RoomGeneralContextMenu-test.tsx +++ b/test/unit-tests/components/views/context_menus/RoomGeneralContextMenu-test.tsx @@ -127,7 +127,7 @@ describe("RoomGeneralContextMenu", () => { user: "@user:id", ts: 1000, }); - room.addLiveEvents([event], {}); + room.addLiveEvents([event], { addToState: true }); const { container } = getComponent({}); diff --git a/test/unit-tests/components/views/dialogs/InviteDialog-test.tsx b/test/unit-tests/components/views/dialogs/InviteDialog-test.tsx index 62cb01b46e..7ed57a7d70 100644 --- a/test/unit-tests/components/views/dialogs/InviteDialog-test.tsx +++ b/test/unit-tests/components/views/dialogs/InviteDialog-test.tsx @@ -141,16 +141,19 @@ describe("InviteDialog", () => { jest.clearAllMocks(); room = new Room(roomId, mockClient, mockClient.getSafeUserId()); - room.addLiveEvents([ - mkMessage({ - msg: "Hello", - relatesTo: undefined, - event: true, - room: roomId, - user: mockClient.getSafeUserId(), - ts: Date.now(), - }), - ]); + room.addLiveEvents( + [ + mkMessage({ + msg: "Hello", + relatesTo: undefined, + event: true, + room: roomId, + user: mockClient.getSafeUserId(), + ts: Date.now(), + }), + ], + { addToState: true }, + ); room.currentState.setStateEvents([ mkRoomCreateEvent(bobId, roomId), mkMembership({ diff --git a/test/unit-tests/components/views/elements/Pill-test.tsx b/test/unit-tests/components/views/elements/Pill-test.tsx index 24fb2ca5dd..ee50417123 100644 --- a/test/unit-tests/components/views/elements/Pill-test.tsx +++ b/test/unit-tests/components/views/elements/Pill-test.tsx @@ -86,7 +86,7 @@ describe("", () => { room: room1Id, msg: "Room 1 Message", }); - room1.addLiveEvents([room1Message]); + room1.addLiveEvents([room1Message], { addToState: true }); room2 = new Room(room2Id, client, user1Id); room2.currentState.setStateEvents([mkRoomMemberJoinEvent(user2Id, room2Id)]); diff --git a/test/unit-tests/components/views/elements/RoomTopic-test.tsx b/test/unit-tests/components/views/elements/RoomTopic-test.tsx index dcf80a95b9..0fe833fe4e 100644 --- a/test/unit-tests/components/views/elements/RoomTopic-test.tsx +++ b/test/unit-tests/components/views/elements/RoomTopic-test.tsx @@ -41,7 +41,7 @@ describe("", () => { ts: 123, event: true, }); - room.addLiveEvents([topicEvent]); + room.addLiveEvents([topicEvent], { addToState: true }); return room; } diff --git a/test/unit-tests/components/views/rooms/NotificationBadge/UnreadNotificationBadge-test.tsx b/test/unit-tests/components/views/rooms/NotificationBadge/UnreadNotificationBadge-test.tsx index ea54dc1085..5b2dddc73a 100644 --- a/test/unit-tests/components/views/rooms/NotificationBadge/UnreadNotificationBadge-test.tsx +++ b/test/unit-tests/components/views/rooms/NotificationBadge/UnreadNotificationBadge-test.tsx @@ -165,7 +165,7 @@ describe("UnreadNotificationBadge", () => { }, ts: 5, }); - room.addLiveEvents([event]); + room.addLiveEvents([event], { addToState: true }); const { container } = render(getComponent(THREAD_ID)); expect(container.querySelector(".mx_NotificationBadge_dot")).toBeTruthy(); diff --git a/test/unit-tests/components/views/rooms/RoomHeader-test.tsx b/test/unit-tests/components/views/rooms/RoomHeader-test.tsx index a7e556e452..3cb4b159cd 100644 --- a/test/unit-tests/components/views/rooms/RoomHeader-test.tsx +++ b/test/unit-tests/components/views/rooms/RoomHeader-test.tsx @@ -579,7 +579,7 @@ describe("RoomHeader", () => { state_key: "", room_id: room.roomId, }); - room.addLiveEvents([joinRuleEvent]); + room.addLiveEvents([joinRuleEvent], { addToState: true }); render(, getWrapper()); diff --git a/test/unit-tests/components/views/settings/Notifications-test.tsx b/test/unit-tests/components/views/settings/Notifications-test.tsx index 69b45135cb..e3d9716901 100644 --- a/test/unit-tests/components/views/settings/Notifications-test.tsx +++ b/test/unit-tests/components/views/settings/Notifications-test.tsx @@ -915,7 +915,7 @@ describe("", () => { user: "@alice:example.org", ts: 1, }); - await room.addLiveEvents([message]); + await room.addLiveEvents([message], { addToState: true }); const { container } = await getComponentAndWait(); const clearNotificationEl = getByTestId(container, "clear-notifications"); diff --git a/test/unit-tests/components/views/settings/notifications/Notifications2-test.tsx b/test/unit-tests/components/views/settings/notifications/Notifications2-test.tsx index 029777c153..2507aa173f 100644 --- a/test/unit-tests/components/views/settings/notifications/Notifications2-test.tsx +++ b/test/unit-tests/components/views/settings/notifications/Notifications2-test.tsx @@ -716,7 +716,7 @@ describe("", () => { user: "@alice:example.org", ts: 1, }); - room.addLiveEvents([message]); + room.addLiveEvents([message], { addToState: true }); room.setUnreadNotificationCount(NotificationCountType.Total, 1); const user = userEvent.setup(); diff --git a/test/unit-tests/events/EventTileFactory-test.ts b/test/unit-tests/events/EventTileFactory-test.ts index 9c8f7718af..7044a883d0 100644 --- a/test/unit-tests/events/EventTileFactory-test.ts +++ b/test/unit-tests/events/EventTileFactory-test.ts @@ -88,7 +88,7 @@ describe("pickFactory", () => { client.getUserId()!, client.deviceId!, ); - room.addLiveEvents([voiceBroadcastStartedEvent]); + room.addLiveEvents([voiceBroadcastStartedEvent], { addToState: true }); voiceBroadcastStoppedEvent = mkVoiceBroadcastInfoStateEvent( roomId, VoiceBroadcastInfoState.Stopped, diff --git a/test/unit-tests/models/Call-test.ts b/test/unit-tests/models/Call-test.ts index 40e929fb4a..316adbbea9 100644 --- a/test/unit-tests/models/Call-test.ts +++ b/test/unit-tests/models/Call-test.ts @@ -119,7 +119,7 @@ const setUpClientRoomAndStores = (): { skey: stateKey, content: content as IContent, }); - room.addLiveEvents([event]); + room.addLiveEvents([event], { addToState: true }); return { event_id: event.getId()! }; }); diff --git a/test/unit-tests/stores/MemberListStore-test.ts b/test/unit-tests/stores/MemberListStore-test.ts index 889a9d3505..184576f317 100644 --- a/test/unit-tests/stores/MemberListStore-test.ts +++ b/test/unit-tests/stores/MemberListStore-test.ts @@ -202,6 +202,7 @@ describe("MemberListStore", () => { function addEventToRoom(room: Room, ev: MatrixEvent) { room.getLiveTimeline().addEvent(ev, { toStartOfTimeline: false, + addToState: true, }); } diff --git a/test/unit-tests/stores/RoomViewStore-test.ts b/test/unit-tests/stores/RoomViewStore-test.ts index 7d397397dc..f7ed1dfbcd 100644 --- a/test/unit-tests/stores/RoomViewStore-test.ts +++ b/test/unit-tests/stores/RoomViewStore-test.ts @@ -397,7 +397,7 @@ describe("RoomViewStore", function () { mockClient.getSafeUserId(), "ABC123", ); - room2.addLiveEvents([broadcastEvent]); + room2.addLiveEvents([broadcastEvent], { addToState: true }); stores.voiceBroadcastPlaybacksStore.getByInfoEvent(broadcastEvent, mockClient); dis.dispatch({ action: Action.ViewRoom, room_id: roomId2 }); diff --git a/test/unit-tests/stores/room-list/MessagePreviewStore-test.ts b/test/unit-tests/stores/room-list/MessagePreviewStore-test.ts index 75013bd4e1..861b6dcd11 100644 --- a/test/unit-tests/stores/room-list/MessagePreviewStore-test.ts +++ b/test/unit-tests/stores/room-list/MessagePreviewStore-test.ts @@ -35,7 +35,7 @@ describe("MessagePreviewStore", () => { event: MatrixEvent, fireAction = true, ): Promise { - room.addLiveEvents([event]); + room.addLiveEvents([event], { addToState: true }); if (fireAction) { // @ts-ignore private access await store.onAction({ diff --git a/test/unit-tests/stores/room-list/algorithms/RecentAlgorithm-test.ts b/test/unit-tests/stores/room-list/algorithms/RecentAlgorithm-test.ts index 18a073b632..e0e06bbaf7 100644 --- a/test/unit-tests/stores/room-list/algorithms/RecentAlgorithm-test.ts +++ b/test/unit-tests/stores/room-list/algorithms/RecentAlgorithm-test.ts @@ -47,11 +47,11 @@ describe("RecentAlgorithm", () => { room.getMyMembership = () => KnownMembership.Join; - room.addLiveEvents([event1]); + room.addLiveEvents([event1], { addToState: true }); expect(algorithm.getLastTs(room, "@jane:matrix.org")).toBe(5); expect(algorithm.getLastTs(room, "@john:matrix.org")).toBe(5); - room.addLiveEvents([event2]); + room.addLiveEvents([event2], { addToState: true }); expect(algorithm.getLastTs(room, "@jane:matrix.org")).toBe(10); expect(algorithm.getLastTs(room, "@john:matrix.org")).toBe(10); @@ -94,8 +94,8 @@ describe("RecentAlgorithm", () => { event: true, }); - room1.addLiveEvents([evt]); - room2.addLiveEvents([evt2]); + room1.addLiveEvents([evt], { addToState: true }); + room2.addLiveEvents([evt2], { addToState: true }); expect(algorithm.sortRooms([room2, room1], DefaultTagID.Untagged)).toEqual([room1, room2]); }); @@ -115,7 +115,7 @@ describe("RecentAlgorithm", () => { event: true, }); - room1.addLiveEvents([evt]); + room1.addLiveEvents([evt], { addToState: true }); expect(algorithm.sortRooms([room2, room1], DefaultTagID.Untagged)).toEqual([room2, room1]); @@ -127,7 +127,7 @@ describe("RecentAlgorithm", () => { ts: 12, }); - room1.addLiveEvents(events); + room1.addLiveEvents(events, { addToState: true }); }); it("orders rooms based on thread replies too", () => { @@ -145,7 +145,7 @@ describe("RecentAlgorithm", () => { ts: 12, length: 5, }); - room1.addLiveEvents(events1); + room1.addLiveEvents(events1, { addToState: true }); const { events: events2 } = mkThread({ room: room2, @@ -155,7 +155,7 @@ describe("RecentAlgorithm", () => { ts: 14, length: 10, }); - room2.addLiveEvents(events2); + room2.addLiveEvents(events2, { addToState: true }); expect(algorithm.sortRooms([room1, room2], DefaultTagID.Untagged)).toEqual([room2, room1]); @@ -169,7 +169,7 @@ describe("RecentAlgorithm", () => { // replies are 1ms after each other ts: 50, }); - room1.addLiveEvents([threadReply]); + room1.addLiveEvents([threadReply], { addToState: true }); expect(algorithm.sortRooms([room1, room2], DefaultTagID.Untagged)).toEqual([room1, room2]); }); diff --git a/test/unit-tests/stores/room-list/previews/ReactionEventPreview-test.ts b/test/unit-tests/stores/room-list/previews/ReactionEventPreview-test.ts index b3facccb06..7a7ce9e2b3 100644 --- a/test/unit-tests/stores/room-list/previews/ReactionEventPreview-test.ts +++ b/test/unit-tests/stores/room-list/previews/ReactionEventPreview-test.ts @@ -70,7 +70,7 @@ describe("ReactionEventPreview", () => { room: roomId, }); - room.getUnfilteredTimelineSet().addLiveEvent(message, {}); + room.getUnfilteredTimelineSet().addLiveEvent(message, { addToState: true }); const event = mkEvent({ event: true, @@ -107,7 +107,7 @@ describe("ReactionEventPreview", () => { room: roomId, }); - room.getUnfilteredTimelineSet().addLiveEvent(message, {}); + room.getUnfilteredTimelineSet().addLiveEvent(message, { addToState: true }); const event = mkEvent({ event: true, diff --git a/test/unit-tests/useTopic-test.tsx b/test/unit-tests/useTopic-test.tsx index cbef9dba60..81afaae985 100644 --- a/test/unit-tests/useTopic-test.tsx +++ b/test/unit-tests/useTopic-test.tsx @@ -29,7 +29,7 @@ describe("useTopic", () => { event: true, }); - room.addLiveEvents([topic]); + room.addLiveEvents([topic], { addToState: true }); function RoomTopic() { const topic = useTopic(room); @@ -52,7 +52,7 @@ describe("useTopic", () => { }); act(() => { - room.addLiveEvents([updatedTopic]); + room.addLiveEvents([updatedTopic], { addToState: true }); }); expect(screen.queryByText("New topic")).toBeInTheDocument(); diff --git a/test/unit-tests/utils/exportUtils/HTMLExport-test.ts b/test/unit-tests/utils/exportUtils/HTMLExport-test.ts index 0fc96e4db7..d169b55a7c 100644 --- a/test/unit-tests/utils/exportUtils/HTMLExport-test.ts +++ b/test/unit-tests/utils/exportUtils/HTMLExport-test.ts @@ -593,18 +593,21 @@ describe("HTMLExport", () => { it("should not make /messages requests when exporting 'Current Timeline'", async () => { client.createMessagesRequest.mockRejectedValue(new Error("Should never be called")); - room.addLiveEvents([ - new MatrixEvent({ - event_id: `$eventId`, - type: EventType.RoomMessage, - sender: client.getSafeUserId(), - origin_server_ts: 123456789, - content: { - msgtype: "m.text", - body: `testing testing`, - }, - }), - ]); + room.addLiveEvents( + [ + new MatrixEvent({ + event_id: `$eventId`, + type: EventType.RoomMessage, + sender: client.getSafeUserId(), + origin_server_ts: 123456789, + content: { + msgtype: "m.text", + body: `testing testing`, + }, + }), + ], + { addToState: true }, + ); const exporter = new HTMLExporter( room, diff --git a/test/unit-tests/utils/notifications-test.ts b/test/unit-tests/utils/notifications-test.ts index 67948ed217..68553de166 100644 --- a/test/unit-tests/utils/notifications-test.ts +++ b/test/unit-tests/utils/notifications-test.ts @@ -121,7 +121,7 @@ describe("notifications", () => { user: USER_ID, msg: "Hello", }); - room.addLiveEvents([message]); + room.addLiveEvents([message], { addToState: true }); sendReadReceiptSpy = jest.spyOn(client, "sendReadReceipt").mockResolvedValue({}); jest.spyOn(client, "getRooms").mockReturnValue([room]); jest.spyOn(SettingsStore, "getValue").mockImplementation((name) => { @@ -187,7 +187,7 @@ describe("notifications", () => { user: USER_ID, ts: 1, }); - room.addLiveEvents([message]); + room.addLiveEvents([message], { addToState: true }); room.setUnreadNotificationCount(NotificationCountType.Total, 1); await clearAllNotifications(client); @@ -202,7 +202,7 @@ describe("notifications", () => { user: USER_ID, ts: 1, }); - room.addLiveEvents([message]); + room.addLiveEvents([message], { addToState: true }); room.setUnreadNotificationCount(NotificationCountType.Total, 1); jest.spyOn(SettingsStore, "getValue").mockReset().mockReturnValue(false); diff --git a/test/unit-tests/voice-broadcast/components/VoiceBroadcastBody-test.tsx b/test/unit-tests/voice-broadcast/components/VoiceBroadcastBody-test.tsx index bf55c45b68..fd416de8ce 100644 --- a/test/unit-tests/voice-broadcast/components/VoiceBroadcastBody-test.tsx +++ b/test/unit-tests/voice-broadcast/components/VoiceBroadcastBody-test.tsx @@ -85,7 +85,7 @@ describe("VoiceBroadcastBody", () => { deviceId, infoEvent, ); - room.addEventsToTimeline([infoEvent], true, room.getLiveTimeline()); + room.addEventsToTimeline([infoEvent], true, true, room.getLiveTimeline()); testRecording = new VoiceBroadcastRecording(infoEvent, client); testPlayback = new VoiceBroadcastPlayback(infoEvent, client, new VoiceBroadcastRecordingsStore()); mocked(VoiceBroadcastRecordingBody).mockImplementation(({ recording }): ReactElement | null => { @@ -127,7 +127,7 @@ describe("VoiceBroadcastBody", () => { describe("when there is a stopped voice broadcast", () => { beforeEach(() => { - room.addEventsToTimeline([stoppedEvent], true, room.getLiveTimeline()); + room.addEventsToTimeline([stoppedEvent], true, true, room.getLiveTimeline()); renderVoiceBroadcast(); }); @@ -148,7 +148,7 @@ describe("VoiceBroadcastBody", () => { describe("and the recordings ends", () => { beforeEach(() => { act(() => { - room.addEventsToTimeline([stoppedEvent], true, room.getLiveTimeline()); + room.addEventsToTimeline([stoppedEvent], true, true, room.getLiveTimeline()); }); }); diff --git a/test/unit-tests/voice-broadcast/models/VoiceBroadcastPlayback-test.tsx b/test/unit-tests/voice-broadcast/models/VoiceBroadcastPlayback-test.tsx index c967189271..9ce24e5921 100644 --- a/test/unit-tests/voice-broadcast/models/VoiceBroadcastPlayback-test.tsx +++ b/test/unit-tests/voice-broadcast/models/VoiceBroadcastPlayback-test.tsx @@ -243,7 +243,7 @@ describe("VoiceBroadcastPlayback", () => { beforeEach(async () => { infoEvent = mkInfoEvent(VoiceBroadcastInfoState.Resumed); createChunkEvents(); - room.addLiveEvents([infoEvent]); + room.addLiveEvents([infoEvent], { addToState: true }); playback = await mkPlayback(); }); @@ -331,7 +331,7 @@ describe("VoiceBroadcastPlayback", () => { infoEvent = mkInfoEvent(VoiceBroadcastInfoState.Resumed); createChunkEvents(); setUpChunkEvents([chunk2Event, chunk1Event]); - room.addLiveEvents([infoEvent, chunk1Event, chunk2Event]); + room.addLiveEvents([infoEvent, chunk1Event, chunk2Event], { addToState: true }); room.relations.aggregateChildEvent(chunk2Event); room.relations.aggregateChildEvent(chunk1Event); playback = await mkPlayback(); @@ -372,7 +372,7 @@ describe("VoiceBroadcastPlayback", () => { describe("and an event with the same transaction Id occurs", () => { beforeEach(() => { - room.addLiveEvents([chunk2BEvent]); + room.addLiveEvents([chunk2BEvent], { addToState: true }); room.relations.aggregateChildEvent(chunk2BEvent); }); @@ -404,7 +404,7 @@ describe("VoiceBroadcastPlayback", () => { infoEvent, 2, ); - room.addLiveEvents([stoppedEvent]); + room.addLiveEvents([stoppedEvent], { addToState: true }); room.relations.aggregateChildEvent(stoppedEvent); chunk2Playback.emit(PlaybackState.Stopped); }); @@ -426,7 +426,7 @@ describe("VoiceBroadcastPlayback", () => { infoEvent, 3, ); - room.addLiveEvents([stoppedEvent]); + room.addLiveEvents([stoppedEvent], { addToState: true }); room.relations.aggregateChildEvent(stoppedEvent); chunk2Playback.emit(PlaybackState.Stopped); }); @@ -435,7 +435,7 @@ describe("VoiceBroadcastPlayback", () => { describe("and the next chunk arrives", () => { beforeEach(() => { - room.addLiveEvents([chunk3Event]); + room.addLiveEvents([chunk3Event], { addToState: true }); room.relations.aggregateChildEvent(chunk3Event); }); @@ -521,7 +521,7 @@ describe("VoiceBroadcastPlayback", () => { createChunkEvents(); // use delayed first chunk here to simulate loading time setUpChunkEvents([chunk2Event, deplayedChunk1Event, chunk3Event]); - room.addLiveEvents([infoEvent, deplayedChunk1Event, chunk2Event, chunk3Event]); + room.addLiveEvents([infoEvent, deplayedChunk1Event, chunk2Event, chunk3Event], { addToState: true }); playback = await mkPlayback(true); }); diff --git a/test/unit-tests/voice-broadcast/utils/hasRoomLiveVoiceBroadcast-test.ts b/test/unit-tests/voice-broadcast/utils/hasRoomLiveVoiceBroadcast-test.ts index 589e1c46a7..37fbf0c277 100644 --- a/test/unit-tests/voice-broadcast/utils/hasRoomLiveVoiceBroadcast-test.ts +++ b/test/unit-tests/voice-broadcast/utils/hasRoomLiveVoiceBroadcast-test.ts @@ -32,7 +32,7 @@ describe("hasRoomLiveVoiceBroadcast", () => { startedEvent?: MatrixEvent, ): MatrixEvent => { const infoEvent = mkVoiceBroadcastInfoStateEvent(room.roomId, state, userId, deviceId, startedEvent); - room.addLiveEvents([infoEvent]); + room.addLiveEvents([infoEvent], { addToState: true }); room.currentState.setStateEvents([infoEvent]); room.relations.aggregateChildEvent(infoEvent); return infoEvent; diff --git a/test/unit-tests/voice-broadcast/utils/isRelatedToVoiceBroadcast-test.ts b/test/unit-tests/voice-broadcast/utils/isRelatedToVoiceBroadcast-test.ts index 17160b8b2b..eae78df109 100644 --- a/test/unit-tests/voice-broadcast/utils/isRelatedToVoiceBroadcast-test.ts +++ b/test/unit-tests/voice-broadcast/utils/isRelatedToVoiceBroadcast-test.ts @@ -31,7 +31,7 @@ const mkRelatedEvent = ( }, user: client.getSafeUserId(), }); - room.addLiveEvents([event]); + room.addLiveEvents([event], { addToState: true }); return event; }; @@ -65,7 +65,7 @@ describe("isRelatedToVoiceBroadcast", () => { user: client.getSafeUserId(), }); - room.addLiveEvents([broadcastEvent, nonBroadcastEvent]); + room.addLiveEvents([broadcastEvent, nonBroadcastEvent], { addToState: true }); }); it("should return true if related (reference) to a broadcast event", () => { diff --git a/test/unit-tests/voice-broadcast/utils/retrieveStartedInfoEvent-test.ts b/test/unit-tests/voice-broadcast/utils/retrieveStartedInfoEvent-test.ts index 9bac7aed3e..70316f3b29 100644 --- a/test/unit-tests/voice-broadcast/utils/retrieveStartedInfoEvent-test.ts +++ b/test/unit-tests/voice-broadcast/utils/retrieveStartedInfoEvent-test.ts @@ -67,7 +67,7 @@ describe("retrieveStartedInfoEvent", () => { it("when the room contains the event, it should return it", async () => { const startEvent = mkStartEvent(); const stopEvent = mkStopEvent(startEvent); - room.addLiveEvents([startEvent]); + room.addLiveEvents([startEvent], { addToState: true }); expect(await retrieveStartedInfoEvent(stopEvent, client)).toBe(startEvent); }); From 0b636aec4bcf4991354c23d4a32986f3fc192e16 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 8 Nov 2024 16:41:57 +0000 Subject: [PATCH 02/44] Improve coverage Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../components/structures/FilePanel-test.tsx | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/test/unit-tests/components/structures/FilePanel-test.tsx b/test/unit-tests/components/structures/FilePanel-test.tsx index 1dce220682..25bdd99676 100644 --- a/test/unit-tests/components/structures/FilePanel-test.tsx +++ b/test/unit-tests/components/structures/FilePanel-test.tsx @@ -7,13 +7,13 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; -import { EventTimelineSet, PendingEventOrdering, Room } from "matrix-js-sdk/src/matrix"; +import { EventTimelineSet, PendingEventOrdering, Room, RoomEvent } from "matrix-js-sdk/src/matrix"; import { screen, render, waitFor } from "jest-matrix-react"; import { mocked } from "jest-mock"; import FilePanel from "../../../../src/components/structures/FilePanel"; import ResizeNotifier from "../../../../src/utils/ResizeNotifier"; -import { stubClient } from "../../../test-utils"; +import { mkEvent, stubClient } from "../../../test-utils"; import { MatrixClientPeg } from "../../../../src/MatrixClientPeg"; jest.mock("matrix-js-sdk/src/matrix", () => ({ @@ -47,4 +47,43 @@ describe("FilePanel", () => { }); expect(asFragment()).toMatchSnapshot(); }); + + describe("addEncryptedLiveEvent", () => { + it("should add file msgtype event to filtered timelineSet", async () => { + const cli = MatrixClientPeg.safeGet(); + const room = new Room("!room:server", cli, cli.getSafeUserId(), { + pendingEventOrdering: PendingEventOrdering.Detached, + }); + cli.reEmitter.reEmit(room, [RoomEvent.Timeline]); + const timelineSet = new EventTimelineSet(room); + room.getOrCreateFilteredTimelineSet = jest.fn().mockReturnValue(timelineSet); + mocked(cli.getRoom).mockReturnValue(room); + + let filePanel: FilePanel | null; + render( + (filePanel = ref)} + />, + ); + await screen.findByText("No files visible in this room"); + + const event = mkEvent({ + type: "m.room.message", + user: cli.getSafeUserId(), + room: room.roomId, + content: { + body: "hello", + url: "mxc://matrix.org/1234", + msgtype: "m.file", + }, + event: true, + }); + filePanel!.addEncryptedLiveEvent(event); + + expect(timelineSet.getLiveTimeline().getEvents()).toContain(event); + }); + }); }); From 3f221891f73bcee5e82105fe51dc5e61c8af1323 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 25 Nov 2024 17:29:32 +0000 Subject: [PATCH 03/44] Remove space-specific right panel store handling This is no longer needed as the right panel always corresponds to the currently viewed room/space only. Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RightPanel.tsx | 25 ++++--------------- src/components/structures/RoomView.tsx | 8 +++--- src/components/structures/SpaceRoomView.tsx | 4 +-- src/components/structures/UserView.tsx | 2 +- .../views/right_panel/RoomSummaryCard.tsx | 2 +- src/components/views/right_panel/UserInfo.tsx | 11 +++----- src/components/views/rooms/RoomHeader.tsx | 2 +- src/components/views/rooms/RoomInfoLine.tsx | 2 +- .../views/toasts/VerificationRequestToast.tsx | 2 +- src/stores/right-panel/RightPanelStore.ts | 13 +++++----- .../right-panel/RightPanelStoreIPanelState.ts | 4 --- .../right-panel/RightPanelStorePhases.ts | 16 +++++------- .../action-handlers/View3pidInvite.ts | 4 +-- src/verification.ts | 2 +- .../components/structures/RightPanel-test.tsx | 4 +-- .../right_panel/RoomSummaryCard-test.tsx | 5 +--- .../views/right_panel/UserInfo-test.tsx | 6 ++--- .../views/rooms/PinnedMessageBanner-test.tsx | 2 +- .../views/rooms/RoomHeader-test.tsx | 2 +- .../right-panel/RightPanelStore-test.ts | 16 ++++++------ .../action-handlers/View3pidInvite-test.ts | 4 +-- 21 files changed, 53 insertions(+), 83 deletions(-) diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx index 9a9f29f82e..8acff9ae44 100644 --- a/src/components/structures/RightPanel.tsx +++ b/src/components/structures/RightPanel.tsx @@ -109,10 +109,10 @@ export default class RightPanel extends React.Component { } // redraw the badge on the membership list - if (this.state.phase === RightPanelPhases.RoomMemberList) { + if (this.state.phase === RightPanelPhases.MemberList) { this.delayedUpdate(); } else if ( - this.state.phase === RightPanelPhases.RoomMemberInfo && + this.state.phase === RightPanelPhases.MemberInfo && member.userId === this.state.cardState?.member?.userId ) { // refresh the member info (e.g. new power level) @@ -157,7 +157,7 @@ export default class RightPanel extends React.Component { const phase = this.props.overwriteCard?.phase ?? this.state.phase; const cardState = this.props.overwriteCard?.state ?? this.state.cardState; switch (phase) { - case RightPanelPhases.RoomMemberList: + case RightPanelPhases.MemberList: if (!!roomId) { card = ( { ); } break; - case RightPanelPhases.SpaceMemberList: - if (!!cardState?.spaceId || !!roomId) { - card = ( - - ); - } - break; - case RightPanelPhases.RoomMemberInfo: - case RightPanelPhases.SpaceMemberInfo: + case RightPanelPhases.MemberInfo: case RightPanelPhases.EncryptionPanel: { if (!!cardState?.member) { const roomMember = cardState.member instanceof RoomMember ? cardState.member : undefined; @@ -203,8 +189,7 @@ export default class RightPanel extends React.Component { } break; } - case RightPanelPhases.Room3pidMemberInfo: - case RightPanelPhases.Space3pidMemberInfo: + case RightPanelPhases.ThreePidMemberInfo: if (!!cardState?.memberInfoEvent) { card = ( diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 470b73de7c..af37226d7d 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -1214,18 +1214,18 @@ export class RoomView extends React.Component { if (payload.member) { if (payload.push) { RightPanelStore.instance.pushCard({ - phase: RightPanelPhases.RoomMemberInfo, + phase: RightPanelPhases.MemberInfo, state: { member: payload.member }, }); } else { RightPanelStore.instance.setCards([ { phase: RightPanelPhases.RoomSummary }, - { phase: RightPanelPhases.RoomMemberList }, - { phase: RightPanelPhases.RoomMemberInfo, state: { member: payload.member } }, + { phase: RightPanelPhases.MemberList }, + { phase: RightPanelPhases.MemberInfo, state: { member: payload.member } }, ]); } } else { - RightPanelStore.instance.showOrHidePhase(RightPanelPhases.RoomMemberList); + RightPanelStore.instance.showOrHidePhase(RightPanelPhases.MemberList); } break; case Action.View3pidInvite: diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx index 3ea2a03c1a..6afa7dfdf0 100644 --- a/src/components/structures/SpaceRoomView.tsx +++ b/src/components/structures/SpaceRoomView.tsx @@ -208,7 +208,7 @@ const SpaceLanding: React.FC<{ space: Room }> = ({ space }) => { const storeIsShowingSpaceMembers = useCallback( () => RightPanelStore.instance.isOpenForRoom(space.roomId) && - RightPanelStore.instance.currentCardForRoom(space.roomId)?.phase === RightPanelPhases.SpaceMemberList, + RightPanelStore.instance.currentCardForRoom(space.roomId)?.phase === RightPanelPhases.MemberList, [space.roomId], ); const isShowingMembers = useEventEmitterState(RightPanelStore.instance, UPDATE_EVENT, storeIsShowingSpaceMembers); @@ -251,7 +251,7 @@ const SpaceLanding: React.FC<{ space: Room }> = ({ space }) => { } const onMembersClick = (): void => { - RightPanelStore.instance.setCard({ phase: RightPanelPhases.SpaceMemberList }); + RightPanelStore.instance.setCard({ phase: RightPanelPhases.MemberList }); }; return ( diff --git a/src/components/structures/UserView.tsx b/src/components/structures/UserView.tsx index 635115877e..66fefbc320 100644 --- a/src/components/structures/UserView.tsx +++ b/src/components/structures/UserView.tsx @@ -82,7 +82,7 @@ export default class UserView extends React.Component { } else if (this.state.member) { const panel = ( ); diff --git a/src/components/views/right_panel/RoomSummaryCard.tsx b/src/components/views/right_panel/RoomSummaryCard.tsx index 664977bbe2..e4ab5bcf3d 100644 --- a/src/components/views/right_panel/RoomSummaryCard.tsx +++ b/src/components/views/right_panel/RoomSummaryCard.tsx @@ -86,7 +86,7 @@ interface IProps { } const onRoomMembersClick = (): void => { - RightPanelStore.instance.pushCard({ phase: RightPanelPhases.RoomMemberList }, true); + RightPanelStore.instance.pushCard({ phase: RightPanelPhases.MemberList }, true); }; const onRoomThreadsClick = (): void => { diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx index d07b3566e2..0005e2efce 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -1739,13 +1739,13 @@ export const UserInfoHeader: React.FC<{ interface IProps { user: Member; room?: Room; - phase: RightPanelPhases.RoomMemberInfo | RightPanelPhases.SpaceMemberInfo | RightPanelPhases.EncryptionPanel; + phase: RightPanelPhases.MemberInfo | RightPanelPhases.MemberInfo | RightPanelPhases.EncryptionPanel; onClose(): void; verificationRequest?: VerificationRequest; verificationRequestPromise?: Promise; } -const UserInfo: React.FC = ({ user, room, onClose, phase = RightPanelPhases.RoomMemberInfo, ...props }) => { +const UserInfo: React.FC = ({ user, room, onClose, phase = RightPanelPhases.MemberInfo, ...props }) => { const cli = useContext(MatrixClientContext); // fetch latest room member if we have a room, so we don't show historical information, falling back to user @@ -1767,8 +1767,6 @@ const UserInfo: React.FC = ({ user, room, onClose, phase = RightPanelPha // We have no previousPhase for when viewing a UserInfo without a Room at this time if (room && phase === RightPanelPhases.EncryptionPanel) { cardState = { member }; - } else if (room?.isSpaceRoom()) { - cardState = { spaceId: room.roomId }; } const onEncryptionPanelClose = (): void => { @@ -1777,8 +1775,7 @@ const UserInfo: React.FC = ({ user, room, onClose, phase = RightPanelPha let content: JSX.Element | undefined; switch (phase) { - case RightPanelPhases.RoomMemberInfo: - case RightPanelPhases.SpaceMemberInfo: + case RightPanelPhases.MemberInfo: content = ( = ({ user, room, onClose, phase = RightPanelPha closeLabel={closeLabel} cardState={cardState} onBack={(ev: ButtonEvent) => { - if (RightPanelStore.instance.previousCard.phase === RightPanelPhases.RoomMemberList) { + if (RightPanelStore.instance.previousCard.phase === RightPanelPhases.MemberList) { PosthogTrackers.trackInteraction("WebRightPanelRoomUserInfoBackButton", ev); } }} diff --git a/src/components/views/rooms/RoomHeader.tsx b/src/components/views/rooms/RoomHeader.tsx index c2642ea733..70002259de 100644 --- a/src/components/views/rooms/RoomHeader.tsx +++ b/src/components/views/rooms/RoomHeader.tsx @@ -392,7 +392,7 @@ export default function RoomHeader({ viewUserOnClick={false} tooltipLabel={_t("room|header_face_pile_tooltip")} onClick={(e: ButtonEvent) => { - RightPanelStore.instance.showOrHidePhase(RightPanelPhases.RoomMemberList); + RightPanelStore.instance.showOrHidePhase(RightPanelPhases.MemberList); e.stopPropagation(); }} aria-label={_t("common|n_members", { count: memberCount })} diff --git a/src/components/views/rooms/RoomInfoLine.tsx b/src/components/views/rooms/RoomInfoLine.tsx index 710ef61758..1487bfe15b 100644 --- a/src/components/views/rooms/RoomInfoLine.tsx +++ b/src/components/views/rooms/RoomInfoLine.tsx @@ -64,7 +64,7 @@ const RoomInfoLine: FC = ({ room }) => { // summary is not still loading const viewMembers = (): void => RightPanelStore.instance.setCard({ - phase: room.isSpaceRoom() ? RightPanelPhases.SpaceMemberList : RightPanelPhases.RoomMemberList, + phase: RightPanelPhases.MemberList, }); members = ( diff --git a/src/components/views/toasts/VerificationRequestToast.tsx b/src/components/views/toasts/VerificationRequestToast.tsx index 54932a12ed..7d31aa6764 100644 --- a/src/components/views/toasts/VerificationRequestToast.tsx +++ b/src/components/views/toasts/VerificationRequestToast.tsx @@ -117,7 +117,7 @@ export default class VerificationRequestToast extends React.PureComponent needs to be changed to RightPanelPhases.EncryptionPanel if there is a pending verification request const { member } = card.state; const pendingRequest = member @@ -385,8 +385,7 @@ export default class RightPanelStore extends ReadyWatchingStore { if (panel?.history) { panel.history = panel.history.filter( (card: IRightPanelCard) => - card.phase != RightPanelPhases.RoomMemberInfo && - card.phase != RightPanelPhases.Room3pidMemberInfo, + card.phase != RightPanelPhases.MemberInfo && card.phase != RightPanelPhases.ThreePidMemberInfo, ); } } diff --git a/src/stores/right-panel/RightPanelStoreIPanelState.ts b/src/stores/right-panel/RightPanelStoreIPanelState.ts index afb7442563..0d205abd2f 100644 --- a/src/stores/right-panel/RightPanelStoreIPanelState.ts +++ b/src/stores/right-panel/RightPanelStoreIPanelState.ts @@ -16,7 +16,6 @@ export interface IRightPanelCardState { verificationRequest?: VerificationRequest; verificationRequestPromise?: Promise; widgetId?: string; - spaceId?: string; // Room3pidMemberInfo, Space3pidMemberInfo, memberInfoEvent?: MatrixEvent; // threads @@ -32,7 +31,6 @@ export interface IRightPanelCardStateStored { memberId?: string; // we do not store the things associated with verification widgetId?: string; - spaceId?: string; // 3pidMemberInfo memberInfoEventId?: string; // threads @@ -80,7 +78,6 @@ export function convertCardToStore(panelState: IRightPanelCard): IRightPanelCard const state = panelState.state ?? {}; const stateStored: IRightPanelCardStateStored = { widgetId: state.widgetId, - spaceId: state.spaceId, isInitialEventHighlighted: state.isInitialEventHighlighted, initialEventScrollIntoView: state.initialEventScrollIntoView, threadHeadEventId: !!state?.threadHeadEvent?.getId() ? state.threadHeadEvent.getId() : undefined, @@ -97,7 +94,6 @@ function convertStoreToCard(panelStateStore: IRightPanelCardStored, room: Room): const stateStored = panelStateStore.state ?? {}; const state: IRightPanelCardState = { widgetId: stateStored.widgetId, - spaceId: stateStored.spaceId, isInitialEventHighlighted: stateStored.isInitialEventHighlighted, initialEventScrollIntoView: stateStored.initialEventScrollIntoView, threadHeadEvent: !!stateStored?.threadHeadEventId diff --git a/src/stores/right-panel/RightPanelStorePhases.ts b/src/stores/right-panel/RightPanelStorePhases.ts index 60b9e50baf..9e7a5697bf 100644 --- a/src/stores/right-panel/RightPanelStorePhases.ts +++ b/src/stores/right-panel/RightPanelStorePhases.ts @@ -10,11 +10,14 @@ import { _t } from "../../languageHandler"; // These are in their own file because of circular imports being a problem. export enum RightPanelPhases { + // Room & Space stuff + MemberList = "MemberList", + MemberInfo = "MemberInfo", + ThreePidMemberInfo = "ThreePidMemberInfo", + // Room stuff - RoomMemberList = "RoomMemberList", FilePanel = "FilePanel", NotificationPanel = "NotificationPanel", - RoomMemberInfo = "RoomMemberInfo", EncryptionPanel = "EncryptionPanel", RoomSummary = "RoomSummary", Widget = "Widget", @@ -22,13 +25,6 @@ export enum RightPanelPhases { Timeline = "Timeline", Extensions = "Extensions", - Room3pidMemberInfo = "Room3pidMemberInfo", - - // Space stuff - SpaceMemberList = "SpaceMemberList", - SpaceMemberInfo = "SpaceMemberInfo", - Space3pidMemberInfo = "Space3pidMemberInfo", - // Thread stuff ThreadView = "ThreadView", ThreadPanel = "ThreadPanel", @@ -42,7 +38,7 @@ export function backLabelForPhase(phase: RightPanelPhases | null): string | null return _t("chat_card_back_action_label"); case RightPanelPhases.RoomSummary: return _t("room_summary_card_back_action_label"); - case RightPanelPhases.RoomMemberList: + case RightPanelPhases.MemberList: return _t("member_list_back_action_label"); case RightPanelPhases.ThreadView: return _t("thread_view_back_action_label"); diff --git a/src/stores/right-panel/action-handlers/View3pidInvite.ts b/src/stores/right-panel/action-handlers/View3pidInvite.ts index e2aa191acb..0f6661819f 100644 --- a/src/stores/right-panel/action-handlers/View3pidInvite.ts +++ b/src/stores/right-panel/action-handlers/View3pidInvite.ts @@ -20,10 +20,10 @@ import { RightPanelPhases } from "../RightPanelStorePhases"; export const onView3pidInvite = (payload: ActionPayload, rightPanelStore: RightPanelStore): void => { if (payload.event) { rightPanelStore.pushCard({ - phase: RightPanelPhases.Room3pidMemberInfo, + phase: RightPanelPhases.ThreePidMemberInfo, state: { memberInfoEvent: payload.event }, }); } else { - rightPanelStore.showOrHidePhase(RightPanelPhases.RoomMemberList); + rightPanelStore.showOrHidePhase(RightPanelPhases.MemberList); } }; diff --git a/src/verification.ts b/src/verification.ts index e446186f80..9c14a64c51 100644 --- a/src/verification.ts +++ b/src/verification.ts @@ -81,7 +81,7 @@ function setRightPanel(state: IRightPanelCardState): void { } else { RightPanelStore.instance.setCards([ { phase: RightPanelPhases.RoomSummary }, - { phase: RightPanelPhases.RoomMemberInfo, state: { member: state.member } }, + { phase: RightPanelPhases.MemberInfo, state: { member: state.member } }, { phase: RightPanelPhases.EncryptionPanel, state }, ]); } diff --git a/test/unit-tests/components/structures/RightPanel-test.tsx b/test/unit-tests/components/structures/RightPanel-test.tsx index e569369db5..ad29791ee9 100644 --- a/test/unit-tests/components/structures/RightPanel-test.tsx +++ b/test/unit-tests/components/structures/RightPanel-test.tsx @@ -91,7 +91,7 @@ describe("RightPanel", () => { if (name !== "RightPanel.phases") return realGetValue(name, roomId); if (roomId === "r1") { return { - history: [{ phase: RightPanelPhases.RoomMemberList }], + history: [{ phase: RightPanelPhases.MemberList }], isOpen: true, }; } @@ -123,7 +123,7 @@ describe("RightPanel", () => { await rpsUpdated; await waitFor(() => expect(screen.queryByTestId("spinner")).not.toBeInTheDocument()); - // room one will be in the RoomMemberList phase - confirm this is rendered + // room one will be in the MemberList phase - confirm this is rendered expect(container.getElementsByClassName("mx_MemberList")).toHaveLength(1); // wait for RPS room 2 updates to fire, then rerender diff --git a/test/unit-tests/components/views/right_panel/RoomSummaryCard-test.tsx b/test/unit-tests/components/views/right_panel/RoomSummaryCard-test.tsx index 4026149f98..d31fc6ed8c 100644 --- a/test/unit-tests/components/views/right_panel/RoomSummaryCard-test.tsx +++ b/test/unit-tests/components/views/right_panel/RoomSummaryCard-test.tsx @@ -254,10 +254,7 @@ describe("", () => { fireEvent.click(getByText("People")); - expect(RightPanelStore.instance.pushCard).toHaveBeenCalledWith( - { phase: RightPanelPhases.RoomMemberList }, - true, - ); + expect(RightPanelStore.instance.pushCard).toHaveBeenCalledWith({ phase: RightPanelPhases.MemberList }, true); }); it("opens room threads list on button click", () => { diff --git a/test/unit-tests/components/views/right_panel/UserInfo-test.tsx b/test/unit-tests/components/views/right_panel/UserInfo-test.tsx index 7e23679fc2..38d38e2a32 100644 --- a/test/unit-tests/components/views/right_panel/UserInfo-test.tsx +++ b/test/unit-tests/components/views/right_panel/UserInfo-test.tsx @@ -188,7 +188,7 @@ describe("", () => { const defaultProps = { user: defaultUser, // idk what is wrong with this type - phase: RightPanelPhases.RoomMemberInfo as RightPanelPhases.RoomMemberInfo, + phase: RightPanelPhases.MemberInfo as RightPanelPhases.MemberInfo, onClose: jest.fn(), }; @@ -455,7 +455,7 @@ describe("", () => { mockCrypto.getUserVerificationStatus.mockResolvedValue(new UserVerificationStatus(false, false, false)); const { container } = renderComponent({ - phase: RightPanelPhases.SpaceMemberInfo, + phase: RightPanelPhases.MemberInfo, verificationRequest, room: mockRoom, }); @@ -649,7 +649,7 @@ describe("", () => { mockClient.getDomain.mockReturnValue("example.com"); const { container } = renderComponent({ - phase: RightPanelPhases.RoomMemberInfo, + phase: RightPanelPhases.MemberInfo, room: mockRoom, }); diff --git a/test/unit-tests/components/views/rooms/PinnedMessageBanner-test.tsx b/test/unit-tests/components/views/rooms/PinnedMessageBanner-test.tsx index f59b9f3a9f..8d380c76bb 100644 --- a/test/unit-tests/components/views/rooms/PinnedMessageBanner-test.tsx +++ b/test/unit-tests/components/views/rooms/PinnedMessageBanner-test.tsx @@ -224,7 +224,7 @@ describe("", () => { // The Right panel is opened on another card jest.spyOn(RightPanelStore.instance, "isOpenForRoom").mockReturnValue(true); jest.spyOn(RightPanelStore.instance, "currentCard", "get").mockReturnValue({ - phase: RightPanelPhases.RoomMemberList, + phase: RightPanelPhases.MemberList, }); renderBanner(); diff --git a/test/unit-tests/components/views/rooms/RoomHeader-test.tsx b/test/unit-tests/components/views/rooms/RoomHeader-test.tsx index 1be9c77713..26ef7ec4fb 100644 --- a/test/unit-tests/components/views/rooms/RoomHeader-test.tsx +++ b/test/unit-tests/components/views/rooms/RoomHeader-test.tsx @@ -158,7 +158,7 @@ describe("RoomHeader", () => { fireEvent.click(facePile); - expect(setCardSpy).toHaveBeenCalledWith({ phase: RightPanelPhases.RoomMemberList }); + expect(setCardSpy).toHaveBeenCalledWith({ phase: RightPanelPhases.MemberList }); }); it("has room info icon that opens the room info panel", async () => { diff --git a/test/unit-tests/stores/right-panel/RightPanelStore-test.ts b/test/unit-tests/stores/right-panel/RightPanelStore-test.ts index 92299426ba..7fb32bcd6e 100644 --- a/test/unit-tests/stores/right-panel/RightPanelStore-test.ts +++ b/test/unit-tests/stores/right-panel/RightPanelStore-test.ts @@ -97,7 +97,7 @@ describe("RightPanelStore", () => { it("does nothing if given an invalid state", async () => { await viewRoom("!1:example.org"); // Needs a member specified to be valid - store.setCard({ phase: RightPanelPhases.RoomMemberInfo }, true, "!1:example.org"); + store.setCard({ phase: RightPanelPhases.MemberInfo }, true, "!1:example.org"); expect(store.roomPhaseHistory).toEqual([]); }); it("only creates a single history entry if given the same card twice", async () => { @@ -114,15 +114,15 @@ describe("RightPanelStore", () => { it("overwrites history if changing the phase", async () => { await viewRoom("!1:example.org"); store.setCard({ phase: RightPanelPhases.RoomSummary }, true, "!1:example.org"); - store.setCard({ phase: RightPanelPhases.RoomMemberList }, true, "!1:example.org"); - expect(store.roomPhaseHistory).toEqual([{ phase: RightPanelPhases.RoomMemberList, state: {} }]); + store.setCard({ phase: RightPanelPhases.MemberList }, true, "!1:example.org"); + expect(store.roomPhaseHistory).toEqual([{ phase: RightPanelPhases.MemberList, state: {} }]); }); }); describe("setCards", () => { it("overwrites history", async () => { await viewRoom("!1:example.org"); - store.setCard({ phase: RightPanelPhases.RoomMemberList }, true, "!1:example.org"); + store.setCard({ phase: RightPanelPhases.MemberList }, true, "!1:example.org"); store.setCards( [{ phase: RightPanelPhases.RoomSummary }, { phase: RightPanelPhases.PinnedMessages }], true, @@ -200,21 +200,21 @@ describe("RightPanelStore", () => { store.setCards( [ { - phase: RightPanelPhases.RoomMemberList, + phase: RightPanelPhases.MemberList, }, { - phase: RightPanelPhases.RoomMemberInfo, + phase: RightPanelPhases.MemberInfo, state: { member: new RoomMember("!1:example.org", "@alice:example.org") }, }, ], true, "!1:example.org", ); - expect(store.currentCardForRoom("!1:example.org").phase).toEqual(RightPanelPhases.RoomMemberInfo); + expect(store.currentCardForRoom("!1:example.org").phase).toEqual(RightPanelPhases.MemberInfo); // Switch away and back await viewRoom("!2:example.org"); await viewRoom("!1:example.org"); - expect(store.currentCardForRoom("!1:example.org").phase).toEqual(RightPanelPhases.RoomMemberList); + expect(store.currentCardForRoom("!1:example.org").phase).toEqual(RightPanelPhases.MemberList); }); }); diff --git a/test/unit-tests/stores/right-panel/action-handlers/View3pidInvite-test.ts b/test/unit-tests/stores/right-panel/action-handlers/View3pidInvite-test.ts index d0b721243f..9503bb4ae3 100644 --- a/test/unit-tests/stores/right-panel/action-handlers/View3pidInvite-test.ts +++ b/test/unit-tests/stores/right-panel/action-handlers/View3pidInvite-test.ts @@ -30,7 +30,7 @@ describe("onView3pidInvite()", () => { }; onView3pidInvite(payload, rightPanelStore); - expect(rightPanelStore.showOrHidePhase).toHaveBeenCalledWith(RightPanelPhases.RoomMemberList); + expect(rightPanelStore.showOrHidePhase).toHaveBeenCalledWith(RightPanelPhases.MemberList); expect(rightPanelStore.pushCard).not.toHaveBeenCalled(); }); @@ -43,7 +43,7 @@ describe("onView3pidInvite()", () => { expect(rightPanelStore.showOrHidePhase).not.toHaveBeenCalled(); expect(rightPanelStore.pushCard).toHaveBeenCalledWith({ - phase: RightPanelPhases.Room3pidMemberInfo, + phase: RightPanelPhases.ThreePidMemberInfo, state: { memberInfoEvent: payload.event }, }); }); From a478463b751fe6ee44293a0351e44f2a967864b0 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 25 Nov 2024 17:43:09 +0000 Subject: [PATCH 04/44] Remove duplicates Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/right_panel/UserInfo.tsx | 2 +- src/stores/right-panel/RightPanelStore.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx index 0005e2efce..b4a775367c 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -1739,7 +1739,7 @@ export const UserInfoHeader: React.FC<{ interface IProps { user: Member; room?: Room; - phase: RightPanelPhases.MemberInfo | RightPanelPhases.MemberInfo | RightPanelPhases.EncryptionPanel; + phase: RightPanelPhases.MemberInfo | RightPanelPhases.EncryptionPanel; onClose(): void; verificationRequest?: VerificationRequest; verificationRequestPromise?: Promise; diff --git a/src/stores/right-panel/RightPanelStore.ts b/src/stores/right-panel/RightPanelStore.ts index ea74aaa3ae..99b2d7fe50 100644 --- a/src/stores/right-panel/RightPanelStore.ts +++ b/src/stores/right-panel/RightPanelStore.ts @@ -305,13 +305,11 @@ export default class RightPanelStore extends ReadyWatchingStore { } return !!card.state?.threadHeadEvent; case RightPanelPhases.MemberInfo: - case RightPanelPhases.MemberInfo: case RightPanelPhases.EncryptionPanel: if (!card.state?.member) { logger.warn("removed card from right panel because of missing member in card state"); } return !!card.state?.member; - case RightPanelPhases.ThreePidMemberInfo: case RightPanelPhases.ThreePidMemberInfo: if (!card.state?.memberInfoEvent) { logger.warn("removed card from right panel because of missing memberInfoEvent in card state"); From 85711be352be993347ccd4836ba5387c45bd3c69 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 26 Nov 2024 11:00:52 -0500 Subject: [PATCH 05/44] Show the correct shield status in tooltip for more conditions (#28476) * Add support for new shield codes in JS SDK * change string used for shield message * fix test --- playwright/e2e/crypto/event-shields.spec.ts | 26 +++++++++++++++++++ src/components/views/rooms/EventTile.tsx | 9 +++++-- .../components/views/rooms/EventTile-test.tsx | 2 ++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/playwright/e2e/crypto/event-shields.spec.ts b/playwright/e2e/crypto/event-shields.spec.ts index b5d3790aaa..c6382f1d72 100644 --- a/playwright/e2e/crypto/event-shields.spec.ts +++ b/playwright/e2e/crypto/event-shields.spec.ts @@ -16,6 +16,7 @@ import { logOutOfElement, verify, } from "./utils"; +import { bootstrapCrossSigningForClient } from "../../pages/client.ts"; test.describe("Cryptography", function () { test.use({ @@ -307,5 +308,30 @@ test.describe("Cryptography", function () { const penultimate = page.locator(".mx_EventTile").filter({ hasText: "test encrypted from verified" }); await expect(penultimate.locator(".mx_EventTile_e2eIcon")).not.toBeVisible(); }); + + test("should show correct shields on events sent by users with changed identity", async ({ + page, + app, + bot: bob, + homeserver, + }) => { + // Verify Bob + await verify(app, bob); + + // Bob logs in a new device and resets cross-signing + const bobSecondDevice = await createSecondBotDevice(page, homeserver, bob); + await bootstrapCrossSigningForClient(await bobSecondDevice.prepareClient(), bob.credentials, true); + + /* should show an error for a message from a previously verified device */ + await bobSecondDevice.sendMessage(testRoomId, "test encrypted from user that was previously verified"); + const last = page.locator(".mx_EventTile_last"); + await expect(last).toContainText("test encrypted from user that was previously verified"); + const lastE2eIcon = last.locator(".mx_EventTile_e2eIcon"); + await expect(lastE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_warning/); + await lastE2eIcon.focus(); + await expect(await app.getTooltipForElement(lastE2eIcon)).toContainText( + "Sender's verified identity has changed", + ); + }); }); }); diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index 8b07368859..78d0ca5b28 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -758,8 +758,13 @@ export class UnwrappedEventTile extends React.Component shieldReasonMessage = _t("encryption|event_shield_reason_mismatched_sender_key"); break; - default: - shieldReasonMessage = _t("error|unknown"); + case EventShieldReason.SENT_IN_CLEAR: + shieldReasonMessage = _t("common|unencrypted"); + break; + + case EventShieldReason.VERIFICATION_VIOLATION: + shieldReasonMessage = _t("timeline|decryption_failure|sender_identity_previously_verified"); + break; } if (this.state.shieldColour === EventShieldColour.GREY) { diff --git a/test/unit-tests/components/views/rooms/EventTile-test.tsx b/test/unit-tests/components/views/rooms/EventTile-test.tsx index 4cb2296760..e57514904a 100644 --- a/test/unit-tests/components/views/rooms/EventTile-test.tsx +++ b/test/unit-tests/components/views/rooms/EventTile-test.tsx @@ -301,6 +301,8 @@ describe("EventTile", () => { [EventShieldReason.UNKNOWN_DEVICE, "unknown or deleted device"], [EventShieldReason.AUTHENTICITY_NOT_GUARANTEED, "can't be guaranteed"], [EventShieldReason.MISMATCHED_SENDER_KEY, "Encrypted by an unverified session"], + [EventShieldReason.SENT_IN_CLEAR, "Not encrypted"], + [EventShieldReason.VERIFICATION_VIOLATION, "Sender's verified identity has changed"], ])("shows the correct reason code for %i (%s)", async (reasonCode: EventShieldReason, expectedText: string) => { mxEvent = await mkEncryptedMatrixEvent({ plainContent: { msgtype: "m.text", body: "msg1" }, From 5f4d78925913bda5a0d15d07793bc0dff3188ffa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:14:36 +0000 Subject: [PATCH 06/44] Update dependency @formatjs/intl-segmenter to v11.7.4 (#28558) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/yarn.lock b/yarn.lock index a2bf286f1b..edf2b0acc4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1585,13 +1585,13 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.8.tgz#21a907684723bbbaa5f0974cf7730bd797eb8e62" integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig== -"@formatjs/ecma402-abstract@2.2.3": - version "2.2.3" - resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.3.tgz#dc5a032e1971c709b32b9ab511fa35504a7d3bc9" - integrity sha512-aElGmleuReGnk2wtYOzYFmNWYoiWWmf1pPPCYg0oiIQSJj0mjc4eUfzUXaSOJ4S8WzI/cLqnCTWjqz904FT2OQ== +"@formatjs/ecma402-abstract@2.2.4": + version "2.2.4" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz#355e42d375678229d46dc8ad7a7139520dd03e7b" + integrity sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg== dependencies: "@formatjs/fast-memoize" "2.2.3" - "@formatjs/intl-localematcher" "0.5.7" + "@formatjs/intl-localematcher" "0.5.8" tslib "2" "@formatjs/fast-memoize@2.2.3": @@ -1601,20 +1601,20 @@ dependencies: tslib "2" -"@formatjs/intl-localematcher@0.5.7": - version "0.5.7" - resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.7.tgz#f889d076881b785d11ff993b966f527d199436d0" - integrity sha512-GGFtfHGQVFe/niOZp24Kal5b2i36eE2bNL0xi9Sg/yd0TR8aLjcteApZdHmismP5QQax1cMnZM9yWySUUjJteA== +"@formatjs/intl-localematcher@0.5.8": + version "0.5.8" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz#b11bbd04bd3551f7cadcb1ef1e231822d0e3c97e" + integrity sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg== dependencies: tslib "2" "@formatjs/intl-segmenter@^11.5.7": - version "11.7.3" - resolved "https://registry.yarnpkg.com/@formatjs/intl-segmenter/-/intl-segmenter-11.7.3.tgz#aeb49c33c81fec68419922c64c72188b659eaa5a" - integrity sha512-IvEDQRe0t0ouqaqZK2KobGt/+BhwDHdtbS8GWhdl+fjmWbhXMz2mHihu5fAYkYChum5eNfGhEF5P+bLCeYq67w== + version "11.7.4" + resolved "https://registry.yarnpkg.com/@formatjs/intl-segmenter/-/intl-segmenter-11.7.4.tgz#f99d87ee3f98515069285438a4913681fc243252" + integrity sha512-pyHgFO86/CReKl20oK9jgaTMzSaG/nIMteMW8YuwUcS22EoMI1qbGTZ65oQ38KMT05SiHiMee2CP3WZvCi8YSQ== dependencies: - "@formatjs/ecma402-abstract" "2.2.3" - "@formatjs/intl-localematcher" "0.5.7" + "@formatjs/ecma402-abstract" "2.2.4" + "@formatjs/intl-localematcher" "0.5.8" tslib "2" "@humanwhocodes/config-array@^0.13.0": From b8c178d1336be36637f6bbdac7f68bde20c704fe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:14:41 +0000 Subject: [PATCH 07/44] Update dependency @vector-im/compound-design-tokens to v2.1.0 (#28563) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index edf2b0acc4..1260ab26c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3415,9 +3415,9 @@ integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== "@vector-im/compound-design-tokens@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@vector-im/compound-design-tokens/-/compound-design-tokens-2.0.1.tgz#add14494caab16cdbe98f2bdabe726908739def4" - integrity sha512-4nkPcrPII+sejispn+UkWZYFN7LecN39e4WGBupdceiMq0NJrfXrnVtJ9/6BDLgSqHInb6R/IWQkIbPbzfqRMg== + version "2.1.1" + resolved "https://registry.yarnpkg.com/@vector-im/compound-design-tokens/-/compound-design-tokens-2.1.1.tgz#d6175a99fe4b97688464126f255386990f3048d6" + integrity sha512-QnUi2K14D9KTXxcLQKUU3V75cforZLMwhaaJDNftT8F5mG86950hAM+qhgDNEpEU+pkTffQj0/g/5859YmqWzQ== "@vector-im/compound-web@^7.4.0": version "7.4.0" From 80cd93678a45eec3d26a4a0d2b87e0f985d442d6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:15:04 +0000 Subject: [PATCH 08/44] Update docker (#28554) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/dockerhub.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerhub.yaml b/.github/workflows/dockerhub.yaml index 7911cf794a..8dae6cf5ab 100644 --- a/.github/workflows/dockerhub.yaml +++ b/.github/workflows/dockerhub.yaml @@ -39,7 +39,7 @@ jobs: - name: Docker meta id: meta - uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5 + uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5 with: images: | vectorim/element-web @@ -51,7 +51,7 @@ jobs: - name: Build and push id: build-and-push - uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6 + uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6 with: context: . push: true From 77962005623a46b67f000601475dd436ca5da627 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:31:10 +0000 Subject: [PATCH 09/44] Update playwright to v1.49.0 (#28566) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- playwright/Dockerfile | 2 +- yarn.lock | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/playwright/Dockerfile b/playwright/Dockerfile index 9d478ff231..2b30c416f7 100644 --- a/playwright/Dockerfile +++ b/playwright/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/playwright:v1.48.2-jammy +FROM mcr.microsoft.com/playwright:v1.49.0-jammy WORKDIR /work diff --git a/yarn.lock b/yarn.lock index 1260ab26c2..7b8611f876 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2073,11 +2073,11 @@ webcrypto-core "^1.8.0" "@playwright/test@^1.40.1": - version "1.48.2" - resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.48.2.tgz#87dd40633f980872283404c8142a65744d3f13d6" - integrity sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw== + version "1.49.0" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.49.0.tgz#74227385b58317ee076b86b56d0e1e1b25cff01e" + integrity sha512-DMulbwQURa8rNIQrf94+jPJQ4FmOVdpE5ZppRNvWVjvhC+6sOeo28r8MgIpQRYouXRtt/FCCXU7zn20jnHR4Qw== dependencies: - playwright "1.48.2" + playwright "1.49.0" "@polka/url@^1.0.0-next.24": version "1.0.0-next.28" @@ -9163,17 +9163,17 @@ pkg-dir@^7.0.0: dependencies: find-up "^6.3.0" -playwright-core@1.48.2, playwright-core@^1.45.1: - version "1.48.2" - resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.48.2.tgz#cd76ed8af61690edef5c05c64721c26a8db2f3d7" - integrity sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA== +playwright-core@1.49.0, playwright-core@^1.45.1: + version "1.49.0" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.49.0.tgz#8e69ffed3f41855b854982f3632f2922c890afcb" + integrity sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA== -playwright@1.48.2: - version "1.48.2" - resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.48.2.tgz#fca45ae8abdc34835c715718072aaff7e305167e" - integrity sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ== +playwright@1.49.0: + version "1.49.0" + resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.49.0.tgz#df6b9e05423377a99658202844a294a8afb95d0a" + integrity sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A== dependencies: - playwright-core "1.48.2" + playwright-core "1.49.0" optionalDependencies: fsevents "2.3.2" From 8a7cdaa3ef855f86e27748326565a87b14863da8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:33:45 +0000 Subject: [PATCH 10/44] Update dependency stylelint-scss to v6.10.0 (#28564) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7b8611f876..65ba575402 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11114,9 +11114,9 @@ stylelint-config-standard@^36.0.0: stylelint-config-recommended "^14.0.1" stylelint-scss@^6.0.0: - version "6.9.0" - resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-6.9.0.tgz#a5ab9b2a8ed7e0a9c113558fdbd1b66ad673b259" - integrity sha512-oWOR+g6ccagfrENecImGmorWWjVyWpt2R8bmkhOW8FkNNPGStZPQMqb8QWMW4Lwu9TyPqmyjHkkAsy3weqsnNw== + version "6.10.0" + resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-6.10.0.tgz#ba5b807793e145421e9879dd15ae672af6820a45" + integrity sha512-y03if6Qw9xBMoVaf7tzp5BbnYhYvudIKzURkhSHzcHG0bW0fAYvQpTUVJOe7DyhHaxeThBil4ObEMvGbV7+M+w== dependencies: css-tree "^3.0.1" is-plain-object "^5.0.0" @@ -11124,7 +11124,7 @@ stylelint-scss@^6.0.0: mdn-data "^2.12.2" postcss-media-query-parser "^0.2.3" postcss-resolve-nested-selector "^0.1.6" - postcss-selector-parser "^6.1.2" + postcss-selector-parser "^7.0.0" postcss-value-parser "^4.2.0" stylelint-value-no-unknown-custom-properties@^6.0.1: From bda045fad0aa9493abaa158073e6f7ed1a13d8f5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:34:01 +0000 Subject: [PATCH 11/44] Update dependency @stylistic/eslint-plugin to v2.11.0 (#28562) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 61 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 65ba575402..9f1995c865 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2562,11 +2562,11 @@ p-map "^4.0.0" "@stylistic/eslint-plugin@^2.9.0": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin/-/eslint-plugin-2.10.1.tgz#809924752a1a13ebff2b0b6d7884fd61d389a907" - integrity sha512-U+4yzNXElTf9q0kEfnloI9XbOyD4cnEQCxjUI94q0+W++0GAEQvJ/slwEj9lwjDHfGADRSr+Tco/z0XJvmDfCQ== + version "2.11.0" + resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin/-/eslint-plugin-2.11.0.tgz#50d0289f36f7201055b7fa1729fdc1d8c46e93fa" + integrity sha512-PNRHbydNG5EH8NK4c+izdJlxajIR6GxcUhzsYNRsn6Myep4dsZt0qFCz3rCPnkvgO5FYibDcMqgNHUT+zvjYZw== dependencies: - "@typescript-eslint/utils" "^8.12.2" + "@typescript-eslint/utils" "^8.13.0" eslint-visitor-keys "^4.2.0" espree "^10.3.0" estraverse "^5.3.0" @@ -3317,6 +3317,14 @@ "@typescript-eslint/types" "8.14.0" "@typescript-eslint/visitor-keys" "8.14.0" +"@typescript-eslint/scope-manager@8.16.0": + version "8.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz#ebc9a3b399a69a6052f3d88174456dd399ef5905" + integrity sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg== + dependencies: + "@typescript-eslint/types" "8.16.0" + "@typescript-eslint/visitor-keys" "8.16.0" + "@typescript-eslint/scope-manager@8.9.0": version "8.9.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.9.0.tgz#c98fef0c4a82a484e6a1eb610a55b154d14d46f3" @@ -3340,6 +3348,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.14.0.tgz#0d33d8d0b08479c424e7d654855fddf2c71e4021" integrity sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g== +"@typescript-eslint/types@8.16.0": + version "8.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.16.0.tgz#49c92ae1b57942458ab83d9ec7ccab3005e64737" + integrity sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ== + "@typescript-eslint/types@8.9.0": version "8.9.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.9.0.tgz#b733af07fb340b32e962c6c63b1062aec2dc0fe6" @@ -3359,6 +3372,20 @@ semver "^7.6.0" ts-api-utils "^1.3.0" +"@typescript-eslint/typescript-estree@8.16.0": + version "8.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz#9d741e56e5b13469b5190e763432ce5551a9300c" + integrity sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw== + dependencies: + "@typescript-eslint/types" "8.16.0" + "@typescript-eslint/visitor-keys" "8.16.0" + debug "^4.3.4" + fast-glob "^3.3.2" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + "@typescript-eslint/typescript-estree@8.9.0": version "8.9.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.9.0.tgz#1714f167e9063062dc0df49c1d25afcbc7a96199" @@ -3373,7 +3400,7 @@ semver "^7.6.0" ts-api-utils "^1.3.0" -"@typescript-eslint/utils@8.14.0", "@typescript-eslint/utils@^8.12.2": +"@typescript-eslint/utils@8.14.0": version "8.14.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.14.0.tgz#ac2506875e03aba24e602364e43b2dfa45529dbd" integrity sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA== @@ -3393,6 +3420,16 @@ "@typescript-eslint/types" "8.9.0" "@typescript-eslint/typescript-estree" "8.9.0" +"@typescript-eslint/utils@^8.13.0": + version "8.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.16.0.tgz#c71264c437157feaa97842809836254a6fc833c3" + integrity sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "8.16.0" + "@typescript-eslint/types" "8.16.0" + "@typescript-eslint/typescript-estree" "8.16.0" + "@typescript-eslint/visitor-keys@8.14.0": version "8.14.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz#2418d5a54669af9658986ade4e6cfb7767d815ad" @@ -3401,6 +3438,14 @@ "@typescript-eslint/types" "8.14.0" eslint-visitor-keys "^3.4.3" +"@typescript-eslint/visitor-keys@8.16.0": + version "8.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz#d5086afc060b01ff7a4ecab8d49d13d5a7b07705" + integrity sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ== + dependencies: + "@typescript-eslint/types" "8.16.0" + eslint-visitor-keys "^4.2.0" + "@typescript-eslint/visitor-keys@8.9.0": version "8.9.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.9.0.tgz#5f11f4d9db913f37da42776893ffe0dd1ae78f78" @@ -11438,9 +11483,9 @@ truncate-utf8-bytes@^1.0.0: utf8-byte-length "^1.0.1" ts-api-utils@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.0.tgz#709c6f2076e511a81557f3d07a0cbd566ae8195c" - integrity sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ== + version "1.4.2" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.2.tgz#a6a6dff26117ac7965624fc118525971edc6a82a" + integrity sha512-ZF5gQIQa/UmzfvxbHZI3JXN0/Jt+vnAfAviNRAMc491laiK6YCLpCW9ft8oaCRFOTxCZtUTE6XB0ZQAe3olntw== ts-morph@^13.0.1: version "13.0.3" From fe7ac684786d567ae2e364833bc383667ae649ff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:34:29 +0000 Subject: [PATCH 12/44] Update definitelyTyped (#28557) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9f1995c865..a2f1f6c2bb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2836,9 +2836,9 @@ integrity sha512-aqBg5oAGo/qh/+wxUfuMadDu2WO0MEWOblyzwaM1Ske2xilUxBfgPqapAFVAfrVTDMVwa0UMarzGot8m64IAzA== "@types/css-tree@^2.3.8": - version "2.3.8" - resolved "https://registry.yarnpkg.com/@types/css-tree/-/css-tree-2.3.8.tgz#0eabc115e45051b2f7abe51ee1531074b234ed19" - integrity sha512-zABG3nI2UENsx7AQv63tI5/ptoAG/7kQR1H0OvG+WTWYHOR5pfAT3cGgC8SdyCrgX/TTxJBZNmx82IjCXs1juQ== + version "2.3.9" + resolved "https://registry.yarnpkg.com/@types/css-tree/-/css-tree-2.3.9.tgz#54c404e0a803e7e660fdc08c84fe73ee5266cece" + integrity sha512-g1FE6xkPDP4tsccmTd6jIugjKZdxIDqAf9h2pc+4LsGgYbOyfa9phNjBHYbm6FtwIlNfT1NBx3f2zSeqO7aRAw== "@types/diff-match-patch@^1.0.32": version "1.0.36" @@ -2861,9 +2861,9 @@ integrity sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz#91f06cda1049e8f17eeab364798ed79c97488a1c" - integrity sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw== + version "5.0.2" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.2.tgz#812d2871e5eea17fb0bd5214dda7a7b748c0e12a" + integrity sha512-vluaspfvWEtE4vcSDlKRNer52DvOGrB2xv6diXy6UKyKW0lqZiWHGNApSyxOv+8DE5Z27IzVvE7hNkxg7EXIcg== dependencies: "@types/node" "*" "@types/qs" "*" @@ -3065,9 +3065,9 @@ integrity sha512-yslwR0zZ3zAT1qXcCPxIcD23CZ6W6nKsl6JufSJHAmdwOBuYwCVJkaMsEo9yzxGV7ATfoX8S+RgtnajOEtKxYA== "@types/node-fetch@^2.6.2": - version "2.6.11" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" - integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== + version "2.6.12" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.12.tgz#8ab5c3ef8330f13100a7479e2cd56d3386830a03" + integrity sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA== dependencies: "@types/node" "*" form-data "^4.0.0" @@ -3080,16 +3080,16 @@ "@types/node" "*" "@types/node@*": - version "22.7.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.6.tgz#3ec3e2b071e136cd11093c19128405e1d1f92f33" - integrity sha512-/d7Rnj0/ExXDMcioS78/kf1lMzYk4BZV8MZGTBKzTGZ6/406ukkbYlIsZmMPhcR5KlkunDHQLrtAVmSq7r+mSw== + version "22.10.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.10.0.tgz#89bfc9e82496b9c7edea3382583fa94f75896e81" + integrity sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA== dependencies: - undici-types "~6.19.2" + undici-types "~6.20.0" "@types/node@18": - version "18.19.64" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.64.tgz#122897fb79f2a9ec9c979bded01c11461b2b1478" - integrity sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ== + version "18.19.66" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.66.tgz#0937a47904ceba5994eedf5cf4b6d503d8d6136c" + integrity sha512-14HmtUdGxFUalGRfLLn9Gc1oNWvWh5zNbsyOLo5JV6WARSeN1QcEBKRnZm9QqNfrutgsl/hY4eJW63aZ44aBCg== dependencies: undici-types "~5.26.4" @@ -11670,10 +11670,10 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -undici-types@~6.19.2: - version "6.19.8" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" - integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== +undici-types@~6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" + integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== unhomoglyph@^1.0.6: version "1.0.6" From df7703a4a5ed885e86f7d46c7685cc9c96de82d6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 18:11:39 +0000 Subject: [PATCH 13/44] Update linkify to v4.1.4 (#28560) * Update linkify to v4.1.4 * Fix types Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- package.json | 8 +++---- test/unit-tests/linkify-matrix-test.ts | 4 ++-- yarn.lock | 32 +++++++++++++------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index a48284bb97..2ef4a6f170 100644 --- a/package.json +++ b/package.json @@ -114,10 +114,10 @@ "jsrsasign": "^11.0.0", "jszip": "^3.7.0", "katex": "^0.16.0", - "linkify-element": "4.1.3", - "linkify-react": "4.1.3", - "linkify-string": "4.1.3", - "linkifyjs": "4.1.3", + "linkify-element": "4.1.4", + "linkify-react": "4.1.4", + "linkify-string": "4.1.4", + "linkifyjs": "4.1.4", "lodash": "^4.17.21", "maplibre-gl": "^4.0.0", "matrix-encrypt-attachment": "^1.0.3", diff --git a/test/unit-tests/linkify-matrix-test.ts b/test/unit-tests/linkify-matrix-test.ts index 97548c62d4..50edff2535 100644 --- a/test/unit-tests/linkify-matrix-test.ts +++ b/test/unit-tests/linkify-matrix-test.ts @@ -332,7 +332,7 @@ describe("linkify-matrix", () => { const event = new MouseEvent("mousedown"); event.preventDefault = jest.fn(); - handlers.click(event); + handlers!.click(event); expect(event.preventDefault).toHaveBeenCalled(); expect(dispatchSpy).toHaveBeenCalledWith( expect.objectContaining({ @@ -372,7 +372,7 @@ describe("linkify-matrix", () => { const event = new MouseEvent("mousedown"); event.preventDefault = jest.fn(); - handlers.click(event); + handlers!.click(event); expect(event.preventDefault).toHaveBeenCalled(); expect(dispatchSpy).toHaveBeenCalledWith( expect.objectContaining({ diff --git a/yarn.lock b/yarn.lock index a2f1f6c2bb..72e2d74710 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8109,10 +8109,10 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -linkify-element@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/linkify-element/-/linkify-element-4.1.3.tgz#c0de98f2a36683bf3a4bfa28eaa23c4c917bd546" - integrity sha512-oUoG7BWaR3Q6kAKdlLi8slsu5rkVRxbiDVVlkpoL7vtidY5THggLzRHIBtmcj+tvMpcAUQomJApDxg0ub0qpdA== +linkify-element@4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/linkify-element/-/linkify-element-4.1.4.tgz#d4050b41fb47c44871e5eed93bc11865e403cc90" + integrity sha512-XhSTTF7b7OoX4KIkwVG8MET5DSFEHohT0Gp5pjmsByYp+JCyZq5rSZGsar5dYzeuKUV6TqTSLtsH/NzBBwBxgQ== linkify-it@^4.0.1: version "4.0.1" @@ -8121,20 +8121,20 @@ linkify-it@^4.0.1: dependencies: uc.micro "^1.0.1" -linkify-react@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/linkify-react/-/linkify-react-4.1.3.tgz#461d348b4bdab3fcd0452ae1b5bbc22536395b97" - integrity sha512-rhI3zM/fxn5BfRPHfi4r9N7zgac4vOIxub1wHIWXLA5ENTMs+BGaIaFO1D1PhmxgwhIKmJz3H7uCP0Dg5JwSlA== +linkify-react@4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/linkify-react/-/linkify-react-4.1.4.tgz#6c709f3f96543914874982f4b0b00f9c9270ce93" + integrity sha512-UI9nqHtFzHYRUvVRrYeua5GIXkc0Jy3RpLsJBWEht7HwqjAa2qSaIksGmNSLqclNpO/5AkwaxUJv71I/pQsk9Q== -linkify-string@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/linkify-string/-/linkify-string-4.1.3.tgz#a47dbbf64c9fbd2f6ae5e26cd41ec2e5748a54d1" - integrity sha512-6dAgx4MiTcvEX87OS5aNpAioO7cSELUXp61k7azOvMYOLSmREx0w4yM1Uf0+O3JLC08YdkUyZhAX+YkasRt/mw== +linkify-string@4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/linkify-string/-/linkify-string-4.1.4.tgz#89fb814e05c5b22f76d2a2a640bc8b1db4c6694f" + integrity sha512-4z2UEzEi4SxnhWMzzZ8Pa8vIOwX/2U0XWxk/0UIA7lI+Dn0ZRKqTE9ildnO6Jl6K5hqVuLKTeMD8p4bdFW6P8g== -linkifyjs@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.3.tgz#0edbc346428a7390a23ea2e5939f76112c9ae07f" - integrity sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg== +linkifyjs@4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.4.tgz#2766605a20078d50c90f35af22275a42dfb7dfc4" + integrity sha512-0/NxkHNpiJ0k9VrYCkAn9OtU1eu8xEr1tCCpDtSsVRm/SF0xAak2Gzv3QimSfgUgqLBCDlfhMbu73XvaEHUTPQ== lint-staged@^15.0.2: version "15.2.10" From 8d28dd3784d3c6e429d2c6efa78a583a04e5fd95 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 18:14:00 +0000 Subject: [PATCH 14/44] Update dependency @sentry/browser to v8.40.0 (#28561) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 101 ++++++++++++++++++++++++------------------------------ 1 file changed, 44 insertions(+), 57 deletions(-) diff --git a/yarn.lock b/yarn.lock index 72e2d74710..0432b5f0f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2375,43 +2375,39 @@ resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== -"@sentry-internal/browser-utils@8.37.1": - version "8.37.1" - resolved "https://registry.yarnpkg.com/@sentry-internal/browser-utils/-/browser-utils-8.37.1.tgz#374028d8e37047aeda14b226707e6601de65996e" - integrity sha512-OSR/V5GCsSCG7iapWtXCT/y22uo3HlawdEgfM1NIKk1mkP15UyGQtGEzZDdih2H+SNuX1mp9jQLTjr5FFp1A5w== +"@sentry-internal/browser-utils@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/browser-utils/-/browser-utils-8.40.0.tgz#972925a9d600723dd1a022297100e97e92f4c903" + integrity sha512-tx7gb/PWMbTEyil/XPETVeRUeS3nKHIvQY2omyebw30TbhyLnibPZsUmXJiaIysL5PcY3k9maub3W/o0Y37T7Q== dependencies: - "@sentry/core" "8.37.1" - "@sentry/types" "8.37.1" - "@sentry/utils" "8.37.1" + "@sentry/core" "8.40.0" + "@sentry/types" "8.40.0" -"@sentry-internal/feedback@8.37.1": - version "8.37.1" - resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-8.37.1.tgz#e2d5fc934ca3b4925a5f5d0e63549830a1cf147e" - integrity sha512-Se25NXbSapgS2S+JssR5YZ48b3OY4UGmAuBOafgnMW91LXMxRNWRbehZuNUmjjHwuywABMxjgu+Yp5uJDATX+g== +"@sentry-internal/feedback@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-8.40.0.tgz#5549f73d32b9a2509ffb0a07bf462ed8085178ec" + integrity sha512-1O9F3z80HNE0VfepKS+v+dixdatNqWlrlwgvvWl4BGzzoA+XhqvZo+HWxiOt7yx7+k1TuZNrB6Gy3u/QvpozXA== dependencies: - "@sentry/core" "8.37.1" - "@sentry/types" "8.37.1" - "@sentry/utils" "8.37.1" + "@sentry/core" "8.40.0" + "@sentry/types" "8.40.0" -"@sentry-internal/replay-canvas@8.37.1": - version "8.37.1" - resolved "https://registry.yarnpkg.com/@sentry-internal/replay-canvas/-/replay-canvas-8.37.1.tgz#e8a5e350e486b16938b3dd99886be23b7b6eff18" - integrity sha512-1JLAaPtn1VL5vblB0BMELFV0D+KUm/iMGsrl4/JpRm0Ws5ESzQl33DhXVv1IX/ZAbx9i14EjR7MG9+Hj70tieQ== +"@sentry-internal/replay-canvas@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/replay-canvas/-/replay-canvas-8.40.0.tgz#6de0d67ee2fe3e503c6f85faeefab5df742a3ebe" + integrity sha512-Zr+m/le0SH4RowZB7rBCM0aRnvH3wZTaOFhwUk03/oGf2BRcgKuDCUMjnXKC9MyOpmey7UYXkzb8ro+81R6Q8w== dependencies: - "@sentry-internal/replay" "8.37.1" - "@sentry/core" "8.37.1" - "@sentry/types" "8.37.1" - "@sentry/utils" "8.37.1" + "@sentry-internal/replay" "8.40.0" + "@sentry/core" "8.40.0" + "@sentry/types" "8.40.0" -"@sentry-internal/replay@8.37.1": - version "8.37.1" - resolved "https://registry.yarnpkg.com/@sentry-internal/replay/-/replay-8.37.1.tgz#6dc2e3955879f6e7ab830db1ddee54e0a9b401f3" - integrity sha512-E/Plhisk/pXJjOdOU12sg8m/APTXTA21iEniidP6jW3/+O0tD/H/UovEqa4odNTqxPMa798xHQSQNt5loYiaLA== +"@sentry-internal/replay@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/replay/-/replay-8.40.0.tgz#54c7f1e3d115f9324f34e1b8875a95463a23049f" + integrity sha512-0SaDsBCSWxNVgNmPKu23frrHEXzN/MKl0hIkfuO55vL5TgjLTwpgkf0Ne4rNvaZQ5omIKk9Qd63HuQP3PHAMaw== dependencies: - "@sentry-internal/browser-utils" "8.37.1" - "@sentry/core" "8.37.1" - "@sentry/types" "8.37.1" - "@sentry/utils" "8.37.1" + "@sentry-internal/browser-utils" "8.40.0" + "@sentry/core" "8.40.0" + "@sentry/types" "8.40.0" "@sentry/babel-plugin-component-annotate@2.22.5": version "2.22.5" @@ -2419,17 +2415,16 @@ integrity sha512-+93qwB9vTX1nj4hD8AMWowXZsZVkvmP9OwTqSh5d4kOeiJ+dZftUk4+FKeKkAX9lvY2reyHV8Gms5mo67c27RQ== "@sentry/browser@^8.0.0": - version "8.37.1" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-8.37.1.tgz#2e6e4accc395ad9e6313e07b09415370c71e5874" - integrity sha512-5ym+iGiIpjIKKpMWi9S3/tXh9xneS+jqxwRTJqed3cb8i4ydfMAAP8sM3U8xMCWWABpWyIUW+fpewC0tkhE1aQ== + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-8.40.0.tgz#de7b4531be2ac4667755e9e1b5da3808851392ae" + integrity sha512-m/Yor6IDBeDHtQochu8n6z4HXrXkrPhu6+o5Ouve0Zi3ptthSoK1FOGvJxVBat3nRq0ydQyuuPuTB6WfdWbwHQ== dependencies: - "@sentry-internal/browser-utils" "8.37.1" - "@sentry-internal/feedback" "8.37.1" - "@sentry-internal/replay" "8.37.1" - "@sentry-internal/replay-canvas" "8.37.1" - "@sentry/core" "8.37.1" - "@sentry/types" "8.37.1" - "@sentry/utils" "8.37.1" + "@sentry-internal/browser-utils" "8.40.0" + "@sentry-internal/feedback" "8.40.0" + "@sentry-internal/replay" "8.40.0" + "@sentry-internal/replay-canvas" "8.40.0" + "@sentry/core" "8.40.0" + "@sentry/types" "8.40.0" "@sentry/bundler-plugin-core@2.22.5": version "2.22.5" @@ -2499,25 +2494,17 @@ "@sentry/cli-win32-i686" "2.37.0" "@sentry/cli-win32-x64" "2.37.0" -"@sentry/core@8.37.1": - version "8.37.1" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-8.37.1.tgz#4bafb25c762ec8680874056f6160df276c1cc7c6" - integrity sha512-82csXby589iDupM3VgCHJeWZagUyEEaDnbFcoZ/Z91QX2Sjq8FcF5OsforoXjw09i0XTFqlkFAnQVpDBmMXcpQ== +"@sentry/core@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-8.40.0.tgz#cb5c02d12e29070bf88692c64cfd7db7700be4ea" + integrity sha512-u/U2CJpG/+SmTR2bPM4ZZoPYTJAOUuxzj/0IURnvI0v9+rNu939J/fzrO9huA5IJVxS5TiYykhQm7o6I3Zuo3Q== dependencies: - "@sentry/types" "8.37.1" - "@sentry/utils" "8.37.1" + "@sentry/types" "8.40.0" -"@sentry/types@8.37.1": - version "8.37.1" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-8.37.1.tgz#e92a7d346cfa29116568f4ffb58f65caedee0149" - integrity sha512-ryMOTROLSLINKFEbHWvi7GigNrsQhsaScw2NddybJGztJQ5UhxIGESnxGxWCufBmWFDwd7+5u0jDPCVUJybp7w== - -"@sentry/utils@8.37.1": - version "8.37.1" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-8.37.1.tgz#6e020cd222d56d79953ea9d4630d91b3e323ceda" - integrity sha512-Qtn2IfpII12K17txG/ZtTci35XYjYi4CxbQ3j7nXY7toGv/+MqPXwV5q2i9g94XaSXlE5Wy9/hoCZoZpZs/djA== - dependencies: - "@sentry/types" "8.37.1" +"@sentry/types@8.40.0": + version "8.40.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-8.40.0.tgz#a98d2bcc48adbc066b403713688ded3ac5eb1cec" + integrity sha512-nuCf3U3deolPM9BjNnwCc33UtFl9ec15/r74ngAkNccn+A2JXdIAsDkGJMO/9mgSFykLe1QyeJ0pQFRisCGOiA== "@sentry/webpack-plugin@^2.7.1": version "2.22.5" From de5ddcf6f785debb85a0bd0f4bc1ab9682ffefe3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 18:23:13 +0000 Subject: [PATCH 15/44] Update guibranco/github-status-action-v2 digest to 66088c4 (#28555) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 14fd5ffd64..0c531f89b4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -104,7 +104,7 @@ jobs: - name: Skip SonarCloud in merge queue if: github.event_name == 'merge_group' || inputs.disable_coverage == 'true' - uses: guibranco/github-status-action-v2@1f26a0237cd1a57626fbb5a0eb2494c9b8797d07 + uses: guibranco/github-status-action-v2@66088c44e212a906c32a047529a213d81809ec1c with: authToken: ${{ secrets.GITHUB_TOKEN }} state: success From af846f8be99ca65a1c7368b28cb38152734999f5 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Tue, 26 Nov 2024 22:34:32 +0100 Subject: [PATCH 16/44] Replace `MatrixClient.isRoomEncrypted` by `MatrixClient.CryptoApi.isEncryptionEnabledInRoom` in RoomView (#28278) * Replace `MatrixClient.isRoomEncrypted` by `MatrixClient.CryptoApi.isEncryptionEnabledInRoom` in RoomView * Add `isRoomEncrypted` to room * Update e2eStatus and urlPreview when isRoomEncrypted is computed * Fix e2e test * Add tests when user verification change * Reduced abusive timeout in e2e test --- .../decryption-failure-messages.spec.ts | 3 + src/components/structures/RoomView.tsx | 163 +++-- src/contexts/RoomContext.ts | 1 + test/test-utils/room.ts | 2 +- test/test-utils/test-utils.ts | 2 +- .../components/structures/RoomView-test.tsx | 90 ++- .../__snapshots__/RoomView-test.tsx.snap | 619 +++++++++++++++++- .../views/rooms/SendMessageComposer-test.tsx | 1 + 8 files changed, 775 insertions(+), 106 deletions(-) diff --git a/playwright/e2e/crypto/decryption-failure-messages.spec.ts b/playwright/e2e/crypto/decryption-failure-messages.spec.ts index ce7ca34d8e..b2a1209a70 100644 --- a/playwright/e2e/crypto/decryption-failure-messages.spec.ts +++ b/playwright/e2e/crypto/decryption-failure-messages.spec.ts @@ -67,6 +67,9 @@ test.describe("Cryptography", function () { await page.locator(".mx_AuthPage").getByRole("button", { name: "I'll verify later" }).click(); await app.viewRoomByName("Test room"); + // In this case, the call to cryptoApi.isEncryptionEnabledInRoom is taking a long time to resolve + await page.waitForTimeout(1000); + // There should be two historical events in the timeline const tiles = await page.locator(".mx_EventTile").all(); expect(tiles.length).toBeGreaterThanOrEqual(2); diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 470b73de7c..58e37606b2 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -9,7 +9,16 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ -import React, { ChangeEvent, ComponentProps, createRef, ReactElement, ReactNode, RefObject, useContext } from "react"; +import React, { + ChangeEvent, + ComponentProps, + createRef, + ReactElement, + ReactNode, + RefObject, + useContext, + JSX, +} from "react"; import classNames from "classnames"; import { IRecommendedVersion, @@ -29,6 +38,7 @@ import { MatrixError, ISearchResults, THREAD_RELATION_TYPE, + MatrixClient, } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; import { logger } from "matrix-js-sdk/src/logger"; @@ -233,6 +243,11 @@ export interface IRoomState { liveTimeline?: EventTimeline; narrow: boolean; msc3946ProcessDynamicPredecessor: boolean; + /** + * Whether the room is encrypted or not. + * If null, we are still determining the encryption status. + */ + isRoomEncrypted: boolean | null; canAskToJoin: boolean; promptAskToJoin: boolean; @@ -417,6 +432,7 @@ export class RoomView extends React.Component { canAskToJoin: this.askToJoinEnabled, promptAskToJoin: false, viewRoomOpts: { buttons: [] }, + isRoomEncrypted: null, }; } @@ -847,7 +863,7 @@ export class RoomView extends React.Component { return isManuallyShown && widgets.length > 0; } - public componentDidMount(): void { + public async componentDidMount(): Promise { this.unmounted = false; this.dispatcherRef = defaultDispatcher.register(this.onAction); @@ -1342,13 +1358,12 @@ export class RoomView extends React.Component { this.context.widgetLayoutStore.on(WidgetLayoutStore.emissionForRoom(room), this.onWidgetLayoutChange); this.calculatePeekRules(room); - this.updatePreviewUrlVisibility(room); this.loadMembersIfJoined(room); this.calculateRecommendedVersion(room); - this.updateE2EStatus(room); this.updatePermissions(room); this.checkWidgets(room); this.loadVirtualRoom(room); + this.updateRoomEncrypted(room); if ( this.getMainSplitContentType(room) !== MainSplitContentType.Timeline && @@ -1377,6 +1392,13 @@ export class RoomView extends React.Component { return room?.currentState.getStateEvents(EventType.RoomTombstone, "") ?? undefined; } + private async getIsRoomEncrypted(roomId = this.state.roomId): Promise { + const crypto = this.context.client?.getCrypto(); + if (!crypto || !roomId) return false; + + return await crypto.isEncryptionEnabledInRoom(roomId); + } + private async calculateRecommendedVersion(room: Room): Promise { const upgradeRecommendation = await room.getRecommendedVersion(); if (this.unmounted) return; @@ -1409,12 +1431,15 @@ export class RoomView extends React.Component { }); } - private updatePreviewUrlVisibility({ roomId }: Room): void { - // URL Previews in E2EE rooms can be a privacy leak so use a different setting which is per-room explicit - const key = this.context.client?.isRoomEncrypted(roomId) ? "urlPreviewsEnabled_e2ee" : "urlPreviewsEnabled"; - this.setState({ - showUrlPreview: SettingsStore.getValue(key, roomId), - }); + private updatePreviewUrlVisibility(room: Room): void { + this.setState(({ isRoomEncrypted }) => ({ + showUrlPreview: this.getPreviewUrlVisibility(room, isRoomEncrypted), + })); + } + + private getPreviewUrlVisibility({ roomId }: Room, isRoomEncrypted: boolean | null): boolean { + const key = isRoomEncrypted ? "urlPreviewsEnabled_e2ee" : "urlPreviewsEnabled"; + return SettingsStore.getValue(key, roomId); } private onRoom = (room: Room): void => { @@ -1456,7 +1481,7 @@ export class RoomView extends React.Component { }; private async updateE2EStatus(room: Room): Promise { - if (!this.context.client?.isRoomEncrypted(room.roomId)) return; + if (!this.context.client || !this.state.isRoomEncrypted) return; // If crypto is not currently enabled, we aren't tracking devices at all, // so we don't know what the answer is. Let's error on the safe side and show @@ -1467,33 +1492,54 @@ export class RoomView extends React.Component { if (this.context.client.getCrypto()) { /* At this point, the user has encryption on and cross-signing on */ - e2eStatus = await shieldStatusForRoom(this.context.client, room); - RoomView.e2eStatusCache.set(room.roomId, e2eStatus); + e2eStatus = await this.cacheAndGetE2EStatus(room, this.context.client); if (this.unmounted) return; this.setState({ e2eStatus }); } } + private async cacheAndGetE2EStatus(room: Room, client: MatrixClient): Promise { + const e2eStatus = await shieldStatusForRoom(client, room); + RoomView.e2eStatusCache.set(room.roomId, e2eStatus); + return e2eStatus; + } + private onUrlPreviewsEnabledChange = (): void => { if (this.state.room) { this.updatePreviewUrlVisibility(this.state.room); } }; - private onRoomStateEvents = (ev: MatrixEvent, state: RoomState): void => { + private onRoomStateEvents = async (ev: MatrixEvent, state: RoomState): Promise => { // ignore if we don't have a room yet - if (!this.state.room || this.state.room.roomId !== state.roomId) return; + if (!this.state.room || this.state.room.roomId !== state.roomId || !this.context.client) return; switch (ev.getType()) { case EventType.RoomTombstone: this.setState({ tombstone: this.getRoomTombstone() }); break; - + case EventType.RoomEncryption: { + await this.updateRoomEncrypted(); + break; + } default: this.updatePermissions(this.state.room); } }; + private async updateRoomEncrypted(room = this.state.room): Promise { + if (!room || !this.context.client) return; + + const isRoomEncrypted = await this.getIsRoomEncrypted(room.roomId); + const newE2EStatus = isRoomEncrypted ? await this.cacheAndGetE2EStatus(room, this.context.client) : null; + + this.setState({ + isRoomEncrypted, + showUrlPreview: this.getPreviewUrlVisibility(room, isRoomEncrypted), + ...(newE2EStatus && { e2eStatus: newE2EStatus }), + }); + } + private onRoomStateUpdate = (state: RoomState): void => { // ignore members in other rooms if (state.roomId !== this.state.room?.roomId) { @@ -2027,6 +2073,8 @@ export class RoomView extends React.Component { public render(): ReactNode { if (!this.context.client) return null; + const { isRoomEncrypted } = this.state; + const isRoomEncryptionLoading = isRoomEncrypted === null; if (this.state.room instanceof LocalRoom) { if (this.state.room.state === LocalRoomState.CREATING) { @@ -2242,14 +2290,16 @@ export class RoomView extends React.Component { let aux: JSX.Element | undefined; let previewBar; if (this.state.timelineRenderingType === TimelineRenderingType.Search) { - aux = ( - - ); + if (!isRoomEncryptionLoading) { + aux = ( + + ); + } } else if (showRoomUpgradeBar) { aux = ; } else if (myMembership !== KnownMembership.Join) { @@ -2325,8 +2375,10 @@ export class RoomView extends React.Component { let messageComposer; const showComposer = + !isRoomEncryptionLoading && // joined and not showing search results - myMembership === KnownMembership.Join && !this.state.search; + myMembership === KnownMembership.Join && + !this.state.search; if (showComposer) { messageComposer = ( { highlightedEventId = this.state.initialEventId; } - const messagePanel = ( -