From 978e4db2a2c310b8987a2554d4acc956d9273fec Mon Sep 17 00:00:00 2001 From: Drikus Roor Date: Tue, 24 Sep 2024 15:20:01 +0200 Subject: [PATCH 1/2] feat: Add useDisableIOSPinchZoomOnTouchDevices hook This commit adds a new hook called useDisableIOSPinchZoomOnTouchDevices to the frontend codebase. The hook is responsible for preventing pinch zoom gestures on iOS devices. It is used in the App component to disable pinch zoom on touch devices. --- frontend/src/components/App/App.tsx | 2 ++ ...eDisableIOSPinchZoomOnTouchDevices.test.ts | 36 +++++++++++++++++++ .../useDisableIOSPinchZoomOnTouchDevices.ts | 20 +++++++++++ 3 files changed, 58 insertions(+) create mode 100644 frontend/src/hooks/useDisableIOSPinchZoomOnTouchDevices.test.ts create mode 100644 frontend/src/hooks/useDisableIOSPinchZoomOnTouchDevices.ts diff --git a/frontend/src/components/App/App.tsx b/frontend/src/components/App/App.tsx index dadbe8a40..bc89cc405 100644 --- a/frontend/src/components/App/App.tsx +++ b/frontend/src/components/App/App.tsx @@ -18,6 +18,7 @@ import Profile from "../Profile/Profile"; import Reload from "../Reload/Reload"; import StoreProfile from "../StoreProfile/StoreProfile"; import useDisableRightClickOnTouchDevices from "../../hooks/useDisableRightClickOnTouchDevices"; +import useDisableIOSPinchZoomOnTouchDevices from "@/hooks/useDisableIOSPinchZoomOnTouchDevices"; import { InternalRedirect } from "../InternalRedirect/InternalRedirect"; import Helmet from "@/components/Helmet/Helmet"; @@ -31,6 +32,7 @@ const App = () => { const queryParams = window.location.search; useDisableRightClickOnTouchDevices(); + useDisableIOSPinchZoomOnTouchDevices(); useEffect(() => { const urlParams = new URLSearchParams(queryParams); diff --git a/frontend/src/hooks/useDisableIOSPinchZoomOnTouchDevices.test.ts b/frontend/src/hooks/useDisableIOSPinchZoomOnTouchDevices.test.ts new file mode 100644 index 000000000..f94e1fdd2 --- /dev/null +++ b/frontend/src/hooks/useDisableIOSPinchZoomOnTouchDevices.test.ts @@ -0,0 +1,36 @@ +import { vi, describe, test, expect, afterEach } from "vitest"; +import { renderHook } from "@testing-library/react-hooks"; +import { waitFor } from "@testing-library/react"; +import useDisableIOSPinchZoomOnTouchDevices from "./useDisableIOSPinchZoomOnTouchDevices"; + +describe("useDisableIOSPinchZoomOnTouchDevices", () => { + afterEach(() => { + vi.unstubAllGlobals(); + }); + + test("should prevent gesturestart on touch devices", async () => { + vi.stubGlobal("ontouchstart", true); + + const mockEvent = new Event('gesturestart'); + mockEvent.preventDefault = vi.fn(); + + const spy = vi.spyOn(mockEvent, 'preventDefault').mockImplementation(() => { }); + + renderHook(() => useDisableIOSPinchZoomOnTouchDevices()); + + await waitFor(() => document.dispatchEvent(mockEvent)); + await waitFor(() => expect(spy).toHaveBeenCalledTimes(1)); + }); + + test("should not prevent gesturestart on non-touch devices", () => { + const mockEvent = new Event('gesturestart'); + mockEvent.preventDefault = vi.fn(); + + const spy = vi.spyOn(mockEvent, 'preventDefault').mockImplementation(() => { }); + + renderHook(() => useDisableIOSPinchZoomOnTouchDevices()); + + document.dispatchEvent(mockEvent); + expect(spy).not.toHaveBeenCalled(); + }); +}); diff --git a/frontend/src/hooks/useDisableIOSPinchZoomOnTouchDevices.ts b/frontend/src/hooks/useDisableIOSPinchZoomOnTouchDevices.ts new file mode 100644 index 000000000..aa607aa14 --- /dev/null +++ b/frontend/src/hooks/useDisableIOSPinchZoomOnTouchDevices.ts @@ -0,0 +1,20 @@ +import { useEffect } from 'react'; + +const useDisableIOSPinchZoomOnTouchDevices = () => useEffect(() => { + const isTouchDevice = () => !!('ontouchstart' in window || !!(navigator.maxTouchPoints)); + + const handlePinchZoom = (event: Event) => { + if (isTouchDevice()) { + event.preventDefault(); + } + }; + + document.addEventListener('gesturestart', handlePinchZoom); + + return () => { + document.removeEventListener('gesturestart', handlePinchZoom); + }; +}, []); + + +export default useDisableIOSPinchZoomOnTouchDevices; From 8ef253d9a3ec2fdb914069b6288ab19851c4bc37 Mon Sep 17 00:00:00 2001 From: Drikus Roor Date: Tue, 24 Sep 2024 15:20:06 +0200 Subject: [PATCH 2/2] feat: Add touch-action property to disable pinch zoom on iOS --- frontend/src/scss/layout.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/scss/layout.scss b/frontend/src/scss/layout.scss index 728cd0dba..3221346ed 100644 --- a/frontend/src/scss/layout.scss +++ b/frontend/src/scss/layout.scss @@ -6,6 +6,9 @@ body.root { background-position: center center; background-repeat: no-repeat; min-height: 100vh; + + /* disable pinch zoom on iOS */ + touch-action: manipulation; } #root {