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

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