📱(frontend) add hook store useResponsiveStore
useResponsiveStore is a hook store that provides the current screen size and the current device type.
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
import { CunninghamProvider } from '@openfun/cunningham-react';
|
import { CunninghamProvider } from '@openfun/cunningham-react';
|
||||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { useCunninghamTheme } from '@/cunningham';
|
import { useCunninghamTheme } from '@/cunningham';
|
||||||
import '@/i18n/initI18n';
|
import '@/i18n/initI18n';
|
||||||
|
import { useResponsiveStore } from '@/stores/';
|
||||||
|
|
||||||
import { Auth } from './auth/';
|
import { Auth } from './auth/';
|
||||||
|
|
||||||
@@ -25,6 +27,15 @@ const queryClient = new QueryClient({
|
|||||||
export function AppProvider({ children }: { children: React.ReactNode }) {
|
export function AppProvider({ children }: { children: React.ReactNode }) {
|
||||||
const { theme } = useCunninghamTheme();
|
const { theme } = useCunninghamTheme();
|
||||||
|
|
||||||
|
const initializeResizeListener = useResponsiveStore(
|
||||||
|
(state) => state.initializeResizeListener,
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const cleanupResizeListener = initializeResizeListener();
|
||||||
|
return cleanupResizeListener;
|
||||||
|
}, [initializeResizeListener]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<CunninghamProvider theme={theme}>
|
<CunninghamProvider theme={theme}>
|
||||||
|
|||||||
1
src/frontend/apps/impress/src/stores/index.ts
Normal file
1
src/frontend/apps/impress/src/stores/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './useResponsiveStore';
|
||||||
61
src/frontend/apps/impress/src/stores/useResponsiveStore.tsx
Normal file
61
src/frontend/apps/impress/src/stores/useResponsiveStore.tsx
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { create } from 'zustand';
|
||||||
|
|
||||||
|
export type ScreenSize = 'small-mobile' | 'mobile' | 'tablet' | 'desktop';
|
||||||
|
|
||||||
|
export interface UseResponsiveStore {
|
||||||
|
isMobile: boolean;
|
||||||
|
isSmallMobile: boolean;
|
||||||
|
screenSize: ScreenSize;
|
||||||
|
screenWidth: number;
|
||||||
|
setScreenSize: (size: ScreenSize) => void;
|
||||||
|
initializeResizeListener: () => () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
isMobile: false,
|
||||||
|
isSmallMobile: false,
|
||||||
|
screenSize: 'desktop' as ScreenSize,
|
||||||
|
screenWidth: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useResponsiveStore = create<UseResponsiveStore>((set) => ({
|
||||||
|
isMobile: initialState.isMobile,
|
||||||
|
isSmallMobile: initialState.isSmallMobile,
|
||||||
|
screenSize: initialState.screenSize,
|
||||||
|
screenWidth: initialState.screenWidth,
|
||||||
|
setScreenSize: (size: ScreenSize) => set(() => ({ screenSize: size })),
|
||||||
|
initializeResizeListener: () => {
|
||||||
|
const resizeHandler = () => {
|
||||||
|
const width = window.innerWidth;
|
||||||
|
if (width < 560) {
|
||||||
|
set({
|
||||||
|
screenSize: 'small-mobile',
|
||||||
|
isMobile: true,
|
||||||
|
isSmallMobile: true,
|
||||||
|
});
|
||||||
|
} else if (width < 768) {
|
||||||
|
set({ screenSize: 'mobile', isMobile: true, isSmallMobile: false });
|
||||||
|
} else if (width >= 768 && width < 1024) {
|
||||||
|
set({ screenSize: 'tablet', isMobile: false, isSmallMobile: false });
|
||||||
|
} else {
|
||||||
|
set({ screenSize: 'desktop', isMobile: false, isSmallMobile: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
set({ screenWidth: width });
|
||||||
|
};
|
||||||
|
|
||||||
|
const debouncedResizeHandler = () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resizeHandler();
|
||||||
|
}, 300);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('resize', debouncedResizeHandler);
|
||||||
|
|
||||||
|
resizeHandler();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('resize', debouncedResizeHandler);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}));
|
||||||
Reference in New Issue
Block a user