import { useState, useRef } from 'react'
import {
View,
Text,
StyleSheet,
Dimensions,
FlatList,
Pressable,
StatusBar as RNStatusBar,
} from 'react-native'
import { StatusBar } from 'expo-status-bar'
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'
import { Image, ImageLoadEventData } from 'expo-image'
import { useTranslation } from 'react-i18next'
import { SameStyleIcon, VideoIcon, WhiteStarIcon } from '@/components/icon'
import { useRouter } from 'expo-router'
const { width: screenWidth, height: screenHeight } = Dimensions.get('window')
const TAB_BAR_HEIGHT = 83 // 底部导航栏高度
// 视频数据
const videoData = [
{
id: 1,
videoUrl: require('@/assets/images/android-icon-background.png'),
thumbnailUrl: require('@/assets/images/android-icon-background.png'),
title: '雅琳圣诞写真',
duration: '00:03',
},
{
id: 2,
videoUrl: require('@/assets/images/android-icon-background.png'),
thumbnailUrl: require('@/assets/images/android-icon-background.png'),
title: '宠物写真',
duration: '00:05',
},
{
id: 3,
videoUrl: require('@/assets/images/android-icon-background.png'),
thumbnailUrl: require('@/assets/images/android-icon-background.png'),
title: '我和小猫的人生合照',
duration: '00:04',
},
]
interface VideoItemProps {
item: typeof videoData[0]
index: number
videoHeight: number
}
function VideoItem({ item, videoHeight }: VideoItemProps) {
const { t } = useTranslation()
const router = useRouter()
const [isPlaying, setIsPlaying] = useState(false)
const [imageSize, setImageSize] = useState<{ width: number; height: number } | null>(null)
const handleImageLoad = (event: ImageLoadEventData) => {
const { source } = event
if (source?.width && source?.height) {
setImageSize({ width: source.width, height: source.height })
}
}
// 根据图片比例计算显示尺寸
const getImageStyle = () => {
if (!imageSize) {
return {
width: screenWidth,
height: videoHeight,
}
}
const imageAspectRatio = imageSize.width / imageSize.height
const screenAspectRatio = screenWidth / videoHeight
let displayWidth = screenWidth
let displayHeight = videoHeight
if (imageAspectRatio > screenAspectRatio) {
// 图片更宽,以宽度为准
displayHeight = screenWidth / imageAspectRatio
} else {
// 图片更高,以高度为准
displayWidth = videoHeight * imageAspectRatio
}
return {
width: displayWidth,
height: displayHeight,
}
}
return (
{/* 主视频区域 */}
{/* 播放按钮 */}
{!isPlaying && (
setIsPlaying(true)}
>
)}
{/* 左下角原图缩略图 */}
{/* 左下角按钮 */}
{item.title}
{/* 右下角按钮 */}
{
router.push({
pathname: '/generateVideo' as any,
params: {
template: JSON.stringify(item),
},
})
}}
>
{t('video.makeSame')}
)
}
export default function VideoScreen() {
const flatListRef = useRef(null)
const insets = useSafeAreaInsets()
const videoHeight = screenHeight - TAB_BAR_HEIGHT
return (
(
)}
keyExtractor={(item) => item.id.toString()}
pagingEnabled
showsVerticalScrollIndicator={false}
snapToInterval={videoHeight}
snapToAlignment="start"
decelerationRate="fast"
getItemLayout={(_, index) => ({
length: videoHeight,
offset: videoHeight * index,
index,
})}
/>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#090A0B',
},
videoContainer: {
width: screenWidth,
backgroundColor: '#090A0B',
position: 'relative',
},
videoWrapper: {
flex: 1,
position: 'relative',
backgroundColor: '#090A0B',
alignItems: 'center',
justifyContent: 'center',
},
playButton: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.3)',
},
playIcon: {
width: 56,
height: 56,
borderRadius: 28,
backgroundColor: 'rgba(255, 255, 255, 0.85)',
alignItems: 'center',
justifyContent: 'center',
},
playTriangle: {
width: 0,
height: 0,
borderLeftWidth: 18,
borderTopWidth: 11,
borderBottomWidth: 11,
borderLeftColor: '#000000',
borderTopColor: 'transparent',
borderBottomColor: 'transparent',
marginLeft: 3,
},
thumbnailContainer: {
position: 'absolute',
left: 12,
bottom: 80,
width: 56,
height: 56,
borderRadius: 8,
overflow: 'hidden',
borderWidth: 2,
borderColor: '#FFFFFF',
backgroundColor: '#090A0B',
},
thumbnail: {
width: '100%',
height: '100%',
},
actionButtonLeft: {
position: 'absolute',
left: 12,
bottom: 16,
flexDirection: 'row',
alignItems: 'center',
gap: 4,
paddingHorizontal: 6,
paddingVertical: 8,
backgroundColor: '#191B1F',
borderRadius: 8,
borderWidth: 1,
borderColor: '#2F3134',
},
actionButtonRight: {
position: 'absolute',
right: 13,
bottom: 13,
flexDirection: 'column',
alignItems: 'center',
},
actionButtonTextTitle: {
color: '#F5F5F5',
fontSize: 11,
},
actionButtonText: {
color: '#CCCCCC',
fontSize: 10,
fontWeight: '500',
},
})