feat: 首页更新

This commit is contained in:
2025-11-12 00:13:26 +08:00
parent b48cce06f4
commit 9ef9233797
46 changed files with 660 additions and 369 deletions

View File

@@ -1,180 +0,0 @@
/**
* 完整首页容器
* 包含 Header、内容区域、BottomTabs
* 支持主题切换和真实数据
*/
import React, { useState, useEffect, useCallback } from 'react';
import { View, ScrollView, RefreshControl, StyleSheet, SafeAreaView, Alert } from 'react-native';
import { useColorScheme } from '@/hooks';
import { createThemeStyles } from '@/theme';
import Colors from '@/constants/Colors';
import Header from './components/Header';
import BannerSwiper from './components/BannerSwiper';
import NoticeBar from './components/NoticeBar';
import GameMainMenus from './components/GameMainMenus';
import Lobby from './components/Lobby';
import HighPrizeGame from './components/HighPrizeGame';
import FastFootNav from './components/FastFootNav';
import { requestHomePageData } from '@/stores/gameStore';
import { useTenantLoad } from '@/stores/tenantStore';
import type {
Banner,
Notice,
GameCategory,
Game,
HighPrizeGame as HighPrizeGameType,
} from '@/types/home';
/**
* 创建主题样式
*/
const styles = createThemeStyles((colors) => ({
container: {
flex: 1,
backgroundColor: colors.background,
},
contentContainer: {
flex: 1,
},
scrollContent: {
paddingBottom: 20,
},
}));
interface HomeScreenCompleteProps {
theme?: 'light' | 'dark';
isDarkTheme?: boolean;
}
/**
* 完整首页容器
*/
export default function HomeScreenComplete({
theme = 'light',
isDarkTheme = false,
}: HomeScreenCompleteProps) {
const colorScheme = useColorScheme();
const actualTheme = theme === 'light' || theme === 'dark' ? theme : colorScheme;
const s = styles[actualTheme];
const [refreshing, setRefreshing] = useState(false);
const [selectedCategory, setSelectedCategory] = useState<number>(0);
const tenantLoad = useTenantLoad();
// 加载首页数据
const loadHomePageData = useCallback(async () => {
try {
await requestHomePageData();
} catch (error) {
console.error('加载首页数据失败:', error);
}
}, []);
// 初始化加载
useEffect(() => {
console.log('租户数据加载完成:', tenantLoad);
if (tenantLoad) {
loadHomePageData();
}
}, [loadHomePageData, tenantLoad]);
// 下拉刷新
const handleRefresh = useCallback(async () => {
setRefreshing(true);
try {
await loadHomePageData();
} finally {
setRefreshing(false);
}
}, [loadHomePageData]);
// 处理分类选择
const handleCategorySelect = useCallback((categoryId: number) => {
setSelectedCategory(categoryId);
// 这里可以根据分类过滤游戏
}, []);
// 处理游戏点击
const handleGamePress = useCallback((game: Game) => {
Alert.alert('游戏', `点击了: ${game.play_up_name}`);
// 这里可以添加打开游戏的逻辑
}, []);
// 处理底部 Tab 点击
const handleTabPress = useCallback((tabId: string, action: string) => {
Alert.alert('导航', `点击了: ${tabId}`);
// 这里可以添加导航逻辑
}, []);
// 处理搜索
const handleSearch = useCallback((keyword: string) => {
Alert.alert('搜索', `搜索关键词: ${keyword}`);
// 这里可以添加搜索逻辑
}, []);
// 根据主题选择要显示的组件
const renderContent = () => {
if (isDarkTheme || actualTheme === 'dark') {
// 深色主题布局
return (
<>
<GameMainMenus
theme={actualTheme}
selectedCategory={selectedCategory}
onCategorySelect={handleCategorySelect}
/>
<BannerSwiper theme={actualTheme} />
<NoticeBar theme={actualTheme} />
<HighPrizeGame theme={actualTheme} onGamePress={handleGamePress} />
<Lobby theme={actualTheme} onGamePress={handleGamePress} />
<FastFootNav theme={actualTheme} onTabPress={handleTabPress} />
</>
);
} else {
// 浅色主题布局
return (
<>
<BannerSwiper theme={actualTheme} />
<NoticeBar theme={actualTheme} />
<GameMainMenus
theme={actualTheme}
selectedCategory={selectedCategory}
onCategorySelect={handleCategorySelect}
/>
<Lobby theme={actualTheme} onGamePress={handleGamePress} />
</>
);
}
};
return (
<SafeAreaView style={s.container}>
{/* Header */}
<Header
theme={actualTheme}
onSearch={handleSearch}
onMessagePress={() => Alert.alert('消息', '消息功能')}
onUserPress={() => Alert.alert('用户', '用户中心')}
unreadCount={3}
/>
{/* 内容区域 */}
<View style={s.contentContainer}>
<ScrollView
style={s.contentContainer}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={handleRefresh}
tintColor={Colors[actualTheme].primary}
/>
}
showsVerticalScrollIndicator={false}
>
<View style={s.scrollContent}>{renderContent()}</View>
</ScrollView>
</View>
</SafeAreaView>
);
}

