Room list: fix scrolling with touch device (#34381)
* Fix touchscreen scroll room list * Add unit tests
This commit is contained in:
+48
@@ -197,6 +197,54 @@ describe("<VirtualizedRoomListView />", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("pointer drag activation", () => {
|
||||
beforeEach(() => {
|
||||
(Sections.args.changeRoomSection as any).mockClear?.();
|
||||
});
|
||||
|
||||
it("does not start a drag when a finger moves (touch scrolling the list)", async () => {
|
||||
// For touch, dragging only activates after a 250ms hold; moving the finger first aborts
|
||||
// it so the list scrolls instead of dragging a room. Simulate a finger press that moves
|
||||
// immediately (as when scrolling) and assert no drag ever starts.
|
||||
const user = userEvent.setup();
|
||||
renderWithMockContext(<Sections />);
|
||||
|
||||
const status = screen.getByRole("status");
|
||||
const roomButton = await screen.findByRole("button", { name: "Open room General" });
|
||||
|
||||
await user.pointer([
|
||||
{ keys: "[TouchA>]", target: roomButton, coords: { x: 20, y: 20 } },
|
||||
{ pointerName: "TouchA", coords: { x: 20, y: 140 } },
|
||||
{ keys: "[/TouchA]" },
|
||||
]);
|
||||
|
||||
expect(status).toHaveTextContent("");
|
||||
expect(Sections.args.changeRoomSection).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("starts a drag when the mouse moves past the activation distance", async () => {
|
||||
// For mouse, dragging activates as soon as the pointer moves past 5px, so the same
|
||||
// press-and-move gesture that scrolls on touch drags the room into another section.
|
||||
const user = userEvent.setup();
|
||||
renderWithMockContext(<Sections />);
|
||||
|
||||
const status = screen.getByRole("status");
|
||||
const roomButton = await screen.findByRole("button", { name: "Open room General" });
|
||||
|
||||
await user.pointer([
|
||||
{ keys: "[MouseLeft>]", target: roomButton, coords: { x: 20, y: 20 } },
|
||||
{ coords: { x: 20, y: 140 } },
|
||||
]);
|
||||
|
||||
// The drag has activated: the live region reflects the ongoing drag.
|
||||
await waitFor(() => expect(status).toHaveTextContent("General"));
|
||||
|
||||
await user.pointer({ keys: "[/MouseLeft]" }); // release to drop
|
||||
|
||||
await waitFor(() => expect(Sections.args.changeRoomSection).toHaveBeenCalled());
|
||||
});
|
||||
});
|
||||
|
||||
describe("scrollToSectionTag", () => {
|
||||
it("skips scroll when scrollToSectionTag does not match any section", () => {
|
||||
const roomListState = {
|
||||
|
||||
+10
-3
@@ -600,10 +600,17 @@ export function VirtualizedRoomListView({ vm, renderAvatar, onKeyDown }: Virtual
|
||||
}
|
||||
}}
|
||||
sensors={[
|
||||
// By default, the PointerSensor activates dragging immediately on pointer down, which interferes with keyboard navigation.
|
||||
// So we start dragging after the pointer has moved by 5 pixels, to allow for click without dragging
|
||||
// By default, PointerSensor activates dragging immediately on mouse pointer down, which interferes
|
||||
// with clicking a room and keyboard navigation, so for mouse/pen we require a small drag distance
|
||||
// before a drag starts (allowing a plain click without dragging).
|
||||
// For touch, a Delay constraint that aborts the drag if the finger moves before the delay elapses is used to avoid accidental drags when scrolling the list with a finger.
|
||||
PointerSensor.configure({
|
||||
activationConstraints: [new PointerActivationConstraints.Distance({ value: 5 })],
|
||||
activationConstraints(event) {
|
||||
if (event.pointerType === "touch") {
|
||||
return [new PointerActivationConstraints.Delay({ value: 250, tolerance: 5 })];
|
||||
}
|
||||
return [new PointerActivationConstraints.Distance({ value: 5 })];
|
||||
},
|
||||
}),
|
||||
// By default, the KeyboardSensor uses both space and enter to start dragging, which interferes with the keyboard enter shortcut to open a room.
|
||||
KeyboardSensor.configure({
|
||||
|
||||
Reference in New Issue
Block a user