diff --git a/.github/workflows/podman.yml b/.github/workflows/podman.yml index 14e73b2df..efe2205cf 100644 --- a/.github/workflows/podman.yml +++ b/.github/workflows/podman.yml @@ -282,7 +282,7 @@ jobs: - name: Prune old images run: podman image prune -a -f - name: Check Podman images - run: podman-compose -f docker compose-deploy.yml ps + run: podman-compose -f docker-compose-deploy.yml ps e2e-acceptance: name: E2E tests on acceptance environment diff --git a/docker-compose.yaml b/docker-compose.yaml index 6ef61d3ae..90fb76bec 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,4 +1,4 @@ -# Docker-compose definition for development +# docker compose definition for development version: '2.4' 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/components/Circle/Circle.scss b/frontend/src/components/Circle/Circle.scss index 0e82be724..d9f0e20e4 100644 --- a/frontend/src/components/Circle/Circle.scss +++ b/frontend/src/components/Circle/Circle.scss @@ -3,20 +3,22 @@ margin-bottom: 15px; margin-top: 15px; - > svg, + >svg, .content { position: absolute; left: 0; top: 0; } - > svg { + >svg { @extend .circleIntro; } .circle-percentage { transition: stroke-dashoffset 0.1s linear; - transform: rotate(-90deg); - transform-origin: 50% 50%; + + // 102.5px is the radius of the circle + // translateX because the circle is rotated -90deg + transform: rotate(-90deg) translateX(calc(-102.5px * 2)); } } 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; 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 { diff --git a/frontend/src/stories/Circle.stories.jsx b/frontend/src/stories/Circle.stories.jsx index 746051a2a..14b4cb7c0 100644 --- a/frontend/src/stories/Circle.stories.jsx +++ b/frontend/src/stories/Circle.stories.jsx @@ -113,7 +113,7 @@ export const LongDuration = { radius: 100, strokeWidth: 5, color: "white", - duration: 30, + duration: 60, animateCircle: true, running: true, }, diff --git a/scripts/build-front b/scripts/build-front index fa7d48725..55c79114c 100755 --- a/scripts/build-front +++ b/scripts/build-front @@ -1,3 +1,2 @@ #!/bin/bash docker compose run --rm client yarn build - diff --git a/scripts/test-back b/scripts/test-back index e85bcb44b..9600c7a95 100755 --- a/scripts/test-back +++ b/scripts/test-back @@ -1,3 +1,2 @@ #!/bin/bash docker compose run --rm server bash -c "python manage.py test $@" - diff --git a/scripts/test-back-coverage b/scripts/test-back-coverage index 344636b72..0c9161475 100755 --- a/scripts/test-back-coverage +++ b/scripts/test-back-coverage @@ -1,3 +1,2 @@ #!/bin/bash docker compose run --rm server bash -c "coverage run manage.py test && coverage report --show-missing" - diff --git a/scripts/test-front b/scripts/test-front index 3815ce120..b85d425df 100755 --- a/scripts/test-front +++ b/scripts/test-front @@ -1,3 +1,2 @@ #!/bin/bash docker compose run --rm client yarn test --watch=false - diff --git a/scripts/test-front-watch b/scripts/test-front-watch index 2600ef7c9..ce5ac315b 100755 --- a/scripts/test-front-watch +++ b/scripts/test-front-watch @@ -1,3 +1,2 @@ #!/bin/bash docker compose run --rm client yarn test --watch=true -