2025-07-22 10:09:25 +08:00

127 lines
4.0 KiB
TypeScript

import { Counter, UserCountData } from "@/types/user";
import * as React from "react";
import { Dimensions, StyleSheet, View } from "react-native";
import { useSharedValue } from "react-native-reanimated";
import Carousel, {
ICarouselInstance
} 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 ref = React.useRef<ICarouselInstance>(null);
const progress = useSharedValue<number>(0);
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={styles.item} key={index}>
<ThemedText style={styles.title}>{item[0]}</ThemedText>
<ThemedText style={styles.number}>{item[1]}</ThemedText>
</View>
))}
</View>
}
React.useEffect(() => {
if (data) {
dataHandle()
}
}, [data]);
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Carousel
ref={ref}
width={width * 0.8}
height={width * 0.8}
data={carouselDataValue || []}
mode="parallax"
onProgressChange={progress}
defaultIndex={carouselDataValue?.findIndex((item) => item?.key === 'total_count') - 1 || 0}
renderItem={({ item }) => {
if (item?.key === 'total_count') {
return totleItem(item.value)
}
return 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>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#FFB645",
padding: 16,
borderRadius: 20,
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
height: '100%',
},
item: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingVertical: 8
},
title: {
color: "#4C320C",
fontWeight: "700",
fontSize: 14,
},
number: {
color: "#fff",
fontWeight: "700",
fontSize: 32,
textAlign: 'right',
flex: 1,
paddingTop: 8
}
})
export default CarouselComponent;