From e349d4f45b1f31aa89d418926ef29a4f31762c89 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Thu, 16 Sep 2021 11:27:23 +0300 Subject: [PATCH] Media Viewer: Fix pinch-to-zoom in PWA (#1428) --- src/components/main/Main.tsx | 4 +-- src/hooks/usePreventIosPinchZoom.ts | 21 ------------- src/hooks/usePreventPinchZoomGesture.ts | 40 +++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 23 deletions(-) delete mode 100644 src/hooks/usePreventIosPinchZoom.ts create mode 100644 src/hooks/usePreventPinchZoomGesture.ts diff --git a/src/components/main/Main.tsx b/src/components/main/Main.tsx index a14b350d..24b7738d 100644 --- a/src/components/main/Main.tsx +++ b/src/components/main/Main.tsx @@ -27,7 +27,7 @@ import useShowTransition from '../../hooks/useShowTransition'; import useBackgroundMode from '../../hooks/useBackgroundMode'; import useBeforeUnload from '../../hooks/useBeforeUnload'; import useOnChange from '../../hooks/useOnChange'; -import usePreventIosPinchZoom from '../../hooks/usePreventIosPinchZoom'; +import usePreventPinchZoomGesture from '../../hooks/usePreventPinchZoomGesture'; import { processDeepLink } from '../../util/deeplink'; import { LOCATION_HASH } from '../../hooks/useHistoryBack'; @@ -228,7 +228,7 @@ const Main: FC = ({ useBackgroundMode(handleBlur, handleFocus); useBeforeUnload(handleBlur); - usePreventIosPinchZoom(isMediaViewerOpen); + usePreventPinchZoomGesture(isMediaViewerOpen); function stopEvent(e: React.MouseEvent) { e.preventDefault(); diff --git a/src/hooks/usePreventIosPinchZoom.ts b/src/hooks/usePreventIosPinchZoom.ts deleted file mode 100644 index 63c19d50..00000000 --- a/src/hooks/usePreventIosPinchZoom.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { useEffect } from '../lib/teact/teact'; -import { IS_IOS } from '../util/environment'; - -export default function usePreventIosPinchZoom(isDisabled = false) { - // Disable viewport zooming on iOS Safari - useEffect(() => { - if (!IS_IOS || isDisabled) { - return undefined; - } - - document.addEventListener('gesturestart', preventEvent); - - return () => { - document.removeEventListener('gesturestart', preventEvent); - }; - }, [isDisabled]); -} - -function preventEvent(e: Event) { - e.preventDefault(); -} diff --git a/src/hooks/usePreventPinchZoomGesture.ts b/src/hooks/usePreventPinchZoomGesture.ts new file mode 100644 index 00000000..d4cfc9e0 --- /dev/null +++ b/src/hooks/usePreventPinchZoomGesture.ts @@ -0,0 +1,40 @@ +import { useEffect } from '../lib/teact/teact'; +import { IS_IOS, IS_PWA, IS_TOUCH_ENV } from '../util/environment'; + +const metaViewport = document.querySelector('meta[name="viewport"]'); +const defaultViewportContent = metaViewport?.getAttribute('content') || ''; + +export default function usePreventPinchZoomGesture(isDisabled = false) { + useEffect(() => { + if (!IS_TOUCH_ENV) { + return undefined; + } + + if (isDisabled) { + // Clean viewport content from values values that disable the ability to zoom a webpage + // https://web.dev/meta-viewport/ + metaViewport?.setAttribute('content', 'width=device-width, initial-scale=1, shrink-to-fit=no'); + return undefined; + } + + metaViewport?.setAttribute('content', defaultViewportContent); + + // Since iOS 10 `user-scaleable=no` is disabled in Safari for iOS, + // this is only applicable for the browser and does not apply to the PWA mode. + // https://newbedev.com/how-do-you-disable-viewport-zooming-on-mobile-safari + if (IS_IOS && !IS_PWA) { + document.addEventListener('gesturestart', preventEvent); + } + + return () => { + metaViewport?.setAttribute('content', 'width=device-width, initial-scale=1, shrink-to-fit=no'); + if (IS_IOS && !IS_PWA) { + document.removeEventListener('gesturestart', preventEvent); + } + }; + }, [isDisabled]); +} + +function preventEvent(e: Event) { + e.preventDefault(); +}