Refactor MFileBody using MVVM and move to shared-components (#32730)

* Refactor MFileBody using MVVM and move to shared component

* Simplyfing rendering properties

* Create a first version of view model for the component

* Simplifying component properties and make it possible to override module css using data-* attributes

* Create a MBodyFactory in element-web and use it to render MFileBodyView from MessageEvent

* Use <MediaBody instead of <button to support legacy rendering

* Updated styling and comments

* Refactoring className from snapshot to component property

* Rename MFileBody* to FileBody*

* Rename MFileBody* to FileBody*

* Refactoring render branches to allow for displaying nothing

* Fix styling issues

* Fix lint errors

* Fix for css selectors in playwright tests

* Remove the MFileBody component and change all callers to use MBodyFactory:FileBodyView

* Remove unused strings in element-web

* Revert to render text in story iframes

* Fix for prettier error

* Fix playwright test css selectors

* Apply legacy styling in element-web

* Add legacy styling for mx_MFileBody

* Restore file

* Change from <div to <button

* Calculate span width ad update screenshots

* Remove width calculation and update snapshots

* Fix for letter-spacing and better content in story

* Updated playwright screenshots

* Updated snapshots

* Fixing Sonar errors/warnings

* Removed extra parentheses

* Changes after review

* Change border-radius to px and updated snapshots

* Fix typo in description

* And another typo fix

* Changes after review
This commit is contained in:
rbondesson
2026-03-16 08:47:23 +00:00
committed by GitHub
parent 394356c4df
commit d791e3fe8a
46 changed files with 2316 additions and 695 deletions
@@ -245,9 +245,9 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
await expect(tile.getByRole("region", { name: "Audio player" })).toBeVisible();
// Assert that replied audio file is rendered as file button inside ReplyChain
const button = tile.locator(".mx_ReplyChain_wrapper .mx_MFileBody_info[role='button']");
const button = tile.locator(".mx_ReplyChain_wrapper .mx_MFileBody [role='button']");
// Assert that the file button has file name
await expect(button.locator(".mx_MFileBody_info_filename")).toBeVisible();
await expect(button.locator("span")).toBeVisible();
await takeSnapshots(page, app, "Selected EventTile of audio player with a reply");
},
@@ -307,9 +307,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
// Assert that the file button contains the name of the file sent at first
await expect(
replyChain
.locator(".mx_MFileBody_info[role='button']")
.locator(".mx_MFileBody_info_filename", { hasText: "upload-first.ogg" }),
replyChain.locator(".mx_MFileBody [role='button']").locator("span", { hasText: "upload-first.ogg" }),
).toBeVisible();
// Take snapshots
@@ -357,9 +355,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
const composer = thread.locator(".mx_MessageComposer--compact");
// Assert that the reply preview contains audio ReplyTile the file info button
await expect(
composer.locator(".mx_ReplyPreview .mx_ReplyTile .mx_MFileBody_info[role='button']"),
).toBeVisible();
await expect(composer.locator(".mx_ReplyPreview .mx_ReplyTile .mx_MFileBody [role='button']")).toBeVisible();
// Select :smile: emoji and send it
await composer.getByTestId("basicmessagecomposer").fill(":smile:");
@@ -367,6 +363,6 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
await composer.getByTestId("basicmessagecomposer").press("Enter");
// Assert that the file name is rendered on the file button
await expect(threadTile.locator(".mx_ReplyTile .mx_MFileBody_info[role='button']")).toBeVisible();
await expect(threadTile.locator(".mx_ReplyTile .mx_MFileBody [role='button']")).toBeVisible();
});
});