fix: bug
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import { Image } from 'expo-image'
|
||||
import { VideoView, useVideoPlayer } from 'expo-video'
|
||||
import { LinearGradient } from 'expo-linear-gradient'
|
||||
import { useRouter, useLocalSearchParams } from 'expo-router'
|
||||
import { StatusBar } from 'expo-status-bar'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { FlashList } from '@shopify/flash-list';
|
||||
import { Image } from 'expo-image';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useLocalSearchParams, useRouter } from 'expo-router';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { VideoView, useVideoPlayer } from 'expo-video';
|
||||
import { memo as ReactMemo, useEffect, useRef, useState } from 'react';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Dimensions,
|
||||
Platform,
|
||||
@@ -14,16 +16,70 @@ import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||
} from 'react-native';
|
||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
|
||||
import { DownArrowIcon, PointsIcon, SearchIcon, WhiteStarIcon } from '@/components/icon'
|
||||
import { HomeSkeleton } from '@/components/skeleton/HomeSkeleton'
|
||||
import { useActivates } from '@/hooks/use-activates'
|
||||
import { useCategories } from '@/hooks/use-categories'
|
||||
import { DownArrowIcon, PointsIcon, SearchIcon, WhiteStarIcon } from '@/components/icon';
|
||||
import { HomeSkeleton } from '@/components/skeleton/HomeSkeleton';
|
||||
import { useActivates } from '@/hooks/use-activates';
|
||||
import { useCategories } from '@/hooks/use-categories';
|
||||
|
||||
const { width: screenWidth } = Dimensions.get('window')
|
||||
|
||||
// 卡片组件 - 使用 useCallback 缓存以优化 FlashList 性能
|
||||
const Card = ReactMemo(({ card, cardWidth, t, onPress }: {
|
||||
card: any
|
||||
cardWidth: number
|
||||
t: any
|
||||
onPress: (id: string) => void
|
||||
}) => {
|
||||
return (
|
||||
<Pressable
|
||||
style={[styles.card, { width: cardWidth }]}
|
||||
onPress={() => onPress(card.id)}
|
||||
>
|
||||
<View
|
||||
style={[
|
||||
styles.cardImageContainer,
|
||||
{ height: card.height || cardWidth * 1.2 },
|
||||
]}
|
||||
>
|
||||
{card.isVideo ? (
|
||||
<VideoPreview source={card.image.uri} style={styles.cardImage} />
|
||||
) : (
|
||||
<Image
|
||||
source={card.image}
|
||||
style={styles.cardImage}
|
||||
contentFit="cover"
|
||||
/>
|
||||
)}
|
||||
<LinearGradient
|
||||
colors={['rgba(17, 17, 17, 0)', 'rgba(17, 17, 17, 0.9)']}
|
||||
start={{ x: 0, y: 0 }}
|
||||
end={{ x: 0, y: 1 }}
|
||||
style={styles.cardImageGradient}
|
||||
/>
|
||||
{card.isHot ? (
|
||||
<View style={styles.hotBadge}>
|
||||
<Text style={styles.hotEmoji}>🔥</Text>
|
||||
<Text style={styles.hotText}>{t('home.hotTemplate')}</Text>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.hotBadge}>
|
||||
<WhiteStarIcon />
|
||||
<Text style={styles.hotText}>
|
||||
{card.users}{t('home.peopleUsed')}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
<Text style={styles.cardTitle} numberOfLines={1}>
|
||||
{card.title}
|
||||
</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
)
|
||||
})
|
||||
|
||||
// 视频预览组件
|
||||
function VideoPreview({ source, style }: { source: string; style: any }) {
|
||||
const player = useVideoPlayer(source, (player) => {
|
||||
@@ -332,7 +388,7 @@ export default function HomeScreen() {
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* 内容网格 */}
|
||||
{/* 内容网格 - 使用 FlashList 优化性能 */}
|
||||
{!showLoading && !showEmptyState && !showEmptyTemplates && (
|
||||
<View
|
||||
style={styles.gridContainer}
|
||||
@@ -341,61 +397,28 @@ export default function HomeScreen() {
|
||||
setGridWidth(width)
|
||||
}}
|
||||
>
|
||||
{displayCardData.map((card, index) => (
|
||||
<Pressable
|
||||
key={card.id}
|
||||
style={[
|
||||
styles.card,
|
||||
{ width: cardWidth },
|
||||
index % 2 === 0 ? styles.cardLeft : styles.cardRight,
|
||||
]}
|
||||
onPress={() => {
|
||||
router.push({
|
||||
pathname: '/templateDetail' as any,
|
||||
params: { id: card.id.toString() },
|
||||
})
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={[
|
||||
styles.cardImageContainer,
|
||||
{ height: card.height || cardWidth * 1.2 },
|
||||
]}
|
||||
>
|
||||
{card.isVideo ? (
|
||||
<VideoPreview source={card.image.uri} style={styles.cardImage} />
|
||||
) : (
|
||||
<Image
|
||||
source={card.image}
|
||||
style={styles.cardImage}
|
||||
contentFit="cover"
|
||||
/>
|
||||
)}
|
||||
<LinearGradient
|
||||
colors={['rgba(17, 17, 17, 0)', 'rgba(17, 17, 17, 0.9)']}
|
||||
start={{ x: 0, y: 0 }}
|
||||
end={{ x: 0, y: 1 }}
|
||||
style={styles.cardImageGradient}
|
||||
/>
|
||||
{card.isHot ? (
|
||||
<View style={styles.hotBadge}>
|
||||
<Text style={styles.hotEmoji}>🔥</Text>
|
||||
<Text style={styles.hotText}>{t('home.hotTemplate')}</Text>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.hotBadge}>
|
||||
<WhiteStarIcon />
|
||||
<Text style={styles.hotText}>
|
||||
{card.users}{t('home.peopleUsed')}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
<Text style={styles.cardTitle} numberOfLines={1}>
|
||||
{card.title}
|
||||
</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
))}
|
||||
<FlashList
|
||||
data={displayCardData}
|
||||
renderItem={({ item, index }) => (
|
||||
<Card
|
||||
card={item}
|
||||
cardWidth={cardWidth}
|
||||
t={t}
|
||||
onPress={(id) => {
|
||||
router.push({
|
||||
pathname: '/templateDetail' as any,
|
||||
params: { id: id.toString() },
|
||||
})
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
keyExtractor={(item) => item.id}
|
||||
numColumns={2}
|
||||
estimatedItemSize={cardWidth * 1.2 + 60}
|
||||
showsVerticalScrollIndicator={false}
|
||||
contentContainerStyle={styles.flashListContent}
|
||||
scrollEventThrottle={Platform.OS === 'ios' ? 16 : 50}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
@@ -622,12 +645,10 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
card: {
|
||||
marginBottom: 12,
|
||||
paddingHorizontal: 5,
|
||||
},
|
||||
cardLeft: {
|
||||
marginRight: 0,
|
||||
},
|
||||
cardRight: {
|
||||
marginLeft: 0,
|
||||
flashListContent: {
|
||||
gap: 10,
|
||||
},
|
||||
cardImageContainer: {
|
||||
width: '100%',
|
||||
|
||||
Reference in New Issue
Block a user