添加赔率行渲染功能,优化比赛卡片中赔率显示逻辑和样式

This commit is contained in:
yuchenglong
2026-01-20 09:15:37 +08:00
parent 7024b03c30
commit 85c9b666d7

View File

@@ -142,6 +142,55 @@ 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;
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}>
<View style={[styles.oddBadge, { backgroundColor: oddBadgeBg }]}>
<ThemedText
style={[
styles.oddText,
{ color: isDark ? "#fff" : "#333" },
isHighlight && styles.oddTextHighlight,
]}
>
{val1}
</ThemedText>
</View>
<View style={[styles.oddBadge, { backgroundColor: oddBadgeBg }]}>
<ThemedText
style={[
styles.oddText,
{ color: isDark ? "#fff" : "#333" },
isHighlight && styles.oddTextHighlight,
]}
>
{val2}
</ThemedText>
</View>
<View style={[styles.oddBadge, { backgroundColor: oddBadgeBg }]}>
<ThemedText
style={[
styles.oddText,
{ color: isDark ? "#fff" : "#333" },
isHighlight && styles.oddTextHighlight,
]}
>
{val3}
</ThemedText>
</View>
</View>
);
};
return (
<Pressable
onPress={handlePress}
@@ -176,103 +225,49 @@ export function MatchCard({
</ThemedText>
</View>
{/* Middle: Teams & Odds */}
{/* Middle: Teams & Odds Row Integration */}
<View style={styles.middle}>
<View style={styles.teamContainer}>
<View style={styles.teamRow}>
{match.homeTeamLogo ? (
<View style={styles.contentRow}>
<View style={styles.teamInfo}>
{match.homeTeamLogo && (
<Image
source={{ uri: match.homeTeamLogo }}
style={styles.teamLogo}
contentFit="contain"
/>
) : null}
)}
<ThemedText
type="defaultSemiBold"
style={styles.teamLine}
style={styles.teamName}
numberOfLines={1}
ellipsizeMode="tail"
>
{match.homeTeamName || match.home}
</ThemedText>
</View>
<View style={styles.teamRow}>
{match.awayTeamLogo ? (
{renderOddsRow(oddsSettings.selectedBookmakers[0], true)}
</View>
<View style={styles.contentRow}>
<View style={styles.teamInfo}>
{match.awayTeamLogo && (
<Image
source={{ uri: match.awayTeamLogo }}
style={styles.teamLogo}
contentFit="contain"
/>
) : null}
)}
<ThemedText
type="defaultSemiBold"
style={styles.teamLine}
style={styles.teamName}
numberOfLines={1}
ellipsizeMode="tail"
>
{match.awayTeamName || match.away}
</ThemedText>
</View>
{renderOddsRow(oddsSettings.selectedBookmakers[1], false)}
</View>
{/* Odds Section */}
{oddsSettings.enabled && odds.length > 0 && (
<View style={styles.oddsContainer}>
{oddsSettings.selectedBookmakers.map((bookmaker, idx) => {
const item = odds.find((o) => o.odd_bookmakers === bookmaker);
if (!item) return null;
// Pick 3 values to display. Using odd_1, odd_x, odd_2 for example.
// Or try to match the screenshot's 3-column style.
const val1 = item.odd_1 || item.ah0_1 || "-";
const val2 = item.odd_x || "0" || "-";
const val3 = item.odd_2 || item.ah0_2 || "-";
return (
<View key={bookmaker} style={styles.bookmakerOddsRow}>
<View
style={[styles.oddBadge, { backgroundColor: oddBadgeBg }]}
>
<ThemedText
style={[
styles.oddText,
{ color: isDark ? "#fff" : "#000" },
idx === 0 && styles.oddTextHighlight,
]}
>
{val1}
</ThemedText>
</View>
<View
style={[styles.oddBadge, { backgroundColor: oddBadgeBg }]}
>
<ThemedText
style={[
styles.oddText,
{ color: isDark ? "#fff" : "#000" },
idx === 0 && styles.oddTextHighlight,
]}
>
{val2}
</ThemedText>
</View>
<View
style={[styles.oddBadge, { backgroundColor: oddBadgeBg }]}
>
<ThemedText
style={[
styles.oddText,
{ color: isDark ? "#fff" : "#000" },
idx === 0 && styles.oddTextHighlight,
]}
>
{val3}
</ThemedText>
</View>
</View>
);
})}
</View>
)}
</View>
{/* Right: Score box + favorite */}
@@ -281,12 +276,16 @@ export function MatchCard({
<View
style={[
styles.scoreBox,
{ borderColor: scoreBorder, backgroundColor: scoreBg },
{
borderColor: isLive ? "#FF9500" : scoreBorder,
backgroundColor: scoreBg,
},
]}
>
<ThemedText style={styles.scoreBoxText} numberOfLines={1}>
{scoreParts.home}
</ThemedText>
<View style={styles.scoreDivider} />
<ThemedText style={styles.scoreBoxText} numberOfLines={1}>
{scoreParts.away}
</ThemedText>
@@ -305,7 +304,7 @@ export function MatchCard({
>
<IconSymbol
name={isFav ? "star" : "star-outline"}
size={22}
size={20}
color={isFav ? "#FFD700" : iconColor}
/>
</TouchableOpacity>
@@ -318,121 +317,114 @@ export function MatchCard({
const styles = StyleSheet.create({
card: {
height: 78,
paddingHorizontal: 14,
marginBottom: 12,
paddingHorizontal: 12,
marginBottom: 8,
borderRadius: 14,
borderWidth: 1,
justifyContent: "center",
overflow: "hidden",
// iOS shadow
shadowColor: "#000",
shadowOffset: { width: 0, height: 0.5 },
shadowOpacity: 0.03,
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.05,
shadowRadius: 2,
// Android elevation
elevation: 1,
elevation: 2,
},
row: {
flexDirection: "row",
alignItems: "center",
gap: 12,
},
left: {
width: 52,
alignItems: "center",
width: 44,
alignItems: "flex-start",
justifyContent: "center",
gap: 6,
gap: 4,
},
leagueShortText: {
fontSize: 12,
fontWeight: "700",
opacity: 0.85,
opacity: 0.8,
},
timeText: {
fontSize: 12,
opacity: 0.55,
opacity: 0.5,
},
timeTextLive: {
color: "#FF3B30",
opacity: 1,
fontWeight: "bold",
fontWeight: "800",
},
middle: {
flex: 1,
justifyContent: "center",
gap: 10,
marginHorizontal: 8,
},
contentRow: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
gap: 8,
minWidth: 0,
},
teamContainer: {
flex: 1,
justifyContent: "center",
gap: 8,
minWidth: 0,
},
teamRow: {
teamInfo: {
flexDirection: "row",
alignItems: "center",
gap: 8,
flex: 1,
marginRight: 6,
},
teamLogo: {
width: 24,
height: 24,
width: 22,
height: 22,
},
teamLine: {
fontSize: 15,
lineHeight: 18,
teamName: {
fontSize: 14,
fontWeight: "600",
marginLeft: 6,
flex: 1,
},
oddsContainer: {
gap: 8,
alignItems: "flex-end",
},
bookmakerOddsRow: {
flexDirection: "row",
gap: 4,
},
oddBadge: {
backgroundColor: "rgba(0,0,0,0.03)",
paddingHorizontal: 6,
paddingHorizontal: 5,
paddingVertical: 2,
borderRadius: 6,
minWidth: 40,
minWidth: 36,
alignItems: "center",
justifyContent: "center",
},
oddText: {
fontSize: 11,
fontWeight: "600",
opacity: 0.8,
fontSize: 10.5,
fontWeight: "700",
opacity: 0.9,
},
oddTextHighlight: {
color: "#FF9500",
opacity: 1,
},
right: {
flexDirection: "row",
alignItems: "center",
gap: 10,
},
scoreBox: {
width: 44,
height: 56,
borderRadius: 10,
borderWidth: 1,
borderColor: "rgba(0,0,0,0.12)",
backgroundColor: "rgba(255,255,255,0.6)",
alignItems: "center",
justifyContent: "center",
gap: 6,
},
scoreBox: {
width: 36,
height: 54,
borderRadius: 8,
borderWidth: 1.5,
alignItems: "center",
justifyContent: "center",
},
scoreBoxText: {
fontSize: 16,
fontWeight: "700",
opacity: 0.9,
fontSize: 20,
fontWeight: "900",
},
scoreDivider: {
width: "60%",
height: 1,
backgroundColor: "rgba(0,0,0,0.06)",
marginVertical: 1,
},
scoreBoxPlaceholder: {
width: 44,
height: 56,
width: 36,
height: 54,
},
});