Initial commit: expo-popcore-app
This commit is contained in:
290
app/searchTemplate.tsx
Normal file
290
app/searchTemplate.tsx
Normal file
@@ -0,0 +1,290 @@
|
||||
import { useState, useEffect, useRef } from 'react'
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
StyleSheet,
|
||||
ScrollView,
|
||||
Pressable,
|
||||
StatusBar as RNStatusBar,
|
||||
Dimensions,
|
||||
TextInput,
|
||||
} 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 { DeleteIcon, ChangeIcon, Close1Icon } from '@/components/icon'
|
||||
import SearchBar from '@/components/SearchBar'
|
||||
|
||||
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 [isDeleteMode, setIsDeleteMode] = useState(false)
|
||||
const [searchHistory, setSearchHistory] = useState(['猫咪写真'])
|
||||
const inputRef = useRef<TextInput>(null)
|
||||
const isNavigatingRef = useRef(false)
|
||||
|
||||
// 当从搜索结果页面返回时,更新搜索文本
|
||||
useEffect(() => {
|
||||
if (params.q && typeof params.q === 'string') {
|
||||
setSearchText(params.q)
|
||||
}
|
||||
}, [params.q])
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={['top']}>
|
||||
<StatusBar style="light" />
|
||||
<RNStatusBar barStyle="light-content" />
|
||||
|
||||
{/* Top Bar with Search */}
|
||||
<SearchBar
|
||||
searchText={searchText}
|
||||
onSearchTextChange={setSearchText}
|
||||
onSearch={(text) => {
|
||||
router.push({
|
||||
pathname: '/searchResults',
|
||||
params: { q: text },
|
||||
})
|
||||
}}
|
||||
onBack={() => router.push('/(tabs)')}
|
||||
inputRef={inputRef}
|
||||
autoFocus={params.focus === 'true'}
|
||||
/>
|
||||
{/* 搜索历史和推荐标签 */}
|
||||
<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}>
|
||||
<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={() => {
|
||||
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={() => {
|
||||
setSearchHistory(searchHistory.filter((_, i) => i !== index))
|
||||
}}
|
||||
>
|
||||
<Close1Icon />
|
||||
</Pressable>
|
||||
)}
|
||||
</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>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#090A0B',
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
paddingHorizontal: 12,
|
||||
},
|
||||
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,
|
||||
},
|
||||
exploreHeader: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: 16,
|
||||
},
|
||||
refreshButton: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 1,
|
||||
paddingVertical: 4,
|
||||
},
|
||||
refreshButtonText: {
|
||||
color: '#8A8A8A',
|
||||
fontSize: 12,
|
||||
fontWeight: '400',
|
||||
},
|
||||
exploreTags: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: 8,
|
||||
},
|
||||
exploreTag: {
|
||||
width: (screenWidth - 24 - 8) / 2, // 屏幕宽度 - 左右padding(12*2) - gap(8) 除以2
|
||||
justifyContent: 'center',
|
||||
paddingVertical: 2,
|
||||
},
|
||||
exploreTagText: {
|
||||
color: '#F5F5F5',
|
||||
fontSize: 14,
|
||||
fontWeight: '400',
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user