mirror of https://github.com/vector-im/riot-web
Fix thread navigation in timeline (#12412)
* Remove thread dispatch action * Add comment * Add e2e testpull/28217/head
parent
77dfc1abee
commit
aadb46358b
|
@ -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").first().getByText("Hello Mr. Bot")).toBeAttached();
|
||||||
await expect(locator.locator(".mx_EventTile").last().getByText("Hello Mr. User")).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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -707,6 +707,8 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||||
newState.initialEventPixelOffset = undefined;
|
newState.initialEventPixelOffset = undefined;
|
||||||
|
|
||||||
const thread = initialEvent?.getThread();
|
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) {
|
if (thread?.rootEvent && !initialEvent?.isThreadRoot) {
|
||||||
dis.dispatch<ShowThreadPayload>({
|
dis.dispatch<ShowThreadPayload>({
|
||||||
action: Action.ShowThread,
|
action: Action.ShowThread,
|
||||||
|
@ -719,16 +721,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||||
newState.initialEventId = initialEventId;
|
newState.initialEventId = initialEventId;
|
||||||
newState.isInitialEventHighlighted = this.context.roomViewStore.isInitialEventHighlighted();
|
newState.isInitialEventHighlighted = this.context.roomViewStore.isInitialEventHighlighted();
|
||||||
newState.initialEventScrollIntoView = this.context.roomViewStore.initialEventScrollIntoView();
|
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(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue