import { Image } from 'expo-image' import { LinearGradient } from 'expo-linear-gradient' import { useRouter } from 'expo-router' import { StatusBar } from 'expo-status-bar' import { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { Animated, Dimensions, Platform, Pressable, StatusBar as RNStatusBar, ScrollView, StyleSheet, Text, View, } from 'react-native' import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context' import { DownArrowIcon, PointsIcon, SearchIcon, WhiteStarIcon } from '@/components/icon' import { useActivates } from '@/hooks/use-activates' const { width: screenWidth } = Dimensions.get('window') // 卡片数据 - 根据 Figma 设计更新 const cardData = [ { id: 1, title: '宠物写真', image: require('@/assets/images/android-icon-background.png'), isHot: true, users: 6349, height: 214, }, { id: 2, title: '我和小猫的人生合照', image: require('@/assets/images/android-icon-background.png'), users: 6349, height: 236, }, { id: 3, title: '猫:晚安~人', image: require('@/assets/images/favicon.png'), users: 6349, height: 214, }, { id: 4, title: '穿越时空的相聚', image: require('@/assets/images/icon.png'), users: 6349, height: 100, }, { id: 5, title: '睡衣版猫咪', image: require('@/assets/images/android-icon-background.png'), users: 6349, height: 120, }, { id: 6, title: '猫咪写真', image: require('@/assets/images/android-icon-background.png'), users: 6349, height: 214, }, { id: 7, title: '站姐视角写真', image: require('@/assets/images/android-icon-background.png'), users: 6349, height: 214, }, { id: 8, title: '猫咪写真', image: require('@/assets/images/android-icon-background.png'), users: 6349, height: 200, }, ] export default function HomeScreen() { const { t } = useTranslation() const insets = useSafeAreaInsets() const router = useRouter() const [activeTab, setActiveTab] = useState(0) // 标签数据 - 根据 Figma 设计更新 const tabs = [ t('home.tabs.featured'), t('home.tabs.christmas'), t('home.tabs.pets'), t('home.tabs.avatar'), t('home.tabs.theater1'), t('home.tabs.theater2'), ] const [gridWidth, setGridWidth] = useState(screenWidth) const [showTabArrow, setShowTabArrow] = useState(false) const [tabsSticky, setTabsSticky] = useState(false) const [tabsHeight, setTabsHeight] = useState(0) const tabsPositionRef = useRef(0) const titleBarHeightRef = useRef(0) const scrollY = useRef(new Animated.Value(0)).current const { load, data: activatesData, error } = useActivates() useEffect(() => { load() }, []) useEffect(() => { console.log({ activatesData, error }) }, [activatesData, error]) const horizontalPadding = 8 * 2 // gridContainer 的左右 padding const cardGap = 5 // 两个卡片之间的间距 const cardWidth = (gridWidth - horizontalPadding - cardGap) / 2 // 渲染标签导航的函数 const renderTabs = (wrapperStyle?: any) => ( { const tabsContainerPadding = 16 * 2 // tabsContent 的左右 padding const availableWidth = screenWidth - tabsContainerPadding setShowTabArrow(contentWidth > availableWidth) }} > {tabs.map((tab, index) => ( setActiveTab(index)} style={styles.tab} > {activeTab === index && ( )} {tab} ))} {showTabArrow && ( router.push('/channels')} > )} ) return ( {/* 标题栏 */} { const { height } = event.nativeEvent.layout titleBarHeightRef.current = height }} > Popcore router.push('/membership' as any)} > 60 router.push('/searchTemplate')} > {/* 吸顶的标签导航 - 适配 iOS 和 Android 的安全区域 */} {tabsSticky && ( {renderTabs(styles.stickyTabs)} )} { const scrollY = event.nativeEvent.contentOffset.y if (scrollY >= tabsPositionRef.current) { setTabsSticky(true) } else { setTabsSticky(false) } }} // iOS 使用 16ms (60fps),Android 使用 50ms 以获得更好的性能 scrollEventThrottle={Platform.OS === 'ios' ? 16 : 50} > {/* 图片区域 */} {activatesData?.activities.map((activity) => ( router.push(activity.link as any)}> {activity.title} {activity.desc} ))} {/* 标签导航 */} { const { y, height } = event.nativeEvent.layout tabsPositionRef.current = y setTabsHeight(height) }} style={tabsSticky ? { opacity: 0, height: tabsHeight } : undefined} > {renderTabs()} {/* 内容网格 */} { const { width } = event.nativeEvent.layout setGridWidth(width) }} > {cardData.map((card, index) => ( { router.push({ pathname: '/templateDetail' as any, params: { id: card.id.toString() }, }) }} > {card.isHot ? ( 🔥 {t('home.hotTemplate')} ) : ( {card.users}{t('home.peopleUsed')} )} {card.title} ))} ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#090A0B', }, header: { backgroundColor: '#090A0B', paddingTop: 8, paddingBottom: 12, }, statusBar: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingHorizontal: 16, paddingBottom: 8, }, time: { color: '#FFFFFF', fontSize: 14, fontWeight: '600', }, statusIcons: { flexDirection: 'row', alignItems: 'center', gap: 4, }, signalBars: { width: 18, height: 12, backgroundColor: '#FFFFFF', borderRadius: 2, }, wifiIcon: { width: 16, height: 12, backgroundColor: '#FFFFFF', borderRadius: 2, }, batteryIcon: { width: 24, height: 12, backgroundColor: '#FFFFFF', borderRadius: 2, }, titleBar: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingHorizontal: 16, paddingBottom: 7, paddingTop: 19, }, appTitle: { color: '#F5F5F5', fontSize: 18, fontWeight: '500', }, headerRight: { flexDirection: 'row', alignItems: 'center', gap: 12, }, pointsContainer: { backgroundColor: '#1C1E22', borderRadius: 12, paddingLeft: 8, paddingRight: 10, paddingVertical: 4, flexDirection: 'row', alignItems: 'center', }, pointsText: { color: '#FFCF00', fontSize: 12, fontWeight: '600', }, searchButton: { padding: 4, }, scrollView: { flex: 1, backgroundColor: '#090A0B', }, scrollContent: { backgroundColor: '#090A0B', }, heroSection: { flexDirection: 'row', paddingLeft: 12, paddingTop: 12, marginBottom: 40, overflow: 'hidden', }, heroSliderContent: { gap: 12, }, heroMainSlide: { width: '100%', }, heroMainImage: { width: 265, height: 150, borderRadius: 12, }, heroTextContainer: { paddingTop: 12, paddingHorizontal: 8, }, heroText: { color: '#ABABAB', fontSize: 12, marginBottom: 4, }, heroSubtext: { color: '#F5F5F5', fontSize: 16, fontWeight: '500', }, heroSide: { width: 120, borderRadius: 12, overflow: 'hidden', }, heroSideImage: { width: '100%', height: 140, }, heroSideTextContainer: { padding: 8, backgroundColor: 'rgba(0, 0, 0, 0.6)', }, heroSideText: { color: '#FFFFFF', fontSize: 12, fontWeight: '500', marginBottom: 2, }, heroSideSubtext: { color: '#FFFFFF', fontSize: 11, opacity: 0.9, }, tabsWrapper: { position: 'relative', marginBottom: 18, }, stickyTabsWrapper: { position: 'absolute', top: 0, left: 0, right: 0, zIndex: 100, backgroundColor: '#090A0B', }, stickyTabs: { marginBottom: 0, }, tabsContainer: { marginBottom: 0, }, tabsContent: { paddingHorizontal: 16, gap: 20, alignItems: 'center', }, tabsContentWithArrow: { paddingRight: 60, }, tab: { paddingBottom: 4, position: 'relative', }, tabLabelWrapper: { position: 'relative', paddingBottom: 2, alignSelf: 'flex-start', justifyContent: 'flex-end', }, tabText: { color: '#FFFFFF', fontSize: 14, fontWeight: '600', }, tabTextActive: { opacity: 1, fontWeight: '600', }, tabUnderline: { position: 'absolute', bottom: 0, left: 0, right: 0, height: 12, }, tabArrowContainer: { position: 'absolute', right: 0, top: 0, zIndex: 10, }, tabArrowGradient: { paddingLeft: 30, paddingRight: 16, paddingVertical: 4, }, tabArrow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', }, gridContainer: { flexDirection: 'row', flexWrap: 'wrap', paddingHorizontal: 8, justifyContent: 'space-between', }, card: { marginBottom: 12, }, cardLeft: { marginRight: 0, }, cardRight: { marginLeft: 0, }, cardImageContainer: { width: '100%', borderRadius: 16, overflow: 'hidden', position: 'relative', }, cardImage: { width: '100%', height: '100%', }, cardImageGradient: { position: 'absolute', bottom: 0, left: 0, right: 0, height: '33.33%', }, hotBadge: { position: 'absolute', top: 8, left: 8, backgroundColor: '#191A1F80', paddingHorizontal: 7, paddingVertical: 4, borderRadius: 100, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 1, }, hotEmoji: { fontSize: 10, }, hotText: { color: '#F5F5F5', fontSize: 11, fontWeight: '500', }, cardTitle: { position: 'absolute', bottom: 12, left: 12, fontSize: 14, fontWeight: '500', color: '#F5F5F5', lineHeight: 20, }, })