网球详情页

This commit is contained in:
xianyi
2026-01-22 14:05:39 +08:00
parent 9e7f8dadec
commit a279083252
13 changed files with 443 additions and 46 deletions

View File

@@ -10,6 +10,7 @@ import { LeagueInfo } from "@/components/match-detail/league-info";
import { MatchInfoCard } from "@/components/match-detail/match-info-card"; import { MatchInfoCard } from "@/components/match-detail/match-info-card";
import { MatchTabs } from "@/components/match-detail/match-tabs"; import { MatchTabs } from "@/components/match-detail/match-tabs";
import { ScoreHeader } from "@/components/match-detail/score-header"; import { ScoreHeader } from "@/components/match-detail/score-header";
import { TennisScoreTable } from "@/components/match-detail/tennis/tennis-score-table";
import { ThemedText } from "@/components/themed-text"; import { ThemedText } from "@/components/themed-text";
import { ThemedView } from "@/components/themed-view"; import { ThemedView } from "@/components/themed-view";
import { Colors } from "@/constants/theme"; import { Colors } from "@/constants/theme";
@@ -59,6 +60,9 @@ export default function MatchDetailScreen() {
} else if (sportId === 2) { } else if (sportId === 2) {
// 篮球 // 篮球
validTabs = ["info", "h2h", "chat"]; validTabs = ["info", "h2h", "chat"];
} else if (sportId === 3) {
// 网球
validTabs = ["info", "chat"];
} else { } else {
// 默认 // 默认
validTabs = ["info", "h2h", "chat"]; validTabs = ["info", "h2h", "chat"];
@@ -77,7 +81,7 @@ export default function MatchDetailScreen() {
setError(null); setError(null);
const result = await fetchMatchDetail(id as string); const result = await fetchMatchDetail(id as string);
setData(result); setData(result);
console.log("首发阵容" , result.match.players?.away_team); console.log("首发阵容", result.match.players?.away_team);
console.log("红黄牌", result.events); console.log("红黄牌", result.events);
@@ -130,6 +134,14 @@ export default function MatchDetailScreen() {
<MatchInfoCard data={data} isDark={isDark} /> <MatchInfoCard data={data} isDark={isDark} />
</> </>
); );
} else if (sportId === 3) {
// 网球:显示 TennisScoreTable 和 MatchInfoCard
return (
<>
<TennisScoreTable data={data} isDark={isDark} />
<MatchInfoCard data={data} isDark={isDark} />
</>
);
} else { } else {
// 默认使用足球组件 // 默认使用足球组件
return ( return (

View File

@@ -65,6 +65,16 @@ export function MatchTabs({
} else if (sportId === 2) { } else if (sportId === 2) {
// 篮球 // 篮球
return commonTabs; return commonTabs;
} else if (sportId === 3) {
// 网球: 详情、聊天
return [
{
id: "info",
label: t("detail.tabs.info"),
icon: "document-text-outline",
},
{ id: "chat", label: t("detail.tabs.chat"), icon: "chatbubbles-outline" },
];
} }
return commonTabs; return commonTabs;
}; };

View File

@@ -1,6 +1,7 @@
import { ThemedText } from "@/components/themed-text"; import { ThemedText } from "@/components/themed-text";
import { IconSymbol } from "@/components/ui/icon-symbol"; import { IconSymbol } from "@/components/ui/icon-symbol";
import { addFavorite, checkFavorite, removeFavorite } from "@/lib/api"; import { addFavorite, checkFavorite, removeFavorite } from "@/lib/api";
import { getInitials, getLogoGradient } from "@/lib/avatar-utils";
import { storage } from "@/lib/storage"; import { storage } from "@/lib/storage";
import { MatchDetailData } from "@/types/api"; import { MatchDetailData } from "@/types/api";
import { LinearGradient } from "expo-linear-gradient"; import { LinearGradient } from "expo-linear-gradient";
@@ -19,6 +20,7 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
const router = useRouter(); const router = useRouter();
const { t } = useTranslation(); const { t } = useTranslation();
const { match } = data; const { match } = data;
const isTennis = match.sportId === 3;
const [isFav, setIsFav] = useState(false); const [isFav, setIsFav] = useState(false);
const [favLoading, setFavLoading] = useState(false); const [favLoading, setFavLoading] = useState(false);
@@ -45,39 +47,45 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
} }
}, [match.eventKey]); }, [match.eventKey]);
// 检查主队收藏状态 // 检查主队/第一球员收藏状态
React.useEffect(() => { React.useEffect(() => {
const loadHomeFav = async () => { const loadHomeFav = async () => {
const token = await storage.getAccessToken(); const token = await storage.getAccessToken();
if (!token) return; if (!token) return;
try { try {
const res = await checkFavorite("team", match.homeTeamKey.toString()); const teamKey = isTennis ? match.firstPlayerKey : match.homeTeamKey;
if (teamKey) {
const res = await checkFavorite("team", teamKey.toString());
setIsHomeFav(res.isFavorite); setIsHomeFav(res.isFavorite);
}
} catch (error) { } catch (error) {
console.error("Check home team favorite status error:", error); console.error("Check home team favorite status error:", error);
} }
}; };
if (match.homeTeamKey) { if (isTennis ? match.firstPlayerKey : match.homeTeamKey) {
loadHomeFav(); loadHomeFav();
} }
}, [match.homeTeamKey]); }, [match.homeTeamKey, match.firstPlayerKey, isTennis]);
// 检查客队收藏状态 // 检查客队/第二球员收藏状态
React.useEffect(() => { React.useEffect(() => {
const loadAwayFav = async () => { const loadAwayFav = async () => {
const token = await storage.getAccessToken(); const token = await storage.getAccessToken();
if (!token) return; if (!token) return;
try { try {
const res = await checkFavorite("team", match.awayTeamKey.toString()); const teamKey = isTennis ? match.secondPlayerKey : match.awayTeamKey;
if (teamKey) {
const res = await checkFavorite("team", teamKey.toString());
setIsAwayFav(res.isFavorite); setIsAwayFav(res.isFavorite);
}
} catch (error) { } catch (error) {
console.error("Check away team favorite status error:", error); console.error("Check away team favorite status error:", error);
} }
}; };
if (match.awayTeamKey) { if (isTennis ? match.secondPlayerKey : match.awayTeamKey) {
loadAwayFav(); loadAwayFav();
} }
}, [match.awayTeamKey]); }, [match.awayTeamKey, match.secondPlayerKey, isTennis]);
const toggleFavorite = async () => { const toggleFavorite = async () => {
if (favLoading) return; if (favLoading) return;
@@ -111,7 +119,7 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
const setFav = isHome ? setIsHomeFav : setIsAwayFav; const setFav = isHome ? setIsHomeFav : setIsAwayFav;
const loading = isHome ? homeFavLoading : awayFavLoading; const loading = isHome ? homeFavLoading : awayFavLoading;
if (loading) return; if (loading || !teamKey) return;
setLoading(true); setLoading(true);
const newFavState = !isTeamFav; const newFavState = !isTeamFav;
@@ -137,6 +145,36 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
} }
}; };
const getScoreDisplay = () => {
if (isTennis) {
const scores = (match.scores as any) || [];
if (scores.length > 0) {
const lastSet = scores[scores.length - 1];
return `${lastSet.score_first || "0"}-${lastSet.score_second || "0"}`;
}
return match.eventGameResult && match.eventGameResult !== "-"
? match.eventGameResult
: "0-0";
}
return match.eventFinalResult && match.eventFinalResult !== "-"
? match.eventFinalResult
: "0-0";
};
const firstPlayerName = isTennis ? match.eventFirstPlayer : match.eventHomeTeam;
const secondPlayerName = isTennis ? match.eventSecondPlayer : match.eventAwayTeam;
const firstPlayerLogo = isTennis ? match.eventFirstPlayerLogo : match.homeTeamLogo;
const secondPlayerLogo = isTennis ? match.eventSecondPlayerLogo : match.awayTeamLogo;
const firstPlayerKey = isTennis ? match.firstPlayerKey : match.homeTeamKey;
const secondPlayerKey = isTennis ? match.secondPlayerKey : match.awayTeamKey;
const hasFirstLogo = firstPlayerLogo && firstPlayerLogo.trim() !== "" && !firstPlayerLogo.includes("placehold");
const hasSecondLogo = secondPlayerLogo && secondPlayerLogo.trim() !== "" && !secondPlayerLogo.includes("placehold");
const firstGradient = getLogoGradient(firstPlayerName || "");
const secondGradient = getLogoGradient(secondPlayerName || "");
const firstInitials = getInitials(firstPlayerName || "");
const secondInitials = getInitials(secondPlayerName || "");
return ( return (
<LinearGradient <LinearGradient
colors={["#521e10", "#0e0e10"]} colors={["#521e10", "#0e0e10"]}
@@ -184,8 +222,12 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
<View style={styles.teamInfo}> <View style={styles.teamInfo}>
<View style={styles.teamLogoRow}> <View style={styles.teamLogoRow}>
<TouchableOpacity <TouchableOpacity
onPress={() => toggleTeamFavorite(match.homeTeamKey, true)} onPress={() => {
disabled={homeFavLoading} if (firstPlayerKey) {
toggleTeamFavorite(firstPlayerKey, true);
}
}}
disabled={homeFavLoading || !firstPlayerKey}
style={styles.starBtnLeft} style={styles.starBtnLeft}
> >
<IconSymbol <IconSymbol
@@ -195,41 +237,69 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
/> />
</TouchableOpacity> </TouchableOpacity>
<View style={styles.logoContainer}> <View style={styles.logoContainer}>
{hasFirstLogo ? (
<Image <Image
source={{ uri: match.homeTeamLogo }} source={{ uri: firstPlayerLogo }}
style={styles.teamLogo} style={styles.teamLogo}
/> />
) : (
<LinearGradient
colors={[firstGradient.color1, firstGradient.color2]}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={styles.teamLogoGradient}
>
<ThemedText style={styles.teamLogoText}>{firstInitials}</ThemedText>
</LinearGradient>
)}
</View> </View>
</View> </View>
<ThemedText style={styles.teamName} numberOfLines={2}> <ThemedText style={styles.teamName} numberOfLines={2}>
{match.eventHomeTeam} {firstPlayerName}
</ThemedText> </ThemedText>
</View> </View>
<View style={styles.centerScore}> <View style={styles.centerScore}>
<View style={styles.scoreBox}> <View style={styles.scoreBox}>
<ThemedText style={styles.scoreValue}> <ThemedText style={styles.scoreValue}>
{match.eventFinalResult && match.eventFinalResult !== "-" {getScoreDisplay()}
? match.eventFinalResult
: "0-0"}
</ThemedText> </ThemedText>
</View> </View>
<TouchableOpacity style={styles.fieldBtn}> <TouchableOpacity style={styles.fieldBtn}>
<IconSymbol name="football-outline" size={16} color="#FFF" /> <IconSymbol
name={isTennis ? "tennisball-outline" : "football-outline"}
size={16}
color="#FFF"
/>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<View style={styles.teamInfo}> <View style={styles.teamInfo}>
<View style={styles.teamLogoRow}> <View style={styles.teamLogoRow}>
<View style={styles.logoContainer}> <View style={styles.logoContainer}>
{hasSecondLogo ? (
<Image <Image
source={{ uri: match.awayTeamLogo }} source={{ uri: secondPlayerLogo }}
style={styles.teamLogo} style={styles.teamLogo}
/> />
) : (
<LinearGradient
colors={[secondGradient.color1, secondGradient.color2]}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={styles.teamLogoGradient}
>
<ThemedText style={styles.teamLogoText}>{secondInitials}</ThemedText>
</LinearGradient>
)}
</View> </View>
<TouchableOpacity <TouchableOpacity
onPress={() => toggleTeamFavorite(match.awayTeamKey, false)} onPress={() => {
disabled={awayFavLoading} if (secondPlayerKey) {
toggleTeamFavorite(secondPlayerKey, false);
}
}}
disabled={awayFavLoading || !secondPlayerKey}
style={styles.starBtnRight} style={styles.starBtnRight}
> >
<IconSymbol <IconSymbol
@@ -240,7 +310,7 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) {
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<ThemedText style={styles.teamName} numberOfLines={2}> <ThemedText style={styles.teamName} numberOfLines={2}>
{match.eventAwayTeam} {secondPlayerName}
</ThemedText> </ThemedText>
</View> </View>
</View> </View>
@@ -326,6 +396,19 @@ const styles = StyleSheet.create({
width: 60, width: 60,
height: 60, height: 60,
resizeMode: "contain", resizeMode: "contain",
borderRadius: 30,
},
teamLogoGradient: {
width: 60,
height: 60,
borderRadius: 30,
alignItems: "center",
justifyContent: "center",
},
teamLogoText: {
fontSize: 20,
fontWeight: "700",
color: "rgba(255, 255, 255, 0.92)",
}, },
teamName: { teamName: {
color: "#FFF", color: "#FFF",

View File

@@ -0,0 +1,205 @@
import { ThemedText } from "@/components/themed-text";
import { MatchDetailData } from "@/types/api";
import { Image } from "expo-image";
import React from "react";
import { useTranslation } from "react-i18next";
import { StyleSheet, View } from "react-native";
import { LinearGradient } from "expo-linear-gradient";
import { getInitials, getLogoGradient } from "@/lib/avatar-utils";
interface TennisScoreTableProps {
data: MatchDetailData;
isDark: boolean;
}
export function TennisScoreTable({ data, isDark }: TennisScoreTableProps) {
const { t } = useTranslation();
const { match } = data;
const bgColor = isDark ? "#1C1C1E" : "#FFF";
const borderColor = isDark ? "#2C2C2E" : "rgba(0,0,0,0.06)";
const headerTextColor = isDark ? "#666" : "#999";
const textColor = isDark ? "#FFF" : "#000";
const isTennis = match.sportId === 3;
const scores = (match.scores as any) || [];
const firstPlayer = match.eventFirstPlayer || "";
const secondPlayer = match.eventSecondPlayer || "";
const firstPlayerLogo = match.eventFirstPlayerLogo || "";
const secondPlayerLogo = match.eventSecondPlayerLogo || "";
const hasFirstLogo = firstPlayerLogo && firstPlayerLogo.trim() !== "" && !firstPlayerLogo.includes("placehold");
const hasSecondLogo = secondPlayerLogo && secondPlayerLogo.trim() !== "" && !secondPlayerLogo.includes("placehold");
const firstGradient = getLogoGradient(firstPlayer);
const secondGradient = getLogoGradient(secondPlayer);
const firstInitials = getInitials(firstPlayer);
const secondInitials = getInitials(secondPlayer);
const headers = [t("detail.score_table.set") || "Set"];
scores.forEach((_, index) => {
headers.push(`${index + 1}`);
});
if (scores.length === 0) {
headers.push("1");
}
return (
<View style={[styles.container, { backgroundColor: bgColor, borderColor }]}>
<View style={[styles.header, { borderBottomColor: borderColor }]}>
<View style={styles.headerLeft}>
<ThemedText style={[styles.headerText, { color: headerTextColor }]}>
{t("detail.score_table.player") || "Player"}
</ThemedText>
</View>
{headers.slice(1).map((header, index) => (
<View key={index} style={styles.headerCell}>
<ThemedText style={[styles.headerText, { color: headerTextColor }]}>
{header}
</ThemedText>
</View>
))}
</View>
<View style={[styles.row, { borderBottomColor: borderColor }]}>
<View style={styles.playerCell}>
{hasFirstLogo ? (
<Image source={{ uri: firstPlayerLogo }} style={styles.playerLogo} />
) : (
<LinearGradient
colors={[firstGradient.color1, firstGradient.color2]}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={styles.playerLogoGradient}
>
<ThemedText style={styles.playerLogoText}>{firstInitials}</ThemedText>
</LinearGradient>
)}
<ThemedText style={[styles.playerName, { color: textColor }]} numberOfLines={1}>
{firstPlayer}
</ThemedText>
</View>
{scores.length > 0 ? (
scores.map((score: any, index: number) => (
<View key={index} style={styles.scoreCell}>
<ThemedText style={[styles.scoreText, { color: textColor }]}>
{score.score_first || "0"}
</ThemedText>
</View>
))
) : (
<View style={styles.scoreCell}>
<ThemedText style={[styles.scoreText, { color: textColor }]}>0</ThemedText>
</View>
)}
</View>
<View style={styles.row}>
<View style={styles.playerCell}>
{hasSecondLogo ? (
<Image source={{ uri: secondPlayerLogo }} style={styles.playerLogo} />
) : (
<LinearGradient
colors={[secondGradient.color1, secondGradient.color2]}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={styles.playerLogoGradient}
>
<ThemedText style={styles.playerLogoText}>{secondInitials}</ThemedText>
</LinearGradient>
)}
<ThemedText style={[styles.playerName, { color: textColor }]} numberOfLines={1}>
{secondPlayer}
</ThemedText>
</View>
{scores.length > 0 ? (
scores.map((score: any, index: number) => (
<View key={index} style={styles.scoreCell}>
<ThemedText style={[styles.scoreText, { color: textColor }]}>
{score.score_second || "0"}
</ThemedText>
</View>
))
) : (
<View style={styles.scoreCell}>
<ThemedText style={[styles.scoreText, { color: textColor }]}>0</ThemedText>
</View>
)}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
marginHorizontal: 16,
marginTop: 12,
borderRadius: 16,
borderWidth: 1,
overflow: "hidden",
},
header: {
flexDirection: "row",
borderBottomWidth: 1,
paddingVertical: 12,
paddingHorizontal: 12,
},
headerLeft: {
flex: 1,
minWidth: 120,
},
headerCell: {
flex: 1,
alignItems: "center",
justifyContent: "center",
minWidth: 40,
},
headerText: {
fontSize: 12,
fontWeight: "600",
},
row: {
flexDirection: "row",
borderBottomWidth: 1,
paddingVertical: 12,
paddingHorizontal: 12,
alignItems: "center",
},
playerCell: {
flex: 1,
flexDirection: "row",
alignItems: "center",
minWidth: 120,
gap: 8,
},
playerLogo: {
width: 32,
height: 32,
borderRadius: 16,
},
playerLogoGradient: {
width: 32,
height: 32,
borderRadius: 16,
alignItems: "center",
justifyContent: "center",
},
playerLogoText: {
fontSize: 10,
fontWeight: "700",
color: "rgba(255, 255, 255, 0.92)",
},
playerName: {
flex: 1,
fontSize: 13,
fontWeight: "600",
},
scoreCell: {
flex: 1,
alignItems: "center",
justifyContent: "center",
minWidth: 40,
},
scoreText: {
fontSize: 15,
fontWeight: "700",
},
});

View File

@@ -115,7 +115,8 @@
"halftime": "Half Time", "halftime": "Half Time",
"full_time": "90'", "full_time": "90'",
"extra_time": "ET", "extra_time": "ET",
"penalty": "Pen" "penalty": "Pen",
"player": "Player"
}, },
"halftime": "Half: {{score}}", "halftime": "Half: {{score}}",
"empty_stats": "No statistics data", "empty_stats": "No statistics data",

View File

@@ -111,7 +111,8 @@
"halftime": "हाफ टाइम", "halftime": "हाफ टाइम",
"full_time": "90'", "full_time": "90'",
"extra_time": "अतिरिक्त समय", "extra_time": "अतिरिक्त समय",
"penalty": "पेनल्टी" "penalty": "पेनल्टी",
"player": "खिलाड़ी"
}, },
"halftime": "हाफ टाइम: {{score}}", "halftime": "हाफ टाइम: {{score}}",
"empty_stats": "कोई आँकड़े उपलब्ध नहीं", "empty_stats": "कोई आँकड़े उपलब्ध नहीं",

