From 2b5df908271d23f8b690c3298c812afe44fc6b30 Mon Sep 17 00:00:00 2001 From: Botzy Date: Tue, 25 Feb 2025 11:40:34 +0200 Subject: [PATCH 1/5] feat(useWindowSize): added hook for screen size --- src/common/index.js | 2 ++ src/common/useWindowSize.js | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/common/useWindowSize.js diff --git a/src/common/index.js b/src/common/index.js index 4acf8b056..ab3723cd0 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -24,6 +24,7 @@ const { default: useShell } = require('./useShell'); const useStreamingServer = require('./useStreamingServer'); const useTorrent = require('./useTorrent'); const useTranslate = require('./useTranslate'); +const useWindowSize = require('./useWindowSize'); module.exports = { FileDropProvider, @@ -55,4 +56,5 @@ module.exports = { useStreamingServer, useTorrent, useTranslate, + useWindowSize, }; diff --git a/src/common/useWindowSize.js b/src/common/useWindowSize.js new file mode 100644 index 000000000..9f7285261 --- /dev/null +++ b/src/common/useWindowSize.js @@ -0,0 +1,18 @@ +// Copyright (C) 2017-2025 Smart code 203358507 + +const { useState, useEffect } = require('react'); + +const useWindowSize = () => { + const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight }); + + useEffect(() => { + const handleResize = () => setSize({ width: window.innerWidth, height: window.innerHeight }); + + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); + + return size; +}; + +module.exports = useWindowSize; From b563ea1d10e24bc21f35af69cfec4fb98fed382e Mon Sep 17 00:00:00 2001 From: Botzy Date: Tue, 25 Feb 2025 11:45:48 +0200 Subject: [PATCH 2/5] fix(BottomSheet): hide BottomSheet when screen is resized --- src/components/BottomSheet/BottomSheet.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/BottomSheet/BottomSheet.tsx b/src/components/BottomSheet/BottomSheet.tsx index 7ebfb79d8..28e2f631a 100644 --- a/src/components/BottomSheet/BottomSheet.tsx +++ b/src/components/BottomSheet/BottomSheet.tsx @@ -4,6 +4,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { createPortal } from 'react-dom'; import classNames from 'classnames'; import useBinaryState from 'stremio/common/useBinaryState'; +import useWindowSize from 'stremio/common/useWindowSize'; import styles from './BottomSheet.less'; const CLOSE_THRESHOLD = 100; @@ -17,6 +18,7 @@ type Props = { const BottomSheet = ({ children, title, show, onClose }: Props) => { const containerRef = useRef(null); + const { width: windowWidth, height: windowHeight } = useWindowSize(); const [startOffset, setStartOffset] = useState(0); const [offset, setOffset] = useState(0); @@ -58,6 +60,10 @@ const BottomSheet = ({ children, title, show, onClose }: Props) => { !opened && onClose(); }, [opened]); + useEffect(() => { + opened && close(); + }, [windowWidth, windowHeight]); + return opened && createPortal((
From 8733af871b2a694e92d676c127664d7c3ce34b94 Mon Sep 17 00:00:00 2001 From: Botzy Date: Tue, 25 Feb 2025 13:57:50 +0200 Subject: [PATCH 3/5] fix(BottomSheet): close BottomSheet on orientation change --- src/common/index.js | 4 +- src/common/useOrientation.ts | 63 ++++++++++++++++++++++ src/common/useWindowSize.js | 18 ------- src/components/BottomSheet/BottomSheet.tsx | 6 +-- 4 files changed, 68 insertions(+), 23 deletions(-) create mode 100644 src/common/useOrientation.ts delete mode 100644 src/common/useWindowSize.js diff --git a/src/common/index.js b/src/common/index.js index ab3723cd0..82f7a6a0c 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -24,7 +24,7 @@ const { default: useShell } = require('./useShell'); const useStreamingServer = require('./useStreamingServer'); const useTorrent = require('./useTorrent'); const useTranslate = require('./useTranslate'); -const useWindowSize = require('./useWindowSize'); +const { default: useOrientation } = require('./useOrientation'); module.exports = { FileDropProvider, @@ -56,5 +56,5 @@ module.exports = { useStreamingServer, useTorrent, useTranslate, - useWindowSize, + useOrientation, }; diff --git a/src/common/useOrientation.ts b/src/common/useOrientation.ts new file mode 100644 index 000000000..b92c7b394 --- /dev/null +++ b/src/common/useOrientation.ts @@ -0,0 +1,63 @@ +// Copyright (C) 2017-2025 Smart code 203358507 + +import { useState, useEffect } from 'react'; + +type DeviceOrientationData = { + alpha: number | null; + beta: number | null; + gamma: number | null; + absolute: boolean | null; + permissionGranted: boolean; +}; + +const useOrientation = () => { + const [orientation, setOrientation] = useState({ + alpha: null, + beta: null, + gamma: null, + absolute: null, + permissionGranted: false, + }); + + const requestPermission = async () => { + if ( + typeof DeviceOrientationEvent !== 'undefined' && + (DeviceOrientationEvent as any).requestPermission + ) { + try { + const permissionState = await (DeviceOrientationEvent as any).requestPermission(); + if (permissionState === 'granted') { + setOrientation((prev) => ({ ...prev, permissionGranted: true })); + } + } catch (error) { + console.error('Error requesting DeviceOrientation permission:', error); + } + } else { + setOrientation((prev) => ({ ...prev, permissionGranted: true })); + } + }; + + useEffect(() => { + const handleOrientationChange = (event: DeviceOrientationEvent) => { + setOrientation((prev) => ({ + ...prev, + alpha: event.alpha ?? null, + beta: event.beta ?? null, + gamma: event.gamma ?? null, + absolute: event.absolute ?? null, + })); + }; + + if (orientation.permissionGranted && window.DeviceOrientationEvent) { + window.addEventListener('deviceorientation', handleOrientationChange); + } + + return () => { + window.removeEventListener('deviceorientation', handleOrientationChange); + }; + }, [orientation.permissionGranted]); + + return { ...orientation, requestPermission }; +}; + +export default useOrientation; diff --git a/src/common/useWindowSize.js b/src/common/useWindowSize.js deleted file mode 100644 index 9f7285261..000000000 --- a/src/common/useWindowSize.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (C) 2017-2025 Smart code 203358507 - -const { useState, useEffect } = require('react'); - -const useWindowSize = () => { - const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight }); - - useEffect(() => { - const handleResize = () => setSize({ width: window.innerWidth, height: window.innerHeight }); - - window.addEventListener('resize', handleResize); - return () => window.removeEventListener('resize', handleResize); - }, []); - - return size; -}; - -module.exports = useWindowSize; diff --git a/src/components/BottomSheet/BottomSheet.tsx b/src/components/BottomSheet/BottomSheet.tsx index 28e2f631a..d7dfe7130 100644 --- a/src/components/BottomSheet/BottomSheet.tsx +++ b/src/components/BottomSheet/BottomSheet.tsx @@ -4,7 +4,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { createPortal } from 'react-dom'; import classNames from 'classnames'; import useBinaryState from 'stremio/common/useBinaryState'; -import useWindowSize from 'stremio/common/useWindowSize'; +import useOrientation from 'stremio/common/useOrientation'; import styles from './BottomSheet.less'; const CLOSE_THRESHOLD = 100; @@ -18,7 +18,7 @@ type Props = { const BottomSheet = ({ children, title, show, onClose }: Props) => { const containerRef = useRef(null); - const { width: windowWidth, height: windowHeight } = useWindowSize(); + const orientation = useOrientation(); const [startOffset, setStartOffset] = useState(0); const [offset, setOffset] = useState(0); @@ -62,7 +62,7 @@ const BottomSheet = ({ children, title, show, onClose }: Props) => { useEffect(() => { opened && close(); - }, [windowWidth, windowHeight]); + }, [orientation]); return opened && createPortal((
From dc5c94b461c2d40f9891bbe0f6cc225b3b67965e Mon Sep 17 00:00:00 2001 From: Botzy Date: Tue, 25 Feb 2025 14:54:32 +0200 Subject: [PATCH 4/5] refactor(useOrientation): refactor hook to not ask for permissions --- src/common/useOrientation.ts | 61 ++++++++++-------------------------- 1 file changed, 16 insertions(+), 45 deletions(-) diff --git a/src/common/useOrientation.ts b/src/common/useOrientation.ts index b92c7b394..ec0eac293 100644 --- a/src/common/useOrientation.ts +++ b/src/common/useOrientation.ts @@ -1,63 +1,34 @@ // Copyright (C) 2017-2025 Smart code 203358507 -import { useState, useEffect } from 'react'; +import { useState, useEffect, useMemo } from 'react'; -type DeviceOrientationData = { - alpha: number | null; - beta: number | null; - gamma: number | null; - absolute: boolean | null; - permissionGranted: boolean; -}; +type DeviceOrientation = 'landscape' | 'portrait'; const useOrientation = () => { - const [orientation, setOrientation] = useState({ - alpha: null, - beta: null, - gamma: null, - absolute: null, - permissionGranted: false, - }); + const [windowHeight, setWindowHeight] = useState(window.innerHeight); + const [windowWidth, setWindowWidth] = useState(window.innerWidth); - const requestPermission = async () => { - if ( - typeof DeviceOrientationEvent !== 'undefined' && - (DeviceOrientationEvent as any).requestPermission - ) { - try { - const permissionState = await (DeviceOrientationEvent as any).requestPermission(); - if (permissionState === 'granted') { - setOrientation((prev) => ({ ...prev, permissionGranted: true })); - } - } catch (error) { - console.error('Error requesting DeviceOrientation permission:', error); - } + const orientation: DeviceOrientation = useMemo(() => { + if (windowHeight > windowWidth) { + return 'portrait'; } else { - setOrientation((prev) => ({ ...prev, permissionGranted: true })); + return 'landscape'; } - }; + }, [windowWidth, windowHeight]); useEffect(() => { - const handleOrientationChange = (event: DeviceOrientationEvent) => { - setOrientation((prev) => ({ - ...prev, - alpha: event.alpha ?? null, - beta: event.beta ?? null, - gamma: event.gamma ?? null, - absolute: event.absolute ?? null, - })); + const handleResize = () => { + setWindowHeight(window.innerHeight); + setWindowWidth(window.innerWidth); }; - if (orientation.permissionGranted && window.DeviceOrientationEvent) { - window.addEventListener('deviceorientation', handleOrientationChange); - } - + window.addEventListener('resize', handleResize); return () => { - window.removeEventListener('deviceorientation', handleOrientationChange); + window.removeEventListener('resize', handleResize); }; - }, [orientation.permissionGranted]); + }, [window.innerWidth, window.innerHeight]); - return { ...orientation, requestPermission }; + return { orientation }; }; export default useOrientation; From a2131393195445ce492d3af268351f06770c5818 Mon Sep 17 00:00:00 2001 From: Botzy Date: Tue, 25 Feb 2025 15:04:27 +0200 Subject: [PATCH 5/5] fix(useOrientation): fix hook return value --- src/common/useOrientation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/useOrientation.ts b/src/common/useOrientation.ts index ec0eac293..add8d1d40 100644 --- a/src/common/useOrientation.ts +++ b/src/common/useOrientation.ts @@ -28,7 +28,7 @@ const useOrientation = () => { }; }, [window.innerWidth, window.innerHeight]); - return { orientation }; + return orientation; }; export default useOrientation;