View File

@@ -2,7 +2,6 @@
* 轮播图组件
*
* 展示首页轮播图,支持自动播放和手动滑动
* 使用真实数据
*/
import React, { useState, useEffect, useRef, useCallback } from 'react';
@@ -17,23 +16,22 @@ import {
Dimensions,
Alert,
} from 'react-native';
import Colors from '@/constants/Colors';
import { useColorScheme } from '@/hooks';
// import type { Banner } from '@/types/home';
import { styles } from './styles';
import useMsgStore from '@/stores/msgStore';
interface BannerSwiperProps {
theme: 'light' | 'dark';
}
interface BannerSwiperProps {}
const { width } = Dimensions.get('window');
/**
* 轮播图组件
*/
export default function BannerSwiper({ theme }: BannerSwiperProps) {
const s = styles[theme];
export default function BannerSwiper({}: BannerSwiperProps) {
const colorScheme = useColorScheme();
const s = styles[colorScheme];
const [currentIndex, setCurrentIndex] = useState(0);
const [loading, setLoading] = useState(true);
const scrollViewRef = useRef<ScrollView>(null);
@@ -102,7 +100,7 @@ export default function BannerSwiper({ theme }: BannerSwiperProps) {
style={[
s.image,
{
backgroundColor: theme === 'dark' ? '#333' : '#e0e0e0',
backgroundColor: colorScheme === 'dark' ? '#333' : '#e0e0e0',
},
]}
/>

View File

@@ -12,7 +12,7 @@ import {
} from 'react-native';
import { useColorScheme } from '@/hooks';
import { createThemeStyles } from '@/theme';
import Colors from '@/constants/Colors';
import { Colors } from '@/theme';
const { width } = Dimensions.get('window');

View File

@@ -14,7 +14,7 @@ import {
Animated,
} from 'react-native';
import { createThemeStyles } from '@/theme';
import Colors from '@/constants/Colors';
import { useColorScheme } from '@/hooks';
import { mockNavItems } from '@/services/mockHomeService';
import type { NavItem } from '@/types/home';
@@ -66,7 +66,6 @@ const styles = createThemeStyles((colors) => ({
}));
interface FastFootNavProps {
theme: 'light' | 'dark';
items?: NavItem[];
onTabPress?: (tabId: string, action: string) => void;
}
@@ -74,8 +73,9 @@ interface FastFootNavProps {
/**
* 快速底部导航组件
*/
export default function FastFootNav({ theme, items: propItems, onTabPress }: FastFootNavProps) {
const s = styles[theme];
export default function FastFootNav({ items: propItems, onTabPress }: FastFootNavProps) {
const colorScheme = useColorScheme();
const s = styles[colorScheme];
const [items, setItems] = useState<NavItem[]>(propItems || []);
const [selectedId, setSelectedId] = useState<string | null>(null);

View File

@@ -5,19 +5,37 @@
*/
import React, { useRef, useEffect, useState, useCallback, useMemo } from 'react';
import { View, Text, ScrollView, TouchableOpacity, Animated } from 'react-native';
import { View, Text, ScrollView, TouchableOpacity, Animated, Image, Platform } from 'react-native';
// import type { GameCategory } from '@/types/home';
import { styles } from './styles';
import { useGameMainMenus, useMenuDataLoaded } from '@/hooks/useGameMenus';
import { styles } from './styles';
import { useGameMainMenus, useMenuDataLoaded, useSelectedCategory } from '@/hooks/useGameMenus';
// import useGameStore from '@/stores/gameStore';
import { ThemeEnum } from '@/constants/theme';
// import { ThemeEnum } from '@/constants/theme';
import { Colors, useColorScheme } from '@/theme';
// 条件导入 LinearGradient - 仅在非 Web 平台使用
let LinearGradient: any = null;
if (Platform.OS !== 'web') {
LinearGradient = require('react-native-linear-gradient').default;
}
// 游戏菜单图片映射 - 使用 require 加载本地资源
const MENU_ICON_MAP: Record<string, any> = {
'recommend': require('../../../../assets/images/game/menu/recommend.png'),
'chess': require('../../../../assets/images/game/menu/chess.png'),
'electronic': require('../../../../assets/images/game/menu/electronic.png'),
'fishing': require('../../../../assets/images/game/menu/fishing.png'),
'lottery': require('../../../../assets/images/game/menu/lottery.png'),
'sports': require('../../../../assets/images/game/menu/sports.png'),
'trial': require('../../../../assets/images/game/menu/trial.png'),
'blockThird': require('../../../../assets/images/game/menu/blockThird.png'),
'clock-solid': require('../../../../assets/images/game/menu/clock-solid.png'),
'clock-solid_dark': require('../../../../assets/images/game/menu/clock-solid_dark.png'),
'home-star-solid': require('../../../../assets/images/game/menu/home-star-solid.png'),
'live': require('../../../../assets/images/game/menu/live.png'),
};
interface GameMainMenuProps {
theme: ThemeEnum;
selectedCategory?: string;
onCategorySelect?: (categoryId: string) => void;
topHeight?: number;
showSubMenus?: boolean;
}
@@ -26,16 +44,17 @@ interface GameMainMenuProps {
* 游戏分类菜单组件
*/
export default function GameMainMenu({
theme,
selectedCategory = '103',
onCategorySelect,
topHeight = 0,
showSubMenus = true,
}: GameMainMenuProps) {
const theme = useColorScheme();
const s = styles[theme];
const scrollViewRef = useRef<ScrollView>(null);
const gameMenus = useGameMainMenus(theme);
// 从 hook 获取选中分类和更新方法
const { selectedCategory, setSelectedCategory } = useSelectedCategory();
// 检查数据加载完成
const isDataLoaded = useMenuDataLoaded();
@@ -55,9 +74,12 @@ export default function GameMainMenu({
}, [selectedIndex]);
// 使用 useCallback 稳定 onPress 回调
const handleCategoryPress = useCallback((categoryKey: string) => {
onCategorySelect?.(categoryKey);
}, [onCategorySelect]);
const handleCategoryPress = useCallback(
(categoryKey: string) => {
setSelectedCategory(categoryKey);
},
[setSelectedCategory]
);
// 骨架屏 - 显示加载中的占位符
const renderSkeleton = () => (
@@ -68,16 +90,16 @@ export default function GameMainMenu({
showsHorizontalScrollIndicator={false}
scrollEventThrottle={16}
>
{[1, 2, 3, 4, 5].map((index) => (
{Array.from({ length: 6 }).map((_, index) => (
<View
key={`skeleton-${index}`}
style={[s.categoryItem, { backgroundColor: theme === 'dark' ? '#333' : '#e0e0e0' }]}
style={[s.menuItem, { backgroundColor: theme === 'dark' ? '#333' : '#e0e0e0' }]}
/>
))}
</ScrollView>
</View>
);
console.log('isDataLoaded', isDataLoaded);
// 如果动态数据还未加载,显示骨架屏
if (!isDataLoaded) {
return renderSkeleton();
@@ -92,20 +114,105 @@ export default function GameMainMenu({
showsHorizontalScrollIndicator={false}
scrollEventThrottle={16}
>
{gameMenus.map((menu) => (
<TouchableOpacity
key={menu.key}
style={[s.menuItem, selectedCategory === menu.key && s.menuItemActive]}
onPress={() => handleCategoryPress(menu.key)}
activeOpacity={0.7}
>
<Text
style={[s.menuText, selectedCategory === menu.key && s.menuTextActive]}
{gameMenus.map((menu) => {
// 处理图片源 - 优先使用 logoURL其次使用 icon本地资源
let imageSource: any = null;
if (menu.logo) {
// logo 是 URL直接使用
imageSource = { uri: menu.logo };
} else if (menu.icon) {
// icon 是本地资源名称,从映射表中获取
imageSource = MENU_ICON_MAP[menu.icon];
}
const isActive = selectedCategory === menu.key;
const themeColors = Colors[theme];
// 获取渐变色 - 从主题色到透明
const gradientStart = `${themeColors.tint}40`; // 主题色 + 40% 透明度
const gradientEnd = `${themeColors.tint}00`; // 完全透明
const menuContent = (
<>
{imageSource && (
<Image source={imageSource} style={s.menuIcon} resizeMode="contain" />
)}
<Text style={[s.menuText, isActive && s.menuTextActive]}>
{menu.name}
</Text>
</>
);
// 如果是选中状态,使用 LinearGradient 包装(非 Web 平台)或 CSS 渐变Web 平台)
if (isActive) {
// Web 平台使用 CSS 渐变
if (Platform.OS === 'web') {
const webStyle = {
...s.menuItem,
...s.menuItemActive,
background: `linear-gradient(to top, ${gradientStart}, ${gradientEnd})`,
backgroundColor: undefined, // 移除 backgroundColor使用 background
} as any;
return (
<TouchableOpacity
key={menu.key}
style={webStyle}
onPress={() => handleCategoryPress(menu.key)}
activeOpacity={0.7}
>
{menuContent}
</TouchableOpacity>
);
}
// 非 Web 平台使用 LinearGradient
if (LinearGradient) {
return (
<LinearGradient
key={menu.key}
colors={[gradientStart, gradientEnd]}
start={{ x: 0.5, y: 1 }} // 从下往上
end={{ x: 0.5, y: 0 }}
style={[s.menuItem, s.menuItemActive]}
>
<TouchableOpacity
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}
onPress={() => handleCategoryPress(menu.key)}
activeOpacity={0.7}
>
{menuContent}
</TouchableOpacity>
</LinearGradient>
);
}
// 备用方案:如果 LinearGradient 不可用,使用纯色
return (
<TouchableOpacity
key={menu.key}
style={[s.menuItem, s.menuItemActive]}
onPress={() => handleCategoryPress(menu.key)}
activeOpacity={0.7}
>
{menuContent}
</TouchableOpacity>
);
}
// 未选中状态,使用普通 TouchableOpacity
return (
<TouchableOpacity
key={menu.key}
style={s.menuItem}
onPress={() => handleCategoryPress(menu.key)}
activeOpacity={0.7}
>
{menu.icon || '🎮'} {menu.name}
</Text>
</TouchableOpacity>
))}
{menuContent}
</TouchableOpacity>
);
})}
</ScrollView>
</View>
);

View File

@@ -1,4 +1,4 @@
import { createThemeStyles } from '@/theme';
import { createThemeStyles, createResponsiveThemeStyles } from '@/theme';
import { Dimensions } from 'react-native';
// const { width } = Dimensions.get('window');
@@ -10,7 +10,7 @@ import { Dimensions } from 'react-native';
export const styles = createThemeStyles((colors) => ({
container: {
backgroundColor: colors.background,
paddingVertical: 10,
paddingTop: 5,
borderBottomWidth: 1,
borderBottomColor: colors.border,
},
@@ -18,11 +18,11 @@ export const styles = createThemeStyles((colors) => ({
paddingHorizontal: 12,
},
menuItem: {
paddingHorizontal: 16,
paddingVertical: 10,
paddingHorizontal: 12,
paddingVertical: 5,
marginRight: 8,
borderRadius: 22,
backgroundColor: colors.backgroundSecondary,
borderRadius: 0,
backgroundColor: 'transparent',
justifyContent: 'center',
alignItems: 'center',
elevation: 1,
@@ -30,18 +30,41 @@ export const styles = createThemeStyles((colors) => ({
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
borderBottomColor: 'transparent',
borderBottomWidth: 2,
},
menuItemActive: {
backgroundColor: colors.primary,
// backgroundColor: `${colors.tint}15`, // 主题色 + 20% 透明度
elevation: 2,
shadowOpacity: 0.15,
borderBottomColor: colors.tint,
borderRadius: 0,
},
menuText: {
fontSize: 13,
fontSize: 14,
color: colors.text,
fontWeight: '600',
},
menuTextActive: {
color: '#FFFFFF',
color: colors.tint,
},
menuIcon: {
width: 30,
height: 30,
marginBottom: 4,
},
}));
export const themeStyles = createResponsiveThemeStyles({
menuItemActive: {
backgroundColor: '',
},
}, {
menuItemActive: {
backgroundColor: '',
},
}, {
menuItemActive: {
backgroundColor: '',
},
});

View File

@@ -15,7 +15,7 @@ import {
} from 'react-native';
import { useColorScheme } from '@/hooks';
import { createThemeStyles } from '@/theme';
import Colors from '@/constants/Colors';
import { Colors } from '@/theme';
const { width } = Dimensions.get('window');
@@ -88,7 +88,6 @@ const styles = createThemeStyles((colors) => ({
}));
interface HeaderProps {
theme?: 'light' | 'dark';
onSearch?: (keyword: string) => void;
onMessagePress?: () => void;
onUserPress?: () => void;
@@ -99,16 +98,14 @@ interface HeaderProps {
* Header 组件
*/
export default function Header({
theme = 'light',
onSearch,
onMessagePress,
onUserPress,
unreadCount = 0,
}: HeaderProps) {
const colorScheme = useColorScheme();
const actualTheme = theme === 'light' || theme === 'dark' ? theme : colorScheme;
const s = styles[actualTheme];
const colors = Colors[actualTheme];
const s = styles[colorScheme];
const colors = Colors[colorScheme];
const [searchText, setSearchText] = useState('');
const [isSearching, setIsSearching] = useState(false);

View File

@@ -15,7 +15,7 @@ import {
Image,
} from 'react-native';
import { createThemeStyles } from '@/theme';
import Colors from '@/constants/Colors';
import { useColorScheme } from '@/hooks';
import { mockHighPrizeGames } from '@/services/mockHomeService';
import type { HighPrizeGame as HighPrizeGameType } from '@/types/home';
@@ -85,7 +85,6 @@ const styles = createThemeStyles((colors) => ({
}));
interface HighPrizeGameProps {
theme: 'light' | 'dark';
games?: HighPrizeGameType[];
onGamePress?: (game: HighPrizeGameType) => void;
}
@@ -93,8 +92,9 @@ interface HighPrizeGameProps {
/**
* 高奖金游戏组件
*/
export default function HighPrizeGame({ theme, games: propGames, onGamePress }: HighPrizeGameProps) {
const s = styles[theme];
export default function HighPrizeGame({ games: propGames, onGamePress }: HighPrizeGameProps) {
const colorScheme = useColorScheme();
const s = styles[colorScheme];
const [games, setGames] = useState<HighPrizeGameType[]>(propGames || []);
const [selectedId, setSelectedId] = useState<string | null>(null);

View File

@@ -15,8 +15,8 @@ import {
ActivityIndicator,
Dimensions,
} from 'react-native';
import { createThemeStyles } from '@/theme';
import Colors from '@/constants/Colors';
import { createThemeStyles, useColorScheme, useThemeInfo } from '@/theme';
import { useSelectedCategory } from '@/hooks/useGameMenus';
import { getMockGamesByCategory } from '@/services/mockHomeService';
import type { Game } from '@/types/home';
@@ -100,9 +100,7 @@ const styles = createThemeStyles((colors) => ({
}));
interface LobbyProps {
theme: 'light' | 'dark';
games?: Game[];
selectedCategory?: number;
onGamePress?: (game: Game) => void;
topHeight?: number;
}
@@ -111,13 +109,14 @@ interface LobbyProps {
* 游戏大厅组件
*/
export default function Lobby({
theme,
games: propGames,
selectedCategory = 0,
onGamePress,
topHeight = 0,
}: LobbyProps) {
const s = styles[theme];
const colorScheme = useColorScheme();
const s = styles[colorScheme];
const { colors } = useThemeInfo();
const { selectedCategory } = useSelectedCategory();
const [games, setGames] = useState<Game[]>(propGames || []);
const [loading, setLoading] = useState(true);
@@ -179,7 +178,7 @@ export default function Lobby({
if (loading) {
return (
<View style={s.loadingContainer}>
<ActivityIndicator size="large" color={Colors[theme].primary} />
<ActivityIndicator size="large" color={colors.primary} />
</View>
);
}

View File

@@ -14,7 +14,7 @@ import {
Dimensions,
} from 'react-native';
import { createThemeStyles } from '@/theme';
import Colors from '@/constants/Colors';
import { useColorScheme } from '@/hooks';
import { mockNotices } from '@/services/mockHomeService';
import type { Notice } from '@/types/home';
@@ -66,7 +66,6 @@ const styles = createThemeStyles((colors) => ({
}));
interface NoticeBarProps {
theme: 'light' | 'dark';
notices?: Notice[];
onNoticePress?: (notice: Notice) => void;
}
@@ -74,8 +73,9 @@ interface NoticeBarProps {
/**
* 公告栏组件
*/
export default function NoticeBar({ theme, notices: propNotices, onNoticePress }: NoticeBarProps) {
const s = styles[theme];
export default function NoticeBar({ notices: propNotices, onNoticePress }: NoticeBarProps) {
const colorScheme = useColorScheme();
const s = styles[colorScheme];
const [notices, setNotices] = useState<Notice[]>(propNotices || []);
const [currentNotice, setCurrentNotice] = useState(0);
const [visible, setVisible] = useState(true);

View File

@@ -7,7 +7,7 @@
import React from 'react';
import BannerSwiperComponent from './BannerSwiper';
import NoticeBarComponent from './NoticeBar';
import GameCategoryMenuComponent from './GameCategoryMenu';
import GameMainMenusComponent from './GameMainMenus';
import LobbyComponent from './Lobby';
import HighPrizeGameComponent from './HighPrizeGame';
import FastFootNavComponent from './FastFootNav';
@@ -17,7 +17,7 @@ import BottomTabsComponent from './BottomTabs';
// 使用 React.memo 优化组件性能,避免不必要的重新渲染
export const BannerSwiper = React.memo(BannerSwiperComponent);
export const NoticeBar = React.memo(NoticeBarComponent);
export const GameCategoryMenu = React.memo(GameCategoryMenuComponent);
export const GameMainMenus = React.memo(GameMainMenusComponent);
export const Lobby = React.memo(LobbyComponent);
export const HighPrizeGame = React.memo(HighPrizeGameComponent);
export const FastFootNav = React.memo(FastFootNavComponent);

View File

@@ -1,23 +1,30 @@
/**
* 首页容器组件
*
* 支持浅色/深色主题,包含完整的首页功能:
* - Header搜索、用户信息
* - 轮播图
* - 游戏分类菜单
* - 游戏大厅
* - 公告栏
* - 高奖金游戏(深色主题)
* - 快速导航(深色主题)
* - BottomTabs底部导航
* 完整首页容器
* 包含 Header、内容区域、BottomTabs
* 支持主题切换和真实数据
*/
import React, { useMemo, useCallback } from 'react';
import { ScrollView, StyleSheet, RefreshControl } from 'react-native';
import { useColorScheme } from '@/hooks';
import { createThemeStyles } from '@/theme';
import Colors from '@/constants/Colors';
import HomeScreenComplete from './HomeScreenComplete';
import React, { useState, useEffect, useCallback } from 'react';
import { View, ScrollView, RefreshControl, Alert } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { createThemeStyles, useColorScheme, useThemeInfo } from '@/theme';
import {
Header,
BannerSwiper,
NoticeBar,
GameMainMenus,
Lobby,
HighPrizeGame,
FastFootNav,
} from './components';
import { requestHomePageData } from '@/stores/gameStore';
import { useTenantLoad } from '@/stores/tenantStore';
import type {
Banner,
Notice,
GameCategory,
Game,
HighPrizeGame as HighPrizeGameType,
} from '@/types/home';
/**
* 创建主题样式
@@ -27,33 +34,124 @@ const styles = createThemeStyles((colors) => ({
flex: 1,
backgroundColor: colors.background,
},
scrollView: {
contentContainer: {
flex: 1,
},
scrollContent: {
paddingBottom: 20,
},
}));
/**
* 首页主容器组件
*/
export default function HomeScreen() {
const theme = useColorScheme();
const s = styles[theme];
const [refreshing, setRefreshing] = React.useState(false);
// 下拉刷新处理
const onRefresh = useCallback(() => {
setRefreshing(true);
// 模拟刷新延迟
setTimeout(() => {
setRefreshing(false);
}, 1000);
/**
* 完整首页容器
*/
export default function HomePage() {
const colorScheme = useColorScheme();
const s = styles[colorScheme];
const { isDark: isDarkTheme, colors } = useThemeInfo();
const [refreshing, setRefreshing] = useState(false);
const tenantLoad = useTenantLoad();
// 加载首页数据
const loadHomePageData = useCallback(async () => {
try {
await requestHomePageData();
} catch (error) {
console.error('加载首页数据失败:', error);
}
}, []);
// 初始化加载
useEffect(() => {
console.log('租户数据加载完成:', tenantLoad);
if (tenantLoad) {
loadHomePageData();
}
}, [loadHomePageData, tenantLoad]);
// 下拉刷新
const handleRefresh = useCallback(async () => {
setRefreshing(true);
try {
await loadHomePageData();
} finally {
setRefreshing(false);
}
}, [loadHomePageData]);
// 处理游戏点击
const handleGamePress = useCallback((game: Game) => {
Alert.alert('游戏', `点击了: ${game.play_up_name}`);
// 这里可以添加打开游戏的逻辑
}, []);
// 处理底部 Tab 点击
const handleTabPress = useCallback((tabId: string, action: string) => {
Alert.alert('导航', `点击了: ${tabId}`);
// 这里可以添加导航逻辑
}, []);
// 处理搜索
const handleSearch = useCallback((keyword: string) => {
Alert.alert('搜索', `搜索关键词: ${keyword}`);
// 这里可以添加搜索逻辑
}, []);
// 根据主题选择要显示的组件
const renderContent = () => {
if (isDarkTheme) {
// 深色主题布局
return (
<>
<GameMainMenus />
<BannerSwiper />
<NoticeBar />
<HighPrizeGame onGamePress={handleGamePress} />
<Lobby onGamePress={handleGamePress} />
<FastFootNav onTabPress={handleTabPress} />
</>
);
} else {
// 浅色主题布局
return (
<>
<BannerSwiper />
<NoticeBar />
<GameMainMenus />
<Lobby onGamePress={handleGamePress} />
</>
);
}
};
return (
<HomeScreenComplete
theme={theme}
isDarkTheme={theme === 'dark'}
/>
<SafeAreaView style={s.container}>
{/* Header */}
<Header
onSearch={handleSearch}
onMessagePress={() => Alert.alert('消息', '消息功能')}
onUserPress={() => Alert.alert('用户', '用户中心')}
unreadCount={3}
/>
{/* 内容区域 */}
<View style={s.contentContainer}>
<ScrollView
style={s.contentContainer}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={handleRefresh}
tintColor={colors.primary}
/>
}
showsVerticalScrollIndicator={false}
>
<View style={s.scrollContent}>{renderContent()}</View>
</ScrollView>
</View>
</SafeAreaView>
);
}