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

@@ -8,6 +8,7 @@ import {
StatusBar as RNStatusBar,
Dimensions,
TextInput,
ActivityIndicator,
} from 'react-native'
import { StatusBar } from 'expo-status-bar'
import { SafeAreaView } from 'react-native-safe-area-context'
@@ -16,39 +17,41 @@ import { useTranslation } from 'react-i18next'
import { DeleteIcon, ChangeIcon, Close1Icon } from '@/components/icon'
import SearchBar from '@/components/SearchBar'
import { useSearchHistory, useTags } from '@/hooks'
const { width: screenWidth } = Dimensions.get('window')
// 探索更多数据
const exploreMore = [
'照片自动唱歌',
'头像ai漫画',
'冬天第一束花',
'真人唱歌动图',
'背景替换',
'闪电动态头像',
'用自己的头像唱歌',
'动漫头像',
'人像',
'戳戳手',
]
export default function SearchTemplateScreen() {
const { t } = useTranslation()
const router = useRouter()
const params = useLocalSearchParams()
const [searchText, setSearchText] = useState('猫咪')
const [searchText, setSearchText] = useState('')
const [isDeleteMode, setIsDeleteMode] = useState(false)
const [searchHistory, setSearchHistory] = useState(['猫咪写真'])
const inputRef = useRef<TextInput>(null)
const isNavigatingRef = useRef(false)
// 使用搜索历史 hook
const { history: searchHistory, addToHistory, removeFromHistory, clearHistory, isLoading: historyLoading } = useSearchHistory()
// 使用推荐标签 hook
const { load: loadTags, data: tagsData, loading: tagsLoading } = useTags()
useEffect(() => {
// 加载推荐标签
loadTags({ page: 1, limit: 20, orderBy: 'sortOrder', order: 'desc' })
}, [])
// 当从搜索结果页面返回时,更新搜索文本
useEffect(() => {
if (params.q && typeof params.q === 'string') {
setSearchText(params.q)
// 将搜索关键词添加到历史记录
addToHistory(params.q)
}
}, [params.q])
}, [params.q, addToHistory])
// 推荐标签数据
const recommendedTags = tagsData?.tags?.map(tag => tag.name) || []
return (
<SafeAreaView style={styles.container} edges={['top']}>
@@ -60,6 +63,8 @@ export default function SearchTemplateScreen() {
searchText={searchText}
onSearchTextChange={setSearchText}
onSearch={(text) => {
// 执行搜索时,添加到历史记录
addToHistory(text)
router.push({
pathname: '/searchResults',
params: { q: text },
@@ -72,51 +77,106 @@ export default function SearchTemplateScreen() {
{/* 搜索历史和推荐标签 */}
<ScrollView
style={styles.scrollView}
// contentContainerStyle={styles.scrollContent}
showsVerticalScrollIndicator={false}
>
{/* 搜索历史 */}
<View style={styles.historySection}>
<View style={styles.historyHeader}>
<Text style={styles.sectionTitle}>{t('search.history')}</Text>
{isDeleteMode ? (
<View style={styles.deleteActions}>
{!historyLoading && searchHistory.length > 0 && (
<View style={styles.historySection}>
<View style={styles.historyHeader}>
<Text style={styles.sectionTitle}>{t('search.history')}</Text>
{isDeleteMode ? (
<View style={styles.deleteActions}>
<Pressable
onPress={() => {
clearHistory()
setIsDeleteMode(false)
}}
>
<Text style={styles.deleteActionText}>{t('search.clearAll')}</Text>
</Pressable>
<View style={styles.deleteActionSeparator} />
<Pressable
onPress={() => setIsDeleteMode(false)}
>
<Text style={styles.deleteActionText}>{t('search.done')}</Text>
</Pressable>
</View>
) : (
<Pressable
onPress={() => {
setSearchHistory([])
setIsDeleteMode(false)
}}
onPress={() => setIsDeleteMode(true)}
>
<Text style={styles.deleteActionText}>{t('search.clearAll')}</Text>
<DeleteIcon />
</Pressable>
<View style={styles.deleteActionSeparator} />
<Pressable
onPress={() => setIsDeleteMode(false)}
)}
</View>
<View style={styles.historyTags}>
{searchHistory.map((item, index) => (
<View
key={index}
style={styles.historyTagContainer}
>
<Text style={styles.deleteActionText}>{t('search.done')}</Text>
</Pressable>
</View>
) : (
<Pressable
onPress={() => setIsDeleteMode(true)}
>
<DeleteIcon />
</Pressable>
)}
<Pressable
style={styles.historyTag}
onPress={() => {
if (!isDeleteMode && !isNavigatingRef.current) {
isNavigatingRef.current = true
requestAnimationFrame(() => {
router.push({
pathname: '/searchResults',
params: { q: item },
})
setTimeout(() => {
isNavigatingRef.current = false
}, 500)
})
}
}}
>
<Text style={styles.historyTagText}>{item}</Text>
{isDeleteMode && (
<Pressable
style={styles.historyTagDeleteButton}
onPress={() => {
removeFromHistory(item)
}}
>
<Close1Icon />
</Pressable>
)}
</Pressable>
</View>
))}
</View>
</View>
<View style={styles.historyTags}>
{searchHistory.map((item, index) => (
<View
key={index}
style={styles.historyTagContainer}
>
)}
{/* 探索更多 - 推荐标签 */}
<View>
<View style={styles.exploreHeader}>
<Text style={styles.sectionTitle}>{t('search.exploreMore')}</Text>
<Pressable
style={styles.refreshButton}
onPress={() => loadTags({ page: 1, limit: 20, orderBy: 'sortOrder', order: 'desc' })}
>
<ChangeIcon />
<Text style={styles.refreshButtonText}>{t('search.refresh')}</Text>
</Pressable>
</View>
{tagsLoading ? (
<View style={styles.loadingContainer}>
<ActivityIndicator size="small" color="#FF6699" />
</View>
) : recommendedTags.length > 0 ? (
<View style={styles.exploreTags}>
{recommendedTags.map((item, index) => (
<Pressable
style={styles.historyTag}
key={index}
style={styles.exploreTag}
onPress={() => {
if (!isDeleteMode && !isNavigatingRef.current) {
if (!isNavigatingRef.current) {
isNavigatingRef.current = true
requestAnimationFrame(() => {
addToHistory(item)
router.push({
pathname: '/searchResults',
params: { q: item },
@@ -128,56 +188,15 @@ export default function SearchTemplateScreen() {
}
}}
>
<Text style={styles.historyTagText}>{item}</Text>
{isDeleteMode && (
<Pressable
style={styles.historyTagDeleteButton}
onPress={() => {
setSearchHistory(searchHistory.filter((_, i) => i !== index))
}}
>
<Close1Icon />
</Pressable>
)}
<Text style={styles.exploreTagText}>{item}</Text>
</Pressable>
</View>
))}
</View>
</View>
{/* 探索更多 */}
<View>
<View style={styles.exploreHeader}>
<Text style={styles.sectionTitle}>{t('search.exploreMore')}</Text>
<Pressable style={styles.refreshButton}>
<ChangeIcon />
<Text style={styles.refreshButtonText}>{t('search.refresh')}</Text>
</Pressable>
</View>
<View style={styles.exploreTags}>
{exploreMore.map((item, index) => (
<Pressable
key={index}
style={styles.exploreTag}
onPress={() => {
if (!isNavigatingRef.current) {
isNavigatingRef.current = true
requestAnimationFrame(() => {
router.push({
pathname: '/searchResults',
params: { q: item },
})
setTimeout(() => {
isNavigatingRef.current = false
}, 500)
})
}
}}
>
<Text style={styles.exploreTagText}>{item}</Text>
</Pressable>
))}
</View>
))}
</View>
) : (
<View style={styles.emptyContainer}>
<Text style={styles.emptyText}>{t('search.noTags') || '暂无推荐标签'}</Text>
</View>
)}
</View>
</ScrollView>
</SafeAreaView>
@@ -271,6 +290,20 @@ const styles = StyleSheet.create({
fontSize: 12,
fontWeight: '400',
},
loadingContainer: {
paddingVertical: 24,
alignItems: 'center',
justifyContent: 'center',
},
emptyContainer: {
paddingVertical: 40,
alignItems: 'center',
justifyContent: 'center',
},
emptyText: {
color: '#ABABAB',
fontSize: 14,
},
exploreTags: {
flexDirection: 'row',
flexWrap: 'wrap',
@@ -287,4 +320,3 @@ const styles = StyleSheet.create({
fontWeight: '400',
},
})