Compare commits

...

102 Commits

Author SHA1 Message Date
R Midhun Suresh
eebf227cf4 Update license 2025-10-30 16:56:37 +05:30
R Midhun Suresh
ebc9e3ace6 room-id is optional 2025-10-30 16:48:45 +05:30
R Midhun Suresh
61306a1e4a Improve comment 2025-10-30 16:31:59 +05:30
R Midhun Suresh
a9fed64637 Add more tests 2025-10-30 16:29:50 +05:30
R Midhun Suresh
8a875e8c6d Fix import 2025-10-30 16:12:23 +05:30
R Midhun Suresh
620ba9231d Fix circular dependency issue 2025-10-30 16:10:34 +05:30
R Midhun Suresh
f2104b5ec0 Fix import 2025-10-30 16:10:34 +05:30
R Midhun Suresh
1c0738be0f Add tests 2025-10-30 16:10:33 +05:30
R Midhun Suresh
c78461db0b Implement new builtins api 2025-10-30 16:10:31 +05:30
R Midhun Suresh
2b05d51e41 Add RoomContextType 2025-10-30 16:08:08 +05:30
R Midhun Suresh
6f6b3bdd8f No need to pass RVS from LoggedInView 2025-10-30 15:44:07 +05:30
R Midhun Suresh
da11cff6ff Fix test 2025-10-30 15:33:25 +05:30
R Midhun Suresh
302b6567ea Remove RoomViewStore from state
This is now accessed through class field
2025-10-30 15:32:40 +05:30
R Midhun Suresh
b8c79f46ee Add roomId to prop 2025-10-30 15:31:56 +05:30
R Midhun Suresh
0e8a617beb RVS is not needed as prop anymore
Since it's passed through context
2025-10-30 15:25:44 +05:30
David Baker
a94328a125 Update module api 2025-10-29 15:45:41 +00:00
David Baker
4d7d06bfc0 Merge remote-tracking branch 'origin/develop' into dbkr/module_experiments 2025-10-29 15:44:22 +00:00
David Langley
a9993aef85 Add aria label to emoji picker search (#31126) 2025-10-29 13:52:16 +00:00
renovate[bot]
9830a8bc6e Update all non-major dependencies (#31107)
* Update all non-major dependencies

* Remove @types/rrweb dependency

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>
2025-10-29 11:12:24 +00:00
renovate[bot]
fa3c3b4c8c Update Node.js to v24 (#31113)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 10:59:33 +00:00
renovate[bot]
8f7ded8747 Update browserslist (#31108)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 10:37:53 +00:00
renovate[bot]
68ead7c989 Update dependency @stylistic/eslint-plugin to v5.5.0 (#31110)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 10:33:48 +00:00
David Langley
ae2acdf311 Use context provided RoomViewStore within the RoomView component hierarchy (#31077)
* Update ContentMessages.ts

Update ContentMessages.ts

* update PlaybackQueue.ts

* Update SpaceHierarchy.tsx

* Update ThreadView.tsx

* Update RoomCallBanner.tsx

* Update useRoomCall.tsx

* Update DateSeparator.tsx

* Update TimelineCard.tsx

* Update UserInfoBasicOptions

* Update slask-commands/utils.ts

* lint

* Update PlaybackQueue, MVoiceMessageBody and UserInfoBasicOptionsView tests.

* Update RoomHeader-test.tsx

* lint

* Add ts docs

* Update utils-test.tsx

* Update message-test.ts

* coverage

* lint

* Improve naming

---------

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2025-10-29 09:40:21 +00:00
renovate[bot]
209dfece21 Update dependency @types/react-dom to v19.2.2 (#31101)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 09:16:00 +00:00
renovate[bot]
f7e1a7b90e Update playwright to v1.56.1 (#31104)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 09:15:18 +00:00
renovate[bot]
94ab980dc4 Update dependency eslint-plugin-storybook to v10 (#31111)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 09:14:28 +00:00
renovate[bot]
c408e12437 Update nginxinc/nginx-unprivileged:alpine-slim Docker digest to 65a7f97 (#31096)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 09:09:39 +00:00
renovate[bot]
26b14dc2f8 Update dependency @sentry/browser to v10.22.0 (#31109)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 09:09:09 +00:00
renovate[bot]
542eb9d1ec Update GitHub Artifact Actions (#31112)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 09:08:43 +00:00
renovate[bot]
5bcbf4f370 Update typescript-eslint monorepo to v8.46.2 (#31106)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 09:07:33 +00:00
renovate[bot]
a5e5125907 Update babel monorepo to v7.28.5 (#31098)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 09:05:49 +00:00
renovate[bot]
e4e33cf239 Update dependency @element-hq/element-call-embedded to v0.16.1 (#31100)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 09:05:40 +00:00
renovate[bot]
3175377cb2 Update dependency testcontainers to v11.7.2 (#31102)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 09:05:24 +00:00
renovate[bot]
1c2b35d809 Update Node.js to 38a57b7 (#31097)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 09:04:02 +00:00
David Langley
80a7de4314 Address code smells from #30453 (#31083)
* check recents length

* Improve sorting logic in capabilities dialog

* Fix allowedHosts regex array check

* Remove double negative in filter checks

* prettier
2025-10-29 08:52:17 +00:00
ElementRobot
3e809cd661 [create-pull-request] automated change (#31121)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2025-10-29 06:26:10 +00:00
ElementRobot
f8ec6b6f9b [create-pull-request] automated change (#31120)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2025-10-29 06:19:38 +00:00
Hubert Chathi
b7db85146f Add a devtool for looking at users and their devices (#30983)
* add devtool for viewing users and their devices

* show number of devices

* apply changes from review

* Fix typo

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

---------

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2025-10-28 20:18:10 +00:00
R Midhun Suresh
5888dfd29d Return RLS instance through function to avoid import side effect (#31091)
* Attach function that returns instance

So that just importing this file does not create a RLS instance.

* Fix jest test
2025-10-28 14:48:07 +00:00
Richard van der Hoff
09c3afd311 Improve logging in DeviceListener (#31082)
* Improve logging in `DeviceListener`

Sometimes we get a logline `4S is missing secrets` but it's hard to see *which*
secrets are missing. https://github.com/matrix-org/matrix-js-sdk/pull/5054
added a method to the js-sdk which allows us to get more info: use it here.

* Use getSecretStorageStatus for analytics reporting too

* Fix unit tests
2025-10-28 09:42:53 +00:00
Michael Telatynski
f6731ec318 Show hover elements when keyboard focus is within an event tile (#31078)
* Show timestamps when keyboard focus is within an event tile

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Ensure toolbar navigation pattern works in MessageActionBar

This requires all buttons within to be roving by using the ref callback given by useRovingTabIndex

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Use PureComponent in EventTile to avoid mass re-rendering due to transitive onFocus/onBlur calls

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Remove unused timestamp event tile prop

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Use MessageTimestamp to generate the wrapping anchor so that focusing it brings up the tooltip

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Tweak MessageTimestamp

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch back to Component as we specify a shouldComponentUpdate already

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update jest tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update playwright timestamp masks

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Revert snapshot

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshot

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix IRC layout

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Use PureComponent in EventTile to avoid mass re-rendering due to transitive onFocus/onBlur calls

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Remove unused timestamp event tile prop

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Use MessageTimestamp to generate the wrapping anchor so that focusing it brings up the tooltip

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Tweak MessageTimestamp

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch back to Component as we specify a shouldComponentUpdate already

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update jest tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update playwright timestamp masks

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Revert snapshot

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshot

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix IRC layout

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Lint styles

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix layout picker

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update screenshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix pcss comment

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate Playwright

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate Playwright

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-10-28 09:33:02 +00:00
ElementRobot
7e04998a58 [create-pull-request] automated change (#31090)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2025-10-28 06:19:25 +00:00
Will Hunt
dae5b6b43b Remove allowVoipWithNoMedia feature flag (#31087)
* Remove allowVoipWithNoMedia feature flag

* whoops

* remove a string
2025-10-27 13:08:31 +00:00
Michael Telatynski
8376e43a03 Ensure toolbar navigation pattern works in MessageActionBar (#31080)
This requires all buttons within to be roving by using the ref callback given by useRovingTabIndex

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-10-27 12:34:17 +00:00
Michael Telatynski
e528fefd4c Make Playwright screenshot test resilient to DST changes (#31089)
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-10-27 12:17:40 +00:00
ElementRobot
5e87f20cd8 [create-pull-request] automated change (#31084)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2025-10-25 06:18:31 +00:00
Will Hunt
7d9981e5dd Ensure sent markers are hidden when showing thread summary. (#31076)
* Ensure read markers are hidden when showing thread summary.

* lint

* update screenshot
2025-10-24 12:45:57 +00:00
ElementRobot
1d20a4c5ee [create-pull-request] automated change (#31075)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2025-10-24 06:27:09 +00:00
ElementRobot
bc97560532 [create-pull-request] automated change (#31074)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2025-10-24 06:19:46 +00:00
David Baker
a6316d99d5 bump shared components version 2025-10-23 15:56:17 +01:00
David Langley
bea3574b30 Provide RoomViewStore from the RoomContext (#30980)
* Pass roomViewStore to the RoomView and add to the RoomContext.

* lint

* lint

* Make constants more DRY

* Make constants more DRY

* Commend non-null assertion on roomViewStore property of the RoomContext

* Update tsdocs.
2025-10-23 09:03:11 +00:00
Florian Duros
0e6bacffed Replace ViewWrapper by useMockedViewModel (#31067)
* feat: replace `ViewWrapper` by `useMockedViewModel`

* feat: update existing story
2025-10-23 08:06:06 +00:00
ElementRobot
9be323dfd0 [create-pull-request] automated change (#31068)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2025-10-23 06:20:23 +00:00
ElementRobot
d6e50598cd [create-pull-request] automated change (#31059)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2025-10-22 06:27:20 +00:00
ElementRobot
41e33a0755 [create-pull-request] automated change (#31058)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2025-10-22 06:20:09 +00:00
Florian Duros
55a7bc5b13 fix: only export setLanguage for shared-component build (#31053) 2025-10-21 13:08:13 +00:00
RiotRobot
b1fdf03236 Reset matrix-js-sdk back to develop branch 2025-10-21 11:53:36 +00:00
RiotRobot
39464f64ab Merge branch 'master' into develop 2025-10-21 11:53:15 +00:00
RiotRobot
09598bcb7a v1.12.2 2025-10-21 11:41:01 +00:00
RiotRobot
6e7dc4cc06 Upgrade dependency to matrix-js-sdk@39.0.0 2025-10-21 11:21:02 +00:00
David Baker
c31d4fea8d Merge branch 'develop' into dbkr/module_experiments 2025-10-21 11:04:34 +01:00
Michael Telatynski
87fd279079 Fix sort order in space hierarchy (#30975)
* Fix sort order in space hierarchy

To match spec and not add unexpected sorting by space vs room

* Update SpaceHierarchy.tsx

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshot

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Add test

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshot

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-10-21 08:25:51 +00:00
Florian Duros
77c41d6789 Fix translation in dev mode (#31045)
* fix: use EW and shared component counterpart

* fix: exclude counterpart from build

* Revert "fix: use EW and shared component counterpart"

This reverts commit 1983d063c6.

* Revert "fix: exclude counterpart from build"

This reverts commit 8e41b137fc.

* fix: force EW and shared components to use EW counterpart
2025-10-21 08:25:07 +00:00
ElementRobot
9e1d0367d0 [create-pull-request] automated change (#31049)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2025-10-21 06:19:51 +00:00
Florian Duros
8fd6e29f2d fix: don't display message preview of thread (#31043) 2025-10-20 14:35:57 +00:00
Florian Duros
cbcceee970 doc: update install doc to link to caching section (#31046) 2025-10-20 14:22:48 +00:00
Florian Duros
d0a8879971 Revert "A11y: move focus to right panel when opened" (#30999)
* Revert "A11y: move focus to right panel when opened (#30553)"

This reverts commit 0c498a66b1.

* test(e2e): update test
2025-10-20 12:08:45 +00:00
Marc
e6e6f87d01 MVVM userinfo basic component (#30305)
* feat: mvvm userinfo basic component

* test: mvvm userinfobasic component

* chore: apply review. rename views, add comment and move some codes

* chore(review): move openDM method into viewmodel
2025-10-20 06:13:20 +00:00
Bojidar Marinov
cf51b256ce Fix highlights in messages (or search results) breaking links (#30264)
* Fix highlights in messages (or search results) breaking links

Fixes #17011 and fixes #29807, by running the linkifier that turns text into links before the highlighter that adds highlights to text.

* Fix jest test

* Fix tests related to emojis and pills-inside-spoilers

* Remove dead code

* Address review comments around sanitizeParams

* Address review comment about linkify-matrix

* Fix code style

* Refactor if statement per review

---------

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2025-10-20 06:10:13 +00:00
David Baker
a5f3876a38 Add test for builtinsapi 2025-10-17 17:05:45 +01:00
David Baker
206905c2f5 Make room names deterministic
So the tests don't fail if you add other tests or run them individually
2025-10-17 16:51:59 +01:00
David Baker
51499fa106 add test 2025-10-17 16:28:05 +01:00
David Baker
1ebead1c8a Add test for multiroomviewstore 2025-10-17 16:07:02 +01:00
David Baker
738eac9b90 Fairly awful workaround
to actually break the dependency nightmare
2025-10-17 11:22:00 +01:00
ElementRobot
9d973c88f9 [create-pull-request] automated change (#31040)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2025-10-17 06:25:57 +00:00
ElementRobot
e33894bed4 [create-pull-request] automated change (#31039)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2025-10-17 06:22:49 +00:00
David Baker
2dd743dea0 Switch to using module api via .instance 2025-10-16 19:14:34 +01:00
David Baker
ced886aa07 Merge remote-tracking branch 'origin/develop' into dbkr/module_experiments 2025-10-16 11:25:03 +01:00
David Baker
0468876aa0 Move some message utils out to their own file (#31035)
* Move some message utils out to their own file

In another attempt at import cycle breaking

* Also add the file

* Move tests
2025-10-16 08:17:46 +00:00
R Midhun Suresh
c8f1c19517 Add missing dependency (#31034) 2025-10-15 16:45:49 +00:00
R Midhun Suresh
2598e4ea22 Move view model code to shared components package (#31024)
* Remove vm related code from element-web/src

* Add and export view model code from package

* Update imports

* Rewrite vm tests using vitest

* Add github action to run vm tests

* Fix lint errors

* Mvoe tests over to jest

* Try fixing code coverage

* Second attempt at fixing code coverage
2025-10-15 13:49:12 +00:00
renovate[bot]
ac96ab0d46 Update react monorepo (#31014)
* Update react monorepo

* Update snapshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update shared-components snapshots

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>
2025-10-15 11:20:34 +00:00
renovate[bot]
949d0dc8a9 Update eslint-plugins (#31033)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-15 10:44:06 +00:00
David Baker
de5a75777f Merge remote-tracking branch 'origin/develop' into dbkr/module_experiments 2025-10-15 11:37:21 +01:00
renovate[bot]
0e0e928040 Update eslint-plugins (#31032)
* Update eslint-plugins

* Bump matrix-org

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>
2025-10-15 10:08:35 +00:00
David Baker
c519438dad Add prepare script (#31030)
Removed it when we switched to publishing, but that doesn't really
make sense
2025-10-15 09:22:42 +00:00
David Baker
146e4772ac Change module API to be an instance getter (#31025)
* Change module API to be an instance getter

Helps with circular dependencies by not instantating the module API
on the initial evaluation of the files.

* Add basic test

* add another test
2025-10-15 09:20:48 +00:00
Florian Duros
6cfe197a38 Update sonar and jest config with new shared components path (#31029)
* fix: update jest config with new shared components path

* fix: update sonar config

* chore: add `storybook` & `@storybook/react-vite` to run the shared components tests
2025-10-15 09:08:49 +00:00
renovate[bot]
a4a44a0c1c Update browserslist (#31021)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-15 08:37:57 +00:00
renovate[bot]
2ce2218549 Update typescript-eslint monorepo to v8.46.0 (#30921)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-15 08:21:23 +00:00
RiotRobot
9c37cdf550 v1.12.2-rc.0 2025-10-14 14:41:41 +00:00
RiotRobot
53ce37de9e Upgrade dependency to matrix-js-sdk@39.0.0-rc.0 2025-10-14 13:37:08 +00:00
David Baker
809b41aa59 Merge remote-tracking branch 'origin/develop' into dbkr/module_experiments 2025-10-13 17:00:24 +01:00
David Baker
b6b1658805 Merge remote-tracking branch 'origin/develop' into dbkr/module_experiments 2025-10-02 15:20:40 +01:00
David Baker
afa340eb18 Remove fetchRoomFn from SpaceNotificationStore
which didn't really seem to have any point as it was only called from
one place
2025-09-26 12:09:07 +01:00
David Baker
7ac4a4a2d4 Merge branch 'develop' into dbkr/module_experiments 2025-09-26 09:51:17 +01:00
David Baker
66bf1dd469 Allow space panel items to be updated
and manage which one is selected, allowing module "spaces" to be
considered spaces
2025-09-25 17:37:48 +01:00
David Baker
9ae447f14f Different interface to add space panel items
A bit less flexible but probably simpler and will help keep things
actually consistent rather than just allowing modules to stick any
JSX into the space panel (which means they also have to worry about
styling if they *do* want it to be consistent).
2025-09-25 11:54:54 +01:00
David Baker
a02a5ac849 Make RoomViewStore able to take a roomId prop 2025-09-24 16:35:28 +01:00
David Baker
e4dee7ab63 Add the MultiRoomViewStore 2025-09-24 16:31:57 +01:00
David Baker
9129c35407 Move ResizerNotifier into SDKContext
so we don't have to pass it into RoomView
2025-09-24 10:56:10 +01:00
David Baker
4b701b55b1 Module API experiments 2025-09-23 19:17:19 +01:00
349 changed files with 7599 additions and 3048 deletions

View File

@@ -66,7 +66,7 @@ jobs:
run: VERSION=$(scripts/get-version-from-git.sh) yarn build
- name: Upload Artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: webapp-${{ matrix.image }}
path: webapp

View File

@@ -62,7 +62,7 @@ jobs:
dpkg-gencontrol -v"$VERSION" -ldebian/tmp/DEBIAN/changelog
dpkg-deb -Zxz --root-owner-group --build debian/tmp element-web.deb
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: element-web.deb
path: element-web.deb

View File

@@ -53,7 +53,7 @@ jobs:
- run: mv dist/element-*.tar.gz dist/develop.tar.gz
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: webapp
path: dist/develop.tar.gz

View File

@@ -25,7 +25,7 @@ jobs:
actions: read
steps:
- name: Download HTML report
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}

View File

@@ -74,7 +74,7 @@ jobs:
run: VERSION=$(scripts/get-version-from-git.sh) yarn build
- name: Upload Artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: webapp
path: webapp
@@ -128,7 +128,7 @@ jobs:
repository: element-hq/element-web
- name: 📥 Download artifact
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: webapp
path: webapp
@@ -172,7 +172,7 @@ jobs:
- name: Upload blob report to GitHub Actions Artifacts
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: all-blob-reports-${{ matrix.project }}-${{ matrix.runner }}
path: blob-report
@@ -212,7 +212,7 @@ jobs:
- name: Download blob reports from GitHub Actions Artifacts
if: inputs.skip != true
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
pattern: all-blob-reports-*
path: all-blob-reports
@@ -228,7 +228,7 @@ jobs:
# Upload the HTML report even if one of our reporters fails, this can happen when stale screenshots are detected
- name: Upload HTML report
if: always() && inputs.skip != true
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: html-report
path: playwright-report

View File

@@ -28,7 +28,7 @@ jobs:
Exercise caution. Use test accounts.
- name: 📥 Download artifact
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}

View File

@@ -27,7 +27,7 @@ jobs:
run: "sudo apt-get install -y tree"
- name: Download Diffs
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}

View File

@@ -70,7 +70,7 @@ jobs:
- name: Upload received images & diffs
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: received-images
path: packages/shared-components/playwright/shared-component-received

View File

@@ -84,7 +84,7 @@ jobs:
- name: Upload Artifact
if: env.ENABLE_COVERAGE == 'true'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: coverage-${{ matrix.runner }}
path: |

View File

@@ -1 +1 @@
22
24

View File

@@ -1,3 +1,26 @@
Changes in [1.12.2](https://github.com/element-hq/element-web/releases/tag/v1.12.2) (2025-10-21)
================================================================================================
## ✨ Features
* Room List: Extend the viewport to avoid so many black spots when scrolling the room list ([#30867](https://github.com/element-hq/element-web/pull/30867)). Contributed by @langleyd.
* Hide calling buttons in room header before a room is created ([#30816](https://github.com/element-hq/element-web/pull/30816)). Contributed by @Half-Shot.
* Improve invite dialog ui - Part 2 ([#30836](https://github.com/element-hq/element-web/pull/30836)). Contributed by @florianduros.
## 🐛 Bug Fixes
* Fix platform settings race condition and make auto-launch tri-state ([#30977](https://github.com/element-hq/element-web/pull/30977)). Contributed by @t3chguy.
* Fix: member count in header and member list ([#30982](https://github.com/element-hq/element-web/pull/30982)). Contributed by @florianduros.
* Fix duration of voice message in timeline ([#30973](https://github.com/element-hq/element-web/pull/30973)). Contributed by @florianduros.
* Fix voice notes rendering at 00:00 when playback had not begun. ([#30961](https://github.com/element-hq/element-web/pull/30961)). Contributed by @Half-Shot.
* Improve handling of animated images, add support for AVIF animations ([#30932](https://github.com/element-hq/element-web/pull/30932)). Contributed by @t3chguy.
* Update key storage toggle when key storage status changes ([#30934](https://github.com/element-hq/element-web/pull/30934)). Contributed by @uhoreg.
* Fix jitsi widget popout ([#30908](https://github.com/element-hq/element-web/pull/30908)). Contributed by @dbkr.
* Improve keyboard navigation on invite dialog ([#30930](https://github.com/element-hq/element-web/pull/30930)). Contributed by @florianduros.
* Prefer UIA flows with supported UIA stages ([#30926](https://github.com/element-hq/element-web/pull/30926)). Contributed by @richvdh.
* Enhance accessibility of dropdown ([#30928](https://github.com/element-hq/element-web/pull/30928)). Contributed by @florianduros.
* Improve accessibility of the `\<AvatarSetting> component ([#30907](https://github.com/element-hq/element-web/pull/30907)). Contributed by @MidhunSureshR.
Changes in [1.12.1](https://github.com/element-hq/element-web/releases/tag/v1.12.1) (2025-10-07)
================================================================================================
## ✨ Features

View File

@@ -1,7 +1,7 @@
# syntax=docker.io/docker/dockerfile:1.19-labs@sha256:dce1c693ef318bca08c964ba3122ae6248e45a1b96d65c4563c8dc6fe80349a2
# Builder
FROM --platform=$BUILDPLATFORM node:22-bullseye@sha256:cd951bb228ddf85882951d4bf4acefc5314eb2eb66eee002256f4bb17c2293e3 AS builder
FROM --platform=$BUILDPLATFORM node:24-bullseye@sha256:c102f42d665c164b4e5e5549813b1547ac8a9f1d343c7d17ddac106905a1c30b AS builder
# Support custom branch of the js-sdk. This also helps us build images of element-web develop.
ARG USE_CUSTOM_SDKS=false
@@ -19,7 +19,7 @@ RUN /src/scripts/docker-package.sh
RUN cp /src/config.sample.json /src/webapp/config.json
# App
FROM nginxinc/nginx-unprivileged:alpine-slim@sha256:304079937327a6490d5c89df47c8951d76f05b346d4c6e3b10cba2e266cd4904
FROM nginxinc/nginx-unprivileged:alpine-slim@sha256:65a7f97c299b919190e96e38e2ff8358132732000d3bc5c00c07cc8763fca53f
# Need root user to install packages & manipulate the usr directory
USER root

View File

@@ -11,7 +11,7 @@ There are some exceptions like when using localhost, which is considered a [secu
1. Download the latest version from <https://github.com/element-hq/element-web/releases>
1. Untar the tarball on your web server
1. Move (or symlink) the `element-x.x.x` directory to an appropriate name
1. Configure the correct caching headers in your webserver (see below)
1. Configure the correct caching headers in your webserver (see [README.md](../README.md#caching-requirements))
1. Configure the app by copying `config.sample.json` to `config.json` and
modifying it. See the [configuration docs](config.md) for details.
1. Enter the URL into your browser and log into Element!

View File

@@ -17,7 +17,7 @@ const config: Config = {
// This is needed to be able to load dual CJS/ESM WASM packages e.g. rust crypto & matrix-wywiwyg
customExportConditions: ["browser", "node"],
},
testMatch: ["<rootDir>/test/**/*-test.[tj]s?(x)", "<rootDir>/src/shared-components/**/*.test.[t]s?(x)"],
testMatch: ["<rootDir>/test/**/*-test.[tj]s?(x)", "<rootDir>/packages/*/src/**/*.test.[t]s?(x)"],
globalSetup: "<rootDir>/test/globalSetup.ts",
setupFiles: ["jest-canvas-mock", "web-streams-polyfill/polyfill"],
setupFilesAfterEnv: ["<rootDir>/test/setupTests.ts"],
@@ -46,6 +46,7 @@ const config: Config = {
],
collectCoverageFrom: [
"<rootDir>/src/**/*.{js,ts,tsx}",
"<rootDir>/packages/**/*.{js,ts,tsx}",
// getSessionLock is piped into a different JS context via stringification, and the coverage functionality is
// not available in that contest. So, turn off coverage instrumentation for it.
"!<rootDir>/src/utils/SessionLock.ts",

View File

@@ -1,6 +1,6 @@
{
"name": "element-web",
"version": "1.12.1",
"version": "1.12.2",
"description": "Element: the future of secure communication",
"author": "New Vector Ltd.",
"repository": {
@@ -68,20 +68,20 @@
"postinstall": "patch-package"
},
"resolutions": {
"**/pretty-format/react-is": "19.1.1",
"@playwright/test": "1.56.0",
"@types/react": "19.1.14",
"@types/react-dom": "19.1.9",
"**/pretty-format/react-is": "19.2.0",
"@playwright/test": "1.56.1",
"@types/react": "19.2.2",
"@types/react-dom": "19.2.2",
"oidc-client-ts": "3.3.0",
"jwt-decode": "4.0.0",
"caniuse-lite": "1.0.30001745",
"caniuse-lite": "1.0.30001751",
"testcontainers": "^11.0.0",
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0",
"wrap-ansi": "npm:wrap-ansi@^7.0.0"
},
"dependencies": {
"@babel/runtime": "^7.12.5",
"@element-hq/element-web-module-api": "1.4.1",
"@element-hq/element-web-module-api": "1.5.0",
"@fontsource/inconsolata": "^5",
"@fontsource/inter": "^5",
"@formatjs/intl-segmenter": "^11.5.7",
@@ -122,6 +122,7 @@
"jsrsasign": "^11.0.0",
"jszip": "^3.7.0",
"katex": "^0.16.0",
"linkify-html": "4.3.2",
"linkify-react": "4.3.2",
"linkify-string": "4.3.2",
"linkifyjs": "4.3.2",
@@ -137,7 +138,7 @@
"opus-recorder": "^8.0.3",
"pako": "^2.0.3",
"png-chunks-extract": "^1.0.0",
"posthog-js": "1.275.1",
"posthog-js": "1.280.1",
"qrcode": "1.5.4",
"re-resizable": "6.11.2",
"react": "^19.0.0",
@@ -180,13 +181,13 @@
"@babel/preset-typescript": "^7.12.7",
"@babel/runtime": "^7.12.5",
"@casualbot/jest-sonar-reporter": "2.2.7",
"@element-hq/element-call-embedded": "0.16.0",
"@element-hq/element-call-embedded": "0.16.1",
"@element-hq/element-web-playwright-common": "^2.0.0",
"@peculiar/webcrypto": "^1.4.3",
"@playwright/test": "^1.50.1",
"@principalstudio/html-webpack-inject-preload": "^1.2.7",
"@rrweb/types": "^2.0.0-alpha.18",
"@sentry/webpack-plugin": "^4.0.0",
"@storybook/react-vite": "^9.1.10",
"@stylistic/eslint-plugin": "^5.0.0",
"@svgr/webpack": "^8.0.0",
"@testing-library/dom": "^10.4.0",
@@ -213,9 +214,9 @@
"@types/node-fetch": "^2.6.2",
"@types/pako": "^2.0.0",
"@types/qrcode": "^1.3.5",
"@types/react": "19.1.14",
"@types/react": "19.2.2",
"@types/react-beautiful-dnd": "^13.0.0",
"@types/react-dom": "19.1.9",
"@types/react-dom": "19.2.2",
"@types/react-transition-group": "^4.4.0",
"@types/sanitize-html": "2.16.0",
"@types/sdp-transform": "^2.4.10",
@@ -239,14 +240,14 @@
"eslint": "8.57.1",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-deprecate": "0.8.5",
"eslint-plugin-deprecate": "0.8.7",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jest": "^28.0.0",
"eslint-plugin-jest": "^29.0.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-matrix-org": "^2.0.2",
"eslint-plugin-matrix-org": "^3.0.0",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-compiler": "^19.0.0-beta-df7b47d-20241124",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-hooks": "^7.0.0",
"eslint-plugin-unicorn": "^56.0.0",
"express": "^5.0.0",
"fake-indexeddb": "^6.0.0",
@@ -287,6 +288,7 @@
"rimraf": "^6.0.0",
"semver": "^7.5.2",
"source-map-loader": "^5.0.0",
"storybook": "^9.1.10",
"stylelint": "^16.23.0",
"stylelint-config-standard": "^39.0.0",
"stylelint-scss": "^6.0.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@element-hq/web-shared-components",
"version": "0.0.0-test.5",
"version": "0.0.0-test.6",
"description": "Shared components for Element",
"author": "New Vector Ltd.",
"repository": {
@@ -31,6 +31,7 @@
],
"scripts": {
"postinstall": "patch-package",
"prepare": "vite build",
"storybook": "storybook dev -p 6007",
"build-storybook": "storybook build",
"lint": "yarn lint:types && yarn lint:js",
@@ -42,7 +43,8 @@
},
"dependencies": {
"matrix-web-i18n": "^3.4.0",
"patch-package": "^8.0.1"
"patch-package": "^8.0.1",
"counterpart": "^0.18.6"
},
"devDependencies": {
"@storybook/addon-a11y": "^9.1.10",
@@ -53,8 +55,7 @@
"@storybook/test-runner": "^0.23.0",
"concurrently": "^9.2.1",
"eslint": "8",
"jest-image-snapshot": "^6.5.1",
"eslint-plugin-storybook": "^9.1.10",
"eslint-plugin-storybook": "^10.0.0",
"jest-image-snapshot": "^6.5.1",
"patch-package": "^8.0.1",
"prettier": "^3.6.2",

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
import React, { type JSX, useMemo, type ComponentType } from "react";
import { omitBy, pickBy } from "lodash";
import { MockViewModel } from "./MockViewModel";
import { type ViewModel } from "./ViewModel";
interface ViewWrapperProps<V> {
/**
* The component to render, which should accept a `vm` prop of type `V`.
*/
Component: ComponentType<{ vm: V }>;
/**
* The props to pass to the component, which can include both snapshot data and actions.
*/
props: Record<string, any>;
}
/**
* A wrapper component that creates a view model instance and passes it to the specified component.
* This is useful for testing components in isolation with a mocked view model and allows to use primitive types in stories.
*
* Props is parsed and split into snapshot and actions. Where values that are functions (`typeof Function`) are considered actions and the rest is considered the snapshot.
*
* @example
* ```tsx
* <ViewWrapper<SnapshotType, ViewModelType> props={Snapshot&Actions} Component={MyComponent} />
* ```
*/
export function ViewWrapper<T, V extends ViewModel<T>>({
props,
Component,
}: Readonly<ViewWrapperProps<V>>): JSX.Element {
const vm = useMemo(() => {
const isFunction = (value: any): value is typeof Function => typeof value === typeof Function;
const snapshot = omitBy(props, isFunction) as T;
const actions = pickBy(props, isFunction);
const vm = new MockViewModel<T>(snapshot);
Object.assign(vm, actions);
return vm as unknown as V;
}, [props]);
return <Component vm={vm} />;
}

View File

@@ -9,18 +9,18 @@ import React, { type JSX } from "react";
import { fn } from "storybook/test";
import type { Meta, StoryFn } from "@storybook/react-vite";
import {
AudioPlayerView,
type AudioPlayerViewActions,
type AudioPlayerViewSnapshot,
type AudioPlayerViewModel,
} from "./AudioPlayerView";
import { ViewWrapper } from "../../ViewWrapper";
import { AudioPlayerView, type AudioPlayerViewActions, type AudioPlayerViewSnapshot } from "./AudioPlayerView";
import { useMockedViewModel } from "../../useMockedViewModel";
type AudioPlayerProps = AudioPlayerViewSnapshot & AudioPlayerViewActions;
const AudioPlayerViewWrapper = (props: AudioPlayerProps): JSX.Element => (
<ViewWrapper<AudioPlayerViewSnapshot, AudioPlayerViewModel> Component={AudioPlayerView} props={props} />
);
const AudioPlayerViewWrapper = ({ togglePlay, onKeyDown, onSeekbarChange, ...rest }: AudioPlayerProps): JSX.Element => {
const vm = useMockedViewModel(rest, {
togglePlay,
onKeyDown,
onSeekbarChange,
});
return <AudioPlayerView vm={vm} />;
};
export default {
title: "Audio/AudioPlayerView",

View File

@@ -13,7 +13,7 @@ import { fireEvent } from "@testing-library/dom";
import * as stories from "./AudioPlayerView.stories.tsx";
import { AudioPlayerView, type AudioPlayerViewActions, type AudioPlayerViewSnapshot } from "./AudioPlayerView";
import { MockViewModel } from "../../MockViewModel";
import { MockViewModel } from "../../viewmodel/MockViewModel.ts";
const { Default, NoMediaName, NoSize, HasError } = composeStories(stories);

View File

@@ -7,7 +7,7 @@
import React, { type ChangeEventHandler, type JSX, type KeyboardEventHandler, type MouseEventHandler } from "react";
import { type ViewModel } from "../../ViewModel";
import { type ViewModel } from "../../viewmodel/ViewModel";
import { useViewModel } from "../../useViewModel";
import { MediaBody } from "../../message-body/MediaBody";
import { Flex } from "../../utils/Flex";

View File

@@ -15,7 +15,7 @@ exports[`AudioPlayerView renders the audio player in default state 1`] = `
<button
aria-disabled="false"
aria-label="Play"
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="_icon-button_1pz9o_8 button"
data-kind="primary"
role="button"
@@ -106,7 +106,7 @@ exports[`AudioPlayerView renders the audio player in error state 1`] = `
<button
aria-disabled="false"
aria-label="Play"
aria-labelledby="«ri»"
aria-labelledby="_r_i_"
class="_icon-button_1pz9o_8 button"
data-kind="primary"
role="button"
@@ -202,7 +202,7 @@ exports[`AudioPlayerView renders the audio player without media name 1`] = `
<button
aria-disabled="false"
aria-label="Play"
aria-labelledby="«r6»"
aria-labelledby="_r_6_"
class="_icon-button_1pz9o_8 button"
data-kind="primary"
role="button"
@@ -293,7 +293,7 @@ exports[`AudioPlayerView renders the audio player without size 1`] = `
<button
aria-disabled="false"
aria-label="Play"
aria-labelledby="«rc»"
aria-labelledby="_r_c_"
class="_icon-button_1pz9o_8 button"
data-kind="primary"
role="button"

View File

@@ -5,7 +5,7 @@ exports[`PlayPauseButton renders the button in default state 1`] = `
<button
aria-disabled="false"
aria-label="Play"
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="_icon-button_1pz9o_8 button"
data-kind="primary"
role="button"
@@ -37,7 +37,7 @@ exports[`PlayPauseButton renders the button in playing state 1`] = `
<button
aria-disabled="false"
aria-label="Pause"
aria-labelledby="«r6»"
aria-labelledby="_r_6_"
class="_icon-button_1pz9o_8 button"
data-kind="primary"
role="button"

View File

@@ -9,7 +9,7 @@ import React from "react";
import { type Meta, type StoryFn } from "@storybook/react-vite";
import { TextualEventView as TextualEventComponent } from "./TextualEventView";
import { MockViewModel } from "../../MockViewModel";
import { MockViewModel } from "../../viewmodel/MockViewModel";
export default {
title: "Event/TextualEvent",

View File

@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
import React, { type ReactNode, type JSX } from "react";
import { type ViewModel } from "../../ViewModel";
import { type ViewModel } from "../../viewmodel/ViewModel";
import { useViewModel } from "../../useViewModel";
export type TextualEventViewSnapshot = {

View File

@@ -21,13 +21,12 @@ export * from "./utils/Box";
export * from "./utils/Flex";
// Utils
export * from "./utils/i18n";
export { setLanguage } from "./utils/i18n";
export * from "./utils/humanize";
export * from "./utils/DateUtils";
export * from "./utils/numbers";
// MVVM
export * from "./ViewWrapper";
export type * from "./ViewModel";
export * from "./viewmodel";
export * from "./useMockedViewModel";
export * from "./useViewModel";
export * from "./MockViewModel";

View File

@@ -11,12 +11,12 @@ exports[`Pill renders the pill 1`] = `
/>
<span
class="label"
id="«r0»"
id="_r_0_"
>
Pill
</span>
<button
aria-describedby="«r0»"
aria-describedby="_r_0_"
aria-label="Delete"
class="_icon-button_1pz9o_8"
data-kind="primary"
@@ -57,7 +57,7 @@ exports[`Pill renders the pill without close button 1`] = `
/>
<span
class="label"
id="«r1»"
id="_r_1_"
>
Pill
</span>

View File

@@ -11,12 +11,12 @@ exports[`RichItem renders the list 1`] = `
>
<span
class="title"
id="«r0»"
id="_r_0_"
>
Rich List Title
</span>
<ul
aria-labelledby="«r0»"
aria-labelledby="_r_0_"
class="content"
role="listbox"
tabindex="0"
@@ -174,7 +174,7 @@ exports[`RichItem renders the list with isEmpty=true 1`] = `
>
<span
class="title"
id="«r1»"
id="_r_1_"
>
Rich List Title
</span>

View File

@@ -0,0 +1,25 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
import { useMemo } from "react";
import { MockViewModel, type ViewModel } from "./viewmodel";
/**
* Hook helper to return a mocked view model created with the given snapshot and actions.
* This is useful for testing components in isolation with a mocked view model and allows to use primitive types in stories.
*
* @param snapshot
* @param actions
*/
export function useMockedViewModel<S, A>(snapshot: S, actions: A): ViewModel<S> & A {
return useMemo(() => {
const vm = new MockViewModel<S>(snapshot);
Object.assign(vm, actions);
return vm as unknown as ViewModel<S> & A;
}, [snapshot, actions]);
}

View File

@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
import { useSyncExternalStore } from "react";
import { type ViewModel } from "./ViewModel";
import { type ViewModel } from "./viewmodel/ViewModel";
/**
* A small wrapper around useSyncExternalStore to use a view model in a shared component view

View File

@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import { type ViewModel } from "../../../packages/shared-components/src/ViewModel";
import { type ViewModel } from "./ViewModel";
import { Disposables } from "./Disposables";
import { Snapshot } from "./Snapshot";
import { ViewModelSubscriptions } from "./ViewModelSubscriptions";

View File

@@ -0,0 +1,13 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
export * from "./BaseViewModel";
export * from "./Disposables";
export * from "./Snapshot";
export * from "./ViewModelSubscriptions";
export type * from "./ViewModel";
export * from "./MockViewModel";

View File

@@ -6,7 +6,7 @@ Please see LICENSE files in the repository root for full details.
import { EventEmitter } from "events";
import { Disposables } from "../../../src/viewmodels/base/Disposables";
import { Disposables } from "..";
describe("Disposable", () => {
it("isDisposed is true after dispose() is called", () => {

View File

@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import { Snapshot } from "../../../src/viewmodels/base/Snapshot";
import { Snapshot } from "..";
interface TestSnapshot {
key1: string;

View File

@@ -2333,6 +2333,17 @@ core-util-is@~1.0.0:
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
counterpart@^0.18.6:
version "0.18.6"
resolved "https://registry.yarnpkg.com/counterpart/-/counterpart-0.18.6.tgz#cf6b60d8ef99a4b44b8bf6445fa99b4bd1b2f9dd"
integrity sha512-cAIDAYbC3x8S2DDbvFEJ4TzPtPYXma25/kfAkfmprNLlkPWeX4SdUp1c2xklfphqCU3HnDaivR4R3BrAYf5OMA==
dependencies:
date-names "^0.1.11"
except "^0.1.3"
extend "^3.0.0"
pluralizers "^0.1.7"
sprintf-js "^1.0.3"
create-ecdh@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e"
@@ -2422,6 +2433,11 @@ cwd@^0.10.0:
find-pkg "^0.1.2"
fs-exists-sync "^0.1.0"
date-names@^0.1.11:
version "0.1.13"
resolved "https://registry.yarnpkg.com/date-names/-/date-names-0.1.13.tgz#c4358f6f77c8056e2f5ea68fdbb05f0bf1e53bd0"
integrity sha512-IxxoeD9tdx8pXVcmqaRlPvrXIsSrSrIZzfzlOkm9u+hyzKp5Wk/odt9O/gd7Ockzy8n/WHeEpTVJ2bF3mMV4LA==
de-indent@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
@@ -2738,10 +2754,10 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
eslint-plugin-storybook@^9.1.10:
version "9.1.10"
resolved "https://registry.yarnpkg.com/eslint-plugin-storybook/-/eslint-plugin-storybook-9.1.10.tgz#f65989fe1e769d9e56b65dfc0233a9c28b4f2c35"
integrity sha512-HAVQ9HTMydcFj5KjnzsETOwPe19eIViwRBhc47lvU04YEFTgEg2rlXN1xozxHUlQ+XkkoKYkIUYoqo7KgGhkIA==
eslint-plugin-storybook@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-storybook/-/eslint-plugin-storybook-10.0.0.tgz#da3ceb6887339048cc6b772109c82146e39e4af7"
integrity sha512-q2NdHr1cRSR+cZef02EQOwaKdQwO+cslaDUndqszIaitfjvR31BzvuU7DCSTSJNhhLUEa8svda/kARZhG/bn2Q==
dependencies:
"@typescript-eslint/utils" "^8.8.1"
@@ -2870,6 +2886,13 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4"
safe-buffer "^5.1.1"
except@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/except/-/except-0.1.3.tgz#98261c91958551536b44482238e9783fb73d292a"
integrity sha512-ouwgJavvMOTOfy0RE8NGQFAIoWh8ehJhkuxDyXxngMVTxTq7HGE7gZopZhqKFnu5lZLI+qQdtvJ8n03ehp7RJg==
dependencies:
indexof "0.0.1"
execa@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
@@ -2918,6 +2941,11 @@ exsolve@^1.0.7:
resolved "https://registry.yarnpkg.com/exsolve/-/exsolve-1.0.7.tgz#3b74e4c7ca5c5f9a19c3626ca857309fa99f9e9e"
integrity sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==
extend@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@@ -3449,6 +3477,11 @@ indent-string@^4.0.0:
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
indexof@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
integrity sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@@ -4994,6 +5027,11 @@ playwright@^1.14.0:
optionalDependencies:
fsevents "2.3.2"
pluralizers@^0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/pluralizers/-/pluralizers-0.1.7.tgz#8d38dd0a1b660e739b10ab2eab10b684c9d50142"
integrity sha512-mw6AejUiCaMQ6uPN9ObjJDTnR5AnBSmnHHy3uVTbxrSFSxO5scfwpTs8Dxyb6T2v7GSulhvOq+pm9y+hXUvtOA==
pngjs@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
@@ -5535,6 +5573,11 @@ spawnd@^5.0.0:
tree-kill "^1.2.2"
wait-port "^0.2.9"
sprintf-js@^1.0.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a"
integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"

View File

@@ -92,7 +92,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
css: `
/* The timestamp is of inconsistent width depending on the time the test runs at */
.mx_MessageTimestamp {
display: none !important;
visibility: hidden;
}
/* The MAB showing up on hover is not needed for the test */
.mx_MessageActionBar {

View File

@@ -124,11 +124,12 @@ test.describe("HTML Export", () => {
const zip = await extractZipFileToPath(zipPath, dirPath);
await page.goto(`file://${dirPath}/${Object.keys(zip.files)[0]}/messages.html`);
await expect(page).toMatchScreenshot("html-export.png", {
mask: [
// We need to mask the whole thing because the width of the time part changes
page.locator(".mx_TimelineSeparator"),
page.locator(".mx_MessageTimestamp"),
],
mask: [page.locator(".mx_TimelineSeparator")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
});
},
);

View File

@@ -138,7 +138,11 @@ test.describe("Editing", () => {
// Take a snapshot of the dialog
await expect(dialog).toMatchScreenshot("message-edit-history-dialog.png", {
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
});
{

View File

@@ -59,9 +59,11 @@ async function editMessage(page: Page, message: Locator, newMsg: string): Promis
}
const screenshotOptions = (page?: Page) => ({
mask: page ? [page.locator(".mx_MessageTimestamp")] : undefined,
// Hide the jump to bottom button in the timeline to avoid flakiness
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
.mx_JumpToBottomButton {
display: none !important;
}

View File

@@ -11,10 +11,12 @@ import fs from "node:fs";
import { test, expect } from "../../element-web-test";
const screenshotOptions = (page: Page) => ({
mask: [page.locator(".mx_MessageTimestamp")],
// Hide the jump to bottom button in the timeline to avoid flakiness
// Exclude timestamp and read marker from snapshot
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
.mx_JumpToBottomButton {
display: none !important;
}

View File

@@ -93,10 +93,12 @@ test.describe("permalinks", () => {
getPill(timeline, danielleId);
await expect(timeline).toMatchScreenshot("permalink-rendering.png", {
mask: [
// Exclude timestamps from the snapshot, for consistency.
page.locator(".mx_MessageTimestamp"),
],
// Exclude timestamps from the snapshot, for consistency.
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
});
});
});

View File

@@ -121,7 +121,11 @@ test.describe("Polls", () => {
.filter({ hasText: pollParams.title })
.getAttribute("data-scroll-tokens");
await expect(getPollTile(page, pollId)).toMatchScreenshot("Polls_Timeline_tile_no_votes.png", {
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
});
// Bot votes 'Maybe' in the poll
@@ -293,7 +297,11 @@ test.describe("Polls", () => {
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot(
"ThreadView_with_a_poll_on_bubble_layout.png",
{
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
},
);
@@ -303,7 +311,11 @@ test.describe("Polls", () => {
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot(
"ThreadView_with_a_poll_on_group_layout.png",
{
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
},
);

View File

@@ -126,7 +126,12 @@ test.describe("FilePanel", () => {
// Take a snapshot of file tiles list on FilePanel
await expect(filePanelMessageList).toMatchScreenshot("file-tiles-list.png", {
// Exclude timestamps & flaky seek bar from snapshot
mask: [page.locator(".mx_MessageTimestamp"), page.getByTestId("audio-player-seek")],
mask: [page.getByTestId("audio-player-seek")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
});
});

View File

@@ -31,8 +31,13 @@ test.describe("Preferences user settings tab", () => {
// Assert that the top heading is rendered
await expect(tab.getByRole("heading", { name: "Preferences" })).toBeVisible();
await expect(tab).toMatchScreenshot("Preferences-user-settings-tab-should-be-rendered-properly-1.png", {
// masked due to daylight saving time
// masked with fixed-width due to daylight saving time making the text content vary
mask: [tab.locator("#mx_dropdownUserTimezone_value")],
css: `
#mx_dropdownUserTimezone_value {
width: 200px;
}
`,
});
});

View File

@@ -361,7 +361,9 @@ test.describe("Sliding Sync", () => {
await expect(page.locator(".mx_ReplyPreview")).toBeVisible();
// now click on the permalink for Permalink me
await page.locator(".mx_EventTile").filter({ hasText: "Permalink me" }).locator("a").dispatchEvent("click");
const tile = page.locator(".mx_EventTile").filter({ hasText: "Permalink me" });
await tile.hover();
await tile.locator("a").dispatchEvent("click");
// make sure it is now selected with the little green |
await expect(page.locator(".mx_EventTile_selected").filter({ hasText: "Permalink me" })).toBeVisible();

View File

@@ -39,7 +39,12 @@ test.describe("Threads", () => {
const ThreadViewGroupSpacingStart = "56px"; // --ThreadView_group_spacing-start
// Exclude timestamp and read marker from snapshots
const mask = [page.locator(".mx_MessageTimestamp"), page.locator(".mx_MessagePanel_myReadMarker")];
const mask = [page.locator(".mx_MessagePanel_myReadMarker")];
const css = `
.mx_MessageTimestamp {
visibility: hidden;
}
`;
const roomViewLocator = page.locator(".mx_RoomView_body");
// User sends message
@@ -74,13 +79,15 @@ test.describe("Threads", () => {
// Take snapshots in group layout and bubble layout (IRC layout is not available on ThreadView)
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot("Initial_ThreadView_on_group_layout.png", {
mask: mask,
mask,
css,
});
await app.settings.setValue("layout", null, SettingLevel.DEVICE, Layout.Bubble);
await expect(page.locator(".mx_ThreadView .mx_EventTile[data-layout='bubble']")).toHaveCount(2);
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot("Initial_ThreadView_on_bubble_layout.png", {
mask: mask,
mask,
css,
});
// Set the group layout
@@ -154,7 +161,8 @@ test.describe("Threads", () => {
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot(
"ThreadView_with_reaction_and_a_hidden_event_on_group_layout.png",
{
mask: mask,
mask,
css,
},
);
@@ -178,7 +186,8 @@ test.describe("Threads", () => {
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot(
"ThreadView_with_reaction_and_a_hidden_event_on_bubble_layout.png",
{
mask: mask,
mask,
css,
},
);
@@ -214,7 +223,8 @@ test.describe("Threads", () => {
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot(
"ThreadView_with_redacted_messages_on_group_layout.png",
{
mask: mask,
mask,
css,
},
);
await app.settings.setValue("layout", null, SettingLevel.DEVICE, Layout.Bubble);
@@ -222,7 +232,8 @@ test.describe("Threads", () => {
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot(
"ThreadView_with_redacted_messages_on_bubble_layout.png",
{
mask: mask,
mask,
css,
},
);
@@ -445,7 +456,7 @@ test.describe("Threads", () => {
await expect(locator.locator(".mx_EventTile").last().getByText("Hello Mr. User")).toBeAttached();
});
test("navigate through right panel", async ({ page, app, user }) => {
test("navigate through right panel", { tag: "@screenshot" }, async ({ page, app, user }) => {
// Create room
const roomId = await app.client.createRoom({});
await page.goto("/#/room/" + roomId);
@@ -497,6 +508,9 @@ test.describe("Threads", () => {
await expect(
threadPanel.locator(".mx_EventTile_last").getByText("Hello again Mr. User in a thread"),
).toBeVisible();
await expect(threadPanel).toMatchScreenshot("thread-panel.png", {
css: ".mx_MessageTimestamp { visibility: hidden !important; }",
});
const rightPanel = page.locator(".mx_RightPanel");
// Check that the threads are listed

View File

@@ -181,8 +181,10 @@ test.describe("Timeline", () => {
await expect(gels.getByRole("button", { name: "Collapse" })).toBeVisible();
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot("expanded-gels-irc-layout.png", {
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}
@@ -215,8 +217,10 @@ test.describe("Timeline", () => {
await expect(gels.getByRole("button", { name: "Collapse" })).toBeVisible();
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot("expanded-gels-modern-layout.png", {
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}
@@ -255,7 +259,11 @@ test.describe("Timeline", () => {
// Save snapshot of expanded generic event list summary on bubble layout
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot("expanded-gels-bubble-layout.png", {
// Exclude timestamp from snapshot
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
});
// Click "collapse" link button on the first hovered info event line
@@ -271,7 +279,11 @@ test.describe("Timeline", () => {
// Save snapshot of collapsed generic event list summary on bubble layout
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot("collapsed-gels-bubble-layout.png", {
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
});
},
);
@@ -312,12 +324,14 @@ test.describe("Timeline", () => {
"event-line-inline-start-margin-irc-layout.png",
{
// Exclude timestamp and read marker from snapshot
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}
`,
.mx_MessageTimestamp {
visibility: hidden;
}
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}
`,
},
);
await expect(axe).toHaveNoViolations();
@@ -409,7 +423,11 @@ test.describe("Timeline", () => {
"collapsed-gels-and-messages-irc-layout.png",
{
// Exclude timestamp from snapshot of mx_MainSplit
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
},
);
@@ -428,7 +446,11 @@ test.describe("Timeline", () => {
"expanded-gels-and-messages-irc-layout.png",
{
// Exclude timestamp from snapshot of mx_MainSplit
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
},
);
@@ -453,7 +475,11 @@ test.describe("Timeline", () => {
"expanded-gels-redaction-placeholder.png",
{
// Exclude timestamp from snapshot of mx_MainSplit
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
},
);
@@ -481,7 +507,11 @@ test.describe("Timeline", () => {
// Record alignment of expanded GELS, placeholder of deleted message, and emote
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot("expanded-gels-emote-irc-layout.png", {
// Exclude timestamp from snapshot of mx_MainSplit
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
});
},
);
@@ -492,12 +522,14 @@ test.describe("Timeline", () => {
async ({ page, app, room }) => {
const screenshotOptions = {
// Hide because flaky - See https://github.com/vector-im/element-web/issues/24957
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}
`,
.mx_MessageTimestamp {
visibility: hidden;
}
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}
`,
};
await sendEvent(app.client, room.roomId);
@@ -605,12 +637,10 @@ test.describe("Timeline", () => {
await messageEdit(page);
// Click timestamp to highlight hidden event line
const timestamp = page.locator(".mx_RoomView_body .mx_EventTile_info a", {
has: page.locator(".mx_MessageTimestamp"),
});
const timestamp = page.locator(".mx_RoomView_body .mx_EventTile_info a.mx_MessageTimestamp");
// wait for the remote echo otherwise we get an error modal due to a 404 on the /event/ API
await expect(timestamp).not.toHaveAttribute("href", /~!/);
await timestamp.locator(".mx_MessageTimestamp").click();
await timestamp.click();
// should not add inline start padding to a hidden event line on IRC layout
await app.settings.setValue("layout", null, SettingLevel.DEVICE, Layout.IRC);
@@ -620,12 +650,14 @@ test.describe("Timeline", () => {
// Exclude timestamp and read marker from snapshot
const screenshotOptions = {
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}
`,
.mx_MessageTimestamp {
visibility: hidden;
}
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}
`,
};
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot(
@@ -654,7 +686,11 @@ test.describe("Timeline", () => {
// Exclude timestamp from snapshot
const screenshotOptions = {
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
};
await sendEvent(app.client, room.roomId);
@@ -795,8 +831,10 @@ test.describe("Timeline", () => {
await app.timeline.scrollToBottom();
await expect(page.locator(".mx_EventTile_last")).toMatchScreenshot("url-preview.png", {
// Exclude timestamp and read marker from snapshot
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}
@@ -892,7 +930,13 @@ test.describe("Timeline", () => {
const tile = page.locator(".mx_EventTile");
await expect(tile).toBeVisible();
await expect(tile).toMatchScreenshot("code-block.png", { mask: [page.locator(".mx_MessageTimestamp")] });
await expect(tile).toMatchScreenshot("code-block.png", {
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
});
// Edit a code block and assert the edited code block has been correctly rendered
await tile.hover();
@@ -904,7 +948,11 @@ test.describe("Timeline", () => {
const newTile = page.locator(".mx_EventTile");
await expect(newTile).toMatchScreenshot("edited-code-block.png", {
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
`,
});
});
@@ -1107,8 +1155,10 @@ test.describe("Timeline", () => {
// Exclude timestamp and read marker from snapshot
const screenshotOptions = {
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}
@@ -1233,12 +1283,14 @@ test.describe("Timeline", () => {
// Exclude timestamp and read marker from snapshot
const screenshotOptions = {
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}
`,
.mx_MessageTimestamp {
visibility: hidden;
}
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}
`,
};
// Make sure the strings do not overflow on IRC layout
@@ -1297,8 +1349,10 @@ test.describe("Timeline", () => {
// Exclude timestamp and read marker from snapshot
const screenshotOptions = {
mask: [page.locator(".mx_MessageTimestamp")],
css: `
.mx_MessageTimestamp {
visibility: hidden;
}
.mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker {
display: none !important;
}

View File

@@ -218,7 +218,7 @@ export class ElementAppPage {
*/
public async inviteUserToCurrentRoom(userId: string): Promise<void> {
await this.toggleRoomInfoPanel(); // TODO skip this if the room info panel is already open
await this.page.getByLabel("Right panel").getByRole("menuitem", { name: "Invite" }).click();
await this.page.getByTestId("right-panel").getByRole("menuitem", { name: "Invite" }).click();
const input = this.page.getByRole("dialog").getByTestId("invite-dialog-input");
await input.fill(userId);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 260 KiB

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Some files were not shown because too many files have changed in this diff Show More