fix: 修复所有 TypeScript 类型错误

- 修复 useTemplates hook 中缺失的必需参数 (page, limit)
- 修复 searchResults 中 execute 和 refetch 的参数类型
- 修复 aspectRatio 类型从 string 转换为 number
- 修复 loadTags 中缺失的必需参数
- 移除 useTags 中不存在的 isActive 属性
- 修复 useTemplateActions 返回值类型

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
imeepos
2026-01-16 14:14:05 +08:00
parent 4270973652
commit fce99a57bf
7 changed files with 300 additions and 196 deletions

View File

@@ -6,27 +6,42 @@ import {
ScrollView,
Dimensions,
Pressable,
ActivityIndicator,
} from 'react-native'
import { Image } from 'expo-image'
import { useRouter } from 'expo-router'
import { useTranslation } from 'react-i18next'
import { WhiteStarIcon } from '@/components/icon'
import type { TemplateGeneration } from '@/hooks'
import type { TemplateDetail } from '@/hooks'
const { width: screenWidth } = Dimensions.get('window')
interface SearchResultItem extends TemplateGeneration {
height: number
interface TemplateSearchResultItem {
id: string
title: string
image: string
image: string | { uri: string }
previewUrl?: string
coverImageUrl?: string
aspectRatio?: number
height?: number
}
interface SearchResultsGridProps {
results: SearchResultItem[]
results: TemplateSearchResultItem[]
loading?: boolean
}
export default function SearchResultsGrid({ results }: SearchResultsGridProps) {
// 计算卡片高度的辅助函数
const calculateCardHeight = (width: number, aspectRatio?: number): number => {
if (aspectRatio) {
return width / aspectRatio
}
// 默认宽高比
return width * 1.2
}
export default function SearchResultsGrid({ results, loading }: SearchResultsGridProps) {
const { t } = useTranslation()
const router = useRouter()
const [gridWidth, setGridWidth] = useState(screenWidth)
@@ -35,17 +50,19 @@ export default function SearchResultsGrid({ results }: SearchResultsGridProps) {
const cardGap = 5
const cardWidth = (gridWidth - horizontalPadding - cardGap) / 2
const handleSameStylePress = (item: SearchResultItem) => {
const templateData = {
id: item.template?.id,
videoUrl: item.resultUrl?.[0] || item.originalUrl,
thumbnailUrl: item.template?.coverImageUrl,
title: item.template?.title || item.template?.titleEn || '',
}
const handleCardPress = (item: TemplateSearchResultItem) => {
router.push({
pathname: '/generateVideo' as any,
params: { template: JSON.stringify(templateData) },
} as any)
pathname: '/templateDetail' as any,
params: { id: item.id.toString() },
})
}
if (loading) {
return (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#FF6699" />
</View>
)
}
if (results.length === 0) {
@@ -68,38 +85,44 @@ export default function SearchResultsGrid({ results }: SearchResultsGridProps) {
setGridWidth(width)
}}
>
{results.map((item, index) => (
<View
key={item.id}
style={[
styles.card,
{ width: cardWidth },
index % 2 === 0 ? styles.cardLeft : styles.cardRight,
]}
>
<View
style={[styles.cardImageContainer, { height: item.height }]}
>
<Image source={item.image} style={styles.cardImage} contentFit="cover" />
</View>
<Text style={styles.cardTitle} numberOfLines={1}>
{item.title}
</Text>
{results.map((item, index) => {
const height = item.height || calculateCardHeight(cardWidth, item.aspectRatio)
return (
<Pressable
style={styles.sameStyleButton}
onPress={() => handleSameStylePress(item)}
key={item.id}
style={[
styles.card,
{ width: cardWidth },
index % 2 === 0 ? styles.cardLeft : styles.cardRight,
]}
onPress={() => handleCardPress(item)}
>
<WhiteStarIcon />
<Text style={styles.sameStyleText}>{t('searchResults.makeSame')}</Text>
<View style={[styles.cardImageContainer, { height }]}>
<Image
source={item.image}
style={styles.cardImage}
contentFit="cover"
/>
<Text style={styles.cardTitle} numberOfLines={1}>
{item.title}
</Text>
</View>
</Pressable>
</View>
))}
)
})}
</View>
</ScrollView>
)
}
const styles = StyleSheet.create({
loadingContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingVertical: 40,
},
scrollView: {
flex: 1,
},
@@ -114,6 +137,7 @@ const styles = StyleSheet.create({
borderBottomLeftRadius: 12,
borderBottomRightRadius: 12,
marginBottom: 12,
overflow: 'hidden',
},
cardLeft: {
marginRight: 0,
@@ -126,44 +150,29 @@ const styles = StyleSheet.create({
borderRadius: 12,
overflow: 'hidden',
marginBottom: 8,
position: 'relative',
},
cardImage: {
width: '100%',
height: '100%',
},
cardTitle: {
position: 'absolute',
bottom: 8,
left: 8,
color: '#FFFFFF',
fontSize: 12,
fontWeight: '500',
paddingHorizontal: 8,
},
sameStyleButton: {
flexDirection: 'row',
alignItems: 'center',
gap: 4,
backgroundColor: '#262A31',
height: 32,
marginHorizontal: 8,
marginTop: 10,
marginBottom: 8,
borderRadius: 100,
justifyContent: 'center',
},
sameStyleText: {
color: '#FFFFFF',
fontSize: 12,
fontWeight: '500',
lineHeight: 17,
},
emptyContainer: {
flex: 1,
backgroundColor: '#090A0B',
justifyContent: 'center',
alignItems: 'center',
paddingVertical: 60,
},
emptyText: {
color: '#8A8A8A',
fontSize: 14,
},
})