diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 1601dc8..1b1016f 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -19,7 +19,9 @@ import { import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'; import { DownArrowIcon, PointsIcon, SearchIcon } from '@/components/icon'; -import { HomeSkeleton } from '@/components/skeleton/HomeSkeleton'; +import ErrorState from '@/components/ErrorState'; +import LoadingState from '@/components/LoadingState'; +import RefreshControl from '@/components/RefreshControl'; import { useActivates } from '@/hooks/use-activates'; import { useCategories } from '@/hooks/use-categories'; import { CategoryTemplate } from '@repo/sdk'; @@ -82,6 +84,7 @@ export default function HomeScreen() { const params = useLocalSearchParams() const [activeTab, setActiveTab] = useState(0) const [selectedCategoryId, setSelectedCategoryId] = useState(null) + const [refreshing, setRefreshing] = useState(false) const { load: loadCategories, data: categoriesData, loading: categoriesLoading, error: categoriesError } = useCategories() const { load, data: activatesData, error } = useActivates() @@ -91,6 +94,12 @@ export default function HomeScreen() { loadCategories() }, []) + const handleRefresh = async () => { + setRefreshing(true) + await Promise.all([load(), loadCategories()]) + setRefreshing(false) + } + useEffect(() => { // 当分类数据加载完成后,默认选中第一个分类 if (categoriesData?.categories && categoriesData.categories.length > 0 && !selectedCategoryId) { @@ -280,6 +289,9 @@ export default function HomeScreen() { style={styles.scrollView} contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false} + refreshControl={ + + } onScroll={(event) => { const scrollY = event.nativeEvent.contentOffset.y if (scrollY >= tabsPositionRef.current) { @@ -330,26 +342,21 @@ export default function HomeScreen() { )} {/* 加载状态 */} - {showLoading && } + {showLoading && } + + {/* 错误状态 - 分类加载失败 */} + {categoriesError && ( + loadCategories()} /> + )} {/* 空状态 - 分类数据为空 */} - {showEmptyState && ( - - 暂无分类数据 - loadCategories()}> - 重新加载 - - + {showEmptyState && !categoriesError && ( + loadCategories()} /> )} {/* 空状态 - 当前分类下没有模板 */} {showEmptyTemplates && ( - - 该分类暂无模板 - loadCategories()}> - 刷新 - - + loadCategories()} /> )} {/* 内容网格 - 使用 FlashList 优化性能 */} @@ -659,26 +666,4 @@ const styles = StyleSheet.create({ color: '#F5F5F5', lineHeight: 20, }, - emptyState: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - paddingVertical: 60, - gap: 16, - }, - emptyStateText: { - color: '#ABABAB', - fontSize: 14, - }, - retryButton: { - backgroundColor: '#FF6699', - paddingHorizontal: 24, - paddingVertical: 12, - borderRadius: 8, - }, - retryButtonText: { - color: '#FFFFFF', - fontSize: 14, - fontWeight: '600', - }, })