Fix thread navigation in timeline (#12412)

* Remove thread dispatch action

* Add comment

* Add e2e test
pull/28217/head
Florian Duros 2024-04-12 11:07:57 +02:00 committed by GitHub
parent 77dfc1abee
commit aadb46358b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 70 additions and 10 deletions

View File

@ -447,4 +447,72 @@ test.describe("Threads", () => {
await expect(locator.locator(".mx_EventTile").first().getByText("Hello Mr. Bot")).toBeAttached();
await expect(locator.locator(".mx_EventTile").last().getByText("Hello Mr. User")).toBeAttached();
});
test("navigate through right panel", async ({ page, app, user }) => {
// Create room
const roomId = await app.client.createRoom({});
await page.goto("/#/room/" + roomId);
/**
* Send a message in the main timeline
* @param message
*/
const sendMessage = async (message: string) => {
const messageComposer = page.getByRole("region", { name: "Message composer" });
const textbox = messageComposer.getByRole("textbox", { name: "Send a message…" });
await textbox.fill(message);
await textbox.press("Enter");
};
/**
* Create a thread from the rootMessage and send a message in the thread
* @param rootMessage
* @param threadMessage
*/
const createThread = async (rootMessage: string, threadMessage: string) => {
// First create a thread
const roomViewBody = page.locator(".mx_RoomView_body");
const messageTile = roomViewBody
.locator(".mx_EventTile[data-scroll-tokens]")
.filter({ hasText: rootMessage });
await messageTile.hover();
await messageTile.getByRole("button", { name: "Reply in thread" }).click();
await expect(page.locator(".mx_ThreadView_timelinePanelWrapper")).toHaveCount(1);
// Send a message in the thread
const threadPanel = page.locator(".mx_ThreadPanel");
const textbox = threadPanel.getByRole("textbox", { name: "Send a message…" });
await textbox.fill(threadMessage);
await textbox.press("Enter");
await expect(threadPanel.locator(".mx_EventTile_last").getByText(threadMessage)).toBeVisible();
// Close thread
await threadPanel.getByRole("button", { name: "Close" }).click();
};
await sendMessage("Hello Mr. Bot");
await sendMessage("Hello again Mr. Bot");
await createThread("Hello Mr. Bot", "Hello Mr. User in a thread");
await createThread("Hello again Mr. Bot", "Hello again Mr. User in a thread");
// Open thread panel
await page.getByRole("button", { name: "Threads" }).click();
const threadPanel = page.locator(".mx_ThreadPanel");
await expect(
threadPanel.locator(".mx_EventTile_last").getByText("Hello again Mr. User in a thread"),
).toBeVisible();
// Open threads list
await threadPanel.getByRole("button", { name: "Threads" }).click();
const rightPanel = page.locator(".mx_RightPanel");
// Check that the threads are listed
await expect(rightPanel.locator(".mx_EventTile").getByText("Hello Mr. User in a thread")).toBeVisible();
await expect(rightPanel.locator(".mx_EventTile").getByText("Hello again Mr. User in a thread")).toBeVisible();
// Open the first thread
await rightPanel.locator(".mx_EventTile").getByText("Hello Mr. User in a thread").click();
await expect(rightPanel.locator(".mx_EventTile").getByText("Hello Mr. User in a thread")).toBeVisible();
await expect(
rightPanel.locator(".mx_EventTile").getByText("Hello again Mr. User in a thread"),
).not.toBeVisible();
});
});

View File

@ -707,6 +707,8 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
newState.initialEventPixelOffset = undefined;
const thread = initialEvent?.getThread();
// Handle the use case of a link to a thread message
// ie: #/room/roomId/eventId (eventId of a thread message)
if (thread?.rootEvent && !initialEvent?.isThreadRoot) {
dis.dispatch<ShowThreadPayload>({
action: Action.ShowThread,
@ -719,16 +721,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
newState.initialEventId = initialEventId;
newState.isInitialEventHighlighted = this.context.roomViewStore.isInitialEventHighlighted();
newState.initialEventScrollIntoView = this.context.roomViewStore.initialEventScrollIntoView();
if (thread?.rootEvent && initialEvent?.isThreadRoot) {
dis.dispatch<ShowThreadPayload>({
action: Action.ShowThread,
rootEvent: thread.rootEvent,
initialEvent,
highlighted: this.context.roomViewStore.isInitialEventHighlighted(),
scroll_into_view: this.context.roomViewStore.initialEventScrollIntoView(),
});
}
}
}