expo-popcore-app/app/channels.tsx

174 lines
6.3 KiB
TypeScript

import { useState } from 'react'
import {
View,
Text,
StyleSheet,
Pressable,
StatusBar as RNStatusBar,
} from 'react-native'
import { StatusBar } from 'expo-status-bar'
import { LinearGradient } from 'expo-linear-gradient'
import { SafeAreaView } from 'react-native-safe-area-context'
import { useRouter } from 'expo-router'
import { useTranslation } from 'react-i18next'
import { TopArrowIcon } from '@/components/icon'
import GradientText from '@/components/GradientText'
export default function ChannelsScreen() {
const { t } = useTranslation()
const router = useRouter()
const [isExpanded, setIsExpanded] = useState(true)
const [selectedChannel, setSelectedChannel] = useState(2) // 默认选中第二个频道
// 频道数据
const channels = Array.from({ length: 13 }, (_, i) => ({
id: i + 1,
name: t('channels.channelName'),
}))
return (
<View style={styles.screen}>
<StatusBar style="light" />
<RNStatusBar barStyle="light-content" />
{/* 顶部容器 - 包含 header 和频道选择区域,带底部圆角 */}
<View style={styles.topContainer}>
<SafeAreaView style={styles.safeArea} edges={['top']}>
{/* 标题栏 */}
<View style={styles.header}>
<Text style={styles.headerTitle}>{t('channels.title')}</Text>
<Pressable
onPress={() => {
if (isExpanded) {
router.push('/')
} else {
setIsExpanded(true)
}
}}
>
<TopArrowIcon />
</Pressable>
</View>
{/* 频道选择区域 */}
{isExpanded && (
<View style={styles.channelsSection}>
<View style={styles.channelsGrid}>
{channels.map((channel) => {
return (
<Pressable
key={channel.id}
onPress={() => setSelectedChannel(channel.id)}
style={[styles.channelButtonWrapper]}
>
{selectedChannel === channel.id ? (
<LinearGradient
colors={['#FF9966', '#FF6699', '#9966FF']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
style={styles.channelButtonGradient}
>
<View style={styles.channelButtonDefault}>
<GradientText
colors={['#FF9966', '#FF6699', '#9966FF']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
style={styles.channelButtonText}
>
{channel.name}
</GradientText>
</View>
</LinearGradient>
) : (
<View style={styles.channelButtonWrapperUnselected}>
<View style={styles.channelButtonDefault}>
<Text style={styles.channelButtonText}>
{channel.name}
</Text>
</View>
</View>
)}
</Pressable>
)
})}
</View>
</View>
)}
</SafeAreaView>
</View>
</View>
)
}
const styles = StyleSheet.create({
screen: {
flex: 1,
backgroundColor: '#0A0A0A',
},
topContainer: {
backgroundColor: '#16181B',
borderBottomLeftRadius: 16,
borderBottomRightRadius: 16,
overflow: 'hidden',
},
safeArea: {
backgroundColor: '#16181B',
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 16,
paddingTop: 27,
paddingBottom: 12,
},
headerTitle: {
color: '#F5F5F5',
fontSize: 12,
fontWeight: '500',
},
searchText: {
color: '#ABABAB',
fontSize: 14,
fontWeight: '400',
},
channelsSection: {
paddingHorizontal: 12,
paddingBottom: 12,
},
channelsGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 8,
},
channelButtonWrapper: {
// 按钮宽度根据内容自适应
},
channelButtonGradient: {
borderRadius: 100,
padding: 1,
},
channelButtonWrapperUnselected: {
borderRadius: 100,
padding: 1,
backgroundColor: 'transparent',
},
channelButtonDefault: {
backgroundColor: '#262A31',
borderRadius: 100,
paddingVertical: 8,
paddingHorizontal: 17,
borderWidth: 1,
borderColor: '#262A31',
},
channelButtonText: {
color: '#F5F5F5',
fontSize: 12,
fontWeight: '500',
textAlign: 'center',
},
})