View File

@@ -111,7 +111,8 @@
"halftime": "Babak Pertama", "halftime": "Babak Pertama",
"full_time": "90'", "full_time": "90'",
"extra_time": "Perpanjangan", "extra_time": "Perpanjangan",
"penalty": "Adu Penalti" "penalty": "Adu Penalti",
"player": "Pemain"
}, },
"halftime": "Babak Pertama: {{score}}", "halftime": "Babak Pertama: {{score}}",
"empty_stats": "Tidak ada data statistik", "empty_stats": "Tidak ada data statistik",

View File

@@ -111,7 +111,8 @@
"halftime": "Separuh Masa", "halftime": "Separuh Masa",
"full_time": "90'", "full_time": "90'",
"extra_time": "Masa Tambahan", "extra_time": "Masa Tambahan",
"penalty": "Sepakan Penalti" "penalty": "Sepakan Penalti",
"player": "Pemain"
}, },
"halftime": "Separuh masa: {{score}}", "halftime": "Separuh masa: {{score}}",
"empty_stats": "Tiada data statistik", "empty_stats": "Tiada data statistik",

View File

@@ -111,7 +111,8 @@
"halftime": "ครึ่งแรก", "halftime": "ครึ่งแรก",
"full_time": "90'", "full_time": "90'",
"extra_time": "ต่อเวลา", "extra_time": "ต่อเวลา",
"penalty": "จุดโทษ" "penalty": "จุดโทษ",
"player": "ผู้เล่น"
}, },
"halftime": "ครึ่งแรก: {{score}}", "halftime": "ครึ่งแรก: {{score}}",
"empty_stats": "ไม่มีข้อมูลสถิติ", "empty_stats": "ไม่มีข้อมูลสถิติ",

