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