Skip to content

Commit c452fb2

Browse files
authored
Merge branch 'develop' into andybalaam/reset-encryption-redesign2
2 parents 001665c + cd05838 commit c452fb2

File tree

303 files changed

+7535
-4044
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

303 files changed

+7535
-4044
lines changed

.eslintrc.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ module.exports = {
3030
["window.innerHeight", "window.innerWidth", "window.visualViewport"],
3131
"Use UIStore to access window dimensions instead.",
3232
),
33+
...buildRestrictedPropertiesOptions(
34+
["React.forwardRef", "*.forwardRef", "forwardRef"],
35+
"Use ref props instead.",
36+
),
3337
...buildRestrictedPropertiesOptions(
3438
["*.mxcUrlToHttp", "*.getHttpUriForMxc"],
3539
"Use Media helper instead to centralise access for customisation.",
@@ -55,6 +59,11 @@ module.exports = {
5559
"error",
5660
{
5761
paths: [
62+
{
63+
name: "react",
64+
importNames: ["forwardRef"],
65+
message: "Use ref props instead.",
66+
},
5867
{
5968
name: "@testing-library/react",
6069
message: "Please use jest-matrix-react instead",

.github/workflows/docker.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ jobs:
132132
cosign sign --yes ${images}
133133
134134
- name: Update repo description
135-
uses: peter-evans/dockerhub-description@0505d8b04853a30189aee66f5bb7fd1511bbac71 # v4
135+
uses: peter-evans/dockerhub-description@432a30c9e07499fd01da9f8a49f0faf9e0ca5b77 # v4
136136
if: github.event_name != 'pull_request'
137137
continue-on-error: true
138138
with:

.github/workflows/release_prepare.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ jobs:
100100
repo: matrix-org/matrix-js-sdk
101101
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
102102
wait-interval: 10
103-
check-name: draft
103+
check-name: "draft / draft"
104104
allowed-conclusions: success
105105

106106
- name: Wait for element-web draft
@@ -111,7 +111,7 @@ jobs:
111111
repo: element-hq/element-web
112112
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
113113
wait-interval: 10
114-
check-name: draft
114+
check-name: "draft / draft"
115115
allowed-conclusions: success
116116

117117
- name: Wait for element-desktop draft
@@ -122,5 +122,5 @@ jobs:
122122
repo: element-hq/element-desktop
123123
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
124124
wait-interval: 10
125-
check-name: draft
125+
check-name: "draft / draft"
126126
allowed-conclusions: success

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ jobs:
104104

105105
- name: Skip SonarCloud in merge queue
106106
if: github.event_name == 'merge_group' || inputs.disable_coverage == 'true'
107-
uses: guibranco/github-status-action-v2@9b1d102b3c32583174557f58c53e3b09d43d1b1d
107+
uses: guibranco/github-status-action-v2@5f2b01ce1394109f70954ae6b69ef41cf7928e63
108108
with:
109109
authToken: ${{ secrets.GITHUB_TOKEN }}
110110
state: success

.github/workflows/triage-assigned.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ jobs:
1111
runs-on: ubuntu-24.04
1212
if: |
1313
contains(github.event.issue.assignees.*.login, 't3chguy') ||
14-
contains(github.event.issue.assignees.*.login, 'andybalaam') ||
14+
contains(github.event.issue.assignees.*.login, 'florianduros') ||
15+
contains(github.event.issue.assignees.*.login, 'dbkr') ||
1516
contains(github.event.issue.assignees.*.login, 'MidhunSureshR')
1617
steps:
1718
- uses: actions/add-to-project@main

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ electron/pub
2525
.env
2626
/coverage
2727
# Auto-generated file
28-
/src/modules.ts
2928
/src/modules.js
3029
/build_config.yaml
3130
/book

CHANGELOG.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
Changes in [1.11.99](https://github.com/element-hq/element-web/releases/tag/v1.11.99) (2025-04-23)
2+
==================================================================================================
3+
No changes, just bumping the version to accommodate a new Element Desktop release
4+
5+
Changes in [1.11.98](https://github.com/element-hq/element-web/releases/tag/v1.11.98) (2025-04-22)
6+
==================================================================================================
7+
## ✨ Features
8+
9+
* print better errors in the search view instead of a blocking modal ([#29724](https://github.com/element-hq/element-web/pull/29724)). Contributed by @Jujure.
10+
* New room list: video room and video call decoration ([#29693](https://github.com/element-hq/element-web/pull/29693)). Contributed by @florianduros.
11+
* Remove Secure Backup, Cross-signing and Cryptography sections in `Security & Privacy` user settings ([#29088](https://github.com/element-hq/element-web/pull/29088)). Contributed by @florianduros.
12+
* Allow reporting a room when rejecting an invite. ([#29570](https://github.com/element-hq/element-web/pull/29570)). Contributed by @Half-Shot.
13+
* RoomListViewModel: Reset primary and secondary filters on space change ([#29672](https://github.com/element-hq/element-web/pull/29672)). Contributed by @MidhunSureshR.
14+
* RoomListStore: Support specific sorting requirements for muted rooms ([#29665](https://github.com/element-hq/element-web/pull/29665)). Contributed by @MidhunSureshR.
15+
* New room list: add notification options menu ([#29639](https://github.com/element-hq/element-web/pull/29639)). Contributed by @florianduros.
16+
* Room List: Scroll to top of the list when active room is not in the list ([#29650](https://github.com/element-hq/element-web/pull/29650)). Contributed by @MidhunSureshR.
17+
18+
## 🐛 Bug Fixes
19+
20+
* Fix unwanted form submit behaviour in memberlist ([#29747](https://github.com/element-hq/element-web/pull/29747)). Contributed by @MidhunSureshR.
21+
* New room list: fix public room icon visibility when filter change ([#29737](https://github.com/element-hq/element-web/pull/29737)). Contributed by @florianduros.
22+
* Fix custom theme support for short hex \& rgba hex strings ([#29726](https://github.com/element-hq/element-web/pull/29726)). Contributed by @t3chguy.
23+
* New room list: minor visual fixes ([#29723](https://github.com/element-hq/element-web/pull/29723)). Contributed by @florianduros.
24+
* Fix getOidcCallbackUrl for Element Desktop ([#29711](https://github.com/element-hq/element-web/pull/29711)). Contributed by @t3chguy.
25+
* Fix some webp images improperly marked as animated ([#29713](https://github.com/element-hq/element-web/pull/29713)). Contributed by @Petersmit27.
26+
* Revert deletion of hydrateSession ([#29703](https://github.com/element-hq/element-web/pull/29703)). Contributed by @Jujure.
27+
* Fix converttoroom \& converttodm not working ([#29705](https://github.com/element-hq/element-web/pull/29705)). Contributed by @t3chguy.
28+
* Ensure forceCloseAllModals also closes priority/static modals ([#29706](https://github.com/element-hq/element-web/pull/29706)). Contributed by @t3chguy.
29+
* Continue button is disabled when uploading a recovery key file ([#29695](https://github.com/element-hq/element-web/pull/29695)). Contributed by @Giwayume.
30+
* Catch errors after syncing recovery ([#29691](https://github.com/element-hq/element-web/pull/29691)). Contributed by @andybalaam.
31+
* New room list: fix multiple visual issues ([#29673](https://github.com/element-hq/element-web/pull/29673)). Contributed by @florianduros.
32+
* New Room List: Fix mentions filter matching rooms with any highlight ([#29668](https://github.com/element-hq/element-web/pull/29668)). Contributed by @MidhunSureshR.
33+
* Fix truncated emoji label during emoji SAS ([#29643](https://github.com/element-hq/element-web/pull/29643)). Contributed by @florianduros.
34+
* Remove duplicate jitsi link ([#29642](https://github.com/element-hq/element-web/pull/29642)). Contributed by @dbkr.
35+
36+
137
Changes in [1.11.97](https://github.com/element-hq/element-web/releases/tag/v1.11.97) (2025-04-08)
238
==================================================================================================
339
## ✨ Features

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# syntax=docker.io/docker/dockerfile:1.14-labs
1+
# syntax=docker.io/docker/dockerfile:1.15-labs
22

33
# Builder
44
FROM --platform=$BUILDPLATFORM node:22-bullseye AS builder

docs/labs.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,6 @@ Under the hood this stops Element Web from adding the `perParticipantE2EE` flag
101101

102102
This is useful while we experiment with encryption and to make calling compatible with platforms that don't use encryption yet.
103103

104-
## Rich text in room topics (`feature_html_topic`) [In Development]
105-
106-
Enables rendering of MD / HTML in room topics.
107-
108104
## Enable the notifications panel in the room header (`feature_notifications`)
109105

110106
Unreliable in encrypted rooms.

package.json

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "element-web",
3-
"version": "1.11.97",
3+
"version": "1.11.99",
44
"description": "Element: the future of secure communication",
55
"author": "New Vector Ltd.",
66
"repository": {
@@ -68,14 +68,14 @@
6868
"postinstall": "patch-package"
6969
},
7070
"resolutions": {
71-
"**/pretty-format/react-is": "19.0.0",
71+
"**/pretty-format/react-is": "19.1.0",
7272
"@playwright/test": "1.51.1",
73-
"@types/react": "19.0.10",
74-
"@types/react-dom": "19.0.4",
73+
"@types/react": "19.1.2",
74+
"@types/react-dom": "19.1.2",
7575
"oidc-client-ts": "3.2.0",
7676
"jwt-decode": "4.0.0",
77-
"caniuse-lite": "1.0.30001707",
78-
"testcontainers": "10.23.0",
77+
"caniuse-lite": "1.0.30001715",
78+
"testcontainers": "10.24.2",
7979
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0",
8080
"wrap-ansi": "npm:wrap-ansi@^7.0.0"
8181
},
@@ -93,7 +93,7 @@
9393
"@types/png-chunks-extract": "^1.0.2",
9494
"@types/react-virtualized": "^9.21.30",
9595
"@vector-im/compound-design-tokens": "^4.0.0",
96-
"@vector-im/compound-web": "^7.10.1",
96+
"@vector-im/compound-web": "^7.10.2",
9797
"@vector-im/matrix-wysiwyg": "2.38.3",
9898
"@zxcvbn-ts/core": "^3.0.4",
9999
"@zxcvbn-ts/language-common": "^3.0.4",
@@ -138,7 +138,7 @@
138138
"opus-recorder": "^8.0.3",
139139
"pako": "^2.0.3",
140140
"png-chunks-extract": "^1.0.0",
141-
"posthog-js": "1.157.2",
141+
"posthog-js": "1.236.7",
142142
"qrcode": "1.5.4",
143143
"re-resizable": "6.11.2",
144144
"react": "^19.0.0",
@@ -151,7 +151,7 @@
151151
"react-virtualized": "^9.22.5",
152152
"rfc4648": "^1.4.0",
153153
"sanitize-filename": "^1.6.3",
154-
"sanitize-html": "2.15.0",
154+
"sanitize-html": "2.16.0",
155155
"tar-js": "^0.3.0",
156156
"temporal-polyfill": "^0.3.0",
157157
"ua-parser-js": "^1.0.2",
@@ -180,13 +180,14 @@
180180
"@babel/preset-typescript": "^7.12.7",
181181
"@babel/runtime": "^7.12.5",
182182
"@casualbot/jest-sonar-reporter": "2.2.7",
183-
"@element-hq/element-call-embedded": "0.9.0",
183+
"@element-hq/element-call-embedded": "0.10.0",
184184
"@element-hq/element-web-playwright-common": "^1.1.5",
185185
"@peculiar/webcrypto": "^1.4.3",
186186
"@playwright/test": "^1.50.1",
187187
"@principalstudio/html-webpack-inject-preload": "^1.2.7",
188+
"@rrweb/types": "^2.0.0-alpha.18",
188189
"@sentry/webpack-plugin": "^3.0.0",
189-
"@stylistic/eslint-plugin": "^3.0.0",
190+
"@stylistic/eslint-plugin": "^4.0.0",
190191
"@svgr/webpack": "^8.0.0",
191192
"@testing-library/dom": "^10.4.0",
192193
"@testing-library/jest-dom": "^6.4.8",
@@ -211,9 +212,9 @@
211212
"@types/node-fetch": "^2.6.2",
212213
"@types/pako": "^2.0.0",
213214
"@types/qrcode": "^1.3.5",
214-
"@types/react": "19.0.10",
215+
"@types/react": "19.1.2",
215216
"@types/react-beautiful-dnd": "^13.0.0",
216-
"@types/react-dom": "19.0.4",
217+
"@types/react-dom": "19.1.2",
217218
"@types/react-transition-group": "^4.4.0",
218219
"@types/sanitize-html": "2.15.0",
219220
"@types/semver": "^7.5.8",
@@ -246,7 +247,7 @@
246247
"eslint-plugin-react-compiler": "^19.0.0-beta-df7b47d-20241124",
247248
"eslint-plugin-react-hooks": "^5.0.0",
248249
"eslint-plugin-unicorn": "^56.0.0",
249-
"express": "^4.18.2",
250+
"express": "^5.0.0",
250251
"fake-indexeddb": "^6.0.0",
251252
"fetch-mock": "9.11.0",
252253
"fetch-mock-jest": "^1.5.1",
@@ -286,13 +287,13 @@
286287
"semver": "^7.5.2",
287288
"source-map-loader": "^5.0.0",
288289
"stylelint": "^16.13.0",
289-
"stylelint-config-standard": "^37.0.0",
290+
"stylelint-config-standard": "^38.0.0",
290291
"stylelint-scss": "^6.0.0",
291292
"stylelint-value-no-unknown-custom-properties": "^6.0.1",
292293
"terser-webpack-plugin": "^5.3.9",
293294
"testcontainers": "^10.20.0",
294295
"ts-node": "^10.9.1",
295-
"typescript": "5.8.2",
296+
"typescript": "5.8.3",
296297
"util": "^0.12.5",
297298
"web-streams-polyfill": "^4.0.0",
298299
"webpack": "^5.89.0",

playwright/e2e/left-panel/room-list-panel/room-list-filter-sort.spec.ts

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -140,29 +140,35 @@ test.describe("Room list filters and sort", () => {
140140
expect(await roomList.locator("role=gridcell").count()).toBe(3);
141141
});
142142

143-
test("unread filter should only match unread rooms that have a count", async ({ page, app, bot }) => {
144-
const roomListView = getRoomList(page);
145-
146-
// Let's configure unread dm room so that we only get notification for mentions and keywords
147-
await app.viewRoomById(unReadDmId);
148-
await app.settings.openRoomSettings("Notifications");
149-
await page.getByText("@mentions & keywords").click();
150-
await app.settings.closeDialog();
151-
152-
// Let's open a room other than unread room or unread dm
153-
await roomListView.getByRole("gridcell", { name: "Open room favourite room" }).click();
154-
155-
// Let's make the bot send a new message in both rooms
156-
await bot.sendMessage(unReadDmId, "Hello!");
157-
await bot.sendMessage(unReadRoomId, "Hello!");
158-
159-
// Let's activate the unread filter now
160-
await page.getByRole("option", { name: "Unread" }).click();
161-
162-
// Unread filter should only show unread room and not unread dm!
163-
await expect(roomListView.getByRole("gridcell", { name: "Open room unread room" })).toBeVisible();
164-
await expect(roomListView.getByRole("gridcell", { name: "Open room unread dm" })).not.toBeVisible();
165-
});
143+
test(
144+
"unread filter should only match unread rooms that have a count",
145+
{ tag: "@screenshot" },
146+
async ({ page, app, bot }) => {
147+
const roomListView = getRoomList(page);
148+
149+
// Let's configure unread dm room so that we only get notification for mentions and keywords
150+
await app.viewRoomById(unReadDmId);
151+
await app.settings.openRoomSettings("Notifications");
152+
await page.getByText("@mentions & keywords").click();
153+
await app.settings.closeDialog();
154+
155+
// Let's open a room other than unread room or unread dm
156+
await roomListView.getByRole("gridcell", { name: "Open room favourite room" }).click();
157+
158+
// Let's make the bot send a new message in both rooms
159+
await bot.sendMessage(unReadDmId, "Hello!");
160+
await bot.sendMessage(unReadRoomId, "Hello!");
161+
162+
// Let's activate the unread filter now
163+
await page.getByRole("option", { name: "Unread" }).click();
164+
165+
// Unread filter should only show unread room and not unread dm!
166+
const unreadDm = roomListView.getByRole("gridcell", { name: "Open room unread room" });
167+
await expect(unreadDm).toBeVisible();
168+
await expect(unreadDm).toMatchScreenshot("unread-dm.png");
169+
await expect(roomListView.getByRole("gridcell", { name: "Open room unread dm" })).not.toBeVisible();
170+
},
171+
);
166172
});
167173

168174
test.describe("Empty room list", () => {

playwright/e2e/left-panel/room-list-panel/room-list.spec.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,47 @@ test.describe("Room list", () => {
142142
await filters.getByRole("option", { name: "People" }).click();
143143
await expect(roomListView.getByRole("gridcell", { name: "Open room room0" })).toBeVisible();
144144
});
145+
146+
test.describe("Shortcuts", () => {
147+
test("should select the next room", async ({ page, app, user }) => {
148+
const roomListView = getRoomList(page);
149+
await roomListView.getByRole("gridcell", { name: "Open room room29" }).click();
150+
await page.keyboard.press("Alt+ArrowDown");
151+
152+
await expect(page.getByRole("heading", { name: "room28", level: 1 })).toBeVisible();
153+
});
154+
155+
test("should select the previous room", async ({ page, app, user }) => {
156+
const roomListView = getRoomList(page);
157+
await roomListView.getByRole("gridcell", { name: "Open room room28" }).click();
158+
await page.keyboard.press("Alt+ArrowUp");
159+
160+
await expect(page.getByRole("heading", { name: "room29", level: 1 })).toBeVisible();
161+
});
162+
163+
test("should select the last room", async ({ page, app, user }) => {
164+
const roomListView = getRoomList(page);
165+
await roomListView.getByRole("gridcell", { name: "Open room room29" }).click();
166+
await page.keyboard.press("Alt+ArrowUp");
167+
168+
await expect(page.getByRole("heading", { name: "room0", level: 1 })).toBeVisible();
169+
});
170+
171+
test("should select the next unread room", async ({ page, app, user, bot }) => {
172+
const roomListView = getRoomList(page);
173+
174+
const roomId = await app.client.createRoom({ name: "1 notification" });
175+
await app.client.inviteUser(roomId, bot.credentials.userId);
176+
await bot.joinRoom(roomId);
177+
await bot.sendMessage(roomId, "I am a robot. Beep.");
178+
179+
await roomListView.getByRole("gridcell", { name: "Open room room20" }).click();
180+
181+
await page.keyboard.press("Alt+Shift+ArrowDown");
182+
183+
await expect(page.getByRole("heading", { name: "1 notification", level: 1 })).toBeVisible();
184+
});
185+
});
145186
});
146187

147188
test.describe("Avatar decoration", () => {
@@ -230,6 +271,22 @@ test.describe("Room list", () => {
230271
await expect(room).toMatchScreenshot("room-list-item-mention.png");
231272
});
232273

274+
test("should render a message preview", { tag: "@screenshot" }, async ({ page, app, user, bot }) => {
275+
const roomListView = getRoomList(page);
276+
277+
await page.getByRole("button", { name: "Room Options" }).click();
278+
await page.getByRole("menuitemcheckbox", { name: "Show message previews" }).click();
279+
280+
const roomId = await app.client.createRoom({ name: "activity" });
281+
await app.client.inviteUser(roomId, bot.credentials.userId);
282+
await bot.joinRoom(roomId);
283+
await bot.sendMessage(roomId, "I am a robot. Beep.");
284+
285+
const room = roomListView.getByRole("gridcell", { name: "activity" });
286+
await expect(room.getByText("I am a robot. Beep.")).toBeVisible();
287+
await expect(room).toMatchScreenshot("room-list-item-message-preview.png");
288+
});
289+
233290
test("should render an activity decoration", { tag: "@screenshot" }, async ({ page, app, user, bot }) => {
234291
const roomListView = getRoomList(page);
235292

0 commit comments

Comments
 (0)