This commit is contained in:
imeepos
2026-01-16 15:16:49 +08:00
parent fce99a57bf
commit dcdab410c6
11 changed files with 292 additions and 124 deletions

View File

@@ -1,32 +1,46 @@
import { useState } from 'react'
import { useState, useEffect } from 'react'
import {
View,
Text,
StyleSheet,
Pressable,
StatusBar as RNStatusBar,
ActivityIndicator,
} 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 { useRouter, useLocalSearchParams } from 'expo-router'
import { useTranslation } from 'react-i18next'
import { TopArrowIcon } from '@/components/icon'
import GradientText from '@/components/GradientText'
import { useCategories } from '@/hooks/use-categories'
export default function ChannelsScreen() {
const { t } = useTranslation()
const router = useRouter()
const params = useLocalSearchParams()
const [isExpanded, setIsExpanded] = useState(true)
const [selectedChannel, setSelectedChannel] = useState(2) // 默认选中第二个频道
// 频道数据
const channels = Array.from({ length: 13 }, (_, i) => ({
id: i + 1,
name: t('channels.channelName'),
}))
// 使用 useCategories hook 获取分类数据
const { load, data: categoriesData, loading: categoriesLoading, error: categoriesError } = useCategories()
// 从路由参数获取当前选中的分类 ID
const currentCategoryId = params.categoryId as string | undefined
useEffect(() => {
// 加载分类数据
load()
}, [])
// 使用接口返回的分类数据
const categories = categoriesData?.categories || []
// 如果没有分类数据,显示加载状态或空状态
const showLoading = categoriesLoading
const showEmptyState = !categoriesLoading && categories.length === 0
return (
<View style={styles.screen}>
@@ -41,11 +55,7 @@ export default function ChannelsScreen() {
<Text style={styles.headerTitle}>{t('channels.title')}</Text>
<Pressable
onPress={() => {
if (isExpanded) {
router.push('/')
} else {
setIsExpanded(true)
}
router.back()
}}
>
<TopArrowIcon />
@@ -55,45 +65,65 @@ export default function ChannelsScreen() {
{/* 频道选择区域 */}
{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>
{showLoading ? (
<View style={styles.loadingContainer}>
<ActivityIndicator size="small" color="#FF6699" />
</View>
) : showEmptyState ? (
<View style={styles.emptyStateContainer}>
<Text style={styles.emptyStateText}>{t('channels.noCategories') || '暂无分类'}</Text>
<Pressable style={styles.retryButton} onPress={() => load()}>
<Text style={styles.retryButtonText}>{t('channels.retry') || '重新加载'}</Text>
</Pressable>
</View>
) : (
<View style={styles.channelsGrid}>
{categories.map((category) => {
const isSelected = currentCategoryId === category.id
return (
<Pressable
key={category.id}
onPress={() => {
// 选择分类后返回首页
router.push({
pathname: '/' as any,
params: { categoryId: category.id },
})
}}
style={[styles.channelButtonWrapper]}
>
{isSelected ? (
<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}
>
{category.name}
</GradientText>
</View>
</LinearGradient>
) : (
<View style={styles.channelButtonWrapperUnselected}>
<View style={styles.channelButtonDefault}>
<Text style={styles.channelButtonText}>
{category.name}
</Text>
</View>
</View>
</LinearGradient>
) : (
<View style={styles.channelButtonWrapperUnselected}>
<View style={styles.channelButtonDefault}>
<Text style={styles.channelButtonText}>
{channel.name}
</Text>
</View>
</View>
)}
</Pressable>
)
})}
</View>
)}
</Pressable>
)
})}
</View>
)}
</View>
)}
</SafeAreaView>
@@ -169,5 +199,31 @@ const styles = StyleSheet.create({
fontWeight: '500',
textAlign: 'center',
},
loadingContainer: {
paddingVertical: 24,
alignItems: 'center',
justifyContent: 'center',
},
emptyStateContainer: {
paddingVertical: 40,
alignItems: 'center',
justifyContent: 'center',
gap: 16,
},
emptyStateText: {
color: '#ABABAB',
fontSize: 14,
},
retryButton: {
backgroundColor: '#FF6699',
paddingHorizontal: 24,
paddingVertical: 12,
borderRadius: 8,
},
retryButtonText: {
color: '#FFFFFF',
fontSize: 14,
fontWeight: '600',
},
})