Files
rn-app/components/Header/index.tsx

168 lines
5.2 KiB
TypeScript
Raw Normal View History

2025-11-12 00:13:26 +08:00
/**
2025-11-13 16:47:10 +08:00
* Header -
* xinyong-web header
*
* - logo
* -
* - /
* -
* -
2025-11-12 00:13:26 +08:00
*/
2025-11-13 16:47:10 +08:00
import React, { useState, useCallback, useMemo } from 'react';
2025-11-12 00:13:26 +08:00
import {
View,
Text,
StyleSheet,
TouchableOpacity,
TextInput,
Image,
Dimensions,
2025-11-13 16:47:10 +08:00
Modal,
ScrollView,
SafeAreaView,
2025-11-12 00:13:26 +08:00
} from 'react-native';
2025-11-13 16:47:10 +08:00
import { useColorScheme, useThemeColors } from '@/theme';
import { useIsLoggedIn, useUser } from '@/stores/userStore';
import { useLogo } from '@/stores/tenantStore';
import { Ionicons, AntDesign } from '@expo/vector-icons';
import LeftMenu from './LeftMenu';
import LoginRegisterModal from './LoginRegisterModal';
import WalletAmount from '../WalletAmount';
import { styles } from './styles';
2025-11-12 00:13:26 +08:00
const { width } = Dimensions.get('window');
interface HeaderProps {
onSearch?: (keyword: string) => void;
onMessagePress?: () => void;
2025-11-13 16:47:10 +08:00
onMenuPress?: () => void;
2025-11-12 00:13:26 +08:00
unreadCount?: number;
}
/**
2025-11-13 16:47:10 +08:00
* Header -
2025-11-12 00:13:26 +08:00
*/
export default function Header({
onSearch,
onMessagePress,
2025-11-13 16:47:10 +08:00
onMenuPress,
2025-11-12 00:13:26 +08:00
unreadCount = 0,
}: HeaderProps) {
2025-11-13 16:47:10 +08:00
const colorScheme = useColorScheme();
const s = styles[colorScheme];
const themeColors = useThemeColors();
const isLoggedIn = useIsLoggedIn();
const user = useUser();
const logoUrl = useLogo();
2025-11-12 00:13:26 +08:00
const [searchText, setSearchText] = useState('');
2025-11-13 16:47:10 +08:00
const [showLeftMenu, setShowLeftMenu] = useState(false);
const [showLoginModal, setShowLoginModal] = useState(false);
2025-11-12 00:13:26 +08:00
const handleSearch = useCallback(() => {
if (searchText.trim()) {
onSearch?.(searchText);
2025-11-13 16:47:10 +08:00
setSearchText('');
2025-11-12 00:13:26 +08:00
}
}, [searchText, onSearch]);
2025-11-13 16:47:10 +08:00
const handleMenuPress = useCallback(() => {
setShowLeftMenu(true);
onMenuPress?.();
}, [onMenuPress]);
const handleLoginPress = useCallback(() => {
setShowLoginModal(true);
2025-11-12 00:13:26 +08:00
}, []);
return (
2025-11-13 16:47:10 +08:00
<>
<View style={s.container}>
{/* 左侧部分 */}
<View style={s.leftSection}>
{/* 菜单按钮 */}
<TouchableOpacity style={s.menuButton} onPress={handleMenuPress} activeOpacity={0.7}>
<AntDesign name="menu-unfold" size={22} color={themeColors.text} />
</TouchableOpacity>
2025-11-12 00:13:26 +08:00
2025-11-13 16:47:10 +08:00
{/* Logo */}
{logoUrl ? <Image source={{ uri: logoUrl }} style={s.logoImage} /> : null}
2025-11-12 00:13:26 +08:00
</View>
2025-11-13 16:47:10 +08:00
{/* 搜索框 */}
{/*<View style={s.searchContainer}>*/}
{/* <Ionicons name="search" size={16} color={themeColors.text + '60'} />*/}
{/* <TextInput*/}
{/* style={s.searchInput}*/}
{/* placeholder="搜索游戏..."*/}
{/* placeholderTextColor={themeColors.text + '60'}*/}
{/* value={searchText}*/}
{/* onChangeText={setSearchText}*/}
{/* onSubmitEditing={handleSearch}*/}
{/* returnKeyType="search"*/}
{/* />*/}
{/* {searchText ? (*/}
{/* <TouchableOpacity onPress={() => setSearchText('')}>*/}
{/* <Ionicons name="close" size={16} color={themeColors.text} />*/}
{/* </TouchableOpacity>*/}
{/* ) : null}*/}
{/*</View>*/}
{/* 右侧部分 */}
<View style={s.rightSection}>
{isLoggedIn && user ? (
<>
{/* 消息按钮 */}
<TouchableOpacity style={s.iconButton} onPress={onMessagePress} activeOpacity={0.7}>
<Ionicons name="chatbubble-outline" size={20} color={themeColors.text} />
{unreadCount > 0 && (
<View style={s.badge}>
<Text style={s.badgeText}>{unreadCount > 99 ? '99+' : unreadCount}</Text>
</View>
)}
</TouchableOpacity>
{/* 用户头像 */}
<TouchableOpacity style={s.iconButton} activeOpacity={0.7}>
{user.avatar ? (
<Image
source={{ uri: user.avatar }}
style={{ width: 32, height: 32, borderRadius: 16 }}
/>
) : (
<Ionicons name="person-circle" size={24} color={themeColors.primary} />
)}
</TouchableOpacity>
</>
) : (
/* 登录/注册按钮 */
<View style={s.authButtons}>
<TouchableOpacity
style={[s.authButton, s.registerButton]}
onPress={() => setShowLoginModal(true)}
activeOpacity={0.7}
>
<Text style={s.registerButtonText}></Text>
</TouchableOpacity>
<TouchableOpacity
style={[s.authButton, s.loginButton]}
onPress={() => setShowLoginModal(true)}
activeOpacity={0.7}
>
<Text style={s.loginButtonText}></Text>
</TouchableOpacity>
2025-11-12 00:13:26 +08:00
</View>
)}
2025-11-13 16:47:10 +08:00
</View>
2025-11-12 00:13:26 +08:00
</View>
2025-11-13 16:47:10 +08:00
{/* 左侧菜单 */}
<LeftMenu visible={showLeftMenu} onClose={() => setShowLeftMenu(false)} />
{/* 登录/注册弹窗 */}
<LoginRegisterModal visible={showLoginModal} onClose={() => setShowLoginModal(false)} />
</>
2025-11-12 00:13:26 +08:00
);
}