feat: integrate UI components into Video tab
Replace inline LoadingState, ErrorState, and FooterLoading components with reusable UI components (LoadingState, ErrorState, RefreshControl, PaginationLoader). Add retry functionality to ErrorState and maintain consistent styling with #FFE500 color theme. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
141ccabe06
commit
e0a56710d0
|
|
@ -41,6 +41,12 @@ jest.mock('@/components/icon', () => ({
|
|||
WhiteStarIcon: 'WhiteStarIcon',
|
||||
}))
|
||||
|
||||
// Mock UI components
|
||||
jest.mock('@/components/LoadingState', () => 'LoadingState')
|
||||
jest.mock('@/components/ErrorState', () => 'ErrorState')
|
||||
jest.mock('@/components/RefreshControl', () => 'RefreshControl')
|
||||
jest.mock('@/components/PaginationLoader', () => 'PaginationLoader')
|
||||
|
||||
// Mock hooks
|
||||
jest.mock('@/hooks', () => ({
|
||||
useTemplates: jest.fn(() => ({
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ import {
|
|||
FlatList,
|
||||
Pressable,
|
||||
StatusBar as RNStatusBar,
|
||||
ActivityIndicator,
|
||||
RefreshControl,
|
||||
Platform,
|
||||
} from 'react-native'
|
||||
import { StatusBar } from 'expo-status-bar'
|
||||
|
|
@ -19,6 +17,10 @@ import { useTranslation } from 'react-i18next'
|
|||
import { SameStyleIcon, WhiteStarIcon } from '@/components/icon'
|
||||
import { useRouter } from 'expo-router'
|
||||
import { useTemplates, type TemplateDetail } from '@/hooks'
|
||||
import LoadingState from '@/components/LoadingState'
|
||||
import ErrorState from '@/components/ErrorState'
|
||||
import RefreshControl from '@/components/RefreshControl'
|
||||
import PaginationLoader from '@/components/PaginationLoader'
|
||||
|
||||
const { width: screenWidth, height: screenHeight } = Dimensions.get('window')
|
||||
const TAB_BAR_HEIGHT = 83
|
||||
|
|
@ -38,23 +40,6 @@ const Layout = ({ children }: { children: React.ReactNode }) => (
|
|||
</SafeAreaView>
|
||||
)
|
||||
|
||||
const LoadingState = () => (
|
||||
<Layout>
|
||||
<View style={styles.centerContainer}>
|
||||
<ActivityIndicator size="large" color="#FFE500" />
|
||||
<Text style={styles.messageText}>加载中...</Text>
|
||||
</View>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
const ErrorState = () => (
|
||||
<Layout>
|
||||
<View style={styles.centerContainer}>
|
||||
<Text style={styles.messageText}>加载失败,请下拉刷新重试</Text>
|
||||
</View>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
const EmptyState = () => (
|
||||
<Layout>
|
||||
<View style={styles.centerContainer}>
|
||||
|
|
@ -63,12 +48,6 @@ const EmptyState = () => (
|
|||
</Layout>
|
||||
)
|
||||
|
||||
const FooterLoading = () => (
|
||||
<View style={styles.footerLoading}>
|
||||
<ActivityIndicator size="small" color="#FFE500" />
|
||||
</View>
|
||||
)
|
||||
|
||||
// 计算图片显示尺寸
|
||||
const calculateImageSize = (
|
||||
imageSize: { width: number; height: number } | null,
|
||||
|
|
@ -207,8 +186,22 @@ export default function VideoScreen() {
|
|||
hasMore,
|
||||
})
|
||||
|
||||
if (loading && templates.length === 0) return <LoadingState />
|
||||
if (error && templates.length === 0) return <ErrorState />
|
||||
if (loading && templates.length === 0) {
|
||||
return (
|
||||
<Layout>
|
||||
<LoadingState color="#FFE500" message="加载中..." />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
if (error && templates.length === 0) {
|
||||
return (
|
||||
<Layout>
|
||||
<ErrorState message="加载失败,请下拉刷新重试" onRetry={handleRefresh} />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
if (!loading && filteredTemplates.length === 0) return <EmptyState />
|
||||
|
||||
return (
|
||||
|
|
@ -228,13 +221,11 @@ export default function VideoScreen() {
|
|||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
onRefresh={handleRefresh}
|
||||
tintColor="#FFE500"
|
||||
colors={['#FFE500']}
|
||||
/>
|
||||
}
|
||||
onEndReached={handleLoadMore}
|
||||
onEndReachedThreshold={0.1}
|
||||
ListFooterComponent={loading ? <FooterLoading /> : null}
|
||||
ListFooterComponent={loading ? <PaginationLoader color="#FFE500" /> : null}
|
||||
maxToRenderPerBatch={5}
|
||||
windowSize={7}
|
||||
initialNumToRender={3}
|
||||
|
|
@ -259,10 +250,6 @@ const styles = StyleSheet.create({
|
|||
fontSize: 14,
|
||||
textAlign: 'center',
|
||||
},
|
||||
footerLoading: {
|
||||
paddingVertical: 20,
|
||||
alignItems: 'center',
|
||||
},
|
||||
videoContainer: {
|
||||
width: screenWidth,
|
||||
position: 'relative',
|
||||
|
|
|
|||
Loading…
Reference in New Issue