import React, { useState, useRef, useMemo, useCallback, useEffect } from 'react' import { View, Text, StyleSheet, Pressable, FlatList, useWindowDimensions, Platform, } from 'react-native' import { Image } from 'expo-image' import { useTranslation } from 'react-i18next' import BottomSheet, { BottomSheetView, BottomSheetBackdrop } from '@gorhom/bottom-sheet' import { CloseIcon, DownArrowIcon } from '@/components/icon' import AIGenerationRecordDrawer from './AIGenerationRecordDrawer' interface UploadReferenceImageDrawerProps { visible: boolean onClose: () => void onSelectImage?: (imageUri: any) => void } type TabType = 'ai-record' | 'recent' | 'project' // 模拟图片数据(保留用于兼容) const mockImages = Array.from({ length: 120 }, (_, i) => ({ id: i + 1, uri: require('@/assets/images/android-icon-background.png'), })) export default function UploadReferenceImageDrawer({ visible, onClose, onSelectImage, }: UploadReferenceImageDrawerProps) { const { t } = useTranslation() const { width: screenWidth } = useWindowDimensions() const bottomSheetRef = useRef(null) const [activeTab, setActiveTab] = useState('ai-record') const [selectedFilter, setSelectedFilter] = useState<'all' | 'face'>('all') const [aiRecordDrawerVisible, setAiRecordDrawerVisible] = useState(false) const snapPoints = useMemo(() => ['98%'], []) useEffect(() => { if (visible) { bottomSheetRef.current?.expand() } else { bottomSheetRef.current?.close() } }, [visible]) const handleSheetChanges = useCallback((index: number) => { if (index === -1) { onClose() } }, [onClose]) const handleImageSelect = (imageSource: any) => { onSelectImage?.(imageSource) onClose() } const renderBackdrop = useCallback( (props: any) => ( ), [] ) const renderImageItem = ({ item, index }: { item: typeof mockImages[0]; index: number }) => { const paddingHorizontal = 0 const gap = 2 const itemWidth = (screenWidth - paddingHorizontal * 2 - gap * 2) / 3 const isLastRow = index >= Math.floor(mockImages.length / 3) * 3 return ( handleImageSelect(item.uri)} > ) } return ( <> {/* 顶部标题栏 */} {t('uploadReference.selectImage')} {t('uploadReference.generateAIVideo')} {/* 标签切换 */} { setActiveTab('ai-record') setAiRecordDrawerVisible(true) }} > {t('uploadReference.aiRecord')} { setActiveTab('recent') setAiRecordDrawerVisible(true) }} > {t('uploadReference.recentUsed')} { setActiveTab('project') setAiRecordDrawerVisible(true) }} > {t('uploadReference.recentProject')} {/* 筛选区域 */} { // 可以展开分类选择 }} > {t('uploadReference.recentProject')} setSelectedFilter('all')} > {t('uploadReference.all')} setSelectedFilter('face')} > {t('uploadReference.face')} {/* 图片网格 */} item.id.toString()} numColumns={3} showsVerticalScrollIndicator={false} removeClippedSubviews={Platform.OS === 'android'} maxToRenderPerBatch={Platform.OS === 'ios' ? 10 : 5} updateCellsBatchingPeriod={Platform.OS === 'ios' ? 50 : 100} initialNumToRender={Platform.OS === 'ios' ? 15 : 10} windowSize={Platform.OS === 'ios' ? 10 : 5} getItemLayout={(data, index) => { const gap = 2 const itemWidth = (screenWidth - gap * 2) / 3 const rowIndex = Math.floor(index / 3) return { length: itemWidth, offset: rowIndex * (itemWidth + gap), index, } }} /> setAiRecordDrawerVisible(false)} onSelectImage={(imageUri) => { handleImageSelect(imageUri) }} type={ activeTab === 'project' ? selectedFilter === 'all' ? 'project-all' : 'project-face' : activeTab } /> ) } const styles = StyleSheet.create({ bottomSheetBackground: { backgroundColor: '#16181B', }, handleIndicator: { backgroundColor: '#666666', }, container: { flex: 1, backgroundColor: '#16181B', paddingTop: 24, }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 16, paddingBottom: 20, }, title: { color: '#F5F5F5', fontSize: 20, fontWeight: '600', }, closeButton: { width: 24, height: 24, alignItems: 'center', justifyContent: 'center', }, 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, }, tabActive: { backgroundColor: '#262A31', }, tabIconContainer: { width: 28, height: 28, alignItems: 'center', justifyContent: 'center', }, tabIcon: { width: 27, height: 27, borderRadius: 6, backgroundColor: '#4A4C4F', }, tabIconSmall: { width: 26, height: 26, borderRadius: 6, backgroundColor: '#4A4C4F', }, tabIconFolder: { width: 24, height: 24, borderRadius: 4, backgroundColor: '#4A4C4F', }, tabText: { color: '#F5F5F5', fontSize: 12, fontWeight: '600', }, tabTextActive: { color: '#F5F5F5', }, filterContainer: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 16, marginBottom: 9, }, categoryButton: { flexDirection: 'row', alignItems: 'center', gap: 8, }, categoryText: { color: '#F5F5F5', fontSize: 14, fontWeight: '600', }, filterButtons: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#1C1E22', borderRadius: 100, height: 32, padding: 3, }, filterButton: { paddingHorizontal: 12, paddingVertical: 4, minWidth: 48, alignItems: 'center', justifyContent: 'center', }, filterButtonActive: { backgroundColor: '#F5F5F5', height: 24, borderRadius: 100, }, filterButtonText: { color: '#CCCCCC', fontSize: 12, }, filterButtonTextActive: { color: '#000000', }, // imageGrid: { // // paddingHorizontal: 16, // // paddingBottom: 20, // }, imageItem: { // aspectRatio = width / height // 1 : 1.3 (width : height) => 1 / 1.3 aspectRatio: 1 / 1.3, overflow: 'hidden', backgroundColor: '#262A31', }, image: { width: '100%', height: '100%', }, })