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,
},
})