import { ThemedText } from "@/components/themed-text"; import { IconSymbol } from "@/components/ui/icon-symbol"; import { LiveScoreMatch } from "@/types/api"; import { LinearGradient } from "expo-linear-gradient"; import { useRouter } from "expo-router"; import React from "react"; import { Image, StyleSheet, TouchableOpacity, View } from "react-native"; interface LiveScoreHeaderProps { match: LiveScoreMatch; topInset: number; } export function LiveScoreHeader({ match, topInset }: LiveScoreHeaderProps) { const router = useRouter(); const parseMin = (t: string) => parseInt(t?.match(/(\d+)/)?.[1] || "0"); const [minutes, setMinutes] = React.useState(parseMin(match.event_time)); const [seconds, setSeconds] = React.useState(0); const lastServerMinRef = React.useRef(parseMin(match.event_time)); // 服务器时间同步 React.useEffect(() => { const serverMin = parseMin(match.event_time); // 只有当服务器分钟数变化时,才同步并重置秒数 if (serverMin !== lastServerMinRef.current) { setMinutes(serverMin); setSeconds(0); lastServerMinRef.current = serverMin; } }, [match.event_time]); // 本地秒级自增计时器 React.useEffect(() => { const status = match.event_status?.toLowerCase() || ""; const isLive = String(match.event_live) === "1" || status.includes("live") || status.includes("play") || /^[12][h]$/.test(status) || (parseInt(status) > 0 && parseInt(status) < 120); if (!isLive || status.includes("ht") || status.includes("half")) return; const interval = setInterval(() => { setSeconds((prevSeconds) => { if (prevSeconds >= 59) { setMinutes((prevMinutes) => prevMinutes + 1); return 0; } return prevSeconds + 1; }); }, 1000); return () => clearInterval(interval); }, [match.event_key, match.event_live, match.event_status]); const displayTime = `${minutes}:${seconds.toString().padStart(2, "0")}`; return ( {/* Top Bar */} router.back()} style={styles.iconBtn} > {match.event_status || "Live"} {/* Score Section */} {match.event_home_team} {match.event_final_result?.replace(" - ", "-") || "0-0"} {match.event_status && match.event_status.toLowerCase() !== displayTime?.toLowerCase().replace("'", "") && ( {match.event_status} )} {displayTime} {match.goalscorers && match.goalscorers.length > 0 && ( {match.goalscorers[match.goalscorers.length - 1].home_scorer || match.goalscorers[match.goalscorers.length - 1].away_scorer} )} {match.event_away_team} ); } const styles = StyleSheet.create({ container: { paddingBottom: 24, }, topBar: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16, marginBottom: 20, }, leftContainer: { width: 60, }, rightActions: { flexDirection: "row", justifyContent: "flex-end", width: 80, }, iconBtn: { padding: 6, marginLeft: 4, }, statusContainer: { backgroundColor: "rgba(255,255,255,0.1)", paddingHorizontal: 12, paddingVertical: 4, borderRadius: 12, }, statusText: { color: "#FFF", fontWeight: "600", fontSize: 14, }, scoreRow: { flexDirection: "row", alignItems: "flex-start", justifyContent: "space-between", paddingHorizontal: 24, }, teamInfo: { alignItems: "center", width: "30%", }, logoContainer: { width: 70, height: 70, marginBottom: 10, justifyContent: "center", alignItems: "center", }, teamLogo: { width: 60, height: 60, resizeMode: "contain", }, teamName: { color: "#FFF", fontSize: 14, fontWeight: "700", textAlign: "center", lineHeight: 18, }, centerScore: { alignItems: "center", justifyContent: "center", width: "40%", paddingTop: 10, }, scoreBox: { backgroundColor: "#FFF", paddingHorizontal: 20, paddingVertical: 10, borderRadius: 14, marginBottom: 8, minWidth: 100, alignItems: "center", }, scoreValue: { color: "#000", fontSize: 30, fontWeight: "700", lineHeight: 30, letterSpacing: 1, }, timeText: { color: "#FF4444", fontWeight: "700", fontSize: 14, }, timeInfoRow: { flexDirection: "row", alignItems: "center", marginBottom: 4, }, statusLabel: { color: "#FFF", fontWeight: "700", fontSize: 14, marginRight: 6, }, lastGoalContainer: { flexDirection: "row", alignItems: "center", marginTop: 4, opacity: 0.9, }, lastGoalText: { color: "#FFF", fontSize: 10, marginLeft: 4, }, });