expo-popcore-app/app/searchWorks.tsx

247 lines
8.3 KiB
TypeScript

import { useState, useRef, useEffect } from 'react'
import {
View,
Text,
StyleSheet,
ScrollView,
StatusBar as RNStatusBar,
TextInput,
Pressable,
} from 'react-native'
import { StatusBar } from 'expo-status-bar'
import { SafeAreaView } from 'react-native-safe-area-context'
import { useRouter, useLocalSearchParams } from 'expo-router'
import { useTranslation } from 'react-i18next'
import SearchBar from '@/components/SearchBar'
import { DeleteIcon, Close1Icon } from '@/components/icon'
export default function SearchWorksScreen() {
const { t } = useTranslation()
const router = useRouter()
const params = useLocalSearchParams()
const [searchText, setSearchText] = useState('')
const [isDeleteMode, setIsDeleteMode] = useState(false)
const [searchHistory, setSearchHistory] = useState<string[]>(['写真', '萌宠', '合拍', '风景'])
const inputRef = useRef<TextInput>(null)
const isNavigatingRef = useRef(false)
// 当从搜索结果页面返回时,更新搜索文本
useEffect(() => {
if (params.q && typeof params.q === 'string') {
setSearchText(params.q)
}
}, [params.q])
const handleSearch = (text: string) => {
const trimmedText = text.trim()
if (trimmedText) {
// 添加到搜索历史(去重,新搜索词放在最前面)
setSearchHistory((prev) => {
const filtered = prev.filter((item) => item !== trimmedText)
return [trimmedText, ...filtered].slice(0, 10) // 最多保留10条
})
// 跳转到搜索结果页面
router.push({
pathname: '/searchWorksResults',
params: { q: trimmedText },
})
}
}
const handleHistoryTagPress = (item: string) => {
if (!isDeleteMode && !isNavigatingRef.current) {
isNavigatingRef.current = true
requestAnimationFrame(() => {
router.push({
pathname: '/searchWorksResults',
params: { q: item },
})
// 延迟重置,防止快速重复点击
setTimeout(() => {
isNavigatingRef.current = false
}, 500)
})
}
}
return (
<SafeAreaView style={styles.container} edges={['top']}>
<StatusBar style="light" />
<RNStatusBar barStyle="light-content" />
{/* Top Bar with Search */}
<SearchBar
searchText={searchText}
onSearchTextChange={setSearchText}
onSearch={handleSearch}
onBack={() => router.push('/worksList')}
placeholder={t('search.searchWorks')}
inputRef={inputRef}
autoFocus={true}
/>
{/* 内容区域 */}
<ScrollView
style={styles.scrollView}
contentContainerStyle={styles.scrollContent}
showsVerticalScrollIndicator={false}
>
{/* 搜索历史 */}
{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={() => {
setSearchHistory([])
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={() => setIsDeleteMode(true)}
>
<DeleteIcon />
</Pressable>
)}
</View>
<View style={styles.historyTags}>
{searchHistory.map((item, index) => (
<View
key={index}
style={styles.historyTagContainer}
>
<Pressable
style={styles.historyTag}
onPress={() => handleHistoryTagPress(item)}
>
<Text style={styles.historyTagText}>{item}</Text>
{isDeleteMode && (
<Pressable
style={styles.historyTagDeleteButton}
onPress={() => {
setSearchHistory(searchHistory.filter((_, i) => i !== index))
}}
>
<Close1Icon />
</Pressable>
)}
</Pressable>
</View>
))}
</View>
</View>
)}
{searchHistory.length === 0 && (
<View style={styles.emptyContainer}>
<Text style={styles.emptyText}>{t('search.searchWorksPlaceholder')}</Text>
</View>
)}
</ScrollView>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#090A0B',
},
scrollView: {
flex: 1,
backgroundColor: '#090A0B',
paddingHorizontal: 12,
},
scrollContent: {
paddingBottom: 20,
},
historySection: {
paddingBottom: 32,
},
historyHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
sectionTitle: {
color: '#F5F5F5',
fontSize: 14,
fontWeight: '500',
lineHeight: 20,
},
historyTags: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 4,
marginTop: 16,
},
historyTagContainer: {
flexDirection: 'row',
alignItems: 'center',
gap: 4,
},
historyTag: {
backgroundColor: '#191B1F',
borderRadius: 100,
paddingHorizontal: 11,
paddingVertical: 6,
borderWidth: 1,
borderColor: '#191B1F',
height: 29,
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
gap: 4,
},
historyTagText: {
color: '#F5F5F5',
fontSize: 12,
},
historyTagDeleteButton: {
justifyContent: 'center',
alignItems: 'center',
},
deleteActions: {
flexDirection: 'row',
alignItems: 'center',
},
deleteActionText: {
color: '#ABABAB',
fontSize: 14,
fontWeight: '400',
},
deleteActionSeparator: {
width: 1,
height: 14,
backgroundColor: '#ABABAB',
marginHorizontal: 12,
},
emptyContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingTop: 100,
},
emptyText: {
color: '#8A8A8A',
fontSize: 14,
},
})