Skip to content

Commit 6b7c808

Browse files
committed
[FIX] Spreadsheet: fix scroll on ios
When opening a spreadsheet and scrolling towards the bottom of the sheet, the "default" behaviour of ios which is to have some sort of wobble when we scrolled all the way down, is triggered. It should not occur when scrolling inside the grid. closes #7514 Task: 5270869 X-original-commit: 83c393f Signed-off-by: Pierre Rousseau (pro) <pro@odoo.com>
1 parent 1a9de79 commit 6b7c808

File tree

5 files changed

+56
-19
lines changed

5 files changed

+56
-19
lines changed

src/components/dashboard/dashboard.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,19 @@ export class SpreadsheetDashboard extends Component<Props, SpreadsheetChildEnv>
6363
});
6464
this.cellPopovers = useStore(CellPopoverStore);
6565

66-
useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
67-
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
68-
return scrollY > 0;
69-
});
66+
useTouchScroll(
67+
this.gridRef,
68+
this.moveCanvas.bind(this),
69+
() => {
70+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
71+
return scrollY > 0;
72+
},
73+
() => {
74+
const { maxOffsetY } = this.env.model.getters.getMaximumSheetOffset();
75+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
76+
return scrollY < maxOffsetY;
77+
}
78+
);
7079
}
7180

7281
get gridContainer() {

src/components/grid/grid.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,19 @@ export class Grid extends Component<Props, SpreadsheetChildEnv> {
196196
() => [this.sidePanel.isMainPanelOpen, this.sidePanel.isSecondaryPanelOpen]
197197
);
198198

199-
useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
200-
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
201-
return scrollY > 0;
202-
});
199+
useTouchScroll(
200+
this.gridRef,
201+
this.moveCanvas.bind(this),
202+
() => {
203+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
204+
return scrollY > 0;
205+
},
206+
() => {
207+
const { maxOffsetY } = this.env.model.getters.getMaximumSheetOffset();
208+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
209+
return scrollY < maxOffsetY;
210+
}
211+
);
203212
}
204213

205214
get highlights() {

src/components/helpers/touch_scroll_hook.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ export const resetTimeoutDuration = 100;
1010

1111
export function useTouchScroll(
1212
ref: Ref<HTMLElement>,
13-
1413
updateScroll: (offsetX: number, offsetY: number) => void,
15-
16-
canMoveUp: () => boolean
14+
canMoveUp: () => boolean,
15+
canMoveDown: () => boolean
1716
) {
1817
let lastX = 0;
1918
let lastY = 0;
@@ -57,13 +56,13 @@ export function useTouchScroll(
5756
lastX = clientX;
5857
lastY = clientY;
5958
lastTime = currentTime;
60-
61-
if (canMoveUp()) {
59+
if ((deltaY < 0 && canMoveUp()) || (deltaY > 0 && canMoveDown())) {
6260
if (event.cancelable) {
6361
event.preventDefault();
6462
}
6563
event.stopPropagation();
6664
}
65+
6766
resetTimeout = setTimeout(() => {
6867
velocityX = 0;
6968
velocityY = 0;

src/plugins/ui_stateful/sheetview.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export class SheetViewPlugin extends UIPlugin {
109109
"getFigureUI",
110110
"getPositionAnchorOffset",
111111
"getGridOffset",
112+
"getMaximumSheetOffset",
112113
] as const;
113114

114115
private viewports: Record<UID, SheetViewports | undefined> = {};
@@ -396,7 +397,7 @@ export class SheetViewPlugin extends UIPlugin {
396397
return { x, y, width, height };
397398
}
398399

399-
private getMaximumSheetOffset(): { maxOffsetX: Pixel; maxOffsetY: Pixel } {
400+
getMaximumSheetOffset(): { maxOffsetX: Pixel; maxOffsetY: Pixel } {
400401
const sheetId = this.getters.getActiveSheetId();
401402
const { width, height } = this.getMainViewportRect();
402403
const viewport = this.getMainInternalViewport(sheetId);

tests/grid/grid_component.test.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ describe("Grid component", () => {
264264
expect(getVerticalScroll()).toBe(50);
265265
});
266266

267-
test("Event is stopped if not at the top", async () => {
267+
test("Event is stopped if not at the top when scrolling upwards", async () => {
268268
const grid = fixture.querySelector(".o-grid-overlay")!;
269269
expect(getHorizontalScroll()).toBe(0);
270270
expect(getVerticalScroll()).toBe(0);
@@ -273,16 +273,35 @@ describe("Grid component", () => {
273273
fixture.addEventListener("touchmove", mockCallback);
274274

275275
triggerTouchEvent(grid, "touchstart", { clientX: 0, clientY: 150, identifier: 1 });
276-
// move down; we are at the top: ev not prevented
276+
// move down; we are at the top: ev is prevented
277277
triggerTouchEvent(grid, "touchmove", { clientX: 0, clientY: 120, identifier: 2 });
278-
expect(mockCallback).toBeCalledTimes(1);
278+
expect(mockCallback).toBeCalledTimes(0);
279279
jest.advanceTimersByTime(10);
280280
// move up:; we are not at the top: ev prevented
281281
triggerTouchEvent(grid, "touchmove", { clientX: 0, clientY: 150, identifier: 3 });
282-
expect(mockCallback).toBeCalledTimes(1);
282+
expect(mockCallback).toBeCalledTimes(0);
283283
// move up again but we are at the stop: ev not prevented
284284
triggerTouchEvent(grid, "touchmove", { clientX: 0, clientY: 150, identifier: 4 });
285-
expect(mockCallback).toBeCalledTimes(2);
285+
expect(mockCallback).toBeCalledTimes(1);
286+
});
287+
288+
test("Event is stopped if not at the top when scrolling downwards", async () => {
289+
const grid = fixture.querySelector(".o-grid-overlay")!;
290+
const { maxOffsetY } = model.getters.getMaximumSheetOffset();
291+
expect(getHorizontalScroll()).toBe(0);
292+
expect(getVerticalScroll()).toBe(0);
293+
294+
const mockCallback = jest.fn(() => {});
295+
fixture.addEventListener("touchmove", mockCallback);
296+
297+
triggerTouchEvent(grid, "touchstart", { clientX: 0, clientY: maxOffsetY + 10, identifier: 1 });
298+
// move down, to scroll all the way down; ev is prevented
299+
triggerTouchEvent(grid, "touchmove", { clientX: 0, clientY: 10, identifier: 2 });
300+
expect(mockCallback).toBeCalledTimes(0);
301+
jest.advanceTimersByTime(10);
302+
// move down again, we are at the bottom: ev prevented
303+
triggerTouchEvent(grid, "touchmove", { clientX: 0, clientY: 0, identifier: 3 });
304+
expect(mockCallback).toBeCalledTimes(1);
286305
});
287306

288307
test("Double clicking only opens composer when actually targetting grid overlay", async () => {

0 commit comments

Comments
 (0)