Skip to content

Commit

Permalink
fix: Focus being forced on last message when interacting with mouse (#…
Browse files Browse the repository at this point in the history
…32187)

Co-authored-by: Guilherme Gazzo <[email protected]>
  • Loading branch information
dougfabris and ggazzo committed Apr 20, 2024
1 parent 8aaccf1 commit 8b28855
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/eleven-seas-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixes an issue that forces the focus on the last message when interacting by mouse on message list
18 changes: 9 additions & 9 deletions apps/meteor/client/views/room/hooks/useMessageListNavigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export const useMessageListNavigation = (): { messageListRef: RefCallback<HTMLEl
const messageListRef = useCallback(
(node: HTMLElement | null) => {
let lastMessageFocused: HTMLElement | null = null;
let triggeredByKeyboard = false;
let initialFocus = true;

if (!node) {
Expand Down Expand Up @@ -68,14 +67,15 @@ export const useMessageListNavigation = (): { messageListRef: RefCallback<HTMLEl

lastMessageFocused = document.activeElement as HTMLElement;
}

triggeredByKeyboard = true;
});

node.addEventListener(
'blur',
(e) => {
if (!triggeredByKeyboard || !(e.currentTarget instanceof HTMLElement && e.relatedTarget instanceof HTMLElement)) {
if (
!(e.relatedTarget as HTMLElement)?.classList.contains('focus-visible') ||
!(e.currentTarget instanceof HTMLElement && e.relatedTarget instanceof HTMLElement)
) {
return;
}

Expand All @@ -89,20 +89,20 @@ export const useMessageListNavigation = (): { messageListRef: RefCallback<HTMLEl
node.addEventListener(
'focus',
(e) => {
const triggeredByKeyboard = (e.target as HTMLElement)?.classList.contains('focus-visible');
if (!triggeredByKeyboard || !(e.currentTarget instanceof HTMLElement && e.relatedTarget instanceof HTMLElement)) {
return;
}

if (initialFocus) {
massageListFocusManager.focusLast({ accept: (node) => isListItem(node) });
lastMessageFocused = document.activeElement as HTMLElement;
initialFocus = false;
}

if (!triggeredByKeyboard || !(e.currentTarget instanceof HTMLElement && e.relatedTarget instanceof HTMLElement)) {
return;
}

if (lastMessageFocused && !e.currentTarget.contains(e.relatedTarget) && node.contains(e.target as HTMLElement)) {
lastMessageFocused?.focus();
lastMessageFocused = null;
triggeredByKeyboard = false;
}
},
{ capture: true },
Expand Down
28 changes: 27 additions & 1 deletion apps/meteor/tests/e2e/messaging.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,37 @@ test.describe.serial('Messaging', () => {
await poHomeChannel.sidenav.openChat(targetChannel);
await page.locator('[data-qa-type="message"]:has-text("msg1")').click();
await poHomeChannel.composer.click();
await page.locator('[data-qa-type="message"]:has-text("msg2")').click();
await page.keyboard.press('Shift+Tab');

await expect(page.locator('[data-qa-type="message"]:has-text("msg2")')).toBeFocused();
});

test('should not focus on the last message when focusing by click', async ({ page }) => {
await poHomeChannel.sidenav.openChat(targetChannel);
await page.locator('[data-qa-type="message"]:has-text("msg1")').click();

await expect(page.locator('[data-qa-type="message"]').last()).not.toBeFocused();
});

test('should focus on the recent message when moving the focus on the list and theres no previous focus', async ({ page }) => {
await poHomeChannel.sidenav.openChat(targetChannel);
await page.getByRole('button', { name: targetChannel }).first().focus();

// move focus to the list
await page.keyboard.press('Tab');
await page.keyboard.press('Tab');
await page.keyboard.press('Tab');
await expect(page.locator('[data-qa-type="message"]').last()).toBeFocused();

await page.getByRole('button', { name: targetChannel }).first().click();

// move focus to the list again
await page.keyboard.press('Tab');
await page.keyboard.press('Tab');
await page.keyboard.press('Tab');
await expect(page.locator('[data-qa-type="message"]').last()).toBeFocused();
});

test('expect show "hello word" in both contexts (targetChannel)', async ({ browser }) => {
await poHomeChannel.sidenav.openChat(targetChannel);
const { page } = await createAuxContext(browser, Users.user2);
Expand Down

0 comments on commit 8b28855

Please sign in to comment.