From 7b09b3552297b299433cee8f74b5619eaeac70a4 Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Mon, 13 May 2024 13:08:47 -0400 Subject: [PATCH] REF: Single source of truth for useIsLargeScreen --- components/Context/LargeScreenProvider.tsx | 43 ++++++++++++++++++++ hooks/useIsLargeScreen.ts | 47 ++++------------------ index.js => index.tsx | 13 +++--- 3 files changed, 59 insertions(+), 44 deletions(-) create mode 100644 components/Context/LargeScreenProvider.tsx rename index.js => index.tsx (74%) diff --git a/components/Context/LargeScreenProvider.tsx b/components/Context/LargeScreenProvider.tsx new file mode 100644 index 000000000..5bab2d89d --- /dev/null +++ b/components/Context/LargeScreenProvider.tsx @@ -0,0 +1,43 @@ +import React, { createContext, useState, useEffect, useMemo, ReactNode } from 'react'; +import { Dimensions } from 'react-native'; +import { isTablet } from 'react-native-device-info'; +import { isDesktop } from '../../blue_modules/environment'; + +interface ILargeScreenContext { + isLargeScreen: boolean; +} + +export const LargeScreenContext = createContext(undefined); + +interface LargeScreenProviderProps { + children: ReactNode; +} + +export const LargeScreenProvider: React.FC = ({ children }) => { + const [windowWidth, setWindowWidth] = useState(Dimensions.get('window').width); + const screenWidth: number = useMemo(() => Dimensions.get('screen').width, []); + + useEffect(() => { + const updateScreenUsage = (): void => { + const newWindowWidth = Dimensions.get('window').width; + if (newWindowWidth !== windowWidth) { + setWindowWidth(newWindowWidth); + } + }; + + const subscription = Dimensions.addEventListener('change', updateScreenUsage); + return () => subscription.remove(); + }, [windowWidth]); + + const isLargeScreen: boolean = useMemo(() => { + const isRunningOnTablet = isTablet(); + const halfScreenWidth = windowWidth >= screenWidth / 2; + const condition = (isRunningOnTablet && halfScreenWidth) || isDesktop; + console.debug( + `LargeScreenProvider.isLargeScreen: width: ${windowWidth}, Screen width: ${screenWidth}, Is tablet: ${isTablet()}, Is large screen: ${condition}, isDesktkop: ${isDesktop}`, + ); + return condition; + }, [windowWidth, screenWidth]); + + return {children}; +}; diff --git a/hooks/useIsLargeScreen.ts b/hooks/useIsLargeScreen.ts index 8c706cade..14ec0cd2d 100644 --- a/hooks/useIsLargeScreen.ts +++ b/hooks/useIsLargeScreen.ts @@ -1,41 +1,10 @@ -import { useState, useEffect, useMemo } from 'react'; -import { Dimensions } from 'react-native'; -import { isTablet } from 'react-native-device-info'; -import { isDesktop } from '../blue_modules/environment'; +import { useContext } from 'react'; +import { LargeScreenContext } from '../components/Context/LargeScreenProvider'; -// Custom hook to determine if the screen is large -export const useIsLargeScreen = () => { - const [windowWidth, setWindowWidth] = useState(Dimensions.get('window').width); - const screenWidth = useMemo(() => Dimensions.get('screen').width, []); - - useEffect(() => { - const updateScreenUsage = () => { - const newWindowWidth = Dimensions.get('window').width; - if (newWindowWidth !== windowWidth) { - console.debug(`Window width changed: ${newWindowWidth}`); - setWindowWidth(newWindowWidth); - } - }; - - // Add event listener for dimension changes - const subscription = Dimensions.addEventListener('change', updateScreenUsage); - - // Cleanup function to remove the event listener - return () => { - subscription.remove(); - }; - }, [windowWidth]); - - // Determine if the window width is at least half of the screen width - const isLargeScreen = useMemo(() => { - const isRunningOnTablet = isTablet(); - const halfScreenWidth = windowWidth >= screenWidth / 2; - const condition = (isRunningOnTablet && halfScreenWidth) || isDesktop; - console.debug( - `Window width: ${windowWidth}, Screen width: ${screenWidth}, Is tablet: ${isTablet()}, Is large screen: ${condition}, isDesktkop: ${isDesktop}`, - ); - return condition; - }, [windowWidth, screenWidth]); - - return isLargeScreen; +export const useIsLargeScreen = (): boolean => { + const context = useContext(LargeScreenContext); + if (context === undefined) { + throw new Error('useIsLargeScreen must be used within a LargeScreenProvider'); + } + return context.isLargeScreen; }; diff --git a/index.js b/index.tsx similarity index 74% rename from index.js rename to index.tsx index 0783e0c0c..8055bca79 100644 --- a/index.js +++ b/index.tsx @@ -8,6 +8,7 @@ import { BlueStorageProvider } from './blue_modules/storage-context'; import A from './blue_modules/analytics'; import { SettingsProvider } from './components/Context/SettingsContext'; import { restoreSavedPreferredFiatCurrencyAndExchangeFromStorage } from './blue_modules/currency'; +import { LargeScreenProvider } from './components/Context/LargeScreenProvider'; if (!Error.captureStackTrace) { // captureStackTrace is only available when debugging @@ -21,11 +22,13 @@ const BlueAppComponent = () => { }, []); return ( - - - - - + + + + + + + ); };