160 lines
4.9 KiB
TypeScript
160 lines
4.9 KiB
TypeScript
import { View, StyleSheet, FlatList, Dimensions } from 'react-native'
|
|
import { Skeleton } from './skeleton'
|
|
|
|
const { width: screenWidth } = Dimensions.get('window')
|
|
|
|
const GAP = 2
|
|
const NUM_COLUMNS = 3
|
|
const ITEM_WIDTH = (screenWidth - GAP * 2) / NUM_COLUMNS
|
|
|
|
export function UploadReferenceImageDrawerSkeleton() {
|
|
return (
|
|
<View style={styles.container}>
|
|
{/* 顶部标题栏骨架 */}
|
|
<View style={styles.header}>
|
|
<View style={styles.headerTitles}>
|
|
<Skeleton width={160} height={18} borderRadius={4} />
|
|
<Skeleton width={140} height={16} borderRadius={4} style={styles.headerSubtitle} />
|
|
</View>
|
|
<Skeleton width={24} height={24} borderRadius={12} />
|
|
</View>
|
|
|
|
{/* 标签切换骨架 */}
|
|
<View style={styles.tabContainer}>
|
|
<View style={styles.tab}>
|
|
<View style={styles.tabIconContainer}>
|
|
<Skeleton width={27} height={27} borderRadius={6} />
|
|
</View>
|
|
<Skeleton width={60} height={14} borderRadius={4} />
|
|
</View>
|
|
<View style={styles.tab}>
|
|
<View style={styles.tabIconContainer}>
|
|
<Skeleton width={26} height={26} borderRadius={6} />
|
|
</View>
|
|
<Skeleton width={80} height={14} borderRadius={4} />
|
|
</View>
|
|
</View>
|
|
|
|
{/* 筛选区域骨架 */}
|
|
<View style={styles.filterContainer}>
|
|
<View style={styles.categoryButton}>
|
|
<Skeleton width={120} height={18} borderRadius={4} />
|
|
<Skeleton width={16} height={16} borderRadius={8} />
|
|
</View>
|
|
<View style={styles.filterButtons}>
|
|
<View style={styles.filterButton}>
|
|
<Skeleton width={36} height={16} borderRadius={8} />
|
|
</View>
|
|
<View style={styles.filterButton}>
|
|
<Skeleton width={36} height={16} borderRadius={8} />
|
|
</View>
|
|
</View>
|
|
</View>
|
|
|
|
{/* 图片网格骨架 */}
|
|
<FlatList
|
|
data={Array.from({ length: 30 }, (_, i) => i)}
|
|
keyExtractor={(item) => item.toString()}
|
|
numColumns={NUM_COLUMNS}
|
|
renderItem={({ index }) => {
|
|
const isLastInRow = (index + 1) % NUM_COLUMNS === 0
|
|
const isLastRow = index >= Math.floor(30 / NUM_COLUMNS) * NUM_COLUMNS
|
|
|
|
return (
|
|
<View
|
|
style={[
|
|
styles.imageItem,
|
|
{
|
|
width: ITEM_WIDTH,
|
|
marginRight: isLastInRow ? 0 : GAP,
|
|
marginBottom: isLastRow ? 0 : GAP,
|
|
},
|
|
]}
|
|
>
|
|
<Skeleton width="100%" height="100%" borderRadius={0} />
|
|
</View>
|
|
)
|
|
}}
|
|
showsVerticalScrollIndicator={false}
|
|
/>
|
|
</View>
|
|
)
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: '#16181B',
|
|
paddingTop: 24,
|
|
},
|
|
header: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
paddingHorizontal: 16,
|
|
paddingBottom: 20,
|
|
},
|
|
headerTitles: {
|
|
gap: 4,
|
|
},
|
|
headerSubtitle: {
|
|
marginTop: 2,
|
|
},
|
|
tabContainer: {
|
|
flexDirection: 'row',
|
|
paddingHorizontal: 16,
|
|
gap: 8,
|
|
marginBottom: 24,
|
|
},
|
|
tab: {
|
|
flex: 1,
|
|
height: 52,
|
|
backgroundColor: '#272A30',
|
|
borderRadius: 12,
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
gap: 4,
|
|
},
|
|
tabIconContainer: {
|
|
width: 28,
|
|
height: 28,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
filterContainer: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
paddingHorizontal: 16,
|
|
marginBottom: 9,
|
|
},
|
|
categoryButton: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: 8,
|
|
},
|
|
filterButtons: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
backgroundColor: '#1C1E22',
|
|
borderRadius: 100,
|
|
height: 32,
|
|
padding: 3,
|
|
},
|
|
filterButton: {
|
|
paddingHorizontal: 12,
|
|
paddingVertical: 4,
|
|
minWidth: 48,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
imageItem: {
|
|
aspectRatio: 1 / 1.3,
|
|
overflow: 'hidden',
|
|
backgroundColor: '#262A31',
|
|
},
|
|
})
|
|
|
|
|