import { TemplateList } from '@/components/templates/template-list'; import { ThemedText } from '@/components/themed-text'; import { ThemedView } from '@/components/themed-view'; import { useAuth } from '@/hooks/use-auth'; import { getTemplates } from '@/lib/api/templates'; import { Template } from '@/lib/types/template'; import { LinearGradient } from 'expo-linear-gradient'; import { useCallback, useEffect, useRef, useState } from 'react'; import { Alert, Animated, StyleSheet, Text } from 'react-native'; export default function HomeScreen() { const { isAuthenticated } = useAuth(); const [templates, setTemplates] = useState([]); const [loading, setLoading] = useState(false); const [refreshing, setRefreshing] = useState(false); const [isLoadingMore, setIsLoadingMore] = useState(false); const [currentPage, setCurrentPage] = useState(1); const [hasMore, setHasMore] = useState(true); const [error, setError] = useState(null); const pulseAnim = useRef(new Animated.Value(0)).current; const bounceAnim = useRef(new Animated.Value(0)).current; const fetchTemplates = useCallback(async (page: number = 1, isRefreshing = false, isLoadMore = false) => { if (!isAuthenticated) return; try { if (isRefreshing) { setRefreshing(true); } else if (isLoadMore) { setIsLoadingMore(true); } else { setLoading(true); } setError(null); const response = await getTemplates({ page, size: 10, status: 'RELEASE' }); if (isRefreshing || page === 1) { // 刷新或首次加载,替换数据 setTemplates(response.data); setCurrentPage(1); } else { // 加载更多,追加数据 setTemplates(prev => [...prev, ...response.data]); setCurrentPage(page); } // 检查是否还有更多数据 setHasMore(response.pagination.page < response.pagination.totalPages); } catch (err: any) { console.error('获取模板列表失败:', err); setError(err.message || '获取模板列表失败'); } finally { setLoading(false); setRefreshing(false); setIsLoadingMore(false); } }, [isAuthenticated]); const loadMore = useCallback(() => { if (!isLoadingMore && hasMore && !refreshing) { fetchTemplates(currentPage + 1, false, true); } }, [currentPage, hasMore, isLoadingMore, refreshing, fetchTemplates]); useEffect(() => { if (isAuthenticated) { fetchTemplates(); } Animated.loop( Animated.sequence([ Animated.timing(pulseAnim, { toValue: 1, duration: 2000, useNativeDriver: false, }), Animated.timing(pulseAnim, { toValue: 0, duration: 2000, useNativeDriver: false, }), ]) ).start(); Animated.loop( Animated.sequence([ Animated.timing(bounceAnim, { toValue: -10, duration: 600, useNativeDriver: true, }), Animated.timing(bounceAnim, { toValue: -5, duration: 200, useNativeDriver: true, }), Animated.timing(bounceAnim, { toValue: 0, duration: 600, useNativeDriver: true, }), Animated.timing(bounceAnim, { toValue: 0, duration: 200, useNativeDriver: true, }), ]) ).start(); }, [isAuthenticated, fetchTemplates, pulseAnim, bounceAnim]); const handleRefresh = useCallback(() => { fetchTemplates(1, true, false); }, [fetchTemplates]); const handleTemplatePress = (template: Template) => { Alert.alert('模板详情', `您选择了: ${template.title}`); }; if (!isAuthenticated) { return ( 欢迎使用 请先登录以查看模板列表 ); } const shadowOpacity = pulseAnim.interpolate({ inputRange: [0, 1], outputRange: [0.3, 0.4], }); return ( New User 50% Off Coupon : NEWUSER 🎁 ); } const styles = StyleSheet.create({ container: { flex: 1, }, headerBanner: { position: 'absolute', top: 16, left: '10%', right: '10%', zIndex: 1000, borderRadius: 20, shadowColor: '#ff6b6b', shadowOffset: { width: 0, height: 4 }, shadowRadius: 12, elevation: 8, overflow: 'hidden', }, gradientBanner: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingVertical: 4, paddingHorizontal: 16, position: 'relative', }, bannerText: { fontSize: 14, fontWeight: '600', color: '#fff', textAlign: 'center', }, couponText: { fontWeight: '800', fontSize: 14, color: '#fff', backgroundColor: 'rgba(255, 255, 255, 0.2)', paddingHorizontal: 8, paddingVertical: 2, borderRadius: 6, marginLeft: 6, borderWidth: 1, borderColor: 'rgba(255, 255, 255, 0.6)', borderStyle: 'dashed', }, giftIcon: { position: 'absolute', right: 8, fontSize: 16, }, centerContent: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20, }, title: { marginBottom: 8, textAlign: 'center', }, subtitle: { textAlign: 'center', opacity: 0.7, }, });