1
0
mirror of https://github.com/element-hq/element-web.git synced 2026-10-28 00:13:00 +03:00

15 Commits

Author SHA1 Message Date
Zack
eab262dba4 Add a Markdown viewer for .md attachments in the right panel (#35203)
* Add marked

* Add the markdown viewer lab

* Add the markdown viewer right panel phase

* Add the open markdown viewer action

* Detect markdown attachments

* Render markdown to sanitized HTML

* Add DocumentViewerView

* Build the PDF viewer on DocumentViewerView

* Add MarkdownViewerView

* Add the markdown viewer

* Show markdown attachments in the right panel

* Pick the attachment viewer in one place

* Offer to open markdown attachments from the timeline

* Put both document viewers behind one lab

* Drop the per-viewer lab flags

* Update snapshots

* Render markdown attachments with the message parser

* Drop marked

* Update snapshot

* Keep the PDF viewer lab key for the shared lab

* Add a document viewer registry with one media handle

* Open every document through one right panel card

* Type the lazy viewer loaders explicitly

* Show an error when a document can no longer be opened
2026-10-02 09:07:46 +00:00
Michael Telatynski
6d644ffe78 Remove legacy Module & Customisation API (#33941)
* Remove legacy Module & Customisation API

in favour of the new runtime modules system

* Delint

* Remove unused i18n string

* Fix tests

* Fix test

* Fix tests

* Iterate

* Fix bad merge

* Bump Module API version

* Bump module-api compatibility ranges

* Update docs

* Fix semver ranges

* Update test module API version

* Too many versions

* Too many versions again
2026-09-11 13:32:48 +00:00
Zack
dce3902a1b Implement PDF viewer to the current filepreview behind labs (#34928)
* Reopen the right panel when the current card is given new state

setCard's "same phase, new state" branch swapped the state of the card at
the top of the history but left the panel's own isOpen alone. If the panel
had been closed, the card was updated behind it and nothing appeared, so
the action looked like it had done nothing.

Show the panel in that branch, as the other two branches already do.

Also drop the unguarded index into a possibly empty history while we are
here: a matching phase can only have come from this room's own history, so
guard on it rather than trusting `hist[hist.length - 1]` to exist.

* Add a PDF viewer to the right panel

Open a PDF attachment in the right panel instead of having to download it
first. The viewer is pdf.js, rendering continuously with fit-to-width zoom,
pinch and ctrl-wheel zoom, and a page selector; the reading position is
remembered per file so reopening a document comes back where you left off.

The file body gains an optional "open" control next to download, which the
view model only asks for on PDFs shown as files in a timeline — not in an
export, and not in the download-only panels. FileBodyView renders nothing
for it otherwise, so every other file body is unchanged.

Encrypted attachments work unchanged: the handle the viewer is given reads
the bytes through MediaEventHelper's sourceBlob, which decrypts first.

The card stores only the source event id, so a restored panel re-derives
the media and drops the card if the event is no longer in the room.

* Add icon into the container instead of outside.

* Update translate + new images

* Load the right panel store lazily when opening a PDF

utils/pdfViewer is reached from the message body view models, and importing
RightPanelStore from it closed a cycle back to the message bodies:

  utils/pdfViewer -> RightPanelStore -> SDKContextClass -> LegacyCallHandler
    -> utils/notifications -> Unread -> EventTileFactory -> MessageEvent
    -> MVoiceOrAudioBody -> MVoiceMessageBody -> extends MAudioBody

MVoiceMessageBody evaluated `extends MAudioBody` while MAudioBody was still
initialising, so the whole MAudioBody suite failed to load with "Class
extends value undefined is not a constructor or null".

Pull the store in through a dynamic import instead, as StoresApi already
does for the room list store. Nothing else under views/messages or
viewmodels imports RightPanelStore, which is what kept this cycle closed
until now.

openPdfViewer becomes async as a result; the click handler fires it with
`void` since opening the panel is not something the caller waits on.

* Code split the PDF viewer behind Suspense

Importing PdfViewer from the card put pdf.js into every module graph that
reaches the right panel, so RoomView pulled it in and the Jest suites failed
to parse it:

  SyntaxError: Cannot use 'import.meta' outside a module

pdf.js locates its worker with `new URL(..., import.meta.url)`, which Jest
cannot compile, since it transpiles to CJS. That took out ExtrasApi-test and
anything else reaching RoomView.

Load the viewer with React.lazy instead, as the beacon components already do
for maplibre-gl. pdf.js is large and of no use until someone opens a PDF, so
keeping it out of the main bundle is worth doing on its own account; the Jest
suites stop seeing it as a side effect.

* Put the PDF viewer behind a lab

Ship the viewer disabled by default, as feature_pdf_viewer under the
Messaging group in Labs, alongside the other flags that change how message
content renders.

Two gates:

 - FileBodyViewModel leads showOpen with the flag, and showInlineDownload
   follows it, so with the lab off the file pill renders exactly as it did
   before: attachment icon, file name, no actions.

 - RightPanelStore drops a stored PdfViewer card when the flag is off, ahead
   of the check for a displayable event. Without it, someone who had a PDF
   open when they turned the lab off would get the viewer back on reload.

The existing "drops a PdfViewer card with no event to display" test now
enables the lab first; the gate had made it pass for the wrong reason.

* Drop the brand name from the PDF viewer lab

The i18n check forbids hardcoding "Element" in translations, since the brand
is configurable, and "Open PDFs in Element" tripped it:

  "labs|pdf_viewer": contains forbidden hardcoded word

Keys that genuinely need the brand are allow-listed in the i18n job, but this
one does not: the label reads fine without it, and naming a panel the viewer
happens to use is the description's job anyway.

* Update card header to show file name + change edit icon to expend icon on filepreview

* Update storybook images to reflect new icon

* Update apps/web/src/viewmodels/message-body/FileBodyViewModel.ts

Co-authored-by: Will Hunt <2072976+Half-Shot@users.noreply.github.com>

* Removed @link as it did not go anywhere.

* Drop the self-referential @link in PdfViewerState docs

* Comment why the file tile actions are hidden in forward previews

* Test the RightPanel PdfViewer phase renders the viewer card

* Take the PDF viewer lab as a prop on FileBodyViewModel

* Dispatch an action to open the PDF viewer instead of importing the store

* Check the PDF signature before parsing the attachment

* MVVM PDF Viewer

* Fix Sonar

* Cap decoded image size and pin XFA off when opening a PDF

* Update apps/web/src/i18n/strings/en_EN.json

Co-authored-by: Will Hunt <2072976+Half-Shot@users.noreply.github.com>

* Use the real SettingsStore for the PDF viewer lab in tests

* Read the PDF viewer lab in the view, not the view model

* Declare the mock viewer's page field with the others

* Use the minified pdf.js worker

* Allow clicking on links in the PDF.

* Force use of a PDF worker

* Reduce logging noise.

* Cap PDF size

* Check blob size too

* Add support for clicking links in the canvas

* Report file size

* Tests

* cleanup

---------

Co-authored-by: Will Hunt <2072976+Half-Shot@users.noreply.github.com>
Co-authored-by: Half-Shot <will@half-shot.uk>
2026-09-10 13:12:54 +00:00
Michael Telatynski
b51c5ed8a7 Tweak oxlint config & delint our code (#34301)
* Remove stale max-len disablements

* Remove stale camelCase & naming-convention disablements

* Remove stale ban-ts-comment disablements

* Remove stale no-var disablements

* Remove stale no-empty-property disablements

* Remove stale react rule disablements

* Remove stale no-constant-condition disablements

* Remove stale no-unused-vars disablements

* Remove stale disablements for disabled rules

* fixup camelcase

* Remove dead code

* Tidy code

* Tweak oxlint config
2026-07-17 07:55:31 +00:00
Michael Telatynski
04fac0a9a4 Update find-unused-settings script (#34252)
* Move more tests over to vitest

* Add exception for test_setting

* Update find-unused-settings script

To not consider usage in tests as real usage

* Remove legacy font settings

They have been being migrated for over 2 years at this point and are flagged by the script as unused

* Re-add test
2026-07-15 10:21:49 +00:00
Michael Telatynski
dc33d736a0 Handle SDKContextClass client initialisation internally (#34146)
* Handle SDKContextClass `client` initialisation internally

Rather than via MatrixChat - this is predominantly for Lifecycle tests as they don't use a MatrixChat and it doesn't make much sense for this component to own this state.

* Fix tests
2026-07-06 16:09:21 +00:00
David Baker
ff8329be09 Take client creating functionality out of MatrixClientPeg (#34092)
* Take client creating functionality out of MatrixClientPeg

Because all sorts of things import MatrixClientPeg and this means
they pull in all manner of things related to creating a client, when
all they need is to get the current one (and specifically it fixes
the import cycle that means I can't add my test).

* Remove fake indexeddb

as it seems like the tests didn't actually see the fake indexeddb before
(somehow) but now do, and are failing because they have that but no postmessage.
It feels like the right solution is for these tests to not need indexeddb.

* Don't mock a refresh token

The tests don't mock out enough for the token refreshing setup to work,
it wa somehow always ending up as null previously and now wasn't, at which
point it broke, so just make it actually unset.

* Move formatter instatiation to lazy

rather than eagerly at parse time, as this apparently shifted one
test to hit this import cycle instead.

* Tests for room name generator
2026-07-03 15:21:59 +00:00
Michael Telatynski
45234b9c94 Migrate more jest tests to vitest (#33898)
* Migrate more jest tests to vitest

* Fix jest config

* Fix jest config

* Make remaining jest tests type-happy
2026-06-19 15:34:18 +00:00
Michael Telatynski
486fa57b68 [Labs] Sign in with QR on new EW using generated QR for MSC4108 v2024 (#33184)
* PoC Sign in with QR on new EW using generated QR for MSC4108 v2024

* Revert package.json changes

* Prettier

* Fix i18n

* Tidy up

* Remove unused state variable

* Iterate tests

* Partial revert

* Iterate

* Wire up qr_login route

* Iterate UI

* Fix React dev mode double rendering issue

* Fix react key warning

* Hide flow header on login

* Re-roll qr code on channel expiry

* Switch to AbortSignal

* Improve auto-retry QR UX

* Ensure we only show sign in with QR button if enabled

* XXX: enable labs flag on Netlify builds

* Tweak QR code sizing

* Move qr login flow into a dialog to match designs

* Fix null deviceId

* Remove duplicate log

* Iterate

* Fix tests

* Fix types

* Fix tests

* Fix tests

* Make Netlify more useful

* Make Netlify more useful v2

* Update copy

* Refactor QR link flow to use new SDK methods

Requires https://github.com/matrix-org/matrix-js-sdk/pull/5283
For element-hq/wat-internal#188
Split out from https://github.com/element-hq/element-web/pull/33184

* Link to js-sdk branch

* Update tests

* Simplify

* Revert js-sdk linking

* Iterate

* Iterate

* Refactor to handle most of the TODOs

* Remove unused code

* Remove unused code

* Use js-sdk isSignInWithQRAvailable API to simplify code

* Restore app-test.ts

* Improve coverage

* Improve coverage

* Remove unused prop/state

* Iterate

* Fix tests

* Iterate

* Tests

* Handle TODOs

* Docs

* Remove redundant call to crossSignDevice()

* Workaround to remove training slash on the serverName before auto-discovery

* Revert "Workaround to remove training slash on the serverName before auto-discovery"

This reverts commit 0335a8fdd1.

* setLoggedIn not to be used with OIDC flows as it clears storage

as per docs on setLoggedIn we should use restoreSessionFromStorage

* Don't show the security_code_prompt unconditionally(i.e. for the web logging in mobile flow)

* Update LoginWithQRFlow-test.tsx.snap

* Update MatrixChat-test from setLoggedInSpy to restoreSessionSpy

* Add todo for server switch

* Add todo about handling base URL or server name

* Handle server name or base URL being returned

* Format

* Fix loading state height

* Handle the homeserver URL differing during QR code login

* Comments

* Comments

* Register OIDC client ID after homeserver swap

* Make QrLoginDialog async to minimise the impact on bundle size

* Handle unsupported HS earlier in the flow

* Iterate

* Delint

* Fix test

* Discard changes to apps/web/element.io/develop/config.json

---------

Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
Co-authored-by: David Langley <langley.dave@gmail.com>
2026-06-04 13:50:17 +00:00
Will Hunt
02b6520f09 Module API for adding new file upload mechanisms (#33355)
* Initial reword of upload to MVVM.

* Update tests

* More incremental improvements

* Refactor tests to use helper method for composer uploads.

* Add drag and drop tests

* lint

* Add commentary

* fixup test

* More precise selector

* Retarget uploads

* lint

* fixup

* one more type

* update snap

* Fixup composerUploadFiles

* fix import

* lint

* Copy and paste fixes too

* Add tests for pasting

* Add tests for pasting files.

* Remove redundant fn

* rm comment

* tidy up

* Test cleanup

* More clean up

* another fix

* Begin fleshing out

* Park changes

* More stuff

* Use condensed version

* Cleanup tests

* more cleaning

* last bity

* Add a test for the composer

* Park up changes

* Rewrite Measured to be a functional component

* Add tests to cover narrow viewports

* lint

* breakpoint is optional

* Cleanup

* Support narrow mode

* fixup

* begone

* Provide default value

* add label

* fixup test

* update copyright

* cleanup

* Be a bit more lazy with FileDropTarget

* remove a debug statement

* Fixup

* fix two snaps

* Update screenshot

* and the other one

* Update snaps

* unfake CIDER

* update screens again

* remove extra test

* Undo accidental snapshots

* Bit of tidyup

* fixup

* even more tidyup

* may drag and drop file

* tidy up again

* snap snap snap

* Use load to make sonarQube happy

* Bunch of refactors

* More cleanup

* cleanup debug code

* tweaks

* remove a test we no longer need

* make it happy

* fix import

* fixup

* Update snaps

* typo

* one off

* Add tests

* lint

* remove only

* Reduce screenshot scope

* fix snapshot usage

* cleanup
2026-05-18 21:41:38 +00:00
Florian Duros
c2e5aa7adc Room list: add collapse/expand all sections (#33318)
* chore: update compound design tokens

* feat(sc): add collapse/expand button to room list header

* feat: add new events to broadcast section state

* feat(vm): add expand/collpase event to room list events

* test: add e2e tests

* chore: fix company name in copyright

* chore: use two differant actions for collapse/expand

* Update apps/web/src/viewmodels/room-list/RoomListHeaderViewModel.ts

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>

* test: fix existing tests

---------

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-30 14:32:43 +00:00
Michael Telatynski
5ff302539e Harden settings types (#33311)
* Harden settings types

* Fix types

* Update apps/web/src/emojipicker/recent.ts

Co-authored-by: Will Hunt <2072976+Half-Shot@users.noreply.github.com>

* Fix suggestion

---------

Co-authored-by: Will Hunt <2072976+Half-Shot@users.noreply.github.com>
2026-04-29 08:46:09 +00:00
Will Hunt
2ea0c4106b Add Module Composer API (#33284)
* Spec composer API

* Add composer api implementation

* Tests

* Copyright

* update sigs

* cleanup

* a snap

* cleanup

* linting

* Tidy up

* Adjust
2026-04-27 10:33:20 +00:00
Will Hunt
89fb388e57 Fix invite-specific join errors not being shown (#32621)
* Fix invite-specific join errors not being shown

* remove horrible non-jest function of getAccountData

* Use an Error

* Always dispatch an Error

* Throw a UserFriendlyError
2026-02-27 11:01:51 +00:00
Michael Telatynski
91a3cb03c1 mv element.io @types __mocks__/ debian docker module_system/ playwright res src test webapp Dockerfile .dockerignore .eslintignore .stylelintrc.cjs babel.config.cjs recorder-worklet-loader.cjs .modernizr.json components.json config.json config.sample.json package.json project.json tsconfig.json tsconfig.module_system.json jest.config.ts playwright.config.ts webpack.config.ts build_config.sample.yaml apps/web/
mkdir apps/web/scripts
mv scripts/{cleanup.sh,ci_package.sh,copy-res.ts,deploy.py,package.sh} apps/web/scripts

And a couple of gitignore tweaks

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2026-02-24 15:43:58 +00:00