接入统计进度

This commit is contained in:
yuchenglong
2026-01-16 10:09:58 +08:00
parent cc88c283ce
commit 5bf27755f3
2 changed files with 95 additions and 20 deletions

View File

@@ -16,20 +16,38 @@ export function LiveScoreHeader({ match, topInset }: LiveScoreHeaderProps) {
const parseMin = (t: string) => parseInt(t?.match(/(\d+)/)?.[1] || "0"); const parseMin = (t: string) => parseInt(t?.match(/(\d+)/)?.[1] || "0");
const [minutes, setMinutes] = React.useState(parseMin(match.event_time)); // 解析初始时间逻辑:(event_status 分钟 - event_time 分钟) : event_time 秒
const [seconds, setSeconds] = React.useState(0); const getInitialTime = () => {
const lastServerMinRef = React.useRef(parseMin(match.event_time)); const statusIdx = parseInt(match.event_status) || 0;
const timeParts = match.event_time?.split(":") || [];
const tMin = parseInt(timeParts[0]) || 0;
const tSec = parseInt(timeParts[1]) || 0;
// 如果 event_status 是纯数字分钟数
if (!isNaN(statusIdx) && /^\d+$/.test(match.event_status)) {
return { min: Math.max(0, statusIdx - tMin), sec: tSec };
}
// 回退到解析 event_time 中的数字
return { min: tMin || parseMin(match.event_time), sec: tSec };
};
const initial = getInitialTime();
const [minutes, setMinutes] = React.useState(initial.min);
const [seconds, setSeconds] = React.useState(initial.sec);
const lastServerMatchRef = React.useRef(
`${match.event_status}-${match.event_time}`
);
// 服务器时间同步 // 服务器时间同步
React.useEffect(() => { React.useEffect(() => {
const serverMin = parseMin(match.event_time); const currentKey = `${match.event_status}-${match.event_time}`;
// 只有当服务器分钟数变化时,才同步并重置秒数 if (currentKey !== lastServerMatchRef.current) {
if (serverMin !== lastServerMinRef.current) { const updated = getInitialTime();
setMinutes(serverMin); setMinutes(updated.min);
setSeconds(0); setSeconds(updated.sec);
lastServerMinRef.current = serverMin; lastServerMatchRef.current = currentKey;
} }
}, [match.event_time]); }, [match.event_time, match.event_status]);
// 本地秒级自增计时器 // 本地秒级自增计时器
React.useEffect(() => { React.useEffect(() => {
@@ -114,13 +132,11 @@ export function LiveScoreHeader({ match, topInset }: LiveScoreHeaderProps) {
</View> </View>
<View style={styles.timeInfoRow}> <View style={styles.timeInfoRow}>
{match.event_status && {match.event_status && (
match.event_status.toLowerCase() !== <ThemedText style={styles.statusLabel}>
displayTime?.toLowerCase().replace("'", "") && ( {match.event_status}
<ThemedText style={styles.statusLabel}> </ThemedText>
{match.event_status} )}
</ThemedText>
)}
<ThemedText style={styles.timeText}>{displayTime}</ThemedText> <ThemedText style={styles.timeText}>{displayTime}</ThemedText>
</View> </View>

View File

@@ -26,6 +26,54 @@ export function StatsCard({ match, isDark }: StatsCardProps) {
const [cardSwitch, setCardSwitch] = useState(true); const [cardSwitch, setCardSwitch] = useState(true);
const [showInfo, setShowInfo] = useState(false); const [showInfo, setShowInfo] = useState(false);
// 实时时间与进度计算
const getInitialMinutes = () => {
const statusIdx = parseInt(match.event_status) || 0;
const timeParts = match.event_time?.split(":") || [];
const tMin = parseInt(timeParts[0]) || 0;
const tSec = parseInt(timeParts[1]) || 0;
if (!isNaN(statusIdx) && /^\d+$/.test(match.event_status)) {
return { min: Math.max(0, statusIdx - tMin), sec: tSec };
}
return { min: tMin, sec: tSec };
};
const initial = getInitialMinutes();
const [minutes, setMinutes] = useState(initial.min);
const [seconds, setSeconds] = useState(initial.sec);
React.useEffect(() => {
const updated = getInitialMinutes();
setMinutes(updated.min);
setSeconds(updated.sec);
}, [match.event_time, match.event_status]);
React.useEffect(() => {
const statusStr = match.event_status?.toLowerCase() || "";
const isLive =
String(match.event_live) === "1" ||
statusStr.includes("live") ||
(parseInt(statusStr) > 0 && parseInt(statusStr) < 120);
if (!isLive || statusStr.includes("ht")) return;
const interval = setInterval(() => {
setSeconds((s) => {
if (s >= 59) {
setMinutes((m) => m + 1);
return 0;
}
return s + 1;
});
}, 1000);
return () => clearInterval(interval);
}, [match.event_key, match.event_live, match.event_status]);
const displayTime = `${minutes}:${seconds.toString().padStart(2, "0")}`;
const totalSeconds = minutes * 60 + seconds;
const progressPercent = Math.min(100, (totalSeconds / (90 * 60)) * 100);
// 从 statistics 中提取数据 // 从 statistics 中提取数据
const stats = match.statistics || []; const stats = match.statistics || [];
const getStatValue = (type: string) => { const getStatValue = (type: string) => {
@@ -194,12 +242,23 @@ export function StatsCard({ match, isDark }: StatsCardProps) {
{/* Time Progress Slider */} {/* Time Progress Slider */}
<View style={styles.sliderContainer}> <View style={styles.sliderContainer}>
<ThemedText style={styles.currentTime}>46:53</ThemedText> <ThemedText style={styles.currentTime}>{displayTime}</ThemedText>
<View style={styles.trackContainer}> <View style={styles.trackContainer}>
<View style={[styles.track, isDark && { backgroundColor: "#333" }]} /> <View style={[styles.track, isDark && { backgroundColor: "#333" }]} />
<View style={[styles.filledTrack, { width: "55%" }]} /> <View
style={[styles.filledTrack, { width: `${progressPercent}%` }]}
/>
<View style={[styles.thumb, { left: "0%" }]} /> <View style={[styles.thumb, { left: "0%" }]} />
<View style={[styles.thumb, { left: "55%" }]} /> <View
style={[
styles.thumb,
{
left: `${progressPercent}%`,
backgroundColor: "#FFAB00",
borderColor: "#FFF",
},
]}
/>
<View <View
style={[ style={[
styles.thumb, styles.thumb,