实现直播详情页时间显示和秒级自增计时器功能
This commit is contained in:
@@ -14,6 +14,50 @@ interface LiveScoreHeaderProps {
|
||||
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 (
|
||||
<LinearGradient
|
||||
colors={["#521e10", "#0e0e10"]}
|
||||
@@ -68,7 +112,18 @@ export function LiveScoreHeader({ match, topInset }: LiveScoreHeaderProps) {
|
||||
{match.event_final_result?.replace(" - ", "-") || "0-0"}
|
||||
</ThemedText>
|
||||
</View>
|
||||
<ThemedText style={styles.timeText}>{match.event_time}</ThemedText>
|
||||
|
||||
<View style={styles.timeInfoRow}>
|
||||
{match.event_status &&
|
||||
match.event_status.toLowerCase() !==
|
||||
displayTime?.toLowerCase().replace("'", "") && (
|
||||
<ThemedText style={styles.statusLabel}>
|
||||
{match.event_status}
|
||||
</ThemedText>
|
||||
)}
|
||||
<ThemedText style={styles.timeText}>{displayTime}</ThemedText>
|
||||
</View>
|
||||
|
||||
{match.goalscorers && match.goalscorers.length > 0 && (
|
||||
<View style={styles.lastGoalContainer}>
|
||||
<IconSymbol name="football-outline" size={12} color="#FFF" />
|
||||
@@ -185,8 +240,18 @@ const styles = StyleSheet.create({
|
||||
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",
|
||||
|
||||
Reference in New Issue
Block a user