183 lines
5.5 KiB
TypeScript
183 lines
5.5 KiB
TypeScript
import { useState, useEffect } from 'react'
|
|
import {
|
|
View,
|
|
Text,
|
|
StyleSheet,
|
|
TextInput,
|
|
Pressable,
|
|
StatusBar as RNStatusBar,
|
|
ActivityIndicator,
|
|
} from 'react-native'
|
|
import { StatusBar } from 'expo-status-bar'
|
|
import { SafeAreaView } from 'react-native-safe-area-context'
|
|
import { useRouter, useLocalSearchParams } from 'expo-router'
|
|
|
|
import { LeftArrowIcon, CloseIcon } from '@/components/icon'
|
|
import SearchResultsGrid from '@/components/SearchResultsGrid'
|
|
import { useTemplates } from '@/hooks/data/use-templates'
|
|
|
|
export default function SearchResultsScreen() {
|
|
const router = useRouter()
|
|
const params = useLocalSearchParams()
|
|
const [searchText, setSearchText] = useState((params.q as string) || '')
|
|
const { execute, data, loading } = useTemplates()
|
|
|
|
useEffect(() => {
|
|
if (searchText) {
|
|
execute({ search: searchText })
|
|
}
|
|
}, [searchText])
|
|
|
|
const searchResults = data?.templates.map((template) => ({
|
|
id: parseInt(template.id),
|
|
title: template.title,
|
|
image: { uri: template.coverImageUrl },
|
|
height: template.aspectRatio === '9:16' ? 236 : 131,
|
|
videoUrl: template.previewUrl,
|
|
thumbnailUrl: template.coverImageUrl,
|
|
})) || []
|
|
|
|
return (
|
|
<SafeAreaView style={styles.container} edges={['top']}>
|
|
<StatusBar style="light" />
|
|
<RNStatusBar barStyle="light-content" />
|
|
|
|
{/* Top Bar with Search */}
|
|
<View style={styles.topBar}>
|
|
<Pressable
|
|
onPress={() => router.back()}
|
|
>
|
|
<LeftArrowIcon />
|
|
</Pressable>
|
|
<Pressable
|
|
style={styles.searchInputContainer}
|
|
onPress={() => {
|
|
router.push({
|
|
pathname: '/searchTemplate',
|
|
params: { q: searchText, focus: 'true' },
|
|
})
|
|
}}
|
|
>
|
|
<TextInput
|
|
style={styles.searchInput}
|
|
value={searchText}
|
|
onChangeText={setSearchText}
|
|
placeholder="搜索"
|
|
placeholderTextColor="#ABABAB"
|
|
underlineColorAndroid="transparent"
|
|
editable={false}
|
|
pointerEvents="none"
|
|
/>
|
|
{searchText.length > 0 && (
|
|
<Pressable
|
|
onPress={(e) => {
|
|
e.stopPropagation()
|
|
router.push({
|
|
pathname: '/searchTemplate',
|
|
params: { q: '', focus: 'true' },
|
|
})
|
|
}}
|
|
style={styles.clearButton}
|
|
>
|
|
<CloseIcon />
|
|
</Pressable>
|
|
)}
|
|
</Pressable>
|
|
<Pressable style={styles.searchButton}>
|
|
<Text style={styles.searchButtonText}>搜索</Text>
|
|
</Pressable>
|
|
</View>
|
|
|
|
{/* 搜索结果网格 */}
|
|
{loading ? (
|
|
<View style={styles.loadingContainer}>
|
|
<ActivityIndicator size="large" color="#FFFFFF" />
|
|
</View>
|
|
) : searchResults.length === 0 ? (
|
|
<View style={styles.emptyContainer}>
|
|
<Text style={styles.emptyText}>未找到相关模板</Text>
|
|
<Text style={styles.emptySubText}>尝试使用其他关键词搜索</Text>
|
|
</View>
|
|
) : (
|
|
<SearchResultsGrid results={searchResults} />
|
|
)}
|
|
</SafeAreaView>
|
|
)
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: '#090A0B',
|
|
},
|
|
topBar: {
|
|
height: 44,
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
paddingHorizontal: 12,
|
|
marginTop: 8,
|
|
marginBottom: 12,
|
|
},
|
|
searchInputContainer: {
|
|
flex: 1,
|
|
marginLeft: 4,
|
|
marginRight: 12,
|
|
position: 'relative',
|
|
height: 40,
|
|
},
|
|
searchInput: {
|
|
flex: 1,
|
|
color: '#F5F5F5',
|
|
fontSize: 14,
|
|
height: 40,
|
|
paddingVertical: 8,
|
|
paddingLeft: 12,
|
|
paddingRight: 36,
|
|
borderWidth: 0,
|
|
borderColor: 'transparent',
|
|
borderRadius: 100,
|
|
backgroundColor: '#16181B',
|
|
},
|
|
clearButton: {
|
|
position: 'absolute',
|
|
right: 8,
|
|
top: 0,
|
|
bottom: 0,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
padding: 4,
|
|
},
|
|
searchButton: {
|
|
paddingHorizontal: 0,
|
|
paddingVertical: 8,
|
|
},
|
|
searchButtonText: {
|
|
color: '#F5F5F5',
|
|
fontSize: 14,
|
|
fontWeight: '500',
|
|
},
|
|
loadingContainer: {
|
|
flex: 1,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
},
|
|
emptyContainer: {
|
|
flex: 1,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
paddingHorizontal: 24,
|
|
},
|
|
emptyText: {
|
|
color: '#F5F5F5',
|
|
fontSize: 16,
|
|
fontWeight: '500',
|
|
marginBottom: 8,
|
|
},
|
|
emptySubText: {
|
|
color: '#ABABAB',
|
|
fontSize: 14,
|
|
fontWeight: '400',
|
|
},
|
|
})
|
|
|