115 lines
2.8 KiB
TypeScript
115 lines
2.8 KiB
TypeScript
/**
|
|
* PostCardGrid 容器组件
|
|
* 网格模式(小红书风格)的帖子卡片容器
|
|
*/
|
|
|
|
import React from 'react';
|
|
import { TouchableOpacity, StyleSheet, StyleProp, ViewStyle, GestureResponderEvent } from 'react-native';
|
|
import { colors, borderRadius } from '../../../theme';
|
|
import { useResponsive } from '../../../hooks/useResponsive';
|
|
import { PostCardGridProps } from './types';
|
|
import { usePostCardActions } from './hooks/usePostCardActions';
|
|
import { usePostGridStyles } from './hooks/usePostCardStyles';
|
|
import { PostGridCover, PostGridInfo } from './components';
|
|
import { convertToImageGridItems, getConsistentAspectRatio } from './utils';
|
|
|
|
const PostCardGrid: React.FC<PostCardGridProps> = ({
|
|
post,
|
|
onAction,
|
|
features,
|
|
style,
|
|
}) => {
|
|
const { isDesktop } = useResponsive();
|
|
const gridStyles = usePostGridStyles();
|
|
|
|
const {
|
|
handlePress,
|
|
handleUserPress,
|
|
handleImagePress,
|
|
} = usePostCardActions(onAction);
|
|
|
|
// 防御性检查:确保 author 存在
|
|
const author = post.author ?? {
|
|
id: '',
|
|
nickname: '匿名用户',
|
|
avatar: '',
|
|
username: '',
|
|
cover_url: '',
|
|
bio: '',
|
|
website: '',
|
|
location: '',
|
|
posts_count: 0,
|
|
followers_count: 0,
|
|
following_count: 0,
|
|
created_at: '',
|
|
};
|
|
|
|
// 获取封面图(第一张图)
|
|
const coverImage = post.images && post.images.length > 0 ? post.images[0] : null;
|
|
|
|
// 根据帖子 ID 生成一致的宽高比
|
|
const aspectRatio = getConsistentAspectRatio(post.id);
|
|
|
|
// 样式计算
|
|
const containerStyle: StyleProp<ViewStyle> = [
|
|
styles.container,
|
|
!coverImage && styles.containerNoImage,
|
|
isDesktop && styles.containerDesktop,
|
|
];
|
|
|
|
const handleContainerPress = () => {
|
|
handlePress();
|
|
};
|
|
|
|
const handleImagePressLocal = () => {
|
|
if (post.images && post.images.length > 0) {
|
|
handleImagePress(convertToImageGridItems(post.images), 0);
|
|
}
|
|
};
|
|
|
|
const handleUserPressLocal = () => {
|
|
handleUserPress();
|
|
};
|
|
|
|
return (
|
|
<TouchableOpacity
|
|
style={[containerStyle, style]}
|
|
onPress={handleContainerPress}
|
|
activeOpacity={0.9}
|
|
>
|
|
{/* 封面 */}
|
|
<PostGridCover
|
|
image={coverImage}
|
|
content={post.content}
|
|
isVote={post.is_vote}
|
|
aspectRatio={aspectRatio}
|
|
onImagePress={handleImagePressLocal}
|
|
/>
|
|
|
|
{/* 标题和信息 */}
|
|
<PostGridInfo
|
|
title={post.title}
|
|
author={author}
|
|
likesCount={post.likes_count}
|
|
onUserPress={handleUserPressLocal}
|
|
/>
|
|
</TouchableOpacity>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
backgroundColor: '#FFF',
|
|
overflow: 'hidden',
|
|
borderRadius: 8,
|
|
},
|
|
containerDesktop: {
|
|
borderRadius: 12,
|
|
},
|
|
containerNoImage: {
|
|
minHeight: 200,
|
|
justifyContent: 'space-between',
|
|
},
|
|
});
|
|
|
|
export default PostCardGrid; |