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>
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
`,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
`,
|
||||
});
|
||||
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
`,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
`,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
`,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
@@ -13,13 +13,14 @@ Please see LICENSE files in the repository root for full details.
|
||||
}
|
||||
|
||||
.mx_MessageTimestamp {
|
||||
color: var(--MessageTimestamp-color);
|
||||
color: var(--MessageTimestamp-color) !important; /* override anchor color */
|
||||
font-size: $font-10px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
display: block; /* enable the width setting below */
|
||||
width: var(--MessageTimestamp-width);
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.mx_MessageTimestamp_lateIcon {
|
||||
|
||||
@@ -200,10 +200,6 @@ $left-gutter: 64px;
|
||||
Replaces margin-top: -6px. This interacts better with a read
|
||||
marker being in between. Content overflows. */
|
||||
height: 1px;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.mx_EventTile_highlight,
|
||||
@@ -273,9 +269,9 @@ $left-gutter: 64px;
|
||||
align-items: flex-start;
|
||||
padding-top: 0;
|
||||
|
||||
> a {
|
||||
text-decoration: none; /* timestamps are links which shouldn't be underlined */
|
||||
.mx_MessageTimestamp {
|
||||
min-width: var(--MessageTimestamp-width); /* ensure space for EventTile without timestamp */
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
> * {
|
||||
@@ -403,10 +399,6 @@ $left-gutter: 64px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mx_MessageTimestamp {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.mx_EditMessageComposer_buttons {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,10 @@ Please see LICENSE files in the repository root for full details.
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
&[data-layout="irc"] .mx_MessageTimestamp {
|
||||
display: none; /* hide the container used for spacing consistency */
|
||||
}
|
||||
|
||||
.mx_EventTile_line {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import MessageContextMenu from "../context_menus/MessageContextMenu";
|
||||
import { aboveLeftOf } from "../../structures/ContextMenu";
|
||||
import MessageTimestamp from "../messages/MessageTimestamp";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { formatFullDate } from "../../../DateUtils";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import { type RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
|
||||
@@ -457,18 +456,15 @@ export default class ImageView extends React.Component<IProps, IState> {
|
||||
const senderName = mxEvent.sender?.name ?? mxEvent.getSender();
|
||||
const sender = <div className="mx_ImageView_info_sender">{senderName}</div>;
|
||||
const messageTimestamp = (
|
||||
<a
|
||||
<MessageTimestamp
|
||||
href={permalink}
|
||||
onClick={this.onPermalinkClicked}
|
||||
aria-label={formatFullDate(new Date(mxEvent.getTs()), showTwelveHour, false)}
|
||||
>
|
||||
<MessageTimestamp
|
||||
showFullDate={true}
|
||||
showTwelveHour={showTwelveHour}
|
||||
ts={mxEvent.getTs()}
|
||||
showSeconds={false}
|
||||
/>
|
||||
</a>
|
||||
showFullDate={true}
|
||||
showTwelveHour={showTwelveHour}
|
||||
ts={mxEvent.getTs()}
|
||||
showSeconds={false}
|
||||
inhibitTooltip
|
||||
/>
|
||||
);
|
||||
const avatar = (
|
||||
<MemberAvatar
|
||||
|
||||
@@ -24,6 +24,24 @@ interface IProps {
|
||||
showFullDate?: boolean;
|
||||
showSeconds?: boolean;
|
||||
showRelative?: boolean;
|
||||
|
||||
/**
|
||||
* If set to true then no tooltip will be shown
|
||||
*/
|
||||
inhibitTooltip?: boolean;
|
||||
|
||||
/**
|
||||
* If specified, will be rendered as an anchor bearing the href, a `span` element will be used otherwise
|
||||
*/
|
||||
href?: string;
|
||||
/**
|
||||
* Optional onClick handler to attach to the DOM element
|
||||
*/
|
||||
onClick?: React.MouseEventHandler<HTMLElement>;
|
||||
/**
|
||||
* Optional onContextMenu handler to attach to the DOM element
|
||||
*/
|
||||
onContextMenu?: React.MouseEventHandler<HTMLElement>;
|
||||
}
|
||||
|
||||
export default class MessageTimestamp extends React.Component<IProps> {
|
||||
@@ -52,12 +70,41 @@ export default class MessageTimestamp extends React.Component<IProps> {
|
||||
icon = <LateIcon className="mx_MessageTimestamp_lateIcon" width="16" height="16" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip description={label} caption={caption}>
|
||||
<span className="mx_MessageTimestamp" aria-hidden={true} aria-live="off">
|
||||
let content;
|
||||
if (this.props.href) {
|
||||
content = (
|
||||
<a
|
||||
href={this.props.href}
|
||||
onClick={this.props.onClick}
|
||||
onContextMenu={this.props.onContextMenu}
|
||||
className="mx_MessageTimestamp"
|
||||
aria-live="off"
|
||||
>
|
||||
{icon}
|
||||
{timestamp}
|
||||
</a>
|
||||
);
|
||||
} else {
|
||||
content = (
|
||||
<span
|
||||
onClick={this.props.onClick}
|
||||
onContextMenu={this.props.onContextMenu}
|
||||
className="mx_MessageTimestamp"
|
||||
aria-hidden={true}
|
||||
aria-live="off"
|
||||
tabIndex={this.props.onClick || !this.props.inhibitTooltip ? 0 : undefined}
|
||||
>
|
||||
{icon}
|
||||
{timestamp}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.inhibitTooltip) return content;
|
||||
|
||||
return (
|
||||
<Tooltip description={label} caption={caption}>
|
||||
{content}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ import ReplyChain from "../elements/ReplyChain";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import { Layout } from "../../../settings/enums/Layout";
|
||||
import { formatTime } from "../../../DateUtils";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import { DecryptionFailureBody } from "../messages/DecryptionFailureBody";
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
@@ -253,6 +252,7 @@ interface IState {
|
||||
reactions?: Relations | null | undefined;
|
||||
|
||||
hover: boolean;
|
||||
focusWithin: boolean;
|
||||
|
||||
// Position of the context menu
|
||||
contextMenu?: {
|
||||
@@ -299,6 +299,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
||||
declare public context: React.ContextType<typeof RoomContext>;
|
||||
|
||||
private unmounted = false;
|
||||
private readonly id = uniqueId();
|
||||
|
||||
public constructor(props: EventTileProps, context: React.ContextType<typeof RoomContext>) {
|
||||
super(props, context);
|
||||
@@ -316,6 +317,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
||||
reactions: this.getReactions(),
|
||||
|
||||
hover: false,
|
||||
focusWithin: false,
|
||||
|
||||
thread,
|
||||
};
|
||||
@@ -922,7 +924,6 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
||||
public render(): ReactNode {
|
||||
const msgtype = this.props.mxEvent.getContent().msgtype;
|
||||
const eventType = this.props.mxEvent.getType();
|
||||
const id = uniqueId();
|
||||
|
||||
const {
|
||||
hasRenderer,
|
||||
@@ -1122,6 +1123,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
||||
(this.props.alwaysShowTimestamps ||
|
||||
this.props.last ||
|
||||
this.state.hover ||
|
||||
this.state.focusWithin ||
|
||||
this.state.actionBarFocused ||
|
||||
Boolean(this.state.contextMenu));
|
||||
|
||||
@@ -1135,20 +1137,32 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
||||
ts = this.props.mxEvent.getTs();
|
||||
}
|
||||
|
||||
const messageTimestamp = (
|
||||
const messageTimestampProps = {
|
||||
showRelative: this.context.timelineRenderingType === TimelineRenderingType.ThreadsList,
|
||||
showTwelveHour: this.props.isTwelveHour,
|
||||
ts,
|
||||
receivedTs: getLateEventInfo(this.props.mxEvent)?.received_ts,
|
||||
};
|
||||
const messageTimestamp = <MessageTimestamp {...messageTimestampProps} />;
|
||||
const linkedMessageTimestamp = (
|
||||
<MessageTimestamp
|
||||
showRelative={this.context.timelineRenderingType === TimelineRenderingType.ThreadsList}
|
||||
showTwelveHour={this.props.isTwelveHour}
|
||||
ts={ts}
|
||||
receivedTs={getLateEventInfo(this.props.mxEvent)?.received_ts}
|
||||
{...messageTimestampProps}
|
||||
href={permalink}
|
||||
onClick={this.onPermalinkClicked}
|
||||
onContextMenu={this.onTimestampContextMenu}
|
||||
/>
|
||||
);
|
||||
|
||||
const timestamp = showTimestamp && ts ? messageTimestamp : null;
|
||||
const useIRCLayout = this.props.layout === Layout.IRC;
|
||||
// Used to simplify the UI layout where necessary by not conditionally rendering an element at the start
|
||||
const dummyTimestamp = useIRCLayout ? <span className="mx_MessageTimestamp" /> : null;
|
||||
const timestamp = showTimestamp && ts ? messageTimestamp : dummyTimestamp;
|
||||
const linkedTimestamp =
|
||||
timestamp !== dummyTimestamp && !this.props.hideTimestamp ? linkedMessageTimestamp : dummyTimestamp;
|
||||
|
||||
let pinnedMessageBadge: JSX.Element | undefined;
|
||||
if (PinningUtils.isPinned(MatrixClientPeg.safeGet(), this.props.mxEvent)) {
|
||||
pinnedMessageBadge = <PinnedMessageBadge aria-describedby={id} tabIndex={0} />;
|
||||
pinnedMessageBadge = <PinnedMessageBadge aria-describedby={this.id} tabIndex={0} />;
|
||||
}
|
||||
|
||||
let reactionsRow: JSX.Element | undefined;
|
||||
@@ -1165,21 +1179,8 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
||||
// If we have reactions or a pinned message badge, we need a footer
|
||||
const hasFooter = Boolean((reactionsRow && this.state.reactions) || pinnedMessageBadge);
|
||||
|
||||
const linkedTimestamp = !this.props.hideTimestamp ? (
|
||||
<a
|
||||
href={permalink}
|
||||
onClick={this.onPermalinkClicked}
|
||||
aria-label={formatTime(new Date(this.props.mxEvent.getTs()), this.props.isTwelveHour)}
|
||||
onContextMenu={this.onTimestampContextMenu}
|
||||
>
|
||||
{timestamp}
|
||||
</a>
|
||||
) : null;
|
||||
|
||||
const useIRCLayout = this.props.layout === Layout.IRC;
|
||||
const groupTimestamp = !useIRCLayout ? linkedTimestamp : null;
|
||||
const ircTimestamp = useIRCLayout ? linkedTimestamp : null;
|
||||
const bubbleTimestamp = this.props.layout === Layout.Bubble ? messageTimestamp : undefined;
|
||||
const groupPadlock = !useIRCLayout && !isBubbleMessage && this.renderE2EPadlock();
|
||||
const ircPadlock = useIRCLayout && !isBubbleMessage && this.renderE2EPadlock();
|
||||
|
||||
@@ -1210,7 +1211,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
||||
forExport={this.props.forExport}
|
||||
permalinkCreator={this.props.permalinkCreator}
|
||||
layout={this.props.layout}
|
||||
alwaysShowTimestamps={this.props.alwaysShowTimestamps || this.state.hover}
|
||||
alwaysShowTimestamps={this.props.alwaysShowTimestamps || this.state.hover || this.state.focusWithin}
|
||||
isQuoteExpanded={isQuoteExpanded}
|
||||
setQuoteExpanded={this.setQuoteExpanded}
|
||||
getRelationsForEvent={this.props.getRelationsForEvent}
|
||||
@@ -1237,13 +1238,20 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
||||
"data-event-id": this.props.mxEvent.getId(),
|
||||
"onMouseEnter": () => this.setState({ hover: true }),
|
||||
"onMouseLeave": () => this.setState({ hover: false }),
|
||||
"onFocus": () => this.setState({ focusWithin: true }),
|
||||
"onBlur": () => this.setState({ focusWithin: false }),
|
||||
},
|
||||
[
|
||||
<div className="mx_EventTile_senderDetails" key="mx_EventTile_senderDetails">
|
||||
{avatar}
|
||||
{sender}
|
||||
</div>,
|
||||
<div id={id} className={lineClasses} key="mx_EventTile_line" onContextMenu={this.onContextMenu}>
|
||||
<div
|
||||
id={this.id}
|
||||
className={lineClasses}
|
||||
key="mx_EventTile_line"
|
||||
onContextMenu={this.onContextMenu}
|
||||
>
|
||||
{this.renderContextMenu()}
|
||||
{replyChain}
|
||||
{renderTile(TimelineRenderingType.Thread, {
|
||||
@@ -1260,9 +1268,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
||||
showHiddenEvents: this.context.showHiddenEvents,
|
||||
})}
|
||||
{actionBar}
|
||||
<a href={permalink} onClick={this.onPermalinkClicked}>
|
||||
{timestamp}
|
||||
</a>
|
||||
{linkedTimestamp}
|
||||
{msgOption}
|
||||
</div>,
|
||||
hasFooter && (
|
||||
@@ -1294,6 +1300,8 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
||||
"data-has-reply": !!replyChain,
|
||||
"onMouseEnter": () => this.setState({ hover: true }),
|
||||
"onMouseLeave": () => this.setState({ hover: false }),
|
||||
"onFocus": () => this.setState({ focusWithin: true }),
|
||||
"onBlur": () => this.setState({ focusWithin: false }),
|
||||
"onClick": (ev: MouseEvent) => {
|
||||
const target = ev.currentTarget as HTMLElement;
|
||||
let index = -1;
|
||||
@@ -1425,13 +1433,20 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
||||
"data-has-reply": !!replyChain,
|
||||
"onMouseEnter": () => this.setState({ hover: true }),
|
||||
"onMouseLeave": () => this.setState({ hover: false }),
|
||||
"onFocus": () => this.setState({ focusWithin: true }),
|
||||
"onBlur": () => this.setState({ focusWithin: false }),
|
||||
},
|
||||
<>
|
||||
{ircTimestamp}
|
||||
{sender}
|
||||
{ircPadlock}
|
||||
{avatar}
|
||||
<div id={id} className={lineClasses} key="mx_EventTile_line" onContextMenu={this.onContextMenu}>
|
||||
<div
|
||||
id={this.id}
|
||||
className={lineClasses}
|
||||
key="mx_EventTile_line"
|
||||
onContextMenu={this.onContextMenu}
|
||||
>
|
||||
{this.renderContextMenu()}
|
||||
{groupTimestamp}
|
||||
{groupPadlock}
|
||||
@@ -1442,7 +1457,6 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
|
||||
// overrides
|
||||
ref: this.tile,
|
||||
isSeeingThroughMessageHiddenForModeration,
|
||||
timestamp: bubbleTimestamp,
|
||||
|
||||
// appease TS
|
||||
highlights: this.props.highlights,
|
||||
|
||||
@@ -64,7 +64,6 @@ export interface EventTileTypeProps
|
||||
| "inhibitInteraction"
|
||||
> {
|
||||
ref?: React.RefObject<any>; // `any` because it's effectively impossible to convince TS of a reasonable type
|
||||
timestamp?: JSX.Element;
|
||||
maxImageHeight?: number; // pixels
|
||||
overrideBodyTypes?: Record<string, React.ComponentType<IBodyProps>>;
|
||||
overrideEventTypes?: Record<string, React.ComponentType<IBodyProps>>;
|
||||
@@ -288,7 +287,6 @@ export function renderTile(
|
||||
callEventGrouper,
|
||||
getRelationsForEvent,
|
||||
isSeeingThroughMessageHiddenForModeration,
|
||||
timestamp,
|
||||
inhibitInteraction,
|
||||
showHiddenEvents,
|
||||
} = props;
|
||||
@@ -336,7 +334,6 @@ export function renderTile(
|
||||
callEventGrouper,
|
||||
getRelationsForEvent,
|
||||
isSeeingThroughMessageHiddenForModeration,
|
||||
timestamp,
|
||||
inhibitInteraction,
|
||||
showHiddenEvents,
|
||||
}),
|
||||
|
||||
@@ -25,6 +25,8 @@ import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||
import { searchPagination, SearchScope } from "../../../../src/Searching";
|
||||
import { SdkContextClass } from "../../../../src/contexts/SDKContext";
|
||||
import SettingsStore from "../../../../src/settings/SettingsStore.ts";
|
||||
import { SettingLevel } from "../../../../src/settings/SettingLevel.ts";
|
||||
|
||||
jest.mock("../../../../src/Searching", () => ({
|
||||
searchPagination: jest.fn(),
|
||||
@@ -438,6 +440,7 @@ describe("<RoomSearchView/>", () => {
|
||||
});
|
||||
|
||||
it("should pass appropriate permalink creator for all rooms search", async () => {
|
||||
await SettingsStore.setValue("alwaysShowTimestamps", null, SettingLevel.DEVICE, true);
|
||||
const room2 = new Room("!room2:server", client, client.getSafeUserId());
|
||||
const room3 = new Room("!room3:server", client, client.getSafeUserId());
|
||||
mocked(client.getRoom).mockImplementation(
|
||||
|
||||
@@ -29,6 +29,7 @@ describe("MessageTimestamp", () => {
|
||||
aria-hidden="true"
|
||||
aria-live="off"
|
||||
class="mx_MessageTimestamp"
|
||||
tabindex="0"
|
||||
>
|
||||
08:09
|
||||
</span>
|
||||
|
||||
@@ -97,7 +97,7 @@ exports[`<LayoutSwitcher /> should render 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="mx_EventTile_line"
|
||||
id="4"
|
||||
id="1"
|
||||
>
|
||||
<div
|
||||
class="mx_MTextBody mx_EventTile_content"
|
||||
@@ -224,7 +224,7 @@ exports[`<LayoutSwitcher /> should render 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="mx_EventTile_line"
|
||||
id="5"
|
||||
id="2"
|
||||
>
|
||||
<div
|
||||
class="mx_MTextBody mx_EventTile_content"
|
||||
@@ -324,6 +324,9 @@ exports[`<LayoutSwitcher /> should render 1`] = `
|
||||
data-self="true"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="mx_MessageTimestamp"
|
||||
/>
|
||||
<div
|
||||
class="mx_DisambiguatedProfile"
|
||||
>
|
||||
@@ -351,7 +354,7 @@ exports[`<LayoutSwitcher /> should render 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="mx_EventTile_line"
|
||||
id="6"
|
||||
id="3"
|
||||
>
|
||||
<div
|
||||
class="mx_MTextBody mx_EventTile_content"
|
||||
|
||||
@@ -467,6 +467,9 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
|
||||
data-self="true"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="mx_MessageTimestamp"
|
||||
/>
|
||||
<div
|
||||
class="mx_DisambiguatedProfile"
|
||||
>
|
||||
|
||||