import { useThemeColor } from '@/hooks/use-theme-color'; import { Template } from '@/lib/types/template'; import { ActivityIndicator, FlatList, RefreshControl, StyleSheet, View } from 'react-native'; import { ThemedText } from '../themed-text'; import { ThemedView } from '../themed-view'; import { TemplateCard } from './template-card'; interface TemplateListProps { templates: Template[]; loading?: boolean; refreshing?: boolean; isLoadingMore?: boolean; hasMore?: boolean; onRefresh?: () => void; onLoadMore?: () => void; onTemplatePress?: (template: Template) => void; onVideoChange?: (template: Template, index: number) => void; error?: string | null; } export function TemplateList({ templates, loading = false, refreshing = false, isLoadingMore = false, hasMore = true, onRefresh, onLoadMore, onTemplatePress, onVideoChange, error, }: TemplateListProps) { const tintColor = useThemeColor({}, 'tint'); const errorColor = useThemeColor({}, 'error'); // 渲染底部加载指示器 const renderFooter = () => { if (isLoadingMore) { return ( 加载中... ); } if (!hasMore && templates.length > 0) { return ( — 没有更多了 — ); } return null; }; if (loading && templates.length === 0) { return ( 加载中... ); } if (error) { return ( ❌ {error} ); } if (templates.length === 0) { return ( 暂无模板 {!hasMore && ( — 没有更多了 — )} ); } return ( item.id} renderItem={({ item, index }) => ( )} numColumns={2} columnWrapperStyle={styles.row} contentContainerStyle={styles.listContent} refreshControl={ onRefresh ? ( ) : undefined } onEndReached={onLoadMore} onEndReachedThreshold={0.2} ListFooterComponent={renderFooter} ListFooterComponentStyle={templates.length > 0 ? styles.footerContainer : null} showsVerticalScrollIndicator={false} removeClippedSubviews={true} maxToRenderPerBatch={10} initialNumToRender={6} windowSize={10} /> ); } const styles = StyleSheet.create({ centerContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20, }, listContent: { paddingHorizontal: 14, paddingTop: 70, paddingBottom: 80, }, row: { justifyContent: 'space-between', paddingHorizontal: 2, }, loadingText: { marginTop: 12, fontSize: 16, opacity: 0.7, }, errorText: { fontSize: 16, textAlign: 'center', }, emptyText: { fontSize: 16, opacity: 0.7, }, footerLoader: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', paddingVertical: 20, gap: 8, }, footerText: { fontSize: 14, opacity: 0.7, }, footerContainer: { paddingBottom: 20, }, noMoreContainer: { paddingVertical: 20, alignItems: 'center', }, noMoreText: { fontSize: 14, opacity: 0.5, color: '#666', }, });