优化比赛卡片组件,增加比分领先状态和额外统计信息的显示逻辑

This commit is contained in:
yuchenglong
2026-01-21 09:26:47 +08:00
parent 0c57af1ca8
commit 547c204e88

View File

@@ -123,12 +123,42 @@ export function MatchCard({
const scoreParts = React.useMemo(() => {
const s = (match.scoreText || "").trim();
const m = s.match(/(\d+)\s*[-:]\s*(\d+)/);
if (m) return { home: m[1], away: m[2], hasScore: true };
if (s && s !== "-" && s !== "0 - 0")
return { home: s, away: "", hasScore: true };
if (s === "0 - 0" || s === "0-0")
return { home: "0", away: "0", hasScore: true };
return { home: "", away: "", hasScore: false };
if (m) {
const h = parseInt(m[1]);
const a = parseInt(m[2]);
return {
home: m[1],
away: m[2],
hasScore: true,
homeLead: h > a,
awayLead: a > h,
};
}
if (s && s !== "-" && s !== "0 - 0") {
return {
home: s,
away: "",
hasScore: true,
homeLead: false,
awayLead: false,
};
}
if (s === "0 - 0" || s === "0-0") {
return {
home: "0",
away: "0",
hasScore: true,
homeLead: false,
awayLead: false,
};
}
return {
home: "",
away: "",
hasScore: false,
homeLead: false,
awayLead: false,
};
}, [match.scoreText]);
const cardsCount = React.useMemo(() => {
@@ -242,17 +272,19 @@ export function MatchCard({
};
const renderOddsRow = (bookmakerName: string, isHighlight: boolean) => {
if (!oddsSettings.enabled || !bookmakerName || odds.length === 0)
return null;
const item = odds.find((o) => o.odd_bookmakers === bookmakerName);
if (!item) return null;
if (!oddsSettings.enabled || !bookmakerName) return null;
const val1 = item.odd_1 || item.ah0_1 || "-";
const val2 = item.odd_x || "0" || "-";
const val3 = item.odd_2 || item.ah0_2 || "-";
const item = odds.find((o) => o.odd_bookmakers === bookmakerName);
const hasOdds = !!item;
const val1 = item?.odd_1 || item?.ah0_1 || "-";
const val2 = item?.odd_x || "0" || "-";
const val3 = item?.odd_2 || item?.ah0_2 || "-";
return (
<View style={styles.bookmakerOddsRow}>
{hasOdds ? (
<>
<View style={[styles.oddBadge, { backgroundColor: oddBadgeBg }]}>
<ThemedText
style={[
@@ -286,6 +318,10 @@ export function MatchCard({
{val3}
</ThemedText>
</View>
</>
) : (
<View style={{ width: 98 }} />
)}
</View>
);
};
@@ -395,31 +431,63 @@ export function MatchCard({
</View>
</View>
{/* Right: Score box + favorite */}
{/* Right: Score box + extra stats + favorite */}
<View style={styles.right}>
<View style={styles.scoreContainer}>
{scoreParts.hasScore ? (
<View
style={[
styles.scoreBox,
{
borderColor: isLive ? "#FF9500" : scoreBorder,
borderColor:
scoreParts.homeLead || scoreParts.awayLead
? "#FF9500"
: scoreBorder,
backgroundColor: scoreBg,
},
]}
>
<ThemedText style={styles.scoreBoxText} numberOfLines={1}>
<View
style={[
styles.scoreHalf,
scoreParts.homeLead && styles.scoreHalfLead,
]}
>
<ThemedText
style={[
styles.scoreBoxText,
scoreParts.homeLead && styles.scoreTextLead,
]}
numberOfLines={1}
>
{scoreParts.home}
</ThemedText>
</View>
<View style={styles.scoreDivider} />
<ThemedText style={styles.scoreBoxText} numberOfLines={1}>
<View
style={[
styles.scoreHalf,
scoreParts.awayLead && styles.scoreHalfLead,
]}
>
<ThemedText
style={[
styles.scoreBoxText,
scoreParts.awayLead && styles.scoreTextLead,
]}
numberOfLines={1}
>
{scoreParts.away}
</ThemedText>
</View>
</View>
) : (
<View style={styles.scoreBoxPlaceholder} />
)}
</View>
{(extraStats.home !== "" || extraStats.away !== "") && (
<View style={styles.extraStatsContainer}>
{extraStats.home !== "" || extraStats.away !== "" ? (
<View style={styles.extraStatsColumn}>
<ThemedText style={styles.extraStatText}>
{extraStats.home}
@@ -428,8 +496,10 @@ export function MatchCard({
{extraStats.away}
</ThemedText>
</View>
)}
) : null}
</View>
<View style={styles.favoriteContainer}>
<TouchableOpacity
onPress={(e) => {
e.stopPropagation();
@@ -446,6 +516,7 @@ export function MatchCard({
</TouchableOpacity>
</View>
</View>
</View>
</Pressable>
);
}
@@ -505,6 +576,7 @@ const styles = StyleSheet.create({
alignItems: "center",
flex: 1,
minWidth: 0,
marginRight: 8,
},
teamLogo: {
width: 18,
@@ -514,13 +586,14 @@ const styles = StyleSheet.create({
fontSize: 12,
fontWeight: "600",
marginLeft: 6,
flex: 1,
flexShrink: 1,
minWidth: 0,
},
bookmakerOddsRow: {
marginLeft: 4,
width: 98,
flexDirection: "row",
gap: 4,
justifyContent: "flex-end",
},
oddBadge: {
paddingHorizontal: 5,
@@ -540,35 +613,58 @@ const styles = StyleSheet.create({
right: {
flexDirection: "row",
alignItems: "center",
gap: 6,
},
scoreContainer: {
width: 25,
alignItems: "center",
},
extraStatsContainer: {
width: 18,
alignItems: "center",
marginHorizontal: 4,
},
favoriteContainer: {
width: 25,
alignItems: "center",
},
scoreBox: {
width: 30,
height: 54,
width: 28,
height: 55,
borderRadius: 8,
borderWidth: 1.5,
borderWidth: 1.2,
alignItems: "stretch",
justifyContent: "center",
overflow: "hidden",
},
scoreHalf: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
scoreHalfLead: {
backgroundColor: "rgba(255, 149, 0, 0.08)",
},
scoreBoxText: {
fontSize: 20,
fontSize: 15,
fontWeight: "900",
},
scoreTextLead: {
color: "#FF9500",
},
scoreDivider: {
width: "60%",
width: "100%",
height: 1,
backgroundColor: "rgba(0,0,0,0.06)",
marginVertical: 1,
},
scoreBoxPlaceholder: {
width: 36,
height: 54,
width: 28,
height: 48,
},
cardsInline: {
flexDirection: "row",
alignItems: "center",
gap: 4,
marginLeft: 6,
gap: 6,
marginLeft: 8,
flexShrink: 0,
},
cardBadge: {
@@ -577,7 +673,7 @@ const styles = StyleSheet.create({
borderRadius: 3,
alignItems: "center",
justifyContent: "center",
paddingHorizontal: 3,
paddingHorizontal: 4,
},
cardBadgeYellow: {
backgroundColor: "#FFC400",
@@ -588,13 +684,13 @@ const styles = StyleSheet.create({
extraStatsColumn: {
alignItems: "center",
justifyContent: "space-between",
height: 48,
height: 55,
paddingVertical: 2,
},
extraStatText: {
fontSize: 12,
fontSize: 11,
fontWeight: "500",
opacity: 0.6,
opacity: 0.4,
},
cardBadgeText: {
fontSize: 10,