View File

@@ -111,7 +111,8 @@
"halftime": "Hiệp 1", "halftime": "Hiệp 1",
"full_time": "90'", "full_time": "90'",
"extra_time": "Hiệp phụ", "extra_time": "Hiệp phụ",
"penalty": "Luân lưu" "penalty": "Luân lưu",
"player": "Cầu thủ"
}, },
"halftime": "Hiệp 1: {{score}}", "halftime": "Hiệp 1: {{score}}",
"empty_stats": "Không có dữ liệu thống kê", "empty_stats": "Không có dữ liệu thống kê",

View File

@@ -115,7 +115,8 @@
"halftime": "半场", "halftime": "半场",
"full_time": "90分钟", "full_time": "90分钟",
"extra_time": "加时", "extra_time": "加时",
"penalty": "点球" "penalty": "点球",
"player": "球员"
}, },
"halftime": "半场: {{score}}", "halftime": "半场: {{score}}",
"empty_stats": "暂无统计数据", "empty_stats": "暂无统计数据",

72
temp.json Normal file
View File

@@ -0,0 +1,72 @@
{
"code": 0,
"message": "ok",
"data": {
"match": {
"ID": 250468,
"CreatedAt": "2026-01-21T05:45:15.704+08:00",
"UpdatedAt": "2026-01-21T05:45:15.704+08:00",
"DeletedAt": null,
"eventKey": "12097737",
"eventDate": "2026-01-22",
"eventTime": "03:00",
"eventHomeTeam": "",
"homeTeamKey": "",
"homeTeamLogo": "",
"eventAwayTeam": "",
"awayTeamKey": "",
"awayTeamLogo": "",
"eventHalftimeResult": "",
"eventFinalResult": "-",
"eventFtResult": "",
"eventPenaltyResult": "",
"eventStatus": "1",
"countryName": "Challenger Men Singles",
"leagueName": "Phan Thiet",
"leagueKey": "13614",
"leagueRound": "Phan Thiet - 1/8-finals",
"leagueSeason": "2026",
"eventLive": "0",
"eventStadium": "",
"eventReferee": "",
"eventCountryKey": "281",
"leagueLogo": "",
"countryLogo": "",
"eventHomeFormation": "",
"eventAwayFormation": "",
"fkStageKey": "",
"stageName": "",
"leagueGroup": "",
"sportId": 3,
"eventQuarter": "",
"eventSet": "",
"eventType": "",
"eventToss": "",
"eventManOfMatch": "",
"eventFirstPlayer": "O. Jasika",
"firstPlayerKey": "1261",
"eventSecondPlayer": "I. Simakin",
"secondPlayerKey": "1238",
"eventFirstPlayerLogo": "https://apiv2.allsportsapi.com/logo-tennis/1261_o-jasika.jpg",
"eventSecondPlayerLogo": "https://apiv2.allsportsapi.com/logo-tennis/1238_i-simakin.jpg",
"eventGameResult": "-",
"eventServe": "",
"eventWinner": "",
"events": null,
"players": null,
"scores": [
{
"score_set": "1",
"score_first": "0",
"score_second": "0"
}
],
"stats": null,
"pointByPoint": null,
"scorecard": null,
"comments": null,
"wickets": null,
"extra": null
}
}
}

View File

@@ -305,6 +305,14 @@ export interface MatchDetailData {
eventType: string; eventType: string;
eventToss: string; eventToss: string;
eventManOfMatch: string; eventManOfMatch: string;
eventFirstPlayer?: string;
eventSecondPlayer?: string;
eventFirstPlayerLogo?: string;
eventSecondPlayerLogo?: string;
firstPlayerKey?: string;
secondPlayerKey?: string;
eventGameResult?: string;
scores?: any[];
events?: MatchEvents; events?: MatchEvents;
players?: { players?: {
home_team?: Player[]; home_team?: Player[];