From 9c572aea45d49ed6487e486a66b400080895d0c6 Mon Sep 17 00:00:00 2001 From: Camille Moussu Date: Thu, 26 Mar 2026 11:25:35 +0100 Subject: [PATCH] [Responsive] tools to get the type of screen --- src/App.tsx | 23 +++++---------------- src/useScreenSizeDetection.ts | 38 +++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 18 deletions(-) create mode 100644 src/useScreenSizeDetection.ts diff --git a/src/App.tsx b/src/App.tsx index a40df7c..d0ad553 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,20 +1,21 @@ import { TwakeMuiThemeProvider } from '@linagora/twake-mui' -import { Suspense, useEffect, useState } from 'react' +import { Suspense, useEffect } from 'react' import { Route, Routes } from 'react-router-dom' import { push } from 'redux-first-history' import { HistoryRouter as Router } from 'redux-first-history/rr6' import './App.styl' import { useAppDispatch, useAppSelector } from './app/hooks' import { history } from './app/store' -import CalendarLayout from './components/Calendar/CalendarLayout' +import { default as CalendarLayout } from './components/Calendar/CalendarLayout' import { Error as ErrorPage } from './components/Error/Error' import { ErrorSnackbar } from './components/Error/ErrorSnackbar' import { Loading } from './components/Loading/Loading' import { AVAILABLE_LANGUAGES } from './features/Settings/constants' -import HandleLogin from './features/User/HandleLogin' +import { default as HandleLogin } from './features/User/HandleLogin' import { CallbackResume } from './features/User/LoginCallback' import { useInitializeApp } from './features/User/useInitializeApp' import { ScreenTooSmall } from './ScreenTooSmall' +import { useScreenSizeDetection } from './useScreenSizeDetection' import { WebSocketGate } from './websocket/WebSocketGate' import { @@ -62,23 +63,9 @@ function App() { } }, [error, dispatch]) - const SMALL_SCREEN_QUERY = '(max-width: 925px)' - const [isTooSmall, setIsTooSmall] = useState( - () => window.matchMedia(SMALL_SCREEN_QUERY).matches - ) - useInitializeApp() - useEffect(() => { - const mediaQuery = window.matchMedia(SMALL_SCREEN_QUERY) - const onChange = (event: MediaQueryListEvent) => - setIsTooSmall(event.matches) - const onChangeInitial = () => setIsTooSmall(mediaQuery.matches) - - onChangeInitial() - mediaQuery.addEventListener('change', onChange) - return () => mediaQuery.removeEventListener('change', onChange) - }, []) + const { isTooSmall } = useScreenSizeDetection() return ( diff --git a/src/useScreenSizeDetection.ts b/src/useScreenSizeDetection.ts new file mode 100644 index 0000000..0adc63e --- /dev/null +++ b/src/useScreenSizeDetection.ts @@ -0,0 +1,38 @@ +import { useState, useEffect } from "react"; + +export const DEVICES_SCREEN_LIMITS = { + tablet: 925, + mobile: 450, +} as const; + +function useWindowWidth(): number { + const [width, setWidth] = useState(() => window.innerWidth); + + useEffect(() => { + let rafId: number | null = null; + + const onResize = () => { + if (rafId !== null) cancelAnimationFrame(rafId); + rafId = requestAnimationFrame(() => setWidth(window.innerWidth)); + }; + + window.addEventListener("resize", onResize); + return () => { + window.removeEventListener("resize", onResize); + if (rafId !== null) cancelAnimationFrame(rafId); + }; + }, []); + + return width; +} + +export function useScreenSizeDetection() { + const width = useWindowWidth(); + + return { + isTooSmall: width <= DEVICES_SCREEN_LIMITS.mobile, + isTablet: + width <= DEVICES_SCREEN_LIMITS.tablet && + width > DEVICES_SCREEN_LIMITS.mobile, + }; +}