feat: 优化图片加载和展示功能
- 新增 SmartImage 组件优化图片加载体验 - 新增 ImageGrid 组件支持多图布局展示 - 新增 imageHelper 工具函数 - 优化 PostCard 帖子卡片图片展示 - 优化消息页面 SegmentRenderer - 优化日程页面 ScheduleScreen - 优化上传服务 uploadService
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
* ImageGrid 图片网格组件
|
||||
* 支持 1-9 张图片的智能布局
|
||||
* 根据图片数量自动选择最佳展示方式
|
||||
* 支持预览图优化
|
||||
*/
|
||||
|
||||
import React, { useMemo, useCallback, useState, useEffect } from 'react';
|
||||
@@ -16,6 +17,7 @@ import {
|
||||
} from 'react-native';
|
||||
import { SmartImage, ImageSource } from './SmartImage';
|
||||
import { colors, spacing, borderRadius } from '../../theme';
|
||||
import { getPreviewImageUrl, ImageDisplayMode } from '../../utils/imageHelper';
|
||||
|
||||
const { width: SCREEN_WIDTH } = Dimensions.get('window');
|
||||
|
||||
@@ -69,6 +71,10 @@ export interface ImageGridProps {
|
||||
onImagePress?: (images: ImageGridItem[], index: number) => void;
|
||||
/** 测试ID */
|
||||
testID?: string;
|
||||
/** 显示模式 */
|
||||
displayMode?: ImageDisplayMode;
|
||||
/** 是否使用预览图 */
|
||||
usePreview?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,6 +207,7 @@ const SingleImageItem: React.FC<SingleImageItemProps> = ({
|
||||
/**
|
||||
* 图片网格组件
|
||||
* 智能布局:根据图片数量自动选择最佳展示方式
|
||||
* 支持预览图优化
|
||||
*/
|
||||
export const ImageGrid: React.FC<ImageGridProps> = ({
|
||||
images,
|
||||
@@ -214,6 +221,8 @@ export const ImageGrid: React.FC<ImageGridProps> = ({
|
||||
gridColumns = 3,
|
||||
onImagePress,
|
||||
testID,
|
||||
displayMode = 'list',
|
||||
usePreview = true,
|
||||
}) => {
|
||||
// 通过 onLayout 拿到容器实际宽度
|
||||
const [containerWidth, setContainerWidth] = useState(0);
|
||||
@@ -256,6 +265,12 @@ export const ImageGrid: React.FC<ImageGridProps> = ({
|
||||
const renderSingleImage = () => {
|
||||
const image = displayImages[0];
|
||||
if (!image) return null;
|
||||
|
||||
// 获取预览图 URL
|
||||
const previewUrl = usePreview && displayMode
|
||||
? getPreviewImageUrl(image as any, displayMode)
|
||||
: (image.uri || image.url || '');
|
||||
|
||||
return (
|
||||
<SingleImageItem
|
||||
image={image}
|
||||
@@ -271,27 +286,33 @@ export const ImageGrid: React.FC<ImageGridProps> = ({
|
||||
const renderHorizontal = () => {
|
||||
return (
|
||||
<View style={[styles.horizontalContainer, { gap }]}>
|
||||
{displayImages.map((image, index) => (
|
||||
<Pressable
|
||||
key={image.id || index}
|
||||
onPress={() => handleImagePress(index)}
|
||||
style={[
|
||||
styles.horizontalItem,
|
||||
{
|
||||
flex: 1,
|
||||
aspectRatio: 1,
|
||||
borderRadius: borderRadiusValue,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<SmartImage
|
||||
source={{ uri: image.uri || image.url, width: image.width, height: image.height }}
|
||||
style={styles.fullSize}
|
||||
resizeMode="cover"
|
||||
borderRadius={borderRadiusValue}
|
||||
/>
|
||||
</Pressable>
|
||||
))}
|
||||
{displayImages.map((image, index) => {
|
||||
const previewUrl = usePreview && displayMode
|
||||
? getPreviewImageUrl(image as any, displayMode)
|
||||
: (image.uri || image.url || '');
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
key={image.id || index}
|
||||
onPress={() => handleImagePress(index)}
|
||||
style={[
|
||||
styles.horizontalItem,
|
||||
{
|
||||
flex: 1,
|
||||
aspectRatio: 1,
|
||||
borderRadius: borderRadiusValue,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<SmartImage
|
||||
source={{ uri: previewUrl }}
|
||||
style={styles.fullSize}
|
||||
resizeMode="cover"
|
||||
borderRadius={borderRadiusValue}
|
||||
/>
|
||||
</Pressable>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
@@ -303,6 +324,10 @@ export const ImageGrid: React.FC<ImageGridProps> = ({
|
||||
{displayImages.map((image, index) => {
|
||||
const isLastVisible = index === displayImages.length - 1;
|
||||
const showOverlay = isLastVisible && remainingCount > 0 && showMoreOverlay;
|
||||
|
||||
const previewUrl = usePreview && displayMode
|
||||
? getPreviewImageUrl(image as any, displayMode)
|
||||
: (image.uri || image.url || '');
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
@@ -317,7 +342,7 @@ export const ImageGrid: React.FC<ImageGridProps> = ({
|
||||
]}
|
||||
>
|
||||
<SmartImage
|
||||
source={{ uri: image.uri || image.url, width: image.width, height: image.height }}
|
||||
source={{ uri: previewUrl }}
|
||||
style={styles.fullSize}
|
||||
resizeMode="cover"
|
||||
borderRadius={borderRadiusValue}
|
||||
@@ -361,6 +386,10 @@ export const ImageGrid: React.FC<ImageGridProps> = ({
|
||||
? image.width / image.height
|
||||
: 1;
|
||||
const height = itemWidth / aspectRatio;
|
||||
|
||||
const previewUrl = usePreview && displayMode
|
||||
? getPreviewImageUrl(image as any, displayMode)
|
||||
: (image.uri || image.url || '');
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
@@ -376,7 +405,7 @@ export const ImageGrid: React.FC<ImageGridProps> = ({
|
||||
]}
|
||||
>
|
||||
<SmartImage
|
||||
source={{ uri: image.uri || image.url, width: image.width, height: image.height }}
|
||||
source={{ uri: previewUrl }}
|
||||
style={styles.fullSize}
|
||||
resizeMode="cover"
|
||||
borderRadius={borderRadiusValue}
|
||||
|
||||
Reference in New Issue
Block a user