import { useEffect, useState, useMemo, useCallback } from 'react'; import useGameStore from '@/stores/gameStore'; import { GameMainTypesEnum, defaultHomeGameTabMenus, gameMainTypesMap } from '@/constants/game'; import { ThemeEnum } from '@/constants/theme'; import { forEach, cloneDeep, map, filter } from 'lodash-es'; import { useIsLoggedIn } from '@/stores/userStore'; import { useShallow } from 'zustand/react/shallow'; import storageManager, { STORAGE_KEYS } from '@/utils/storageManager'; type GameMenu = { name: string; key: string; icon?: string; logo?: string; children?: GameMenu[]; }; // 有子菜单的游戏类型 const hasSubGameMainTypes = [ GameMainTypesEnum.CHESS, GameMainTypesEnum.ELECTRONIC, GameMainTypesEnum.FISHING, GameMainTypesEnum.BLOCK_THIRD, ]; export const useGameMainMenus = (theme: ThemeEnum) => { // 在 hook 顶层调用 useIsLoggedIn const isLogin = useIsLoggedIn(); // 从 store 获取必要的数据 - 直接获取,不使用 useShallow const menuSort = useGameStore((state) => state.menuSort); const gameBigClass = useGameStore((state) => state.gameBigClass); if (__DEV__) { console.log('🎮 useGameMainMenus - menuSort:', menuSort, 'length:', menuSort?.length); } // 使用 useMemo 缓存计算结果,避免每次都创建新对象 return useMemo(() => { const defaultMenus = cloneDeep(defaultHomeGameTabMenus); if (theme === ThemeEnum.DARK) { forEach(defaultMenus, (item) => { if (item.key === GameMainTypesEnum.RECENT) { item.icon = 'clock-solid_dark'; } }); } const gameMenu = map(menuSort, (item: Record) => { const typeName = gameMainTypesMap[item.type as GameMainTypesEnum]; const children = hasSubGameMainTypes.includes(item.type) ? map(gameBigClass?.[typeName], (it) => { return { name: it.play_cname, key: `${it.play_id}`, play_sort: it.play_sort, darkImgSrc: `/images/game/${typeName}/dark_${it.play_id}.png`, lightImgSrc: `/images/game/${typeName}/light_${it.play_id}.png`, colorImgSrc: it.logo3_img_url || `/images/game/${typeName}/color_${it.play_id}.png`, }; }) : []; return { name: item.play_name, key: `${item.type}`, icon: typeName, logo: item.logo_url1, children, }; }); if (__DEV__) { console.log(gameMenu, 'gameMenu'); } return map( [ ...filter(defaultMenus, (item) => [GameMainTypesEnum.RECOMMEND].includes(item.key)), ...(isLogin ? filter(gameMenu, (item) => Number(item.key) !== GameMainTypesEnum.TRIAL) : gameMenu), ...filter(defaultMenus, (item) => [GameMainTypesEnum.COLLECT, GameMainTypesEnum.RECENT].includes(item.key) ), ], (item) => ({ ...item, // 为了在 React Native 中正确加载本地图片,使用 require 的方式 // 这里保留原始的 icon 名称,在组件中使用 require 加载 icon: item.icon, key: `${item.key}`, }) ) as GameMenu[]; }, [theme, isLogin, menuSort, gameBigClass]); }; export const useMenuDataLoaded = () => useGameStore((state) => state.menuSort?.length > 0); /** * 游戏分类选择 Hook(统一管理) * * 管理当前选中的游戏分类,支持: * - 从 gameStore 获取当前选中分类 * - 更新选中分类并保存到 session storage * - 页面刷新后恢复选中分类 * * @returns {Object} 包含 selectedCategory 和 setSelectedCategory 的对象 * * @example * ```typescript * const { selectedCategory, setSelectedCategory } = useSelectedCategory(); * * // 获取当前选中分类 * console.log(selectedCategory); // '103' * * // 更新选中分类 * setSelectedCategory('1'); * ``` */ export const useSelectedCategory = () => { const selectedCategory = useGameStore((state) => state.selectedCategory); const setSelectedCategoryInStore = useGameStore((state) => state.setSelectedCategory); // 初始化时从 session storage 恢复选中分类 useEffect(() => { const initializeSelectedCategory = async () => { try { const savedCategory = storageManager.session.getItem(STORAGE_KEYS.APP_ACTIVE_MAIN_MENU_TAB); if (savedCategory) { setSelectedCategoryInStore(savedCategory); } } catch (error) { console.error('Failed to restore selected category:', error); } }; initializeSelectedCategory(); }, [setSelectedCategoryInStore]); // 更新选中分类的回调函数 const setSelectedCategory = useCallback( (categoryId: string) => { setSelectedCategoryInStore(categoryId); }, [setSelectedCategoryInStore] ); return { selectedCategory, setSelectedCategory, }; };