From 909cb2737684b26f8a00396ecba1eca5258fc008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cintia=20S=C3=A1nchez=20Garc=C3=ADa?= Date: Wed, 30 Aug 2023 18:14:01 +0200 Subject: [PATCH] Add zoom level and selected view to context (#144) Signed-off-by: Cintia Sanchez Garcia --- web/src/layout/context/AppContext.tsx | 70 ++++++++++++++++++- web/src/layout/explore/Content.tsx | 14 ++-- web/src/layout/explore/gridCategory/Grid.tsx | 12 ++-- web/src/layout/explore/gridCategory/index.tsx | 2 - web/src/layout/explore/index.tsx | 67 ++++++------------ 5 files changed, 102 insertions(+), 63 deletions(-) diff --git a/web/src/layout/context/AppContext.tsx b/web/src/layout/context/AppContext.tsx index 57b913be..2214491d 100644 --- a/web/src/layout/context/AppContext.tsx +++ b/web/src/layout/context/AppContext.tsx @@ -1,5 +1,9 @@ -import { createContext, useCallback, useMemo, useState } from 'react'; +import { createContext, useCallback, useEffect, useMemo, useState } from 'react'; +import { useSearchParams } from 'react-router-dom'; +import { DEFAULT_VIEW_MODE, DEFAULT_ZOOM_LEVELS, VIEW_MODE_PARAM, ZOOM_LEVELS } from '../../data'; +import { useBreakpointDetect } from '../../hooks/useBreakpointDetect'; +import { Breakpoint, ViewMode } from '../../types'; import itemsDataGetter from '../../utils/itemsDataGetter'; export type FullDataProps = { @@ -14,9 +18,19 @@ export type ZoomProps = { visibleZoomView?: ActiveSection; }; +export type ViewModeProps = { + selectedViewMode?: ViewMode; +}; + +export type ZoomLevelProps = { + zoomLevel: number; +}; + export type ActionsContext = { updateActiveItemId: (itemId?: string) => void; updateActiveSection: (activeSection?: ActiveSection) => void; + updateViewMode: (viewMode: ViewMode) => void; + updateZoomLevel: (level: number) => void; }; export interface ActiveSection { @@ -32,12 +46,22 @@ interface Props { export const FullDataContext = createContext(null); export const ItemContext = createContext(null); export const ZoomContext = createContext(null); +export const ViewModeContext = createContext(null); +export const ZoomLevelContext = createContext(null); export const AppActionsContext = createContext(null); const AppContextProvider = (props: Props) => { + const [searchParams] = useSearchParams(); + const point = useBreakpointDetect(); const [visibleItemId, setVisibleItemId] = useState(); const [visibleZoomView, setVisibleZoomView] = useState(); const [fullDataReady, setFullDataReady] = useState(false); + const [selectedViewMode, setSelectedViewMode] = useState( + (searchParams.get(VIEW_MODE_PARAM) as ViewMode) || DEFAULT_VIEW_MODE + ); + const [zoomLevel, setZoomLevel] = useState( + point ? DEFAULT_ZOOM_LEVELS[point] : DEFAULT_ZOOM_LEVELS[Breakpoint.XL] + ); const updateActiveItemId = useCallback((id?: string) => { setVisibleItemId(id); @@ -47,6 +71,26 @@ const AppContextProvider = (props: Props) => { setVisibleZoomView(section); }, []); + const updateViewMode = useCallback((viewMode: ViewMode) => { + setSelectedViewMode(viewMode); + }, []); + + const updateZoomLevel = useCallback((level: number) => { + setZoomLevel(level); + + // Update card-size variable depending on zoom level + const bodyStyles = document.body.style; + bodyStyles.setProperty('--card-size-width', `${ZOOM_LEVELS[level][0]}px`); + bodyStyles.setProperty('--card-size-height', `${ZOOM_LEVELS[level][1]}px`); + }, []); + + useEffect(() => { + if (point) { + updateZoomLevel(DEFAULT_ZOOM_LEVELS[point]); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [point]); + const fullDataValue = useMemo( () => ({ fullDataReady, @@ -68,12 +112,28 @@ const AppContextProvider = (props: Props) => { [visibleZoomView] ); + const viewModeValue = useMemo( + () => ({ + selectedViewMode, + }), + [selectedViewMode] + ); + + const zoomLevelValue = useMemo( + () => ({ + zoomLevel, + }), + [zoomLevel] + ); + const contextActionsValue = useMemo( () => ({ updateActiveItemId, updateActiveSection, + updateViewMode, + updateZoomLevel, }), - [updateActiveItemId, updateActiveSection] + [updateActiveItemId, updateActiveSection, updateViewMode, updateZoomLevel] ); itemsDataGetter.subscribe({ @@ -86,7 +146,11 @@ const AppContextProvider = (props: Props) => { - {props.children} + + + {props.children} + + diff --git a/web/src/layout/explore/Content.tsx b/web/src/layout/explore/Content.tsx index 85c99ef3..9e9f8c7b 100644 --- a/web/src/layout/explore/Content.tsx +++ b/web/src/layout/explore/Content.tsx @@ -1,8 +1,9 @@ -import { memo } from 'react'; +import { memo, useContext } from 'react'; import { ViewMode } from '../../types'; import arePropsEqual from '../../utils/areEqualProps'; import { CategoriesData } from '../../utils/prepareData'; +import { ViewModeContext, ViewModeProps } from '../context/AppContext'; import CardCategory from './cardCategory'; import GridCategory from './gridCategory'; @@ -10,26 +11,25 @@ interface Props { isSelected: boolean; containerWidth: number; data: CategoriesData; - selectedViewMode: ViewMode; - cardWidth: number; categories_overridden?: string[]; } // Memoized version of content to avoid unnecessary const Content = memo(function Content(props: Props) { + const { selectedViewMode } = useContext(ViewModeContext) as ViewModeProps; + return ( <> -
+
-
+
diff --git a/web/src/layout/explore/gridCategory/Grid.tsx b/web/src/layout/explore/gridCategory/Grid.tsx index 688ba096..980bcb53 100644 --- a/web/src/layout/explore/gridCategory/Grid.tsx +++ b/web/src/layout/explore/gridCategory/Grid.tsx @@ -3,6 +3,7 @@ import { isUndefined } from 'lodash'; import { memo, useContext, useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; +import { ZOOM_LEVELS } from '../../../data'; import { BaseItem, Item, SVGIconKind } from '../../../types'; import arePropsEqual from '../../../utils/areEqualProps'; import getGridCategoryLayout, { @@ -15,14 +16,13 @@ import getGridCategoryLayout, { import { SubcategoryData } from '../../../utils/prepareData'; import sortItemsByOrderValue from '../../../utils/sortItemsByOrderValue'; import SVGIcon from '../../common/SVGIcon'; -import { ActionsContext, AppActionsContext } from '../../context/AppContext'; +import { ActionsContext, AppActionsContext, ZoomLevelContext, ZoomLevelProps } from '../../context/AppContext'; import styles from './Grid.module.css'; import GridItem from './GridItem'; interface Props { categoryData: { [key: string]: SubcategoryData }; containerWidth: number; - itemWidth: number; categoryName: string; isOverriden: boolean; subcategories: SubcategoryDetails[]; @@ -31,8 +31,10 @@ interface Props { } const Grid = memo(function Grid(props: Props) { + const { zoomLevel } = useContext(ZoomLevelContext) as ZoomLevelProps; const { updateActiveSection } = useContext(AppActionsContext) as ActionsContext; const [grid, setGrid] = useState(); + const itemWidth = ZOOM_LEVELS[zoomLevel][0]; useEffect(() => { if (props.containerWidth > 0) { @@ -40,19 +42,19 @@ const Grid = memo(function Grid(props: Props) { transformGridLayout({ grid: getGridCategoryLayout({ containerWidth: props.containerWidth, - itemWidth: props.itemWidth, + itemWidth: itemWidth, categoryName: props.categoryName, isOverriden: props.isOverriden, subcategories: props.subcategories, }), - itemWidth: props.itemWidth, + itemWidth: itemWidth, containerWidth: props.containerWidth, subcategories: props.subcategories, }) ); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [props.containerWidth, props.itemWidth, props.subcategories]); + }, [props.containerWidth, itemWidth, props.subcategories]); if (isUndefined(grid)) return null; diff --git a/web/src/layout/explore/gridCategory/index.tsx b/web/src/layout/explore/gridCategory/index.tsx index 2e8e781b..36a24e4d 100644 --- a/web/src/layout/explore/gridCategory/index.tsx +++ b/web/src/layout/explore/gridCategory/index.tsx @@ -15,7 +15,6 @@ import styles from './GridCategory.module.css'; interface Props { containerWidth: number; data: CategoriesData; - cardWidth: number; categories_overridden?: string[]; } @@ -66,7 +65,6 @@ const GridCategory = memo(function GridCategory(props: Props) {
{ const navigate = useNavigate(); const location = useLocation(); - const point = useBreakpointDetect(); const { fullDataReady } = useContext(FullDataContext) as FullDataProps; + const { selectedViewMode } = useContext(ViewModeContext) as ViewModeProps; + const { zoomLevel } = useContext(ZoomLevelContext) as ZoomLevelProps; + const { updateViewMode, updateZoomLevel } = useContext(AppActionsContext) as ActionsContext; const [searchParams] = useSearchParams(); const container = useRef(null); const [containerWidth, setContainerWidth] = useState(0); const [landscapeData, setLandscapeData] = useState(); - const [levelZoom, setLevelZoom] = useState( - point ? DEFAULT_ZOOM_LEVELS[point] : DEFAULT_ZOOM_LEVELS[Breakpoint.XL] - ); const [selectedGroup, setSelectedGroup] = useState( props.data.groups ? searchParams.get(GROUP_PARAM) || props.data.groups[0].name : undefined ); - const [selectedViewMode, setSelectedViewMode] = useState( - (searchParams.get(VIEW_MODE_PARAM) as ViewMode) || DEFAULT_VIEW_MODE - ); const [visibleItems, setVisibleItems] = useState<(BaseItem | Item)[]>(props.data.items); const [visibleFiltersModal, setVisibleFiltersModal] = useState(false); const [activeFilters, setActiveFilters] = useState({}); @@ -91,13 +85,6 @@ const Landscape = (props: Props) => { } }, [landscapeData]); - // Update card-size variable depending on zoom level - useEffect(() => { - const bodyStyles = document.body.style; - bodyStyles.setProperty('--card-size-width', `${ZOOM_LEVELS[levelZoom][0]}px`); - bodyStyles.setProperty('--card-size-height', `${ZOOM_LEVELS[levelZoom][1]}px`); - }, [levelZoom]); - const removeFilter = useCallback( (name: FilterCategory, value: string) => { const tmpActiveFilters: string[] = (activeFilters[name] || []).filter((f: string) => f !== value); @@ -141,12 +128,6 @@ const Landscape = (props: Props) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [visibleItems, selectedGroup]); - useEffect(() => { - if (point) { - setLevelZoom(DEFAULT_ZOOM_LEVELS[point]); - } - }, [point]); - useEffect(() => { const checkContainerWidth = throttle(() => { if (container && container.current) { @@ -226,7 +207,7 @@ const Landscape = (props: Props) => { })} onClick={() => { if (!isActive) { - setSelectedViewMode(value); + updateViewMode(value); updateQueryString(VIEW_MODE_PARAM, value); } }} @@ -247,10 +228,9 @@ const Landscape = (props: Props) => {