/** * 游戏子菜单组件 * 基于 xinyong-web 的 SubGameCategoryMenu 组件重建 * 功能包括: * - 水平/竖直菜单切换 * - 菜单项滚动和自动定位 * - 弹窗选择菜单 * - 主题适配 */ import React, { useState, useCallback, useMemo, useRef, useEffect } from 'react'; import { View, Text, ScrollView, TouchableOpacity, Modal, FlatList, Dimensions, } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { useColorScheme, useThemeColors } from '@/theme'; import { styles } from './styles'; import { useGameMainMenus, useGameMenuTabs } from '@/hooks/useGameMenus'; import { Image } from '@/components'; const { width } = Dimensions.get('window'); interface GameSubMenusProps { vertical?: boolean; onSubMenuChange?: (menuKey: string) => void; } /** * 游戏子菜单组件 */ export default function GameSubMenus({ vertical = false, onSubMenuChange }: GameSubMenusProps) { const colorScheme = useColorScheme(); const s = styles[colorScheme]; const themeColors = useThemeColors(); // 获取主菜单数据 const gameMenus = useGameMainMenus(colorScheme); const { activeMainMenuTab, activeSubMenuTab, setActiveSubMenuTab } = useGameMenuTabs(); // 获取当前选中的主菜单 const currentMenu = useMemo(() => { return gameMenus.find((menu) => menu.key === activeMainMenuTab); }, [gameMenus, activeMainMenuTab]); // 获取当前选中的子菜单 const subMenus = useMemo((): Record[] => { return currentMenu?.children || []; }, [currentMenu]); // 弹窗状态 const [showPopup, setShowPopup] = useState(false); // 滚动视图引用 const scrollViewRef = useRef(null); // 当前选中的子菜单索引 const selectedSubMenuIndex = useMemo(() => { return subMenus.findIndex((menu) => menu.key === activeSubMenuTab); }, [subMenus, activeSubMenuTab]); // 处理子菜单选择 const handleSubMenuPress = useCallback( (menuKey: string) => { setActiveSubMenuTab(menuKey); onSubMenuChange?.(menuKey); }, [setActiveSubMenuTab, onSubMenuChange] ); // 处理打开弹窗 const handleOpenPopup = useCallback(() => { setShowPopup(true); }, []); // 处理关闭弹窗 const handleClosePopup = useCallback(() => { setShowPopup(false); }, []); // 处理弹窗中的菜单选择 const handlePopupMenuSelect = useCallback( (menuKey: string) => { handleSubMenuPress(menuKey); handleClosePopup(); }, [handleSubMenuPress, handleClosePopup] ); // 自动滚动到选中项 useEffect(() => { if (selectedSubMenuIndex >= 0 && !vertical) { const scrollPosition = selectedSubMenuIndex * 112; // 100 (width) + 12 (margin) scrollViewRef.current?.scrollTo({ x: scrollPosition, animated: true, }); } }, [selectedSubMenuIndex, vertical]); // 如果没有子菜单,返回空 if (subMenus.length === 0) { return null; } // 渲染菜单项 const renderMenuItem = (item: any, isActive: boolean) => ( handleSubMenuPress(item.key)} activeOpacity={0.7} > {item.colorImgSrc && ( )} {item.name} ); // 水平布局 if (!vertical) { return ( {subMenus.map((item) => ( {renderMenuItem(item, item.key === activeSubMenuTab)} ))} {/* 更多菜单按钮 */} 更多 ); } // 竖直布局 return ( {subMenus.map((item) => ( {renderMenuItem(item, item.key === activeSubMenuTab)} ))} {/* 弹窗 */} {/* 弹窗头部 */} 平台选择 {/* 弹窗内容 - 网格布局 */} ( handlePopupMenuSelect(item.key)} activeOpacity={0.7} > {item.colorImgSrc && ( )} {item.name} )} keyExtractor={(item) => item.key} numColumns={2} scrollEnabled={false} contentContainerStyle={s.modalGrid} /> ); }