feat: 首页更新
This commit is contained in:
165
components/Header/index.tsx
Normal file
165
components/Header/index.tsx
Normal file
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* 首页 Header 组件
|
||||
* 包含搜索、用户信息、消息等功能
|
||||
*/
|
||||
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
TextInput,
|
||||
Image,
|
||||
Dimensions,
|
||||
} from 'react-native';
|
||||
import { createThemeStyles, useColorScheme, useThemeInfo } from '@/theme';
|
||||
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
|
||||
/**
|
||||
* 创建主题样式
|
||||
*/
|
||||
const styles = createThemeStyles((colors) => ({
|
||||
container: {
|
||||
backgroundColor: colors.background,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 8,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border,
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingVertical: 8,
|
||||
},
|
||||
logo: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
color: colors.primary,
|
||||
},
|
||||
searchContainer: {
|
||||
flex: 1,
|
||||
marginHorizontal: 12,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: colors.card,
|
||||
borderRadius: 20,
|
||||
paddingHorizontal: 12,
|
||||
height: 36,
|
||||
},
|
||||
searchInput: {
|
||||
flex: 1,
|
||||
marginLeft: 8,
|
||||
fontSize: 14,
|
||||
color: colors.text,
|
||||
},
|
||||
searchPlaceholder: {
|
||||
color: colors.text + '80',
|
||||
},
|
||||
iconButton: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
borderRadius: 18,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginLeft: 8,
|
||||
},
|
||||
badge: {
|
||||
position: 'absolute',
|
||||
top: -4,
|
||||
right: -4,
|
||||
backgroundColor: colors.primary,
|
||||
borderRadius: 8,
|
||||
minWidth: 16,
|
||||
height: 16,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
badgeText: {
|
||||
color: '#fff',
|
||||
fontSize: 10,
|
||||
fontWeight: '600',
|
||||
textAlign: 'center',
|
||||
},
|
||||
}));
|
||||
|
||||
interface HeaderProps {
|
||||
onSearch?: (keyword: string) => void;
|
||||
onMessagePress?: () => void;
|
||||
onUserPress?: () => void;
|
||||
unreadCount?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Header 组件
|
||||
*/
|
||||
export default function Header({
|
||||
onSearch,
|
||||
onMessagePress,
|
||||
onUserPress,
|
||||
unreadCount = 0,
|
||||
}: HeaderProps) {
|
||||
const theme = useColorScheme();
|
||||
const s = styles[theme];
|
||||
const { colors } = useThemeInfo();
|
||||
|
||||
const [searchText, setSearchText] = useState('');
|
||||
const [isSearching, setIsSearching] = useState(false);
|
||||
|
||||
const handleSearch = useCallback(() => {
|
||||
if (searchText.trim()) {
|
||||
onSearch?.(searchText);
|
||||
}
|
||||
}, [searchText, onSearch]);
|
||||
|
||||
const handleClearSearch = useCallback(() => {
|
||||
setSearchText('');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<View style={s.container}>
|
||||
{/* 顶部栏 */}
|
||||
<View style={s.header}>
|
||||
{/* Logo */}
|
||||
<Text style={s.logo}>🎮 游戏大厅</Text>
|
||||
|
||||
{/* 搜索框 */}
|
||||
<View style={s.searchContainer}>
|
||||
<Text style={{ color: colors.text + '60', fontSize: 16 }}>🔍</Text>
|
||||
<TextInput
|
||||
style={[s.searchInput, s.searchPlaceholder]}
|
||||
placeholder="搜索游戏..."
|
||||
placeholderTextColor={colors.text + '60'}
|
||||
value={searchText}
|
||||
onChangeText={setSearchText}
|
||||
onSubmitEditing={handleSearch}
|
||||
returnKeyType="search"
|
||||
/>
|
||||
{searchText ? (
|
||||
<TouchableOpacity onPress={handleClearSearch}>
|
||||
<Text style={{ fontSize: 16 }}>✕</Text>
|
||||
</TouchableOpacity>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
{/* 消息按钮 */}
|
||||
<TouchableOpacity style={s.iconButton} onPress={onMessagePress} activeOpacity={0.7}>
|
||||
<Text style={{ fontSize: 18 }}>💬</Text>
|
||||
{unreadCount > 0 && (
|
||||
<View style={s.badge}>
|
||||
<Text style={s.badgeText}>{unreadCount > 99 ? '99+' : unreadCount}</Text>
|
||||
</View>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* 用户按钮 */}
|
||||
<TouchableOpacity style={s.iconButton} onPress={onUserPress} activeOpacity={0.7}>
|
||||
<Text style={{ fontSize: 18 }}>👤</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user