import { Image } from 'expo-image';
import React, { useEffect, useRef, useState } from 'react';
import { Animated, Dimensions, ScrollView, StyleSheet, View } from 'react-native';
import { Images } from '@/constants/images';
import TransCard from './TransCard';
const { width: SCREEN_WIDTH } = Dimensions.get('window');
// 3 columns. Uniapp: 220rpx (approx 30%).
// Let's use 3 columns with some spacing.
const COLUMNS = 3;
const ITEM_WIDTH = (SCREEN_WIDTH - 40) / COLUMNS; // 20px padding left/right
const ITEM_HEIGHT = ITEM_WIDTH * 1.5; // Aspect ratio
interface FlipCardProps {
item: any;
index: number;
delay: number;
onFlipComplete?: () => void;
}
const FlipCard = ({ item, index, delay, onFlipComplete }: FlipCardProps) => {
const animValue = useRef(new Animated.Value(0)).current;
useEffect(() => {
Animated.sequence([
Animated.delay(delay),
Animated.timing(animValue, {
toValue: 180, // We'll map 0-180 to the flip
duration: 600, // Flip duration
useNativeDriver: true,
})
]).start(() => {
onFlipComplete && onFlipComplete();
});
}, [delay]);
// Front (Back Image) Interpolation: 0 -> 90 derived from 0->180 range
// Actually standard flip:
// Front: 0deg to 180deg (starts visible, goes back)
// Back: 180deg to 360deg (starts invisible back, goes front)
// Uniapp Logic:
// Back (Card Back): rotateY 0deg -> 90deg (Hide)
// Front (Result): rotateY -90deg -> 0deg (Show)
// Let's use animValue 0 -> 1.
// 0 -> 0.5: Back rotates 0 -> 90.
// 0.5 -> 1: Front rotates -90 -> 0.
const backStyle = {
transform: [
{
rotateY: animValue.interpolate({
inputRange: [0, 90],
outputRange: ['0deg', '90deg'],
extrapolate: 'clamp',
})
}
],
opacity: animValue.interpolate({
inputRange: [0, 89, 90],
outputRange: [1, 1, 0], // Hide when 90 to prevent z-fighting/artifacts
extrapolate: 'clamp',
})
};
const frontStyle = {
transform: [
{
rotateY: animValue.interpolate({
inputRange: [90, 180],
outputRange: ['-90deg', '0deg'], // or 270 to 360
extrapolate: 'clamp',
})
}
],
opacity: animValue.interpolate({
inputRange: [0, 90, 91],
outputRange: [0, 0, 1],
extrapolate: 'clamp',
})
};
return (
{/* Card Back (Initially Visible) */}
{/* Result Face (Initially Hidden) */}
);
};
interface LotteryGridProps {
results: any[];
onFinish: () => void;
}
export default function LotteryGrid({ results, onFinish }: LotteryGridProps) {
// Determine staggered delay
// 10 items.
// We want them to flip sequentially or semi-sequentially.
// Uniapp likely does it index based.
const [completedCount, setCompletedCount] = useState(0);
const handleFlipComplete = () => {
setCompletedCount(prev => {
const newCount = prev + 1;
if (newCount === results.length) {
// All done
setTimeout(onFinish, 1000); // Wait a bit before finish
}
return newCount;
});
};
return (
{results.map((item, index) => (
))}
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
width: '100%',
},
scrollContent: {
paddingTop: 20, // Reduced from 100 to avoid being too low (parent has margin)
paddingBottom: 150, // Increased to avoid overlapping with absolute bottom button
},
grid: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'center',
},
cardContainer: {
width: ITEM_WIDTH,
height: ITEM_HEIGHT,
alignItems: 'center',
justifyContent: 'center',
marginVertical: 10,
},
cardFace: {
position: 'absolute',
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
backfaceVisibility: 'hidden', // Android support varies, relying on opacity/rotation logic
}
});