130 lines
4.1 KiB
TypeScript
130 lines
4.1 KiB
TypeScript
|
|
/**
|
|||
|
|
* 聊天头部组件
|
|||
|
|
* 支持响应式布局(宽屏下显示更多信息)
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import React, { useMemo } from 'react';
|
|||
|
|
import { View, TouchableOpacity, StyleSheet } from 'react-native';
|
|||
|
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|||
|
|
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
|||
|
|
import { Avatar, Text } from '../../../../components/common';
|
|||
|
|
import { colors, spacing } from '../../../../theme';
|
|||
|
|
import { chatScreenStyles as baseStyles } from './styles';
|
|||
|
|
import { useResponsive, useBreakpointGTE } from '../../../../hooks/useResponsive';
|
|||
|
|
import { ChatHeaderProps } from './types';
|
|||
|
|
|
|||
|
|
export const ChatHeader: React.FC<ChatHeaderProps> = ({
|
|||
|
|
isGroupChat,
|
|||
|
|
groupInfo,
|
|||
|
|
otherUser,
|
|||
|
|
routeGroupName,
|
|||
|
|
typingHint,
|
|||
|
|
onBack,
|
|||
|
|
onTitlePress,
|
|||
|
|
onMorePress,
|
|||
|
|
}) => {
|
|||
|
|
// 响应式布局
|
|||
|
|
const { width } = useResponsive();
|
|||
|
|
const isWideScreen = useBreakpointGTE('lg');
|
|||
|
|
|
|||
|
|
// 合并样式
|
|||
|
|
const styles = useMemo(() => {
|
|||
|
|
return StyleSheet.create({
|
|||
|
|
...baseStyles,
|
|||
|
|
headerContainer: {
|
|||
|
|
...baseStyles.headerContainer,
|
|||
|
|
maxWidth: isWideScreen ? 1200 : undefined,
|
|||
|
|
alignSelf: isWideScreen ? 'center' : undefined,
|
|||
|
|
width: isWideScreen ? '100%' : undefined,
|
|||
|
|
},
|
|||
|
|
header: {
|
|||
|
|
...baseStyles.header,
|
|||
|
|
paddingHorizontal: isWideScreen ? spacing.xl : spacing.md,
|
|||
|
|
},
|
|||
|
|
headerName: {
|
|||
|
|
...baseStyles.headerName,
|
|||
|
|
fontSize: isWideScreen ? 19 : 17,
|
|||
|
|
},
|
|||
|
|
memberCount: {
|
|||
|
|
...baseStyles.memberCount,
|
|||
|
|
fontSize: isWideScreen ? 14 : 13,
|
|||
|
|
},
|
|||
|
|
typingHint: {
|
|||
|
|
...baseStyles.typingHint,
|
|||
|
|
fontSize: isWideScreen ? 13 : 12,
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
}, [isWideScreen]);
|
|||
|
|
|
|||
|
|
// 获取显示标题
|
|||
|
|
const getDisplayTitle = () => {
|
|||
|
|
if (isGroupChat) {
|
|||
|
|
return routeGroupName || groupInfo?.name || '群聊';
|
|||
|
|
}
|
|||
|
|
return otherUser?.nickname || '用户';
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<SafeAreaView edges={['top']} style={styles.headerContainer}>
|
|||
|
|
<View style={styles.header}>
|
|||
|
|
<TouchableOpacity
|
|||
|
|
style={styles.backButton}
|
|||
|
|
onPress={onBack}
|
|||
|
|
>
|
|||
|
|
<MaterialCommunityIcons name="arrow-left" size={22} color={colors.primary.dark} />
|
|||
|
|
</TouchableOpacity>
|
|||
|
|
|
|||
|
|
<View style={styles.headerCenter}>
|
|||
|
|
<TouchableOpacity
|
|||
|
|
style={styles.titleRow}
|
|||
|
|
onPress={onTitlePress}
|
|||
|
|
activeOpacity={0.75}
|
|||
|
|
>
|
|||
|
|
{isGroupChat ? (
|
|||
|
|
<>
|
|||
|
|
<View style={styles.titleLeading}>
|
|||
|
|
<MaterialCommunityIcons name="account-group" size={20} color={colors.primary.main} />
|
|||
|
|
</View>
|
|||
|
|
<View style={styles.titleContent}>
|
|||
|
|
<Text style={styles.headerName} numberOfLines={1}>{getDisplayTitle()}</Text>
|
|||
|
|
<View style={styles.subtitleRow}>
|
|||
|
|
<Text style={styles.memberCount}>{groupInfo?.member_count || 0}位成员</Text>
|
|||
|
|
{typingHint && (
|
|||
|
|
<Text style={styles.typingHint} numberOfLines={1}>{typingHint}</Text>
|
|||
|
|
)}
|
|||
|
|
</View>
|
|||
|
|
</View>
|
|||
|
|
</>
|
|||
|
|
) : (
|
|||
|
|
<>
|
|||
|
|
<Avatar
|
|||
|
|
source={otherUser?.avatar || null}
|
|||
|
|
size={32}
|
|||
|
|
name={otherUser?.nickname || ''}
|
|||
|
|
/>
|
|||
|
|
<View style={styles.titleContent}>
|
|||
|
|
<Text style={styles.headerName} numberOfLines={1}>{getDisplayTitle()}</Text>
|
|||
|
|
{typingHint && (
|
|||
|
|
<View style={styles.subtitleRow}>
|
|||
|
|
<Text style={styles.typingHint} numberOfLines={1}>{typingHint}</Text>
|
|||
|
|
</View>
|
|||
|
|
)}
|
|||
|
|
</View>
|
|||
|
|
</>
|
|||
|
|
)}
|
|||
|
|
</TouchableOpacity>
|
|||
|
|
</View>
|
|||
|
|
|
|||
|
|
<TouchableOpacity
|
|||
|
|
style={styles.moreButton}
|
|||
|
|
onPress={onMorePress}
|
|||
|
|
>
|
|||
|
|
<MaterialCommunityIcons name="dots-horizontal" size={22} color="#667085" />
|
|||
|
|
</TouchableOpacity>
|
|||
|
|
</View>
|
|||
|
|
</SafeAreaView>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export default ChatHeader;
|