添加网球详情
This commit is contained in:
244
components/live-detail/tennis-scoreboard.tsx
Normal file
244
components/live-detail/tennis-scoreboard.tsx
Normal file
@@ -0,0 +1,244 @@
|
||||
import { ThemedText } from "@/components/themed-text";
|
||||
import { LiveScoreMatch } from "@/types/api";
|
||||
import { Image } from "expo-image";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { StyleSheet, View } from "react-native";
|
||||
|
||||
interface TennisScoreboardProps {
|
||||
match: LiveScoreMatch;
|
||||
isDark: boolean;
|
||||
}
|
||||
|
||||
export function TennisScoreboard({ match, isDark }: TennisScoreboardProps) {
|
||||
const { t } = useTranslation();
|
||||
// Tennis Logic
|
||||
const isTennis =
|
||||
!!match.event_first_player ||
|
||||
(match.league_name &&
|
||||
/ATP|WTA|ITF|Challenger/i.test(match.league_name || ""));
|
||||
|
||||
if (!isTennis) return null;
|
||||
|
||||
const homeName = isTennis ? match.event_first_player : match.event_home_team;
|
||||
const awayName = isTennis ? match.event_second_player : match.event_away_team;
|
||||
const homeLogo = isTennis
|
||||
? match.event_first_player_logo
|
||||
: match.home_team_logo;
|
||||
const awayLogo = isTennis
|
||||
? match.event_second_player_logo
|
||||
: match.away_team_logo;
|
||||
|
||||
const tennisScores = React.useMemo(() => {
|
||||
if (!match.scores) return [];
|
||||
try {
|
||||
const s = match.scores;
|
||||
return Array.isArray(s) ? s : [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}, [match.scores]);
|
||||
|
||||
const gamePoints = React.useMemo(() => {
|
||||
if (!match.event_game_result) return { p1: "0", p2: "0" };
|
||||
const parts = match.event_game_result.split("-");
|
||||
if (parts.length === 2) {
|
||||
return { p1: parts[0].trim(), p2: parts[1].trim() };
|
||||
}
|
||||
return { p1: "0", p2: "0" };
|
||||
}, [match.event_game_result]);
|
||||
|
||||
const totalSets = React.useMemo(() => {
|
||||
if (!match.event_final_result) return { p1: 0, p2: 0 };
|
||||
const parts = match.event_final_result.split("-");
|
||||
if (parts.length === 2) {
|
||||
return {
|
||||
p1: parseInt(parts[0].trim()) || 0,
|
||||
p2: parseInt(parts[1].trim()) || 0,
|
||||
};
|
||||
}
|
||||
return { p1: 0, p2: 0 };
|
||||
}, [match.event_final_result]);
|
||||
|
||||
const bgColor = isDark ? "#1E1E20" : "#FFF";
|
||||
const textColor = isDark ? "#FFF" : "#000";
|
||||
const headerColor = isDark ? "#888" : "#666";
|
||||
const borderColor = isDark ? "#333" : "#F0F0F0";
|
||||
|
||||
return (
|
||||
<View style={[styles.tennisBoardContainer, { backgroundColor: bgColor }]}>
|
||||
<View style={styles.header}>
|
||||
<ThemedText
|
||||
style={{ fontSize: 16, fontWeight: "700", marginBottom: 12 }}
|
||||
>
|
||||
{t("detail.scoreboard", "Scoreboard")}
|
||||
</ThemedText>
|
||||
</View>
|
||||
<View
|
||||
style={[styles.tennisBoardHeader, { borderBottomColor: borderColor }]}
|
||||
>
|
||||
<ThemedText style={[styles.boardHeaderLabel, { color: headerColor }]}>
|
||||
Player
|
||||
</ThemedText>
|
||||
<ThemedText
|
||||
style={[
|
||||
styles.boardHeaderLabel,
|
||||
styles.boardColCenter,
|
||||
{ color: "#4CAF50" },
|
||||
]}
|
||||
>
|
||||
Game
|
||||
</ThemedText>
|
||||
{[1, 2, 3, 4, 5].map((i) => (
|
||||
<ThemedText
|
||||
key={i}
|
||||
style={[
|
||||
styles.boardHeaderLabel,
|
||||
styles.boardColCenter,
|
||||
{
|
||||
color:
|
||||
i.toString() === match.event_status?.replace("Set ", "")
|
||||
? "#4CAF50"
|
||||
: headerColor,
|
||||
},
|
||||
]}
|
||||
>
|
||||
S{i}
|
||||
</ThemedText>
|
||||
))}
|
||||
<ThemedText
|
||||
style={[
|
||||
styles.boardHeaderLabel,
|
||||
styles.boardColCenter,
|
||||
{ color: headerColor },
|
||||
]}
|
||||
>
|
||||
Sets
|
||||
</ThemedText>
|
||||
</View>
|
||||
|
||||
<View style={styles.tennisRow}>
|
||||
<View style={styles.boardPlayerCol}>
|
||||
<Image source={{ uri: homeLogo }} style={styles.miniAvatar} />
|
||||
</View>
|
||||
<ThemedText
|
||||
style={[styles.boardVal, styles.boardColCenter, { color: "#4CAF50" }]}
|
||||
>
|
||||
{gamePoints.p1}
|
||||
</ThemedText>
|
||||
{[1, 2, 3, 4, 5].map((i) => {
|
||||
const setScore = tennisScores.find((s: any) => s.score_set == i);
|
||||
return (
|
||||
<ThemedText
|
||||
key={i}
|
||||
style={[
|
||||
styles.boardVal,
|
||||
styles.boardColCenter,
|
||||
{
|
||||
color:
|
||||
i.toString() === match.event_status?.replace("Set ", "")
|
||||
? "#4CAF50"
|
||||
: textColor,
|
||||
},
|
||||
]}
|
||||
>
|
||||
{setScore ? setScore.score_first : "-"}
|
||||
</ThemedText>
|
||||
);
|
||||
})}
|
||||
<ThemedText
|
||||
style={[styles.boardVal, styles.boardColCenter, { color: textColor }]}
|
||||
>
|
||||
{totalSets.p1}
|
||||
</ThemedText>
|
||||
</View>
|
||||
|
||||
<View style={styles.tennisRow}>
|
||||
<View style={styles.boardPlayerCol}>
|
||||
<Image source={{ uri: awayLogo }} style={styles.miniAvatar} />
|
||||
</View>
|
||||
<ThemedText
|
||||
style={[styles.boardVal, styles.boardColCenter, { color: "#4CAF50" }]}
|
||||
>
|
||||
{gamePoints.p2}
|
||||
</ThemedText>
|
||||
{[1, 2, 3, 4, 5].map((i) => {
|
||||
const setScore = tennisScores.find((s: any) => s.score_set == i);
|
||||
return (
|
||||
<ThemedText
|
||||
key={i}
|
||||
style={[
|
||||
styles.boardVal,
|
||||
styles.boardColCenter,
|
||||
{
|
||||
color:
|
||||
i.toString() === match.event_status?.replace("Set ", "")
|
||||
? "#4CAF50"
|
||||
: textColor,
|
||||
},
|
||||
]}
|
||||
>
|
||||
{setScore ? setScore.score_second : "-"}
|
||||
</ThemedText>
|
||||
);
|
||||
})}
|
||||
<ThemedText
|
||||
style={[styles.boardVal, styles.boardColCenter, { color: textColor }]}
|
||||
>
|
||||
{totalSets.p2}
|
||||
</ThemedText>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
tennisBoardContainer: {
|
||||
marginHorizontal: 16,
|
||||
borderRadius: 16,
|
||||
padding: 16,
|
||||
marginTop: 12,
|
||||
marginBottom: 16,
|
||||
shadowColor: "#000",
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 10,
|
||||
elevation: 2,
|
||||
},
|
||||
header: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
tennisBoardHeader: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
borderBottomWidth: 1,
|
||||
paddingBottom: 8,
|
||||
marginBottom: 8,
|
||||
},
|
||||
boardHeaderLabel: {
|
||||
fontSize: 12,
|
||||
fontWeight: "500",
|
||||
},
|
||||
boardPlayerCol: {
|
||||
width: 40,
|
||||
alignItems: "center",
|
||||
},
|
||||
boardColCenter: {
|
||||
flex: 1,
|
||||
textAlign: "center",
|
||||
},
|
||||
tennisRow: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
height: 36,
|
||||
},
|
||||
miniAvatar: {
|
||||
width: 28,
|
||||
height: 28,
|
||||
borderRadius: 14,
|
||||
},
|
||||
boardVal: {
|
||||
fontSize: 14,
|
||||
fontWeight: "600",
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user