添加网球相关数据映射和逻辑到 MatchCard 组件,优化比赛信息展示
This commit is contained in:
@@ -106,6 +106,36 @@ export function MatchCard({
|
||||
return !!match.isLive;
|
||||
}, [match.isLive]);
|
||||
|
||||
// Tennis logic
|
||||
const isTennis = match.sportId === 3 || match.sport === "tennis";
|
||||
const homeName = isTennis
|
||||
? liveDetail?.event_first_player || match.eventFirstPlayer
|
||||
: liveDetail?.event_home_team || match.homeTeamName || match.home;
|
||||
const awayName = isTennis
|
||||
? liveDetail?.event_second_player || match.eventSecondPlayer
|
||||
: liveDetail?.event_away_team || match.awayTeamName || match.away;
|
||||
const homeLogo = isTennis
|
||||
? liveDetail?.event_first_player_logo || match.eventFirstPlayerLogo
|
||||
: liveDetail?.home_team_logo || match.homeTeamLogo;
|
||||
const awayLogo = isTennis
|
||||
? liveDetail?.event_second_player_logo || match.eventSecondPlayerLogo
|
||||
: liveDetail?.away_team_logo || match.awayTeamLogo;
|
||||
|
||||
const tennisScores = React.useMemo(() => {
|
||||
// 优先使用 liveDetail 中的 scores
|
||||
if (isTennis && liveDetail?.scores && Array.isArray(liveDetail.scores)) {
|
||||
return liveDetail.scores;
|
||||
}
|
||||
|
||||
if (!isTennis || !match.scores) return [];
|
||||
try {
|
||||
const parsed = JSON.parse(match.scores);
|
||||
return Array.isArray(parsed) ? parsed : [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}, [match.scores, isTennis, liveDetail]);
|
||||
|
||||
const timeLabel = React.useMemo(() => {
|
||||
const raw = (match.time || "").trim();
|
||||
if (!raw) return "";
|
||||
@@ -121,7 +151,31 @@ export function MatchCard({
|
||||
}, [match.leagueName, match.league]);
|
||||
|
||||
const scoreParts = React.useMemo(() => {
|
||||
if (isTennis) {
|
||||
if (tennisScores.length > 0) {
|
||||
const last = tennisScores[tennisScores.length - 1];
|
||||
const h = parseInt(last.score_first || "0");
|
||||
const a = parseInt(last.score_second || "0");
|
||||
return {
|
||||
home: last.score_first || "0",
|
||||
away: last.score_second || "0",
|
||||
hasScore: true,
|
||||
homeLead: h > a,
|
||||
awayLead: a > h,
|
||||
};
|
||||
}
|
||||
// 如果没有分数(如未开始),显示 0-0 或 -
|
||||
return {
|
||||
home: "0",
|
||||
away: "0",
|
||||
hasScore: true, // 保持 ScoreBox 显示,以便显示 0-0
|
||||
homeLead: false,
|
||||
awayLead: false,
|
||||
};
|
||||
}
|
||||
|
||||
const s = (match.scoreText || "").trim();
|
||||
|
||||
const m = s.match(/(\d+)\s*[-:]\s*(\d+)/);
|
||||
if (m) {
|
||||
const h = parseInt(m[1]);
|
||||
@@ -271,7 +325,33 @@ export function MatchCard({
|
||||
}
|
||||
};
|
||||
|
||||
const renderTennisSetScores = (isHome: boolean) => {
|
||||
// 显示除最后一盘之外的盘分 (当前盘分在右侧大框显示)
|
||||
// 如果只有一盘,则这里不显示任何内容
|
||||
if (tennisScores.length <= 1) return null;
|
||||
|
||||
const prevSets = tennisScores.slice(0, tennisScores.length - 1);
|
||||
|
||||
return (
|
||||
<View style={styles.tennisScoresRow}>
|
||||
{prevSets.map((s: any, i: number) => (
|
||||
<ThemedText
|
||||
key={i}
|
||||
style={[
|
||||
styles.tennisScoreText,
|
||||
{ color: isDark ? "#CCC" : "#666" },
|
||||
]}
|
||||
>
|
||||
{isHome ? s.score_first : s.score_second}
|
||||
</ThemedText>
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const renderOddsRow = (bookmakerName: string, isHighlight: boolean) => {
|
||||
if (isTennis) return renderTennisSetScores(isHighlight); // Reuse isHighlight param as 'isHome' (true for first player logic)
|
||||
|
||||
if (!oddsSettings.enabled || !bookmakerName) return null;
|
||||
|
||||
const item = odds.find((o) => o.odd_bookmakers === bookmakerName);
|
||||
@@ -386,7 +466,7 @@ export function MatchCard({
|
||||
<View style={styles.teamLogoPlaceholder}>
|
||||
<Image
|
||||
source={{
|
||||
uri: match.homeTeamLogo,
|
||||
uri: homeLogo,
|
||||
}}
|
||||
style={styles.teamLogo}
|
||||
contentFit="contain"
|
||||
@@ -398,9 +478,10 @@ export function MatchCard({
|
||||
numberOfLines={1}
|
||||
ellipsizeMode="tail"
|
||||
>
|
||||
{match.homeTeamName || match.home}
|
||||
{homeName}
|
||||
</ThemedText>
|
||||
{renderCardsInline(cardsCount.homeYellow, cardsCount.homeRed)}
|
||||
{!isTennis &&
|
||||
renderCardsInline(cardsCount.homeYellow, cardsCount.homeRed)}
|
||||
</View>
|
||||
{renderOddsRow(oddsSettings.selectedBookmakers[0], true)}
|
||||
</View>
|
||||
@@ -410,7 +491,7 @@ export function MatchCard({
|
||||
<View style={styles.teamLogoPlaceholder}>
|
||||
<Image
|
||||
source={{
|
||||
uri: match.awayTeamLogo,
|
||||
uri: awayLogo,
|
||||
}}
|
||||
style={styles.teamLogo}
|
||||
contentFit="contain"
|
||||
@@ -422,9 +503,10 @@ export function MatchCard({
|
||||
numberOfLines={1}
|
||||
ellipsizeMode="tail"
|
||||
>
|
||||
{match.awayTeamName || match.away}
|
||||
{awayName}
|
||||
</ThemedText>
|
||||
{renderCardsInline(cardsCount.awayYellow, cardsCount.awayRed)}
|
||||
{!isTennis &&
|
||||
renderCardsInline(cardsCount.awayYellow, cardsCount.awayRed)}
|
||||
</View>
|
||||
{renderOddsRow(oddsSettings.selectedBookmakers[1], false)}
|
||||
</View>
|
||||
@@ -710,4 +792,16 @@ const styles = StyleSheet.create({
|
||||
cardBadgeTextDark: {
|
||||
color: "#000",
|
||||
},
|
||||
tennisScoresRow: {
|
||||
flexDirection: "row",
|
||||
gap: 12,
|
||||
marginRight: 4,
|
||||
alignItems: "center",
|
||||
},
|
||||
tennisScoreText: {
|
||||
fontSize: 14,
|
||||
fontWeight: "500",
|
||||
minWidth: 14,
|
||||
textAlign: "center",
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user