2025-07-22 15:24:23 +08:00

153 lines
5.2 KiB
TypeScript

import HandersSvg from "@/assets/icons/svg/handers.svg";
import UserinfoTotalSvg from "@/assets/icons/svg/userinfoTotal.svg";
import { Counter, UserCountData } from "@/types/user";
import * as React from "react";
import { Dimensions, StyleSheet, View, ViewStyle } from "react-native";
import Carousel from "react-native-reanimated-carousel";
import { ThemedText } from "../ThemedText";
import { formatDuration } from "../utils/time";
import CategoryComponent from "./category";
interface Props {
data: Counter
}
interface CarouselData {
key: string,
value: UserCountData
}[]
const width = Dimensions.get("window").width;
function CarouselComponent(props: Props) {
const { data } = props;
const [carouselDataValue, setCarouselDataValue] = React.useState<CarouselData[]>([]);
const dataHandle = () => {
const carouselData = { ...data?.category_count, total_count: data?.total_count }
// 1. 转换为数组并过滤掉 'total'
const entries = Object?.entries(carouselData)
?.filter(([key]) => key !== 'total_count')
?.map(([key, value]) => ({ key, value }));
// 2. 找到 total 数据
const totalEntry = {
key: 'total_count',
value: carouselData?.total_count
};
// 3. 插入到中间位置
const middleIndex = Math.floor((entries || [])?.length / 2);
entries?.splice(middleIndex, 0, totalEntry);
setCarouselDataValue(entries)
return entries;
}
const totleItem = (data: UserCountData) => {
return <View style={styles.container}>
{Object?.entries(data)?.filter(([key]) => key !== 'cover_url')?.map((item, index) => (
<View style={index === Object?.entries(data)?.length - 2 ? { ...styles.item, borderBottomWidth: 0 } : styles.item} key={index}>
<ThemedText style={styles.title}>{item[0]}</ThemedText>
<ThemedText style={styles.number}>{item[1]}</ThemedText>
</View>
))}
<View style={styles.image}>
<UserinfoTotalSvg />
<View style={{ position: 'absolute', bottom: -5, right: 0, left: 0, justifyContent: 'center', alignItems: 'center' }}><HandersSvg /></View>
</View>
</View>
}
React.useEffect(() => {
if (data) {
dataHandle()
}
}, [data]);
return (
<View style={{ flex: 1 }}>
<Carousel
width={width}
height={width * 0.75}
data={carouselDataValue || []}
mode="parallax"
defaultIndex={carouselDataValue?.findIndex((item) => item?.key === 'total_count') - 1 || 0}
modeConfig={{
parallaxScrollingScale: 1,
parallaxScrollingOffset: 160,
parallaxAdjacentItemScale: 0.7
}}
renderItem={({ item, index }) => {
const style: ViewStyle = {
width: width,
height: width * 0.8,
alignItems: "center",
};
return (
<View key={index} style={style}>
{item?.key === 'total_count' ? (
totleItem(item.value)
) : (
<View style={{ flex: 1, width: width * 0.65 }}>
{CategoryComponent({
title: item?.key,
data: [
{ title: 'Video', number: item?.value?.video_count },
{ title: 'Photo', number: item?.value?.photo_count },
{ title: 'Length', number: formatDuration(item?.value?.video_length || 0) }
],
bgSvg: item?.value?.cover_url,
})}
</View>
)}
</View>
)
}}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#FFB645",
paddingVertical: 8,
paddingHorizontal: 16,
borderRadius: 16,
display: "flex",
flexDirection: "column",
position: 'relative',
width: width * 0.6,
height: '85%'
},
image: {
position: 'absolute',
bottom: 0,
right: 0,
left: 0,
alignItems: 'center',
justifyContent: 'flex-end',
},
item: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingVertical: 8,
borderBottomColor: '#fff',
borderBottomWidth: 1,
},
title: {
color: "#4C320C",
fontWeight: "700",
fontSize: 14,
},
number: {
color: "#fff",
fontWeight: "700",
fontSize: 32,
textAlign: 'right',
flex: 1,
paddingTop: 8
}
})
export default CarouselComponent;